PHP:从变量实例化一个奇怪的失败

时间:2014-01-03 16:41:06

标签: php laravel instantiation eloquent laravel-3

我正在尝试通过变量实例化一个类(一个Laravel3 Eloquent模型),我收到一个错误,说找不到该类。
但是,当我对类名进行硬编码时,它的工作正常 (仅供参考,$contact_type下面的代码可能是电话,传真或电子邮件。)

这就是我现在正在玩的东西:

    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
        }
    }

当我按上述方式运行代码时,会抛出 “Class'Phone'未找到” 错误。
当我用new $contact_type()(或传真或电子邮件)替换new Phone()时,它可以正常工作 我打赌有一些简单的东西,我只是在看:)我错过了什么? 请帮忙!

1 个答案:

答案 0 :(得分:4)

涵盖此内容的相关手册条目为herehere。引用第二个链接:

  

如果包含类名称的字符串与new一起使用,则将创建该类的新实例。如果类在命名空间中,则在执行此操作时必须使用其完全限定名称。

这对我有用:

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

产生输出:

object(Phone)#1 (0) {
}

确保您不在命名空间中(如果是,请在字符串中包含Phone类的命名空间)。或者,您也可以尝试使用反射:

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

如果Phone类在命名空间中,这也有效:

<强> Phone.php

<?php namespace Contact;

class Phone {}

<强> test.php的

<?php

include 'Phone.php';

$classtype = 'Contact\Phone';
$phone = new $classtype();
var_dump($phone);

我不是百分之百确定原因,虽然我怀疑在评估变量类名时,当前的命名空间映射是不可见的。请考虑以下代码:

<?php namespace Foo;

use SomePackage\SomeClass as WeirdName;

$test = new WeirdName();

将其与:

进行比较
<?php namespace Foo;

use SomePackage\SomeClass as WeirdName;

$class = 'WeirdName';
$test = new $class();

当PHP决定为新实例分配内存时,如何知道将WeirdName的类名别名映射到SomePackage\Someclass?该别名仅对当前文件有效,实际执行该操作的代码甚至不在userland代码中,更不用于同一文件。