Accolades en chaîne en PHP

Réponses:

289

C'est la syntaxe complexe (bouclée) pour l'interpolation de chaîne. À partir du manuel:

Syntaxe complexe (bouclée)

Cela n'est pas appelé complexe parce que la syntaxe est complexe, mais parce qu'elle 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 inclus 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 }. Comme {ne peut pas être échappé, cette syntaxe ne sera reconnue que lorsque le $suivant suit immédiatement le {. Utilisez {\$pour obtenir un littéral {$. Quelques exemples pour clarifier les choses:

<?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 faire:

$out = "${a}efgh"; // or
$out = "{$a}efgh";
cletus
la source
42
trop de pinailler anal sur le copier / coller. Si cela facilite la compréhension / la recherche, alors c'était une bonne décision. +1 de moi, c'était exactement ce que je cherchais, et je ne l'ai pas trouvé sur le manuel PHP - peut-être parce qu'ils l'appellent par le nom propre, ou autre. Mais je l'ai trouvé ici.
Gabriel Magana
9
Pour les boucles littérales, doublez-les, par exemple $vars='x:3,y:9'; $json="{{$vars}}";. Merci à l'article de QiGuang .
Bob Stein
... Ou $out = '$aefgh'; (si vous avez besoin du littéralement $ aefgh)
Roko C. Buljan
Un exemple de cas d'utilisation intéressant est SimpleXMLElement: {}est utilisé pour accéder au nœud lui-même, par exemple $element[0]->{0}. Puisque la propriété "0" ne peut pas exister, cela déclenchera __get/ __setmethod. Cela vous permet essentiellement une alternative à l' ArrayAccessaccès à l'index, par exemple 3v4l.org/1F254 .
Gajus
2
Si un contenu à l'intérieur d'accolades littérales contient aussi des variables, alors ajoutez des accolades à chaque variable: $min=1;$max=5; echo ".{{$min},{$max}}"yields .{1,5}(j'ai eu du mal à savoir où "doubler [les accolades] vers le haut" mentionné dans le commentaire de @ BobStein)
Xenos
47

Quant à moi, les accolades servent de substitution à la concaténation, elles sont plus rapides à 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 la 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

?>
Kredo900
la source
1
"leur contenu est analysé par PHP" - Ceci est trompeur. Vous ne pouvez pas simplement mettre des expressions PHP arbitraires dans la syntaxe d'accolades, c'est ce que je lis dans votre citation.
Mark Amery
1
OMI, dans l'ensemble, il n'est pas plus rapide de taper avec des crochets. Vous devez SHIFTappuyer sur la touche pour les guillemets doubles et pour les accolades. Ce serait plus rapide si vous utilisez strictement des guillemets doubles.
déflime le
2
Merci d'avoir mis en évidence les guillemets doubles contre les guillemets simples, +1
cameronjonesweb
J'utiliserais à la evaluateplace deparse
Cholthi Paul Ttiopic
tout ce qui a un guillemet simple attribué à une variable est traité comme une chaîne.
shashikant kuswaha
19

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, qui n'existe pas!

Obiware
la source
3

J'ai également trouvé utile d'accéder aux attributs d'objet où les noms d'attributs varient selon un itérateur. Par exemple, j'ai utilisé le modèle ci-dessous pour un ensemble de périodes: heure, jour, 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 pouvez facilement argumenter pour utiliser simplement un tableau pour le stockage de valeur par période. Si cette application était uniquement PHP, je serais d'accord. J'utilise ce modèle lorsque les attributs de classe sont mappés aux champs d'une table de base de données. Bien qu'il soit possible de stocker des tableaux dans une base de données à l'aide de la sérialisation, il est inefficace et inutile si les champs individuels doivent être indexés. J'ajoute souvent un tableau des noms de champs, saisis 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,
        );
    }
}
Ray N. Franklin
la source
-5

voici le code que j'ai obtenu d'un plugin wordpress

$data = $wpdb->get_results("select * from {$wpdb->prefix}download_monitor_files");

C'est une technique très pratique pour formater des chaînes complexes.

user1232972
la source