我需要一个深刻的答案.
例如,为什么下面这个应该用instance方法呢?
控制器:
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,实例vs静态等等.但是我需要一个完整的答案来了解事情的原因和原因.
重要的是要注意,当处理实例方法时,你正在使用一个对象,而使用静态方法你正在使用一个类.当使用静态方法时,您将无法访问通常可用于实例的任何非静态属性.
以下列代码为例:
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的实例,则该对象可以使用所有属性和方法.
如果Foo被静态引用,那么只有$tavern属性changeTavern()方法和getTavern()方法可用于该类.
我们来看下面的代码:
$foo = new Foo(); $foo->changeBar('Tipsy Turvy'); echo $foo->getBar(); //prints Tipsy Turvy
由于$foo是和Foo的实例,它可以访问整个类.调用changeBar()将修改$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. }
如果要从静态方法访问类属性,那么这些属性也必须声明为静态.这将在上述类的上下文中工作.您还会注意到,Foo的一个实例在读取静态属性时没有问题.
Foo::changeTavern('Stumble Inn'); echo Foo::getTavern(); //prints Stumble Inn echo $foo->getTavern(); //also prints Stumble Inn
关于静态代码的另一件事是它不像一个实例.当Foo的第一个实例被建立了两个属性$bar和$小酒馆没有价值.如果要创建另一个Foo实例,您将发现只有其中一个属性不再包含值. (我现在肯定可以猜到哪一个.)
$anotherFoo = new Foo(); echo $anotherFoo->getBar(); //prints nothing echo $anotherFoo->getTavern(); //prints Stumble Inn echo Foo::getTavern(); //prints Stumble Inn
所以再次,静态代码意味着你正在直接使用一个类 – 实例意味着你正在使用一个对象.重要的是要注意,你写的任何类型的类,打算有某种状态,应该被用作一个实例.
静态类可能有点难以调试和测试.测试可能是有问题的,因为创建新实例时静态属性不会更改.调试也可能很困难,因为静态属性的值在类的所有实例中都相同.改变一个,你会在所有这些变化.跟踪哪个实例发生变化是一个痛苦.
以隐喻的方式说话,只要在需要的时候,就像糖一样使用静态类.
希望有助于阐明这个话题.