What is the meaning of utility functions in Laravel

Viewed 1906

Good day to all, I am new to Laravel and the thing that I encountered with and cannot understand is utility methods that are used in the framework, for example, Customer::all() where Customer is model or Customer::find(). So, what is the point of utility methods and why all() and find() are static.

5 Answers

When you do User::find() , you are actually asking for a new instance, either an instance of Collection or a QueryBuilder.

Illuminate\Database\Eloquent\Model : https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Eloquent/Model.php

As a side note, you'll also see another way of using static methods in Laravel e.g. Input::get(). These are called Facades.

Facades provide a "static" interface to classes that are available in the application's IoC container ... Laravel "facades" serve as "static proxies" to underlying classes in the IoC container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.

When a user references any static method on the ... facade, Laravel resolves the cache binding from the IoC container and runs the requested method (in this case, get) against that object.

You can read more about Laravel Facades at: http://laravel.com/docs/facades

Utility functions in general offer some sort of utility, i.e. functionality which is usually just for convenience and can also be achieved by following a set of steps.

For example Model::find() is functionality that can also be achieved by creating a query builder object and then performing a query e.g.

Model::getQuery()->where('id', '=', $id)->first();

For convenience you can just do Model::find($id) which is shorter and more intuitive.

It is static because it does not make sense for it not to be static. A non-static method requires an instance of the class however in ORMs an instance of a class corresponds to a potential database entry (which either exists or could exist). Therefore since find is used to retrieve a database entry it makes no sense to require a backing database entry in order to use it.

In short what this means is, if you execute method $object = Model::find(1) you will get back a model which corresponds to database entry with identifier 1. There is a 1 to 1 mapping of the PHP object to the relational object. If make changes to $object and call $object->save() then changes will be persisted in the database (i.e. $object already exists). If on the other hand you do $object = new Model() you will get back a new model which does not currently correspond to a database entry. However calling $object->save() will make that object correspond to a new database entry and it will be updated accordingly (i.e. the new object could exist). If a framework required you to make a "dummy" object just to access some helper methods there's always a chance that (either by omission or through unknown side-effects) save() gets called on that dummy object and you end up filling up your database with what is essentially junk.

The takeaway from this is that in an ORM it does not make sense to create a model instance if you don't intend to store it in the database. Laravel does not strictly obey this rule, but in general it does, and you should too.

The same applies to all which gets all database entries. It doesn't make sense to get all database entries by requiring to first get one entry.

Same applies to getQuery used above which returns a query builder instance. Note that most people don't actually use getQuery because it runs implicitly when someone uses something like e.g. Model::where(..) so technically Model::where() is also a utility. I mention this because when you see something like Model::where('id', $id)->where('name', $name) the 2nd where is after a -> which implies it's on an instance rather than static, however that instance is actually a query builder instance and not a model instance.

Laravel includes a variety of global "helper" PHP functions. Many of these functions are used by the framework itself; however, you are free to use them in your own applications if you find them convenient.

So, basically, helpers in Laravel are built-in utility functions that you can call from anywhere within your application. If they hadn't been provided by the core framework, you might have ended up developing your own helper classes.

Although the core provides a variety of helpers already, there’s always a chance that you’ll need your own and would like to develop one so you don’t have to repeat the same code here and there, thus enforcing better maintainability.

all() find() where() etc.. these methods are not utility methods, they are orm methods and coming from Query Builder.

They are static so they provide you using them without creating an instance

Those methods are part of the Eloquent system and help you to retrieve records from your database.

The all method gets all of the records for the given model from the database and returns a Collection of instances of that model. If you were to do User::all(), a collection of every single user in your database would be returned as a Collection of User objects.

$users = User::all(); // Returns a Collection of User objects
foreach ($users as $user) {
    // Here, each $user will be an instance of User
}

The find method is used to find a model in the database by its primary key. This method actually returns a single model instance if it finds a record matching the given primary key, or null if it doesn't find anything.

$user = User::find(1); // Find a User with the primary key 1, or null

Those methods aren't actually static, though you can use them as if they were. The find method is a non-static method on the Illuminate\Database\Eloquent\Builder object and the all method is a utility method on Illuminate\Database\Eloquent\Model which eventually calls the Builder object's get method.

When you call User::find(1), Laravel will create a new query or a Builder object and call the find method on the Builder which will return you a new User object, or null. Similarly, when calling User::all(), Laravel will create a new query or Builder object and call the get() method which will return your collection of models.

The Illuminate\Database\Eloquent\Model class uses the __callStatic magic method to redirect static method calls for non-existent static methods to the Builder object. That's how you're able to call them in a static context:

public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}

So you could effectively do this to achieve the same results:

$user = (new User)->find(1);
$allUsers = (new User)->get();
Related