PHP 类:何时使用 :: vs. ->?
Posted
技术标签:
【中文标题】PHP 类:何时使用 :: vs. ->?【英文标题】:PHP Classes: when to use :: vs. ->? 【发布时间】:2010-11-16 12:33:52 【问题描述】:我知道有两种方法可以访问 php 类 - “::”和“->”。有时一种似乎对我有用,而另一种则不起作用,我不明白为什么。
每种都有什么好处,在什么情况下可以使用它们?
【问题讨论】:
您可以阅读本主题:***.com/questions/151969/php-self-vs-this> 链接错误,***.com/questions/151969/php-self-vs-this 【参考方案1】:“::”符号用于访问已使用 static 关键字声明的对象的方法/属性,“->”用于访问表示实例方法/属性的对象的方法/属性。
【讨论】:
说“使用静态关键字”有点不正确。这不是唯一的情况 - 访问父方法和常量都需要::
运算符,两者都不必声明为静态。【参考方案2】:
简单地说,::
用于类级属性,->
用于对象级属性。
如果属性属于类,使用::
如果属性属于类的实例,请使用->
class Tester
public $foo;
const BLAH;
public static function bar()
$t = new Tester;
$t->foo;
Tester::bar();
Tester::BLAH;
【讨论】:
所以,例如...如果我有一个库类,并且其中有一个函数将返回一个连接到我的 mysql(基本上作为单例),我可以并且应该通过以下方式引用它做类似 library::connect();而不是 $libraryObject->connect(); ? 另外,如果我使用对象,我必须将它传递给其他函数,但如果我使用静态运算符,我可以避免范围问题吗?提前致谢! @jonnietheblack:没有应该,这是你想做什么的问题。如果你想使用一个可以传递、复制、克隆等的对象,你可以从类中实例化对象(使用new Class
),然后使用->
使用对象内部的东西。如果您没有实例化对象,而只是想“按原样”调用类函数,则使用::
。这实际上取决于您对 Class 的使用,一种方法并不比另一种更好。
换一种说法:$object->func()
没问题,注意$object
是一个变量,即它被实例化了。 ClassName::func()
也可以,注意ClassName
不是变量,它只是类名。 $object::func()
不好,您试图在实例化对象上静态调用方法。 ClassName->func()
反过来也不好。
过于简化...任何阅读此答案的人,请检查使用静态的所有优点/缺点。我读到有人说“静态方法不是 OOP,它们是变相的程序代码”【参考方案3】:
当你声明一个类时,它默认是“静态的”。您可以使用::
运算符在任何范围内访问该类中的任何方法。这意味着如果我创建了一个 lib 类,我可以在任何我想要的地方访问它,并且不需要全局化:
class lib
static function foo()
echo "hi";
lib::foo(); // prints hi
现在,当您使用 new
关键字创建此类的实例时,您使用 ->
来访问方法和值,因为您指的是该类的特定实例。您可以将->
视为inside of
。 (注意,必须去掉 static 关键字) IE:
class lib
function foo()
echo "hi";
$class = new lib;
$class->foo(); // I am accessing the foo() method INSIDE of the $class instance of lib.
【讨论】:
您的第一个示例将在 E_STRICT 中引发错误:不应静态调用非静态方法 lib::foo()。 已更新,尽管我从未遇到过错误,尽管文档上说应该。【参考方案4】:还应该注意,每个静态函数也可以使用类的实例来调用,但不能反过来。
所以这行得通:
class Foo
public static function bar()
$f = new Foo();
$f->bar(); //works
Foo::bar(); //works
这不是:
class Foo
protected $test="fddf";
public function bar() echo $this->test;
$f = new Foo();
$f->bar(); //works
Foo::bar(); //fails because $this->test can't be accessed from a static call
当然,您应该限制自己以静态方式调用静态方法,因为实例化实例不仅会消耗内存,而且没有多大意义。
这个解释主要是为了说明为什么它在某些时候对你有用。
【讨论】:
这没有任何意义,因为没有实例就没有此方法可以访问的非静态变量。你试过吗?如果是这样,您使用的是哪个版本?此外,如果它可以工作,静态关键字也不会给方法带来任何变化。 刚刚尝试了一下,发现只有当您调用在静态上下文中使用动态变量的动态方法时,它才会死掉。 PHP 在某些方面严重缺乏清晰的编码风格:-/【参考方案5】:采购WikiPedia - Class
在面向对象编程中,一个 类是一种编程语言 用作蓝图的构造 创建对象。这个蓝图 描述状态和行为 创建的对象都共享。一个 类创建的对象是 类的实例和类 创建该实例的可以是 被视为该对象的类型, 例如一种由 a 创建的对象的类型 “水果”类将是“水果”。
::
操作符访问在 php 中使用 static
关键字定义的类方法和属性。类const
也可以使用::
访问
->
运算符访问类实例的方法和属性。
如果函数在实例上运行,您将使用->
。如果它在类本身上运行,您将使用::
::
的另一个用途是当你想调用你的parent
函数时。如果一个类继承另一个类 - 它可以覆盖父类的方法,然后使用 parent::function()
调用它们
【讨论】:
【参考方案6】:Php 在这方面可能会令人困惑,您应该阅读this。
同样令人困惑的是,您可以使用 :: 符号调用非静态函数。当您来自 Java 时,这很奇怪。当我第一次看到它时,它确实让我感到惊讶。
例如:
class Car
public $name = "Herbie <br/>";
public function drive()
echo "driving <br/>";
public static function gas()
echo "pedal to the metal<br/>";
Car::drive(); //will work
Car::gas(); //will work
$car = new Car();
$car->drive(); // will work
$car->gas(); //will work
echo $car->name; // will work
echo Car::$name; // wont work error
如您所见,静态在 php 中非常松散。您可以使用 -> 和 :: 符号调用任何函数。但是当你用 :: 调用时有区别,没有对实例的 $this 引用。请参阅manual 中的示例 #1。
【讨论】:
【参考方案7】:::
用于访问类静态属性。而->
用于访问类实例(对象的)属性。
考虑这个 Product 类,它有两个用于检索产品详细信息的函数。一个函数getProductDetails
属于一个类的实例,而另一个getProductDetailsStatic
只属于这个类。
class Product
protected $product_id;
public function __construct($product_id)
$this->product_id = $product_id;
public function getProductDetails()
$sql = "select * from products where product_id= $this->product_id ";
return Database::execute($sql);
public static function getProductDetailsStatic($product_id)
$sql = "select * from products where product_id= $product_id ";
return Database::execute($sql);
让我们获取产品:
$product = new Product('129033'); // passing product id to constructor
var_dump( $product->getProductDetails() ); // would get me product details
var_dump( Product::getProductDetailsStatic('129033') ); // would also get me product details
你什么时候使用Static properties
?
考虑这个可能不需要实例化的类:
class Helper
static function bin2hex($string = '')
static function encryptData($data = '')
static function string2Url($string = '')
static function generateRandomString()
【讨论】:
以上是关于PHP 类:何时使用 :: vs. ->?的主要内容,如果未能解决你的问题,请参考以下文章
Hadoop MapReduce vs MPI(vs Spark vs Mahout vs Mesos) - 何时使用一个而不是另一个?