Quel est le sens de { }
(accolades) dans les littéraux de chaîne en PHP?
C'est la syntaxe complexe (bouclée) pour l'interpolation de chaîne. Du manuel:
Syntaxe complexe (frisée)
Ce n'est pas appelé complexe parce que la syntaxe est complexe, mais parce qu'il permet l'utilisation d'expressions complexes.
Toute variable scalaire, élément de tableau ou propriété d'objet avec une représentation sous forme de chaîne peut être incluse via cette syntaxe. Écrivez simplement l'expression de la même manière qu'elle apparaîtrait en dehors de la chaîne, puis enveloppez-la dans
{
Et}
. Puisque{
Ne peut pas être échappé, cette syntaxe ne sera reconnue que lorsque$
Suit immédiatement le{
. Utilisez{\$
Pour obtenir un littéral{$
. Quelques exemples pour le rendre clair:<?php // Show all errors error_reporting(E_ALL); $great = 'fantastic'; // Won't work, outputs: This is { fantastic} echo "This is { $great}"; // Works, outputs: This is fantastic echo "This is {$great}"; echo "This is ${great}"; // Works echo "This square is {$square->width}00 centimeters broad."; // Works, quoted keys only work using the curly brace syntax echo "This works: {$arr['key']}"; // Works echo "This works: {$arr[4][3]}"; // This is wrong for the same reason as $foo[bar] is wrong outside a string. // In other words, it will still work, but only because PHP first looks for a // constant named foo; an error of level E_NOTICE (undefined constant) will be // thrown. echo "This is wrong: {$arr[foo][3]}"; // Works. When using multi-dimensional arrays, always use braces around arrays // when inside of strings echo "This works: {$arr['foo'][3]}"; // Works. echo "This works: " . $arr['foo'][3]; echo "This works too: {$obj->values[3]->name}"; echo "This is the value of the var named $name: {${$name}}"; echo "This is the value of the var named by the return value of getName(): {${getName()}}"; echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}"; // Won't work, outputs: This is the return value of getName(): {getName()} echo "This is the return value of getName(): {getName()}"; ?>
Souvent, cette syntaxe est inutile. Par exemple, ceci:
$a = 'abcd';
$out = "$a $a"; // "abcd abcd";
se comporte exactement comme ceci:
$out = "{$a} {$a}"; // same
Les accolades sont donc inutiles. Mais ceci :
$out = "$aefgh";
selon votre niveau d'erreur, ne fonctionnera pas ou produira une erreur car il n'y a pas de variable nommée $aefgh
, vous devez donc procéder comme suit:
$out = "${a}efgh"; // or
$out = "{$a}efgh";
Quant à moi, les accolades servent de substitution à la concaténation, elles sont plus rapide taper et le code semble plus propre. N'oubliez pas d'utiliser des guillemets doubles ("") car leur contenu est analysé par PHP, car entre guillemets simples ('') vous obtiendrez le nom littéral de variable fournie:
<?php
$a = '12345';
// This works:
echo "qwe{$a}rty"; // qwe12345rty, using braces
echo "qwe" . $a . "rty"; // qwe12345rty, concatenation used
// Does not work:
echo 'qwe{$a}rty'; // qwe{$a}rty, single quotes are not parsed
echo "qwe$arty"; // qwe, because $a became $arty, which is undefined
?>
Exemple:
$number = 4;
print "You have the {$number}th edition book";
//output: "You have the 4th edition book";
Sans accolades PHP essaierait de trouver une variable nommée $numberth
, ça n'existe pas!
J'ai également trouvé utile d'accéder à des attributs d'objet où les noms d'attribut varient d'un itérateur à l'autre. Par exemple, j'ai utilisé le modèle ci-dessous pour une série de périodes: heure, jour et mois.
$periods=array('hour', 'day', 'month');
foreach ($periods as $period)
{
$this->{'value_'.$period}=1;
}
Ce même modèle peut également être utilisé pour accéder aux méthodes de classe. Construisez simplement le nom de la méthode de la même manière, en utilisant des chaînes et des variables de chaîne.
Vous pourriez facilement argumenter en utilisant simplement un tableau pour la valeur de stockage par période. Si cette application était PHP seulement, je suis d'accord. J'utilise ce modèle lorsque les attributs de classe sont mappés sur des champs d'une table de base de données. S'il est possible de stocker des tableaux dans une base de données à l'aide de la sérialisation, est inefficace, et inutile si les champs individuels doivent être indexés. J'ajoute souvent un tableau des noms de champs, indexés par l'itérateur, pour le meilleur des deux mondes.
class timevalues
{
// Database table values:
public $value_hour; // maps to values.value_hour
public $value_day; // maps to values.value_day
public $value_month; // maps to values.value_month
public $values=array();
public function __construct()
{
$this->value_hour=0;
$this->value_day=0;
$this->value_month=0;
$this->values=array(
'hour'=>$this->value_hour,
'day'=>$this->value_day,
'month'=>$this->value_month,
);
}
}