PHP5类范围怪癖

时间:2010-10-22 16:52:02

标签: php oop class self

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

致命错误:在第5行的 MyClass.php

中没有活动范围时,无法访问self ::

现在,显然如果我在课堂外使用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 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

试试这个:

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

另见http://php.net/call_user_func

上的示例#4

答案 3 :(得分:0)

您的代码似乎很好。如果它有问题,我一定是错过了这个问题。看来你对self ::的调用完全属于一个类的范围!还有一个静态范围,具体来说,就是self :: is for。

从PHP对象模式和实践的第3版(一本很棒的书):

  

从同一个类中访问静态方法或属性   (而不是从孩子),我会使用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将结果传递给闭包的范围。

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