PHP 中的 :: (双冒号) 和 -> (箭头) 有什么区别?

php
2022-08-30 06:16:55

在PHP中访问方法有两种不同的方法,但是有什么区别呢?

$response->setParameter('foo', 'bar');

sfConfig::set('foo', 'bar');

我假设(大于符号或V形的破折号)用于变量的函数,(双冒号)用于类的函数。正确?->::

赋值运算符是否仅用于在数组中赋值数据?这是否与用于实例化或修改变量的赋值运算符相反?=>=


答案 1

当左侧部件是对象实例时,可以使用 。否则,请使用 。->::

这意味着它主要用于访问实例成员(尽管它也可用于访问静态成员,不鼓励使用此类),而通常用于访问静态成员(尽管在一些特殊情况下,它用于访问实例成员)。->::

通常,用于范围解析,并且它可能在其左侧有一个类名、、或(在 PHP 5.3 中)。 指使用它的类的超类的范围; 指使用它的类的范围; 指的是“被调用的作用域”(请参阅后期的静态绑定)。::parentselfstaticparentselfstatic

规则是,当且仅当以下情况时,with 的调用是实例调用:::

  • 目标方法未声明为静态
  • 在调用时有一个兼容的对象上下文,这意味着这些必须为真:
    1. 调用是从存在且$this
    2. 的类可以是被调用方法的类,也可以是它的子类。$this

例:

class A {
    public function func_instance() {
        echo "in ", __METHOD__, "\n";
    }
    public function callDynamic() {
        echo "in ", __METHOD__, "\n";
        B::dyn();
    }

}

class B extends A {
    public static $prop_static = 'B::$prop_static value';
    public $prop_instance = 'B::$prop_instance value';

    public function func_instance() {
        echo "in ", __METHOD__, "\n";
        /* this is one exception where :: is required to access an
         * instance member.
         * The super implementation of func_instance is being
         * accessed here */
        parent::func_instance();
        A::func_instance(); //same as the statement above
    }

    public static function func_static() {
        echo "in ", __METHOD__, "\n";
    }

    public function __call($name, $arguments) {
        echo "in dynamic $name (__call)", "\n";
    }

    public static function __callStatic($name, $arguments) {
        echo "in dynamic $name (__callStatic)", "\n";
    }

}

echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";

echo '$b->func_instance():', "\n", $b->func_instance(), "\n";

/* This is more tricky
 * in the first case, a static call is made because $this is an
 * instance of A, so B::dyn() is a method of an incompatible class
 */
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
 * instance of B (despite the fact we are in a method of A), so
 * B::dyn() is a method of a compatible class (namely, it's the
 * same class as the object's)
 */
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";

输出:

B::$prop_static: B::$prop_static value
B::func_static(): in B::func_static

$b->prop_instance: B::$prop_instance value
$b->func_static(): in B::func_static

$b->func_instance():
in B::func_instance
in A::func_instance
in A::func_instance

$a->dyn():
in A::callDynamic
in dynamic dyn (__callStatic)

$b->dyn():
in A::callDynamic
in dynamic dyn (__call)

答案 2

::静态上下文中使用,即。当某些方法或属性声明为静态时:

class Math {
    public static function sin($angle) {
        return ...;
    }
}

$result = Math::sin(123);

此外,当您调用父类的方法/属性时,运算符(范围解析运算符,又名 Paamayim Nekudotayim)在动态上下文中使用:::

class Rectangle {
     protected $x, $y;

     public function __construct($x, $y) {
         $this->x = $x;
         $this->y = $y;
     }
}

class Square extends Rectangle {
    public function __construct($x) {
        parent::__construct($x, $x);
    }
}

->用于动态上下文,即。当您处理某个类的某些实例时:

class Hello {
    public function say() {
       echo 'hello!';
    }
}

$h = new Hello();
$h->say();

顺便说一句:我不认为当你没有任何OOP经验时使用Symfony是一个好主意。


推荐