我认为通常我们使用静态方法,因为我们不需要实例化对象。我们可以使用className::staticFunction
来调用静态方法,今天发现了:
<?php
class Foo {
static public function helloWorld() {
print "Hello world " ;
}
}
Foo::helloWorld();
<?php
class Foo {
public function helloWorld() {
print "Hello world " ;
}
}
Foo::helloWorld();
问题:
以上两个脚本都有效。我们没有将函数声明为static
,我们仍然可以使用className::staticFunction
来调用函数。为什么我们需要使用静态方法?
答案 0 :(得分:5)
我们没有将函数声明为static,我们仍然可以使用
className::staticFunction
您可能没有注意到的是PHP抱怨第二种类型的调用:
PHP严格标准:不应在第1行的php shell代码中静态调用非静态方法
Foo::helloWorld()
严格标准:不应在第1行的php shell代码中静态调用非静态方法
Foo::helloWorld()
要使这些通知可见,您需要使用-1
或ini_set()
配置文件将error_reporting
的值设置为php.ini
;顺便说一下,这是在开发过程中推荐的。
<强>结论强>
静态调用的函数应声明为static function xyz()
。
<强>更新强>
顺便说一句,使用范围解析运算符::
并不一定意味着您正在进行静态调用;考虑这个例子:
class Foo
{
public function helloWorld()
{
print "Hello world ";
}
public function doSomething()
{
self::helloWorld();
}
}
$f = new Foo;
$f->doSomething();
这是有效的,因为使用self::
而不是Foo::
不会更改调用“模式”(除非您调用的方法定义为static
)。
答案 1 :(得分:2)
静态方法的“问题”是它们的调用方式:
Foo::bar();
对静态方法的任何调用都必须是硬编码的,不能轻易替换。与:比较:
$foo->bar();
$foo
这里是变量,这意味着可以替换bar()
的确切对象和实现。这对依赖注入很重要,也是依赖注入的基础。
您将使用静态方法:
DateTime::createFromFormat()
而不是new DateTime
你可能在其他场景中使用静态函数,但这些是要点。您需要注意,声明一个静态方法意味着您需要静态调用它,这意味着它的调用时间使用不能真正改变。关于这一主题的长期条约,请阅读How Not To Kill Your Testability Using Statics。
答案 2 :(得分:0)
从上面的例子 test1.php
由于您添加了静态关键字, helloworld()
函数无法 覆盖或重载。
但是在第二个例子中, test2.php
helloworld()
功能可以 重载和覆盖
插图:1 (作品)
<?php
class Foo {
function helloWorld() {
print "Hello world " ;
}
}
class Foo1 extends Foo
{
function helloWorld()
{
echo "Foo's World";
}
}
$Foo1 = new Foo1();
$Foo1->helloWorld(); //Foo's World
插图:2(失败)
无法使静态方法Foo :: helloWorld()非静态
<?php
class Foo {
static function helloWorld() {
print "Hello world " ;
}
}
class Foo1 extends Foo
{
function helloWorld()
{
echo "Foo's World";
}
}
$Foo1 = new Foo1();
$Foo1->helloWorld();
答案 3 :(得分:0)
一个简单的hello world程序可能无法显示出很大的区别是静态vs的使用而不是看看这个类
class foo {
private $a = 1;
private static $b = 2;
public function foobar()
{
echo $this->a;
}
}
如果您静态拨打foobar
,则上述课程中的将无法解决$this->a
。
答案 4 :(得分:0)
PHP很有趣,但我通常会有一个实用程序类,它接受事物的参数来执行逻辑并返回。像这样的东西不需要实例化的类。由用户/开发人员正确调用方法(读取:使用正确的方法访问器)。
答案 5 :(得分:0)
当您处理基于OOP的大型项目时,您无疑将使用许多类(父类和子类)。这样做的一个不幸结果是,为了访问来自不同类的元素,必须手动传递每个类(或者更糟糕的是,将实例存储在全局变量中)。这可能令人沮丧,并且可能导致代码混乱和整体糟糕的项目设计。值得庆幸的是,可以从任何上下文(即脚本中的任何位置)访问静态元素,因此您可以访问这些方法,而无需将类的实例从对象传递到对象。
由于您不需要声明对象实例来访问静态元素,因此可以从不必要的声明中保存,以访问看似简单的函数。
静态元素在类的每个实例中都可用,因此您可以设置希望对类型的所有成员可用的值。