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

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

and

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

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

=>赋值操作符仅用于赋值数组中的数据吗?这与用于实例化或修改变量的=赋值操作符相反吗?


当左边是一个对象实例时,使用->。否则,使用::。

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

通常,::用于作用域解析,它的左边可能有类名、父类名、self或(在PHP 5.3中)static。父类指的是使用它的类的超类的范围;Self指的是使用它的类的范围;静态指的是“被调用的作用域”(参见后期静态绑定)。

规则是使用::的调用是实例调用当且仅当:

目标方法没有声明为静态和 在调用时有一个兼容的对象上下文,这意味着这些必须为真: 调用是从$this存在的上下文中进行的 $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)

=>操作符用于在关联数组中分配键-值对。例如:

$fruits = array(
  'Apple'  => 'Red',
  'Banana' => 'Yellow'
);

它在foreach语句中的含义类似:

foreach ($fruits as $fruit => $color)
  echo "$fruit is $color in color.";

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

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();

顺便说一句:我认为如果您没有任何面向对象开发经验,那么使用Symfony不是一个好主意。


静态方法和实例化方法和属性之间的差异似乎是那些刚开始使用PHP 5中的OOP PHP的人最大的障碍之一。

双冒号操作符(在希伯来语中称为Paamayim Nekudotayim -琐事)用于从静态上下文中调用对象或属性。这意味着还没有创建对象的实例。

相反,箭头操作符调用来自对象实例引用的方法或属性。

静态方法在用于创建和删除方法而链接到数据库的对象模型中特别有用,因为您可以将返回值设置为插入的表id,然后使用构造函数根据行id实例化对象。


是的,我刚刚击中我的第一个“PHP解析错误:语法错误,意外的T_PAAMAYIM_NEKUDOTAYIM”。我的坏,我有一个$instance::method(),应该是$instance->method()。愚蠢的我。

奇怪的是,这在我的本地机器(运行PHP 5.3.8)上仍然可以正常工作-什么都没有,甚至没有error_reporting = E_ALL的警告-但在测试服务器上完全没有,在那里它只是伴随着语法错误和浏览器中的白色屏幕爆炸。由于PHP日志记录在测试机器上被关闭了,而托管公司又太忙而没有打开它,所以问题并不明显。

因此,请注意:显然,某些PHP安装将允许您使用$instance::method(),而其他安装则不允许。

如果有人能详细说明原因,请说。


实际上,通过这个符号,我们可以调用一个静态的类方法,它不依赖于其他初始化…

class Test {

    public $name;

    public function __construct() {
        $this->name = 'Mrinmoy Ghoshal';
    }

    public static function doWrite($name) {
        print 'Hello '.$name;
    }

    public function write() {
        print $this->name;
    }
}

这里的doWrite()函数不依赖于任何其他方法或变量,它是一个静态方法。这就是为什么我们可以通过这个操作符调用这个方法,而不需要初始化这个类的对象。

测试:doWrite(“Mrinmoy”); //输出:Hello Mrinmoy。

但是如果你想以这种方式调用write方法,它会生成一个错误,因为它依赖于初始化。