Question Quelle est la différence entre :: (double deux points) et -> (flèche) en PHP?


Il y a deux manières distinctes d'accéder aux méthodes en PHP, mais quelle est la différence?

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

et

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

je suppose -> (tiret avec plus grand que signe ou chevron) est utilisé pour les fonctions pour les variables, et :: (double-deux-points) est utilisé pour les fonctions pour les classes. Correct?

Est le => opérateur d'affectation utilisé uniquement pour affecter des données dans un tableau? Est-ce en contraste avec le = opérateur d'affectation qui est utilisé pour instancier ou modifier une variable?


165
2017-07-04 02:17


origine


Réponses:


Lorsque la partie gauche est une instance d'objet, vous utilisez ->. Sinon, vous utilisez ::.

Cela signifie que -> est principalement utilisé pour accéder aux membres de l'instance (bien qu'il puisse également être utilisé pour accéder aux membres statiques, cet usage est déconseillé), tandis que :: est généralement utilisé pour accéder aux membres statiques (bien que dans certains cas particuliers, il soit utilisé pour accéder aux membres de l'instance).

En général, :: est utilisé pour résolution de la portée, et il peut avoir soit un nom de classe, parent, self, ou (en PHP 5.3) static à sa gauche. parent fait référence à la portée de la superclasse de la classe où il est utilisé; self fait référence à la portée de la classe où il est utilisé; static se réfère à la "portée appelée" (voir reliures statiques tardives).

La règle est qu'un appel avec :: est un appel d'instance si et seulement si:

  • la méthode cible n'est pas déclarée comme statique et
  • il existe un contexte d'objet compatible au moment de l'appel, ce qui signifie que ces objets doivent être vrais:
    1. l'appel est fait à partir d'un contexte où $this existe et
    2. la classe de $this est soit la classe de la méthode appelée ou une sous-classe de celle-ci.

Exemple:

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";

Sortie:

B :: $ prop_static: valeur B :: $ prop_static
B :: func_static (): dans B :: func_static

$ b-> prop_instance: B :: $ prop_instance la valeur
$ b-> func_static (): dans B :: func_static

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

$ a-> dyn ():
dans A :: callDynamic
en dynamique dyn (__callStatic)

$ b-> dyn ():
dans A :: callDynamic
en dynamique dyn (__call)

150
2017-07-04 02:20



:: est utilisé dans statique contexte, c.-à-d. quand une méthode ou une propriété est déclarée comme statique:

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

$result = Math::sin(123);

Également :: opérateur (l’opérateur Scope Resolution, a.k.a Paamayim Nekudotayim) est utilisé dans un contexte dynamique lorsque vous appelez une méthode / propriété d'une classe parente:

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

-> est utilisé dans dynamique contexte, c.-à-d. lorsque vous traitez avec une instance d'une classe:

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

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

Au fait: je ne pense pas que l'utilisation de Symfony soit une bonne idée quand vous n'avez aucune expérience OOP.


38
2017-07-04 02:30



En fait, par ce symbole, nous pouvons appeler une méthode de classe qui est statique et ne dépend pas d'une autre initialisation ...

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;
    }
}

Ici, la fonction doWrite () ne dépend d'aucune autre méthode ou variable, et c'est une méthode statique. C'est pourquoi nous pouvons appeler cette méthode par cet opérateur sans initialiser l'objet de cette classe.

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

Mais si vous voulez appeler le writeCette méthode générera une erreur car elle dépend de l'initialisation.


19
2017-12-08 08:00



le => L'opérateur est utilisé pour affecter des paires clé-valeur dans un tableau associatif. Par exemple:

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

Sa signification est similaire dans le foreach déclaration:

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

14
2017-07-04 02:28



La différence entre les méthodes et les propriétés statiques et instanciées semble être l'un des plus gros obstacles à ceux qui commencent tout juste avec PHP en PHP 5.

L'opérateur double côlon (appelé Paamayim Nekudotayim de l'hébreu - trivia) est utilisé lors de l'appel d'un objet ou d'une propriété depuis un statique le contexte. Cela signifie qu'une instance de l'objet n'a pas encore été créée.

L'opérateur de flèches, inversement, appelle des méthodes ou des propriétés qui proviennent d'une référence d'une instance de l'objet.

Les méthodes statiques peuvent être particulièrement utiles dans les modèles d'objet liés à une base de données pour les méthodes create et delete, car vous pouvez définir la valeur de retour sur l'ID de la table insérée, puis utiliser le constructeur pour instancier l'objet par l'ID de ligne.


12
2017-07-06 20:12



Oui, je viens de frapper mon premier 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. Mon mauvais, j'ai eu un $instance::method() cela aurait dû être $instance->method(). Que je suis bête.

La chose étrange est que cela fonctionne toujours très bien sur ma machine locale (PHP 5.3.8) - rien, pas même un avertissement avec error_reporting = E_ALL - mais pas du tout sur le serveur de test, il explose avec une erreur de syntaxe et un écran blanc dans le navigateur. Comme la journalisation PHP était désactivée sur la machine de test et que la société d'hébergement était trop occupée pour l'activer, cela n'était pas trop évident.

Donc, un mot d'avertissement: apparemment, certaines installations PHP vous permettront d'utiliser un $ instance :: method (), d'autres pas. 

Si quelqu'un peut expliquer pourquoi, veuillez le faire.


2
2018-03-07 09:41