【问题标题】:PHP: Instantiating a class from a variable oddly failsPHP:从变量实例化一个类奇怪地失败了
【发布时间】:2014-01-21 09:48:57
【问题描述】:

我正在尝试通过变量实例化一个类(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' not found" 错误。
当我用new Phone()(或传真或电子邮件)替换new $contact_type() 时,它工作得很好。
我敢打赌,我只是在看一些简单的东西 :) 我错过了什么?
请帮忙!

【问题讨论】:

  • 你在命名空间中吗?
  • @deceze - 打败我。我打赌就是这样。想不出别的了。
  • 这里的命名空间如何关联?如果命名空间相关,$obj = new Phone() 也不应该工作
  • @RoyalBg 实际上,当您在 USE 语句中为命名空间或类起别名时,手动编写时它可以工作,但不能作为变量工作。
  • @Jessica - 不仅仅是useing。使用字符串时也不会解析当前命名空间中的类。

标签: php laravel instantiation eloquent laravel-3


【解决方案1】:

涵盖此内容的相关手册条目是 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);

我不是 100% 确定原因,尽管我怀疑在评估变量类名时,当前的命名空间映射不可见。考虑这段代码:

<?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 代码中,更不用说同一个文件了。

【讨论】:

  • 问题是命名空间。我的脚本顶部有use Person\Model\Eloquent\Phone(这就是为什么当我调用new Phone() 时它会起作用),但由于某种原因,当像new $var() 这样实例化时,我必须在变量中定义完整的命名空间......如果有人能解释原因,我非常有兴趣学习。
  • 我不是 100% 确定为什么,但我用我怀疑的原因更新了我的答案
  • Tnx,我也通过在变量中定义命名空间来修复它。在处理多个类时这并不是一件坏事(不必单独使用它们)。虽然,当使用带有 Route::model() 的动态类名时,这可能会导致您的 php artisan route:list 命令出错。因为它找不到类空字符串:p
猜你喜欢
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多