关于类:PHP类:何时使用:: vs. – >?

PHP Classes: when to use :: vs. ->?

我知道访问PHP类有两种方法——":"和"->"。有时一个似乎为我工作,而另一个却不为我工作,我不明白为什么。

每种方法的好处是什么?使用哪种方法是正确的?


简而言之,::表示类级属性,->表示对象级属性。

如果属性属于该类,则使用::

如果该属性属于该类的实例,请使用->

1
2
3
4
5
6
7
8
9
10
11
12
class Tester
{
  public $foo;
  const BLAH;

  public static function bar(){}
}

$t = new Tester;
$t->foo;
Tester::bar();
Tester::BLAH;


"::"符号用于访问用静态关键字声明的对象的方法/属性,"->"用于访问表示实例方法/属性的对象的方法/属性。


当您声明一个类时,它默认为"static"。您可以使用::操作符在任何范围内访问该类中的任何方法。这意味着,如果我创建了一个lib类,我可以在任何我想要的地方访问它,并且它不需要全局化:

1
2
3
4
5
6
7
8
class lib
{
    static function foo()
    {
       echo"hi";
    }
}
lib::foo(); // prints hi

现在,当您使用new关键字创建此类的实例时,您使用->访问方法和值,因为您引用的是该类的特定实例。你可以把->看作inside of。(注意,必须删除静态关键字)即:

1
2
3
4
5
6
7
8
9
class lib
    {
        function foo()
        {
           echo"hi";
        }
    }
$class = new lib;
$class->foo(); // I am accessing the foo() method INSIDE of the $class instance of lib.


在这方面,PHP可能会令人困惑,您应该阅读本文。

另一个令人困惑的是,您可以使用::符号调用非静态函数。这是非常奇怪的当你来自爪哇。当我第一次看到它的时候,它的确让我吃惊。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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引用。参见手册中的示例1。


::用于访问类静态属性。->用于访问类实例(对象)属性。

考虑这个产品类,它有两个用于检索产品详细信息的函数。一个函数getProductDetails属于一个类的实例,而另一个函数getProductDetailsStatic只属于该类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
  }
}

让我们来看看产品:

1
2
3
4
$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

考虑不需要实例化的此类:

1
2
3
4
5
6
7
8
9
10
class Helper {
  static function bin2hex($string = '') {
  }
  static function encryptData($data = '') {
  }
  static function string2Url($string = '') {
  }
  static function generateRandomString() {
  }
}

还应该注意的是,每个静态函数也可以使用类的一个实例来调用,但不能反过来调用。

因此,这是可行的:

1
2
3
4
5
6
7
8
class Foo
{
  public static function bar(){}
}

$f = new Foo();
$f->bar(); //works
Foo::bar(); //works

但这并不是:

1
2
3
4
5
6
7
8
9
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

当然,您应该限制自己以静态的方式调用静态方法,因为实例化一个实例不仅需要内存,而且也没有多大意义。

这个解释主要是为了说明为什么它在某些时候对你有用。


源维基百科-类

In object-oriented programming, a
class is a programming language
construct that is used as a blueprint
to create objects. This blueprint
describes the state and behavior that
the created objects all share. An
object created by a class is an
instance of the class, and the class
that created that instance can be
considered as the type of that object,
e.g. a type of an object created by a
"Fruit" class would be"Fruit".

::运算符访问使用static关键字在PHP中定义的类方法和属性。类const也可以使用::访问。

->运算符访问类实例的方法和属性。

如果函数在一个实例上运行,那么您将使用->。如果它在类本身上操作,那么您将使用::

::的另一个用途是当您想调用parent函数时。如果一个类继承另一个类-它可以重写父类中的方法,然后使用parent::function()调用它们。