对象的子变量中的变量字符串被忽略

时间:2012-02-15 00:29:52

标签: php oop class

我正在尝试使用循环动态加载库然后将它们添加到$this并且我尝试使用instanceof来查看它是否已经在尝试再次启动它之前已经启动:

    $libraries = array('strings');
    foreach ($libraries as $lib) {
        require_once('lib/'.$lib.'.lib.php');
        if(!($this->lib_{$lib} instanceof $lib)){
            $this->lib_{$lib} = new $lib();
        } else {
            continue;
        }
    }

但是当我尝试这个时,我只是从apache获得了500个内部服务器错误。

我得到的错误是:

[15-Feb-2012 10:31:21] PHP Notice:  Undefined property: load::$lib_ in /home/wwwsrv/public_html/system/core.lib.php on line 57

(第57行是指if语句的行)

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

看起来你没有初始化的成员变量与YOUR_CLASS :: $ lib_SOMELIB匹配,所以PHP正在发出通知。

我会尝试类似的事情:

if ((!isset($this->lib_{$lib})) || 
    (!($this->lib_{$lib} instanceof $lib))) {

另外,您可能希望研究使用魔术方法; __set and __get动态设置YOUR_CLASS的成员变量,因此您无需维护清单。

- 编辑#2 -

不确定为什么会收到stdObject错误,可能是早先尝试初始化该值。看看这个片段,看看它是否有帮助。我测试了它并且有效。

class strings
{
    public function __toString()
    {
        return __CLASS__;
    }
}

class MyClass
{
    private $dynamicMembers = array();

    public function loadLibs()
    {
        $libraries = array('strings');

        foreach ($libraries as $lib) {

            // Had to do it this way, b/c it was resulting in lib_ and not lib_strings
            $memberName = 'lib_' . $lib;

            if ((!isset($this->$memberName)) ||
                (!($this->$memberName instanceof $lib))) {
                var_dump(sprintf('I would have required: (%s)', 'lib/'.$lib.'.lib.php'));
                $this->$memberName = new $lib();
            } else {
                continue;
            }
        }
    }

    public function __set($name, $value)
    {
        $this->dynamicMembers[$name] = $value;
    }

    public function __get($name)
    {
        if (array_key_exists($name, $this->dynamicMembers)) {
            return $this->dynamicMembers[$name];
        }
    }
}

$myClass = new MyClass();

$myClass->loadLibs();

var_dump((string) $myClass->lib_strings);
var_dump($myClass->lib_strings);

exit;

- 编辑#1 -

仔细检查您的代码后,您似乎正在尝试创建一个加载lazy-load pattern的自动加载器。延迟加载在某些情况下运行良好,但请记住,调用代码来设置要实例化的对象的特定成员属性将很困难,如果这不是问题,则忽略。

另外,我建议阅读PHP的内置spl_autoload功能。

答案 1 :(得分:0)

以下哪项更适合您?

class Library_Loader {
    protected $_loadedLibraries = array();

    public function load($library) {
        if (!array_key_exists($library, $this->_loadedLibraries)) {
            $path = realpath('lib/' . $library . '.lib.php');

            if (false === $path) {
                throw new Exception("Invalid library $library");
            }

            require_once $path;
            $this->_loadedLibraries[$library] = new $library();
        }

        return $this->_loadedLibraries[$library];
    }
}

$libraries = array('strings');
$loader = new Library_Loader;

foreach ($libraries as $library) {
    $loader->load($library);
}

您还可以查看wrapping this up into an autoloader,这样您就可以在代码中调用new strings();并自动为您加载课程。