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】:

:: 用于访问类静态属性。而-&gt; 用于访问类实例(对象的)属性。

考虑这个 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. ->?的主要内容,如果未能解决你的问题,请参考以下文章

什么决定了类对象何时在 PHP 中被销毁?

私有继承 VS 组合:何时使用哪个?

Hadoop MapReduce vs MPI(vs Spark vs Mahout vs Mesos) - 何时使用一个而不是另一个?

何时使用包装类和原始类型

IEnumerable,IEnumerator vs foreach,何时使用啥[重复]

何时使用 [self.obj message] vs [obj message] [重复]