The Difference Between Service Classes and Traits in PHP
Tags: php, laravel
Published: 2022-03-28 22:35:03

---
title: The Difference Between Service Classes and Traits in PHP
published: true
description: Overview of the difference between service classes and traits in PHP with examples
tags: #php, #laravel
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzjji6xmbh9na5xkialw.jpeg
canonical_url: https://blog.savetchuk.com/the-difference-between-service-classes-and-traits-in-php
---

The main difference between service classes and traits is that **service classes provide a complete implementation of a specific service** or functionality, whereas **traits provide a set of methods that can be mixed into multiple classes** to provide them with additional functionality.

Both service classes and traits can be reused throughout an application and service classes can utilize traits.

## Service Classes​

We can think of a service class like a PHP object that performs some sort of a "global" task. Service classes are often used to encapsulate complex business logic or to provide a unified interface to interact with external services, such as databases or web services.

For example, there may be a **mailing service** or a **user creation** service. These are tasks that need to be repeated over and over again in different places. This makes them good candidates for a service class.

Some ideas for service classes:

* Service class responsible for sending SMS via Twilio.
    
* Service class responsible for sending Emails via Mailgun (Newsletter Service).
    
* Service class responsible for working with UptimeRobot APIs.
    
* Service class responsible for storing and deleting images on the cloud.
    

### Example of a Service Class in Laravel​

Here is an example of the `App\Services\UptimeRobotAPI.php` service class that is responsible for connecting to the UptimeRobot API and retrieving data:

```php
<?php

namespace App\Services;

use GuzzleHttp\Client;

class UptimeRobotAPI
{
  protected string $url;
  protected string $http;
  protected array $headers;

  public function __construct(Client $client)
  {
    $this->url = 'https://api.uptimerobot.com/v2/';
    $this->http = $client;
    $this->headers = [
      'cache-control' => 'no-cache',
      'content-type'  => 'application/x-www-form-urlencoded',
    ];
  }

  private function getResponse(string $path)
  {
    // Making a GET request to UptimeRobot API using GuzzleHttp...
  }

  private function postResponse(string $path, array $params = [])
  {
    // Making a POST request to UptimeRobot API using GuzzleHttp...
  }

  public function getMonitors()
  {
    return $this->getResponse('getMonitors');
  }
}
```

The UptimeRobotAPI service is now can be used like so:

```php
<?php

namespace App\Http\Controllers;

use App\Services\UptimeRobotAPI;

class MonitorsController extends Controller
{
  public function index(UptimeRobotAPI $uptimeRobotAPI)
  {
    $monitors = $uptimeRobotAPI->getMonitors();

    return view('monitors.index', compact('monitors'));
  }
}
```

### More Service Class Examples

Another example of a service class would be a `PaymentService` or `StripeService` - a service class that encapsulates payment-related functionality, such as processing payments, managing payment methods, and handling refunds.

---

## Traits

In PHP, a class can only inherit from a single parent class, which can limit the ability to reuse code. Traits were introduced to solve this problem by providing a way to reuse code across multiple classes without using inheritance. They allow developers to define a set of methods that can be shared among multiple classes, allowing for more flexible and modular code. Traits are particularly useful when building complex applications that require a lot of code reuse.

### Example of a Trait in Laravel

Here is an example of the `app/Traits/ApiResponder.php` trait I often use when developing Laravel applications:

```php
<?php

namespace App\Traits;

use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpFoundation\Response;

trait ApiResponder
{
  public function successResponse($data, int $code = Response::HTTP_OK): JsonResponse {
    return response()->json([
      'data' => $data,
      'code' => $code,
    ], $code)->header('Content-Type', 'application/json');
  }

  public function errorResponse($error, int $code): JsonResponse
  {
    return response()->json([
      'error' => $error,
      'code'  => $code,
    ], $code)->header('Content-Type', 'application/json');
  }
}
```

Once the trait is created, you can import it as follows:

```php
<?php

namespace App\Http\Controllers;

use App\Traits\ApiResponder;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
  use AuthorizesRequests, DispatchesJobs, ValidatesRequests, ApiResponder;

  // ...
}
```

Once the trait is imported it is ready to use:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;

class TwilioSettingsController extends Controller
{
  public function fetchSettings(): JsonResponse
  {
    $response = TwilioSettings::getSettings();

    return $this->successResponse($response);
  }
}
```

### More Trait Examples

Another example of a trait would be a `LoggableTrait` - a trait that adds logging functionality to a class, allowing it to log messages to a log file or other logging system. This trait can be used by multiple PHP classes, including Service Classes.

---

The end, I hope this information was helpful, stay tuned for more content :)