php调用类方法来自同一个类中的静态方法,但是没有实例化

时间:2012-10-24 01:29:47

标签: php instance static-methods

php 5.3 +

很抱歉这个问题很长,但我想完全了解这一点。

我知道我不能在静态方法中调用非静态相同类方法,而不将类实例化为对象。

class Person 
{
    private $people_array;

    function data_all_get()
    { // touch database, return array of people
      $this->people_array = // etc dbquery results
    }

    static function showPeople()
    {  // call class method
       $people_data = $this->data_all_get();
       // Fatal error: Using $this when not in object context
    }
} // end class Person

通过搜索SO,我找到了一些有趣的方法,但想知道每种方法如何影响代码环境。

我的问题如下:

我可以将类实例化为静态方法中的对象,以获得对非静态方法的访问

static function showPeople()
{  // instantiate as object
   $person = New Person();
   // call class method
   $people_data = $this->data_all_get();
}

Q1 - 这会导致什么问题? 在我的情况下,该类没有构造函数,因此该实例不会影响其他类方法或变量。在脚本执行期间,这个新对象会占用内存中的一小块空间吗?似乎并不太糟糕......


另一种选择是将“data_all_get”方法转换为静态方法,因此可以从静态方法“showPeople”中调用,即

self::showPeople()

当实例化为对象时,类中的其他方法正在使用“data_all_get”方法,以设置私有var的值,以减少到数据库的行程(如果已经设置)。我知道这可能是构造函数的一部分,但我从来不需要每个php脚本请求多次实例化这个“Person”对象,该类主要用于将函数和变量组合在一起进行组织。

Q2 - 将“data_all_get”变为静态方法会有什么影响? 有没有?如果方法是静态的,但它设置私有var $ people_array的值(它不是静态的),我认为如果对象需要在单个中第二次实例化,则可以更新或覆盖var脚本请求,对吗?此外,由于该属性不是静态的,因此该类的其他方法可以访问它。

Q3 - 我可以根据需要多次调用静态方法“data_all_get”而不会“破坏任何东西”(加载的问题IK)。

Q4 - 每次调用静态方法时是否只使用额外的内存?

谢谢

1 个答案:

答案 0 :(得分:11)

class Person 
{
    private static $people_array;

    static public function data_all_get()
    { 
         self::$people_array = //DBStuff
    }

    static public function showPeople()
    {  
        $people_data = self::data_all_get();
    }
 }

只是一些笔记,有些可能很明显。 1)因为你没有返回任何东西,所以很明显上面的代码会失败。用上面的代码来说,没有任何错误。在回答你的Q1时,你所做的就是使用全局变量进行一对函数调用,并将它们封装在一个类中。我建议反对有时使用它作为实例化的类,有时不这样做,因为它会使你的最终代码更不易读,更难以让人们在查看它时理解。

如果您担心不止一次实例化这个问题,您可能需要查看单例设计模式,但总的来说,如果您计划在某个时刻实例化该类,我会重新检查您为什么会这样做首先要静态地调用这些。除了对我来说“感觉不对”之外,没有任何问题。

Q2)将data_all_get变为静态数组的唯一含义是引用静态属性,这反过来意味着如果实例化该属性将无法访问。此外,您正在失去实例化此类的多个版本的能力(如果这很重要)并且基本上将people_array转换为全局变量。这不一定是坏事,但不知道你的其余功能是什么,很难说它的含义是什么。

Q3)多次运行它的唯一问题是A)消除人员阵列中的任何内容,以及B)多个DB调用。在没有看到其他代码发生的情况下,这个问题或多或少都无法回答。

Q4)一个方法的内存大小与你在这里列出的内容相差无几,可以忽略不计。问题来自于DB调用本身以及在那里访问的行数

最后,由于你现在编写了这段代码,所以有点奇怪,因为showPeople与data_all_get完全相同。您可能想在showPeople中编写一些逻辑来查看$ people_array是否为空,如果是,则运行data_all_get,如果不是,则返回people_array。这将避免额外的DB读取。如果你每次都要去读DB,那么你也可以让data_all_get返回$ people_array,在这种情况下,这些都不需要在一个类中,它只能是一个函数调用,返回它的内容在数据库中找到。