3

嘿 php 大师。我遇到了一些奇怪的类范围问题,这些问题显然与 php 中的一些怪癖有关。谁能告诉我什么异常情况可能会出现以下错误...

致命错误:无法访问 self:: 当第 5 行的 MyClass.php 中没有活动的类范围时

现在,显然如果我在课堂之外使用 self:: ,我会得到错误......但我不是。这是情况的简化版本...

//file1
class MyClass{
   public static function search($args=array()){
       $results = MyDbObject::getQueryResults("some query");
       $ordered_results = self::stack($results); //Error occurs here

       return $ordered_results;
   }
   public static function stack($args){
       //Sort the results
       return $ordered_results;
   }
}

//file 2
include_once("MyClass.php");
$args = array('search_term'=>"Jimmy Hoffa");
$results = MyClass::search($args);

鉴于此设置,我怎么能得到上面的错误?这是我到目前为止发现的...

MyClass::search($args) //does not give the error (usually)
call_user_func("MyClass::search"); // this gives the error!

还有其他情况吗?

4

4 回答 4

1

如果我理解正确,您正在寻找Late Static Binding。此功能至少需要 PHP 5.3 版。

于 2010-10-22T17:10:13.397 回答
1

您没有传递任何参数,但您的方法正在寻找它们。尝试

call_user_func("MyClass::search", $args);

这适用于 php 5.3.1,但call_user_func("MyClass::search");没有

于 2010-10-22T17:57:15.417 回答
0

试试这个:

call_user_func(array('MyClass', 'search'));

另请参见http://php.net/call_user_func上的示例 #4

于 2010-10-22T18:03:29.650 回答
0

你的代码看起来不错。如果它有问题,我一定是错过了问题。看来您对 self:: 的调用完全在课程的范围内!还有一个静态范围,具体来说,这就是 self:: 的用途。

来自 PHP Objects Patterns and Practice 的第 3 版(一本很棒的书):

要从同一个类(而不是子类)中访问静态方法或属性,我会使用 self 关键字。self 之于类就像 $this 伪变量之于对象。因此,从 StaticExample 类外部,我使用其类名访问 $aNum 属性:

StaticExample::$aNum;

在 StaticExample 类中,我可以使用 self 关键字:

class StaticExample {`
    static public $aNum = 0;

    static public function sayHello() {
        self::$aNum++;
        print "hello (".self::$aNum.")\n";
    }
}

所以,我不确定为什么这段代码会失败。也许是一个 PHP 错误?我在实际尝试在类范围之外使用 self:: 时遇到了这个错误——我的错误看起来像这样:

public static function get_names() {
    $machine_names = self::get_machine_names();

    return array_map(function ($machine_name) {
        $service_settings = self::get_settings_by_machine_name($machine_name);
        return $service_settings . $machine_name;
        },
        $machine_names
    );
}

所以,我得到了错误,因为我在闭包的范围内使用了 self::。为了解决这个错误,我可以在闭包之前调用 self::get_settings_by_machine_name() ,并将结果传递给闭包的作用域use

不确定您的代码中发生了什么。

于 2012-06-10T15:58:32.867 回答