First, is user_service() an appropriate class name for my user() model or is there another standard?

That's acceptable. However, you should rather use one of the established PHP coding conventions, such as the PEAR or ZF conventions. In both cases, class names are UpperCamelCase and method names lowerCamelCase. Using this, the classes would be User and UserService

Since the methods in my service will only be doing one task, is it correct to think that these can always be a static function? A service class isn't representing data, but rather is a series a actions, so this seems appropriate.

No. It's a poor design choice to make methods static - and this applies to most code, not just services. One of the main reasons in case of a service would be that generally your service needs to interact with a data store or another class which represents the data layer (repository, data access object, whatever).

When your service has static methods, this means you would need to instanciate your dependencies in your methods. This in turn means that, amongst other things, the code becomes hard to test, as you can't easily replace the dependencies.

There's some good reading on this for example here (In fact nearly everything on that blog is good reading for software devs)

Should a service method only accept one argument, which would be an array?

This is dependent on what the method does. Assuming your example of processing a form's resultset, then yes this will probably work. In some other case it might be a poor choice.

I can add another field to my form and I won't have to update the controller, just the service. [ ... ]

If I didn't pass an array, I could setup functions with multiple arguments. [ ... ]

Yep, your argumentation for these two cases is pretty much spot on for this use-case in my opinion.

I could pass an object, but does that make sense? If I'm creating an object, it should the be the object it represents (the user in this case) right? But does it make sense that the controller instantiates the user object? Isn't that the whole point of the service layer in the first place?

This depends. For example, if you were using a framework which lets you represent forms as objects (such as the Zend Framework and Zend_Form), you could consider passing the form object straight to the service.

Maybe there is an argument for having some methods with multiple arguments (when there are just one to three) and some methods that accept an array (when there are lots of fields). This just seems like it could be a nightmare, as you would always have to reference the class to know what that particular method was asking for.

You should usually aim to make the parameters at least half-guessable based on the method's name. In something I work on, we have a model which has for example businesses and products, where a business can sponsor a product. In a ProductService, we have a method called sponsorProduct which takes a business and a product as parameters. You can pretty much guess it would take these two (if you were familiar with the codebase anyway)

IDE's generally help you with this too - they provide code-assist which displays what params functions take. This is one of the main reasons I think IDE's are very useful in larger projects where you can't always remember what exactly a certain function needs as parameters.

As for parameter count, I think usually you should try to have separate parameters. This allows anyone to easily see what parameters are required by just looking at the function's signature, and allows you to define typehints and default values quite easily.

However there is a point when you get so many parameters it's too much. This is maybe at +5 or so, depending a bit on what sort of method it is. In this case you can consider using an array, or something called a Parameter Object, which is essentially an object that contains all the parameters for the call. More on parameter objects here

Answer from Jani Hartikainen on Stack Overflow
Top answer
1 of 1
25

First, is user_service() an appropriate class name for my user() model or is there another standard?

That's acceptable. However, you should rather use one of the established PHP coding conventions, such as the PEAR or ZF conventions. In both cases, class names are UpperCamelCase and method names lowerCamelCase. Using this, the classes would be User and UserService

Since the methods in my service will only be doing one task, is it correct to think that these can always be a static function? A service class isn't representing data, but rather is a series a actions, so this seems appropriate.

No. It's a poor design choice to make methods static - and this applies to most code, not just services. One of the main reasons in case of a service would be that generally your service needs to interact with a data store or another class which represents the data layer (repository, data access object, whatever).

When your service has static methods, this means you would need to instanciate your dependencies in your methods. This in turn means that, amongst other things, the code becomes hard to test, as you can't easily replace the dependencies.

There's some good reading on this for example here (In fact nearly everything on that blog is good reading for software devs)

Should a service method only accept one argument, which would be an array?

This is dependent on what the method does. Assuming your example of processing a form's resultset, then yes this will probably work. In some other case it might be a poor choice.

I can add another field to my form and I won't have to update the controller, just the service. [ ... ]

If I didn't pass an array, I could setup functions with multiple arguments. [ ... ]

Yep, your argumentation for these two cases is pretty much spot on for this use-case in my opinion.

I could pass an object, but does that make sense? If I'm creating an object, it should the be the object it represents (the user in this case) right? But does it make sense that the controller instantiates the user object? Isn't that the whole point of the service layer in the first place?

This depends. For example, if you were using a framework which lets you represent forms as objects (such as the Zend Framework and Zend_Form), you could consider passing the form object straight to the service.

Maybe there is an argument for having some methods with multiple arguments (when there are just one to three) and some methods that accept an array (when there are lots of fields). This just seems like it could be a nightmare, as you would always have to reference the class to know what that particular method was asking for.

You should usually aim to make the parameters at least half-guessable based on the method's name. In something I work on, we have a model which has for example businesses and products, where a business can sponsor a product. In a ProductService, we have a method called sponsorProduct which takes a business and a product as parameters. You can pretty much guess it would take these two (if you were familiar with the codebase anyway)

IDE's generally help you with this too - they provide code-assist which displays what params functions take. This is one of the main reasons I think IDE's are very useful in larger projects where you can't always remember what exactly a certain function needs as parameters.

As for parameter count, I think usually you should try to have separate parameters. This allows anyone to easily see what parameters are required by just looking at the function's signature, and allows you to define typehints and default values quite easily.

However there is a point when you get so many parameters it's too much. This is maybe at +5 or so, depending a bit on what sort of method it is. In this case you can consider using an array, or something called a Parameter Object, which is essentially an object that contains all the parameters for the call. More on parameter objects here

🌐
SymfonyCasts
symfonycasts.com › screencast › oo-ep2 › service-classes
Service Classes > OOP (Course 2): Services, Dependency Injection and Containers | SymfonyCasts
That's all you need to change: functions work the same inside or outside of a class: they have arguments, they return stuff. But we do need to change code where we call this function - in battle.php. So how can we call this? Well, when we want to call a method on Ship, we need to have a Ship object first.
Discussions

Opinion based discussion: Service class, how to use them?
Tbh this logic is so simple that I would avoid another layer of abstraction. Doesn't look like you need any logic there and it's not like you're doing API calls there. Just use the model directly. And you seem to be trying too much error handling yourself. I am not sure what errors are you expecting, but almost never need try/catch around things like this. FYI Car::where("id", $id)->first() is equivalent to Car::find($id) unless you've done some strange customization of the model. And maybe what you want to do is just Car::findOrFail($id) which throws an appropriate 404 response itself? The convention is that model names are singular, after all you're instantiating a new Car not a new Cars. So I used singular in my examples. More on reddit.com
🌐 r/laravel
36
9
December 2, 2020
Injecting an object (from the IOC) using Laravel Blade Service Injection

This feels so wrong on so many levels.

More on reddit.com
🌐 r/PHP
35
1
June 9, 2015
Data Transfer Objects in PHP
If he's using 'data structure' to describe DTOs, he's dead wrong about the terminology. More on reddit.com
🌐 r/PHP
30
34
April 7, 2014
why are there no proper enums in php? are they planned in future releases?

I have been working on a “true” enum implementation which I might finish up and announce soon (7.2 feature freeze looms).

In the meantime there's SplEnum.

More on reddit.com
🌐 r/PHP
55
47
June 22, 2017
🌐
Revathskumar
blog.revathskumar.com › 2015 › 08 › php-service-classes.html
PHP : Service classes
August 4, 2015 - Once I moved the order creation logic to service class, now my controller action looks like, <?php class OrdersController extends Controller { public function actionCreate() { $orderData = Yii::app()->request->getParam('order'); try { $order = new OrdersService(); $res = $order->create($orderData); if(isset($res['status']) && $res['status'] == 'success') { $res['message'] = 'Order placed successfully.'; $this->_sendResponse(200, $res); } $this->_sendResponse(403, $res); } catch(OrdersServiceException $e) { $this->_sendResponse(403, array( 'status' => 'error', 'message' => $e->getMessage() )); } catch(Exception $e) { $this->_sendResponse(403, array( 'status' => 'error', 'message' => $e->getMessage() )); } } } ?>
🌐
DEV Community
dev.to › otutukingsley › using-the-service-layer-pattern-in-php-for-clean-and-scalable-code-15fb
Using the Service Layer Pattern in PHP for Clean and Scalable Code - DEV Community
October 28, 2024 - With our PostService class set up, let’s integrate it into a controller. This will keep the controller focused on handling HTTP requests and responses, while business logic resides in the service. <?php namespace App\Http\Controllers; use App\Services\PostService; use Illuminate\Http\Request; class PostController extends Controller { protected function postService(): PostService { return new PostService(); } public function store(Request $request) { $validatedData = $request->validate([ 'title' => 'required|string|max:255', 'content' => 'required|string', 'user_id' => 'required|integer|exists:users,id' ]); $post = $this->postService()->createPost($validatedData); return response()->json($post, 201); } }
🌐
DZone
dzone.com › coding › languages › practical php patterns: service layer
Practical PHP Patterns: Service Layer
May 2, 2010 - The sample features two service classes, one as a stubbed implementation of an interface of the Domain Model and one that it is employed only at an higher level. <?php require_once 'domain.php'; /** * Adapter for an interface defined in the ...
🌐
Savetchuk
blog.savetchuk.com › the-difference-between-service-classes-and-traits-in-php
The Difference Between Service Classes and Traits in PHP
March 28, 2022 - Service class responsible for storing and deleting images on the cloud. Here is an example of the App\Services\UptimeRobotAPI.php service class that is responsible for connecting to the UptimeRobot API and retrieving data:
🌐
Medium
medium.com › @jorisvdaalsvoort › mastering-the-service-layer-pattern-in-php-best-practices-for-maintainable-applications-0a8ba24d2df5
Mastering the Service Layer Pattern in PHP: Best Practices for Maintainable Applications
January 7, 2025 - The service class is where all the business logic for a specific use case will live. For example, let’s create a UserService that handles user-related operations:
Find elsewhere
🌐
Laravel Daily
laraveldaily.com › code-examples › tag › service-classes
Code Examples of service classes | Laravel Daily
Developers use a "service classes" term, usually referring to almost any PHP class related to some topic. So, you create any PHP class and then use its methods somewhere in Controllers, for example.
🌐
SitePoint
sitepoint.com › blog › cms & frameworks › an introduction to services
An Introduction to Services — SitePoint
November 15, 2024 - While the class’ functionality is limited, it shows in a nutshell how to build a service layer that mediates between the model and a couple of clients which expect to get in data in a specific format. Of course I’d be a jerk if I didn’t show you how to finally get things rolling with such a service, So, the example below uses it for fetching users from the database: <?php use LibraryLoaderAutoloader, LibraryDatabasePdoAdapter, ModelMapperUserMapper, ServiceUserService, ServiceSerializer, ServiceJsonEncoder;
🌐
DevInTheWild.
devinthewild.com › article › using-service-classes-in-php-a-guide
A Comprehensive Guide To Service Classes In PHP
October 20, 2023 - With practice and experience, you ... using service classes effectively. ... Login To Add Comments. Login with GitHub · Subscribe to occasional updates. Charles R. Bowen ... It's common practice to hinge logic off which route or page is active in the user's browser. Here's a few easy ways of checking the current route to power your app functionality off. ... When you have thousands of tests in a PHP application ...
🌐
Medium
medium.com › @laravelprotips › understanding-laravel-service-classes-a-comprehensive-guide-1f22310c70bd
Understanding Laravel Service Classes: A Comprehensive Guide | by Laravel Pro Tips | Medium
March 28, 2024 - Many times, when there’s a need for added logic linked to a particular Eloquent model, a Service Class comes into play. For instance, for the “User” model, you might have a “UserService.” There can also be Service Classes tailored ...
🌐
YouTube
youtube.com › drupalize.me
PHP Service Classes - YouTube
In this series we're going to continue on from the Introduction to Object-oriented PHP series. We're working on the same spaceship project: it has ships, you...
Published   August 12, 2015
Views   2K
🌐
Laravel
laravel.com › docs › 11.x › container
Service Container | Laravel 11.x - The clean stack for Artisans and agents
For example, you may type-hint a service defined by your application in a controller's constructor. The service will automatically be resolved and injected into the class: ... <?php namespace App\Http\Controllers; use App\Services\AppleMusic; class PodcastController extends Controller { /** * Create a new controller instance.
🌐
Laravel
laravel.com › docs › 12.x › container
Service Container | Laravel 12.x - The clean stack for Artisans and agents
For example, you may type-hint a service defined by your application in a controller's constructor. The service will automatically be resolved and injected into the class: ... <?php namespace App\Http\Controllers; use App\Services\AppleMusic; class PodcastController extends Controller { /** * Create a new controller instance.
🌐
Laravel
laravel.com › docs › 11.x › providers
Service Providers | Laravel 11.x - The clean stack for Artisans and agents
Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider. To defer the loading of a provider, implement the \Illuminate\Contracts\Support\DeferrableProvider interface and define a provides method. The provides method should return the service container bindings registered by the provider: ... <?php namespace App\Providers; use App\Services\Riak\Connection; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Support\DeferrableProvider; use Illuminate\Support\ServiceProvider; class RiakServiceProvider extends ServiceProvider implements DeferrableProvider { /** * Register any application services.
🌐
Laravel Daily
laraveldaily.com › post › service-classes-laravel-open-source-examples
Service Classes in Laravel: 10 Open-Source Practical Examples
September 23, 2024 - The first example is from an open-source project called pterodactyl/panel. Here, we have a UserCreationService service, which creates a user using the handle() method. app/Services/Users/UserCreationService.php: class UserCreationService · { public function handle(array $data): User ·
🌐
DEV Community
dev.to › andrewsavetchuk › the-difference-between-service-classes-and-traits-in-php-41jm
The Difference Between Service Classes and Traits in PHP - DEV Community
March 3, 2023 - Service class responsible for storing and deleting images on the cloud. Here is an example of the App\Services\UptimeRobotAPI.php service class that is responsible for connecting to the UptimeRobot API and retrieving data:
🌐
Laravel
laravel.com › docs › 9.x › container
Service Container - Laravel 9.x - The PHP Framework For Web Artisans
March 4, 2020 - The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods. ... <?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Repositories\UserRepository; use App\Models\User; class UserController extends Controller { /** * The user repository implementation.
🌐
PHP
php.net › manual › en › win32service.examples.php
PHP: Examples - Manual
<?php win32_create_service(array( 'service' => 'dummyphp', # the name of your service 'display' => 'sample dummy PHP service', # short description 'description' => 'This is a dummy Windows service created using PHP.', # long description 'params' ...
🌐
PHPpot
phppot.com › php › php-restful-web-service
PHP RESTful Web Service API – Part 1 – Introduction with Step-by-step Example - PHPpot
In the next section, we can see all the file structures and the purpose of each file of this example. <?php /* * A domain Class to demonstrate RESTful web services */ class Mobile { private $mobiles = array( 1 => 'Apple iPhone 6S', 2 => 'Samsung Galaxy S6', 3 => 'Apple iPhone 6S Plus', 4 => 'LG G4', 5 => 'Samsung Galaxy S6 edge', 6 => 'OnePlus 2' ); /* * you should hookup the DAO here */ public function getAllMobile() { return $this->mobiles; } public function getMobile($id) { $mobile = array( $id => ($this->mobiles[$id]) ?