sleepless
sleepless

Reputation: 1789

PHP - init class with a static function

I would like to call a class without initializing it even if it's normally not static. So basically it should init itself with the first method call.

I'm wondering how laravel is doing this:

$someClass = SomeClass::where()->get()

This works on every method they provide.

I googled a long time but as long as you don't know the name of this behavior it's really hard to find.

Would be nice if you could help me out.

Upvotes: 2

Views: 2048

Answers (2)

lukasgeiter
lukasgeiter

Reputation: 152890

As it has been mentioned, it is all in the source code. Take a look at this part of the Illuminate\Database\Eloquent\Model class (Github link)

public static function __callStatic($method, $parameters)
{
    $instance = new static;
    return call_user_func_array(array($instance, $method), $parameters);
}

Every static method call for which no method exists (which is the case with most of the methods you can statically call on a model class) will end up at __callStatic.

Then, with new static, an instance of the class will be created and the method is called using call_user_func_array.

Upvotes: 4

Alana Storm
Alana Storm

Reputation: 166066

Laravel (sometimes) calls this feature a "Facade" -- explaining how this is accomplished in Laravel means going way down the Laravel rabbit hole and is beyond the scope of a single Stack Overflow answer -- if you're interested in that I'm the author of a 10 article series that covers the implementation details of a lot of Laravel's "magic" methods -- worth checking out if you're the sort who likes those sort of nitty gritty details. The PHP manual entry on overloading is also useful.

The short version is, all PHP classes have a magic method named __callStatic. If your class has __callStatic defined

class Foo
{
    public function __callStatic($method, $args)
    {
    }
}

and you call a method that does not exist, or is protected/private

Foo::notThere(1,2,'foo');

Then PHP will call the __callStatic method instead, with $method being the method's name (notThere above) and $args being an array of parameters passed to the method (1, 2, and foo above)

Upvotes: 2

Related Questions