PHP: Instantiating a class from a variable oddly fails

后端 未结 1 792
暖寄归人
暖寄归人 2021-01-22 21:06

I\'m trying to instantiate a class (a Laravel3 Eloquent model) by a variable, and I\'m getting an error saying that the class is not found.
When I hardcode the class name, t

相关标签:
1条回答
  • 2021-01-22 21:54

    The relevant manual entries that covers this are here and here. To quote the second link:

    If a string containing the name of a class is used with new, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this.

    This works for me:

    class Phone {}
    $classtype = 'Phone';
    $phone = new $classtype();
    var_dump($phone);
    

    Produces the output:

    object(Phone)#1 (0) {
    }
    

    Look to make sure you're not in a namespace (include the Phone class' namespace in the string if you are). Or, you can also try using reflection:

    class Phone {}
    $classtype = 'Phone';
    $reflectionClass = new ReflectionClass($classtype);
    $phone = $reflectionClass->newInstanceArgs();
    var_dump($phone);
    

    If the Phone class is in a namespace, this also works:

    Phone.php

    <?php namespace Contact;
    
    class Phone {}
    

    test.php

    <?php
    
    include 'Phone.php';
    
    $classtype = 'Contact\Phone';
    $phone = new $classtype();
    var_dump($phone);
    

    I'm not 100% sure why, although I suspect that when evaluating a variable class name the current namespace mappings aren't visible. Consider this code:

    <?php namespace Foo;
    
    use SomePackage\SomeClass as WeirdName;
    
    $test = new WeirdName();
    

    Compare that with:

    <?php namespace Foo;
    
    use SomePackage\SomeClass as WeirdName;
    
    $class = 'WeirdName';
    $test = new $class();
    

    When PHP decides to allocate memory for a new instance, how will it know to map the class name alias of WeirdName to SomePackage\Someclass? That alias is only valid for the current file, and the code that actually performs that operation isn't even in userland code, much less the same file.

    0 讨论(0)
提交回复
热议问题