Andrew Savetchuk
Andrew Savetchuk's Blog

Andrew Savetchuk's Blog

The difference between Service Classes and Traits in PHP

The difference between Service Classes and Traits in PHP

Overview of the difference between service classes and traits in PHP with examples

Andrew Savetchuk's photo
Andrew Savetchuk
·Mar 28, 2022·

3 min read

Service Classes​

A service class is a class that performs some business logic that you want to use in various places. It is any PHP object that performs some sort of a "global" task.

When code does not naturally fit into one class or another nicely then you have a candidate for a service. 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 connecting to UptimeRobot APIs and retrieving data.
  • Service class responsible for cropping, watermarking, and storing images on the server or 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

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 $uri = NULL)
  {
    // Making a GET request to UptimeRobot API using GuzzleHttp...
  }

  private function postResponse (string $uri = NULL, 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

namespace App\Http\Controllers;

use App\Services\UptimeRobotAPI;

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

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

Traits

A trait is a set of methods that you want to reuse across multiple classes, but can't because those classes extend to different parents. Traits are a language construct and were created because PHP does not support multi-class extensions.

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

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

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

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;

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

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

The end. I hope you found this article helpful. Stay tuned for more content!

If you want to support me, you can buy me a coffee :)

 
Share this