質問

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, though, it works just fine.
(FYI, in the code below $contact_type is expected to either be Phone, Fax, or Email.)

Here's what I'm playing with at the moment:

    foreach( $input AS $contact_type => $contact_info )
    {
        foreach( $contact_info AS $data )
        {
            $obj = new $contact_type( (array)$data);
            echo'<pre>Obj: ',print_r($obj),'</pre>';  // <----- For Testing
        }
    }

When I run the code as above, it throws a "Class 'Phone' not found" error.
When I replace new $contact_type() with new Phone() (or Fax or Email), it works just fine.
I bet there's something simple I'm just looking over :) What am I missing?
Please help!

役に立ちましたか?

解決

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top