【发布时间】:2010-11-16 12:33:52
【问题描述】:
我知道有两种方法可以访问 PHP 类 - “::”和“->”。有时一种似乎对我有用,而另一种则不起作用,我不明白为什么。
每种都有什么好处,在什么情况下可以使用它们?
【问题讨论】:
-
您可以阅读本主题:stackoverflow.com/questions/151969/php-self-vs-this>
我知道有两种方法可以访问 PHP 类 - “::”和“->”。有时一种似乎对我有用,而另一种则不起作用,我不明白为什么。
每种都有什么好处,在什么情况下可以使用它们?
【问题讨论】:
“::”符号用于访问已使用 static 关键字声明的对象的方法/属性,“->”用于访问表示实例方法/属性的对象的方法/属性。
【讨论】:
:: 运算符,两者都不必声明为静态。
简单地说,:: 用于类级属性,-> 用于对象级属性。
如果属性属于类,使用::
如果属性属于类的实例,请使用->
class Tester
{
public $foo;
const BLAH;
public static function bar(){}
}
$t = new Tester;
$t->foo;
Tester::bar();
Tester::BLAH;
【讨论】:
new Class),然后使用-> 使用对象内部的东西。如果您没有实例化对象,而只是想“按原样”调用类函数,则使用::。这实际上取决于您对 Class 的使用,一种方法并不比另一种更好。
$object->func() 没问题,注意$object 是一个变量,即它被实例化了。 ClassName::func() 也可以,注意ClassName 不是变量,它只是类名。 $object::func() 不好,您试图在实例化对象上静态调用方法。 ClassName->func() 反过来也不好。
当你声明一个类时,它默认是“静态的”。您可以使用:: 运算符在任何范围内访问该类中的任何方法。这意味着如果我创建了一个 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.
【讨论】:
还应该注意,每个静态函数也可以使用类的实例来调用,但不能反过来。
所以这行得通:
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
当然,您应该限制自己以静态方式调用静态方法,因为实例化实例不仅会消耗内存,而且没有多大意义。
这个解释主要是为了说明为什么它在某些时候对你有用。
【讨论】:
在面向对象编程中,一个 类是一种编程语言 用作蓝图的构造 创建对象。这个蓝图 描述状态和行为 创建的对象都共享。一个 类创建的对象是 类的实例和类 创建该实例的可以是 被视为该对象的类型, 例如一种由 a 创建的对象的类型 “水果”类将是“水果”。
:: 操作符访问在 php 中使用 static 关键字定义的类方法和属性。类const 也可以使用:: 访问
-> 运算符访问类实例的方法和属性。
如果函数在实例上运行,您将使用->。如果它在类本身上运行,您将使用::
:: 的另一个用途是当你想调用你的parent 函数时。如果一个类继承另一个类 - 它可以覆盖父类的方法,然后使用 parent::function() 调用它们
【讨论】:
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。
【讨论】:
:: 用于访问类静态属性。而-> 用于访问类实例(对象的)属性。
考虑这个 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() {
}
}
【讨论】: