在我公司的代码库中,我看到了在静态和对象上下文中使用的函数。对于例如A类具有一个函数b(),该函数同时使用A :: b()和/或object_of_type_A-> b()来调用。我知道如果严格打开,这会引发错误。但我想知道这是否是一种不好的做法,如果是的话,那为什么?感谢任何答案。应该在静态和对象上下文中使用函数
让我知道如果我没有任何意义。我会很乐意澄清。
在我公司的代码库中,我看到了在静态和对象上下文中使用的函数。对于例如A类具有一个函数b(),该函数同时使用A :: b()和/或object_of_type_A-> b()来调用。我知道如果严格打开,这会引发错误。但我想知道这是否是一种不好的做法,如果是的话,那为什么?感谢任何答案。应该在静态和对象上下文中使用函数
让我知道如果我没有任何意义。我会很乐意澄清。
下面是一些测试代码:
<?php
error_reporting(E_ALL | E_STRICT);
class Foo{
public function a(){
}
public static function b(){
}
}
$MyFoo = new Foo;
Foo::a(); // Strict Standards: Non-static method Foo::a() should not be called statically
Foo::b();
$MyFoo->a();
$MyFoo->b(); // No complaints
?>
PHP/5.3警告非静态方法是静态调用,因为他们是受故障这是很好的,只要你想访问$this
。但它并不会抱怨静态函数的对象上下文调用:没有什么可以出错的。 This behaviour is documented:
声明类属性或方法 静态使他们访问 不需要的 类的一个实例。声明为静态 属性可以不与 实例化的类对象(虽然 静态方法可以) [...] 因为静态方法调用 而不创建对象 的一个实例中,伪变量进行访问$这是 在声明为静态的方法 内不可用。
所以,就PHP而言,你在代码库中发现的东西并没有错。不过,我认为这有点混乱。
+1中无效,我想这正是我正在寻找的...所以,行为是正确的,但令人困惑: - )...是否有任何其他原因需要关注?感谢您的答案.. – pinaki 2010-07-10 19:06:46
我不是一个PHP的家伙,但这听起来就像Java,它允许但不鼓励。
如果它是静态的,我会强烈建议只能以静态方式调用它。否则它看起来喜欢它取决于你应该打电话给它的对象的状态。
在Java中,最好的例子是Thread.sleep()
。这是一种静态方法,可以使当前线程始终处于睡眠状态。不过看这代码:
Thread t = new Thread(someTask);
t.start();
t.sleep(1000);
是什么看起来像的代码是干什么的?它似乎将其他线程休眠,而实际上它将成为当前正在休眠的线程。当你将其更改为普通的静态调用,这是比较明显的:
Thread.sleep(1000);
这并不是指t
,所以必须是对当前线程。
除非有特定于php的地方,通过变量调用静态方法会给你一些多态性,我建议你坚持以静态方式调用它。严格模式告诉你这样做的事实是一个非常强大的暗示,IMO :)
还有没有涉及多态性。该函数在静态以及对象上下文中都被调用。我仍然不清楚,但如果这只是最佳实践或任何其他问题涉及此处。谢谢你的答案。 – pinaki 2010-07-09 06:12:14
使用它目前没有任何伤害,除非当被称为静态函数时,您无法访问$这个成员。
严格错误的原因是因为没有将您的代码写入严格的标准可能会导致错误发生,因为缺乏勤奋。在将来它可能会导致你的代码被破坏。一个静态函数没有$这个成员,它可能会破坏参数传递。
发挥它的安全只使用A :: b()类型调用调用静态函数。
DC
感谢您的回答。目前,它并没有在严格函数中使用$ this。 – pinaki 2010-07-09 06:15:25
静态成员函数不能期望$ this是有效的,因此不应该使用$ this指针。通过比较,C++具有静态成员和非静态成员,尽管它通常使用隐式指针,您可以使用this-> staticfunction()调用静态成员函数,而不会出现任何问题。但如果你试图在静态成员函数中使用'this',它会导致编译时错误,因为这在静态函数 – DeveloperChris 2010-07-12 01:20:59
关于在一个静态函数中访问$ this,我发现了一些有点古怪的事情(可能会在PHP的更高版本中进行更改,尽管我认为我运行了5.2版本)。
你可以在这里看到它,但它在瑞典语。但使用谷歌翻译,它应该是可以理解的。
+1,非常有趣的帖子(但与我的问题无关;-)).. – pinaki 2010-07-10 19:04:51
即使他调用foo :: getname(),它仍然没有问题,它仍然被称为非静态成员,因此$这指向第一次调用中的'foo'类和第二次中的'bar'类,因此他得到并调用奇怪的结果正是他应该得到的结果。 – DeveloperChris 2010-07-12 01:02:22
如果您的代码引发错误,请修复它们。如果您可以通过关闭E_STRICT来解决问题,则无关紧要。它在那里,你知道如何解决它,所以修复它。 – Gordon 2010-07-09 06:29:09
@gordon - 这里的问题是函数没有被定义为静态的,也没有使用任何类变量($ this)。所以,虽然我可以继续并将所有地方改为静态/对象,但我需要明确的理由在组织中指定我的工作......我希望现在这个问题更有意义。 – pinaki 2010-07-10 18:59:24
它已经有意义了:)但我认为你不应该向你的公司解释你为什么修复触发错误的代码,即使它只是* E_STRICT。你看,PHP已经告诉你不应该这样调用,所以为什么不去注意这一点。在旁注中,如果您有兴趣提高组织中的代码质量,请查看http://qualityassuranceinphpprojects.com/pages/tools.html – Gordon 2010-07-10 19:34:01