Какая разница между:: (двойной двоеточие) и → (стрелкой) в PHP?

Есть два разных способа доступа к методам в PHP, но какая разница?

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

и

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

Я предполагаю, что -> (тире с большим знаком или шевроном) используется для функций для переменных, а для функций для классов используется :: (double colons). Правильно?

Является ли оператор присваивания => использован только для назначения данных в массиве? Это в отличие от оператора присваивания =, который используется для создания или изменения переменной?

Ответ 1

Когда левая часть является экземпляром объекта, вы используете ->. В противном случае вы используете ::.

Это означает, что -> в основном используется для доступа к членам экземпляра (хотя он также может использоваться для доступа к статическим членам, такое использование не рекомендуется), а :: обычно используется для доступа к статическим членам (хотя в нескольких специальные случаи, он использовался для доступа к членам экземпляра).

В общем случае :: используется для разрешения области видимости и может иметь либо имя класса, parent, self, или (в PHP 5.3) static слева. parent относится к объему суперкласса класса, в котором он использовался; self относится к области применения класса; static ссылается на "вызываемый объем" (см. поздние статические привязки).

Правило состоит в том, что вызов с :: является вызовом экземпляра тогда и только тогда, когда:

  • целевой метод не объявляется как статический и
  • во время вызова существует совместимый контекст объекта, то есть они должны быть истинными:
    • вызов выполняется из контекста, где $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 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);

Кроме того, оператор :: (Оператор разрешения области действия, aka 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 - хорошая идея, когда у вас нет опыта ООП.

Ответ 3

Фактически этим символом мы можем вызвать метод класса, который является статическим и не зависит от другой инициализации...

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() не зависит от какого-либо другого метода или переменной, и это статический метод. Вот почему мы можем вызвать этот метод этим оператором без инициализации объекта этого класса.

Test::doWrite('Mrinmoy'); // Output: Hello Mrinmoy.

Но если вы хотите вызвать метод write таким образом, он будет генерировать ошибку, потому что она зависит от инициализации.

Ответ 4

Оператор => используется для назначения пар ключ-значение в ассоциативном массиве. Например:

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

Это значение похоже в выражении foreach:

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

Ответ 5

Разница между статическими и инстанцированными методами и свойствами, по-видимому, является одним из самых больших препятствий для тех, кто только начинается с OOP PHP в PHP 5.

Оператор двойной толстой кишки (называемый Paamayim Nekudotayim из иврита - пустяки) используется при вызове объекта или свойства из контекста static. Это означает, что экземпляр объекта еще не создан.

Оператор стрелки, наоборот, вызывает методы или свойства, которые ссылаются на экземпляр объекта.

Статические методы могут быть особенно полезны в объектных моделях, которые связаны с базой данных для методов создания и удаления, поскольку вы можете установить возвращаемое значение в вставленный идентификатор таблицы, а затем использовать конструктор для создания объекта с помощью идентификатора строки.

Ответ 6

Да, я просто ударил мой первый 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. Мой плохой, у меня был $instance::method(), который должен был быть $instance->method(). Дурак я.

Странно, что это все еще отлично работает на моей локальной машине (работает PHP 5.3.8) - ничего, даже предупреждение с error_reporting = E_ALL - но совсем не на тестовом сервере, там оно просто взрывается с синтаксическая ошибка и белый экран в браузере. Поскольку регистрация PHP была отключена на тестовой машине, а хостинговая компания была слишком занята, чтобы включить ее, это было не слишком очевидно.

Итак, слово предупреждения: по-видимому, некоторые установки PHP позволят вам использовать метод $instance:: method(), а другие нет.

Если кто-то может расшифровать, почему это так, сделайте.

Ответ 7

Оператор разрешения области (также называемый Paamayim Nekudotayim) или, проще говоря, двойное двоеточие, является токеном, который обеспечивает доступ к статическим, постоянным и переопределенным свойствам или методам класса. При ссылке на эти элементы вне определения класса используйте имя класса.

Ответ 8

Константа класса, свойство класса (статическое) и функция класса (статическое) могут иметь одно и то же имя и быть доступными через двойное двоеточие.