PHP - 静态方法与实例方法

2022-08-30 23:12:52

我有点困惑,因为我在PHP的OOP方面没有太多经验。我总是听说使用实例方法比使用静态方法更好,这是为什么呢?

我需要一个深刻的答案和解释,拜托。

例如,为什么应该使用实例方法完成下面的操作?

控制器:

public function getProperty($id){
        $property = Property::getProperty($id);
        return $property;
}

型:

public static function getProperty($id){
        //$query = DB::table('properties')...
        //Some Code;
        return $query;         
}

我正在阅读有关 setter/getter、instance vs static 等的信息。但我需要一个完整的答案来理解事情的方式原因


答案 1

通常,如前所述,实例方法是更好的做法。这并不是说静态方法是完全邪恶的,它们只是有一个不同的和独特的目的。

请务必注意,在处理实例方法时,您使用的是对象,而静态方法使用的是。使用静态方法时,您将无法访问实例通常可用的任何非静态属性。

以下代码为例:

class Foo
{
    private $bar;
    private static $tavern;

    public function changeBar($value)
    {
        $this->bar = $value;
    }

    public function getBar()
    {
        return $this->bar;
    }

    public static function changeTavern($value)
    {
        self::$tavern = $value;
    }

    public static function getTavern()
    {
        return self::$tavern;
    }
}

类具有静态属性和非静态属性 。Foo$tavern$bar

如果创建了 的实例,则所有属性和方法都可用于该对象Foo

如果 静态引用,则只有属性、方法和方法可用于该类Foo$tavernchangeTavern()getTavern()

让我们看一下下面的代码:

$foo = new Foo();
$foo->changeBar('Tipsy Turvy');
echo $foo->getBar(); // prints Tipsy Turvy

因为 是 的一个实例,所以它可以访问整个类。调用将修改属性。直接从静态方法更改属性将触发错误,因为该属性对对象而对可用。$fooFoochangeBar()$bar$bar$bar

// Calling this method would trigger an error
public static function changeBar($value)
{
    $this->bar = $value; // PHP will crash and burn if you try this.
}

如果要从静态方法访问类属性,则还必须将这些属性声明为 static。这将在上述类的上下文中工作。您还会注意到,的实例在读取静态属性时没有问题。Foo

Foo::changeTavern('Stumble Inn');
echo Foo::getTavern(); // prints Stumble Inn
echo $foo->getTavern(); // also prints Stumble Inn

关于静态代码要记住的另一件事是,它的行为不像一个实例。当第一个实例构建时,两个属性都没有价值。如果要创建 另一个实例,您会发现这些属性中只有一个不再包含值。(我相信到现在为止,你可以猜到哪一个。Foo$bar$tavernFoo

$anotherFoo = new Foo();
echo $anotherFoo->getBar(); // prints nothing
echo $anotherFoo->getTavern(); // prints Stumble Inn
echo Foo::getTavern(); // prints Stumble Inn

所以同样,静态代码意味着你直接使用一个 - 实例意味着你正在使用一个对象。请务必注意,您编写的任何类型的类,如果打算对其具有某种状态,都应用作实例。

静态类可能有点难以调试和测试。测试可能会有问题,因为在创建新实例时静态属性不会更改。调试也可能很困难,因为静态属性的值在类的所有实例中都是相同的。在一个中进行更改,您将在所有这些更改中进行更改。跟踪哪个实例进行了更改是一件痛苦的事情。

打个比喻,使用像糖这样的静态类 - 谨慎地,只在必要时。

希望这有助于阐明这个话题。


答案 2

实例方法并不比静态方法更好,它们只是意味着以不同的方式使用。例如,使工厂方法非静态将是疯狂的。

通常,当方法与类的当前实例有关时(使用该对象的某些状态,可能是配置参数),并且如果它只是属于整个类,则使实例方法成为静态方法,例如创建新对象,处理基元...

例如,ActiveRecords模式通常使用实例作为记录的映射,因此实例方法对记录进行读取/操作,以及静态方法,如搜索,批量更新/删除等。


推荐