脚本范围访问

时间:2015-07-17 02:09:52

标签: php

所以,我一直在做一个小项目,没有什么广泛的。我一直无法理解为什么我的主要脚本无法访问我的匿名对象中的某个函数。

好吧,所以我的“初始化程序”,或者在任何关键操作之前加载的脚本,实例化一个匿名对象,以便在我的整个项目范围内访问。

<?php

    class T_EMPTY {
        public function __call($method, $args) {
            if(isset($this->$method) && is_callable($this->$method)) {
                return call_user_func_array(
                    $this->$method, 
                    $args
                );
            }
        }
    }

    $scope = new T_EMPTY;

    $scope->config = array(
        'path' => $_SERVER['DOCUMENT_ROOT'],
        'loct' => '*'
    );
        set_include_path ( $scope->config['path'] );

    $scope->controller = $scope->service = $scope->service->injector = new T_EMPTY;
        // #    instantiate our empty structures
    $scope->service->injector->inject = function($rsc) {
        global $scope;
        if( is_array( $rsc ) && count( $rsc ) >= 1 ):
            foreach( $rsc as $r ):
                require_once( $scope->config['path'] . '/api/services/' . $r . '.php' );
            endforeach;
        else:
            require_once( $scope->config['path'] . '/api/services/' . $rsc . '.php' );
        endif;
    };
    $scope->service->injector->f = "foobar";

问题在于,通过

将其导入我的主脚本后
require_once

我无法访问'注入'功能。

global $scope;
$f = & $scope->service->injector;
$f->inject( 'communicator' ); // # function marked undefined
echo $f->f; // element exists

无论出于何种原因,该函数都是未定义的,但我可以毫无困难地访问'f'。

1 个答案:

答案 0 :(得分:2)

问题是$scope->service没有injector属性。初始化$scope->service->injector的链式作业并不是按照您的想法进行的,因为作业会从右到左关联。所以

$scope->controller = $scope->service = $scope->service->injector = new T_EMPTY;

执行就像它的

一样
$temp1 = $scope->service->injector = new T_EMPTY;
$temp2 = $scope->service = $temp1;
$scope->controller = $temp2;

$scope->service的分配会覆盖$scope->service对象,该对象是通过使用新$scope->service->injector实例分配给T_EMPTY隐式创建的,并且没有一个injector财产。

链式分配的另一个问题是,您要将它们全部设置为相同 T_EMPTY实例(当对象未被复制时,它们不会被复制分配,像数组一样),这可能不是你想要的。将该行更改为:

$scope->controller = new T_EMPTY;
$scope->service = new T_EMPTY;
$scope->service->injector = new T_EMPTY;