Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 426
3rgo Avatar asked Jan 12 '14 15:01

3rgo


2 Answers

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);
like image 165
Phil Avatar answered Oct 29 '22 23:10

Phil


@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).

like image 2
yodabar Avatar answered Oct 29 '22 23:10

yodabar