3

以下是静态方法和非静态方法的php类代码示例。

示例 1:

class A{
    //None Static method
    function foo(){
        if (isset($this)) {
            echo '$this is defined (';
            echo get_class($this);
            echo ")<br>";
        } else {
            echo "\$this is not defined.<br>";
        }
    }
 }

 $a = new A();
 $a->foo();
 A::foo();

 //result
 $this is defined (A)
 $this is not defined.

示例 2:

class A{
    //Static Method
    static function foo(){
        if (isset($this)) {
            echo '$this is defined (';
            echo get_class($this);
            echo ")<br>\n";
        } else {
            echo "\$this is not defined.<br>\n";
        }
    }
 }

 $a = new A();
 $a->foo();
 A::foo();

 //result
 $this is not defined.
 $this is not defined.

我试图弄清楚这两个类之间有什么区别。

正如我们在非静态方法的结果中看到的那样,定义了“$this”。

但另一方面,即使它们都被实例化,静态方法的结果也没有定义。

我想知道为什么它们都有不同的结果,因为它们都被实例化了?

请您告诉我这些代码发生了什么。

4

2 回答 2

5

在我们继续之前:请养成始终指定对象属性和方法的可见性/可访问性的习惯。而不是写

function foo()
{//php 4 style method
}

写:

public function foo()
{
    //this'll be public
}
protected function bar()
{
    //protected, if this class is extended, I'm free to use this method
}
private function foobar()
{
    //only for inner workings of this object
}

首先,您的第一个示例A::foo将触发通知(静态调用非静态方法总是这样做)。
其次,在第二个示例中,调用 时A::foo(),PHP 不会创建即时实例,也不会在您调用时调用实例上下文中的方法$a->foo()(顺便说一句,这也会发出通知)。本质上,静态是全局函数,因为在内部,PHP 对象只不过是一个 C struct,而方法只是具有指向该结构的指针的函数。至少,这是它的要点,更多细节在这里

静态属性或方法的主要区别(如果使用得当的话)是,它们在所有实例中共享并且可以全局访问:

class Foo
{
    private static $bar = null;
    public function __construct($val = 1)
    {
        self::$bar = $val;
    }
    public function getBar()
    {
        return self::$bar;
    }
}
$foo = new Foo(123);
$foo->getBar();//returns 123
$bar = new Foo('new value for static');
$foo->getBar();//returns 'new value for static'

如您所见,$bar不能在每个实例上设置静态属性,如果更改其值,则更改适用于所有实例。
如果$bar是公开的,你甚至不需要一个实例来改变任何地方的属性:

class Bar
{
    public $nonStatic = null;
    public static $bar = null;
    public function __construct($val = 1)
    {
        $this->nonStatic = $val;
    }
}
$foo = new Bar(123);
$bar = new Bar('foo');
echo $foo->nonStatic, ' != ', $bar->nonStatic;//echoes "123 != foo"
Bar::$bar = 'And the static?';
echo $foo::$bar,' === ', $bar::$bar;// echoes 'And the static? === And the static?'

查看工厂模式,并且(纯粹提供信息)还可以查看 Singleton 模式。就单例模式而言:还有谷歌为什么使用它。IoC、DI、SOLID 是您很快就会遇到的首字母缩略词。阅读他们的意思并弄清楚为什么他们(每个人都以自己的方式)不去单身人士的主要原因

于 2013-07-15T11:00:09.017 回答
2

有时你需要使用一个方法但你不想调用类,因为类中的某些函数会自动调用,如 __construct、__destruct、...(魔术方法)。

称为类:

$a = new A();
$a->foo();

不要调用类:(只是运行 foo() 函数)

A::foo();

http://php.net/manual/en/language.oop5.magic.php

于 2013-07-15T11:13:56.997 回答