PHP static method call with variable class name and namespaces

I’m trying to call a static method for a namespaced class from another class with the same namespace. But the other class’ name is contained in a variable :

<?php 

namespace MyApp\Api;
use \Eloquent;

class Product extends Eloquent {

    public static function find($id)
    {
        //....
    }

    public static function details($id)
    {
        $product = self::find($id);
        if($product)
        {
            $type = $product->type; // 'Book'
            $product = $type::find($product->id);
            return $product;
        }
    }
}

Here is the Book class :

<?php

namespace MyApp\Api;
use \Eloquent;

class Book extends Eloquent {

    public static function find($id)
    {
        //....
    }

}

My type variable contains a valid class name here Book. This class is in the same folder, and uses the same namespace.
This code returns the error Class 'Book' not found.
I have tried several variations (from the SO questions I found) using backslashes, or the call_user_func function, but nothing worked.
Anyone knows what’s wrong ?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

When using a variable to reference your class, you need to use a fully qualified name. Try this…

$type = __NAMESPACE__ . '\\' . $product->type;
$product = $type::find($product->id);

Solution 2

@Phil pointed out the right solution.

For a more complete point of view, I clarify that the fully qualified name is necessary when accessing static methods or attributes, out of the global namespace.

When accessing dynamic methods or attributes (I mean properties of an instance) without qualifying the name, PHP automatically looks for the property inside the current namespace.

In my opinion this asymmetry is not useful, as the opportunity to invoke foreign namespace properties are equal either for static or dynamic properties.

(Valid on PHP 7.2.0 at the moment I am writing).

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply