web-dev-qa-db-fra.com

Inclure une constante dans la chaîne sans concaténer

Existe-t-il un moyen dans PHP d'inclure une constante dans une chaîne sans concaténer?)

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";
149
Brian

Non.

Avec Strings, il n'y a aucun moyen pour PHP) de distinguer les données de chaîne des identificateurs de constante. Cela s'applique à tous les formats de chaîne en PHP, y compris heredoc.

constant() est un moyen alternatif d'obtenir une constante, mais un appel de fonction ne peut pas être mis dans une chaîne sans concaténation non plus.

Manuel sur les constantes en PHP

130
Pekka 웃

Oui c'est (en quelque sorte;)):

define('FOO', 'bar');

$test_string = sprintf('This is a %s test string', FOO);

Ce n'est probablement pas ce que vous vouliez, mais je pense que techniquement ce n'est pas une concaténation mais une substitution et à partir de cette hypothèse, il inclut une constante dans une chaîne sans concaténer.

101
Felix Kling

Pour utiliser des constantes dans des chaînes, vous pouvez utiliser la méthode suivante:

define( 'ANIMAL', 'turtles' ); 
$constant = 'constant';

echo "I like {$constant('ANIMAL')}";


Comment cela marche-t-il?

Vous pouvez utiliser n'importe quel nom de fonction de chaîne et paramètres arbitraires

On peut placer n'importe quel nom de fonction dans une variable et l'appeler avec des paramètres dans une chaîne entre guillemets. Fonctionne aussi avec plusieurs paramètres.

$fn = 'substr';

echo "I like {$fn('turtles!', 0, -1)}";

Produit

J'aime les tortues

Fonctions anonymes aussi

Vous pouvez également utiliser des fonctions anonymes à condition que vous utilisiez PHP 5.3+.

$escape   = function ( $string ) {
    return htmlspecialchars( (string) $string, ENT_QUOTES, 'utf-8' );
};
$userText = "<script>alert('xss')</script>";
echo( "You entered {$escape( $userText )}" );

Produit correctement échappé HTML comme prévu.

Les tableaux de rappel ne sont pas autorisés!

Si vous avez maintenant l'impression que le nom de la fonction peut être appelé, ce n'est pas le cas, car un tableau qui retourne true lorsqu'il est passé à is_callable provoquerait une erreur fatale lorsqu’il est utilisé dans une chaîne:

class Arr
{

    public static function get( $array, $key, $default = null )
    {
        return is_array( $array ) && array_key_exists( $key, $array ) 
            ? $array[$key] 
            : $default;
    }
}

$fn = array( 'Arr', 'get' );
var_dump( is_callable( $fn ) ); // outputs TRUE

// following line throws Fatal error "Function name must be a string"
echo( "asd {$fn( array( 1 ), 0 )}" ); 

Garder en tete

Cette pratique est déconseillée, mais aboutit parfois à un code beaucoup plus lisible, vous avez donc la possibilité - la possibilité existe.

54
raveren
define( 'FOO', 'bar');  
$FOO = FOO;  
$string = "I am too lazy to concatenate $FOO in my string";
21
Macswork
define('FOO', 'bar');
$constants = create_function('$a', 'return $a;');
echo "Hello, my name is {$constants(FOO)}";
14
thetaiko

Si vous voulez vraiment voulez faire écho à une constante sans concaténation voici la solution:

define('MY_CONST', 300);
echo 'here: ', MY_CONST, ' is a number';

note: dans cet exemple, echo prend un certain nombre de paramètres (regardez les virgules), donc ce n'est pas une vraie concaténation

L'écho se comporte comme une fonction, il prend plus de paramètres, il est plus efficace que la concaténation, car il n'a pas besoin de concaténer puis d'écho, il fait simplement écho à tout sans qu'il soit nécessaire de créer un nouvel objet enchaîné String :))

EDIT

Aussi, si vous considérez concaténer, chaînes, en passant les chaînes comme paramètres ou en écrivant chaînes entières avec ", Le , (virgule version) est toujours la plus rapide, la prochaine passe . (concaténation avec ' guillemets simples) et la méthode de construction de chaîne la plus lente utilise des guillemets doubles ", car les expressions écrites de cette façon doivent être évaluées par rapport aux variables et fonctions déclarées.

12
Juraj Blahunka

Vous pourriez faire:

define( 'FOO', 'bar' );

$constants = get_defined_constants(true); // the true argument categorizes the constants
$constants = $constants[ 'user' ]; // this gets only user-defined constants

echo "Hello, my name is {$constants['FOO']}";
11
Simon

Comme d'autres l'ont souligné, vous ne pouvez pas faire cela. PHP a une fonction constant()] qui ne peut pas être appelée directement dans une chaîne, mais nous pouvons facilement contourner ce problème.

$constant = function($cons){
   return constant($cons);
};

et un exemple de base sur son utilisation:

define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}"; 
5
Yamiko

Le plus simple est

define('MY_CONSTANT', 42);

$my_constant = MY_CONSTANT;
echo "This is my constant: $my_constant";

Une autre façon en utilisant (s)printf

define('MY_CONSTANT', 42);

// Note that %d is for numeric values. Use %s when constant is a string    
printf('This is my constant: %d', MY_CONSTANT);

// Or if you want to use the string.

$my_string = sprintf('This is my constant: %d', MY_CONSTANT);
echo $my_string;
4
Jekis

Voici quelques alternatives aux autres réponses, qui semblent se concentrer principalement sur le truc "{$}". Bien qu'aucune garantie ne soit faite sur leur vitesse; c'est tout le sucre syntaxique pur. Pour ces exemples, supposons que l'ensemble des constantes ci-dessous a été défini.

define( 'BREAD', 'bread' ); define( 'EGGS', 'eggs' ); define( 'MILK', 'milk' );

en utilisant extract ()
Celui-ci est agréable car le résultat est identique aux variables. Tout d'abord, vous créez une fonction réutilisable:

function constants(){ return array_change_key_case( get_defined_constants( true )[ 'user' ] ); }

Puis appelez-le de n'importe quelle portée:

extract( constants() );
$s = "I need to buy $bread, $eggs, and $milk from the store.";

Dans ce cas, les constantes doivent être réduites en minuscules, mais vous pouvez supprimer array_change_key_case () pour les conserver telles quelles. Si vous avez déjà des noms de variables locales en conflit, les constantes ne les remplacent pas.

tiliser le remplacement de chaîne
Celui-ci est similaire à sprintf (), mais utilise un seul jeton de remplacement et accepte un nombre illimité d'arguments. Je suis sûr qu'il existe de meilleures façons de le faire, mais pardonnez-moi et essayez de vous concentrer sur l'idée qui se cache derrière.

Comme auparavant, vous créez une fonction réutilisable:

function fill(){
    $arr = func_get_args(); $s = $arr[ 0 ]; array_shift( $arr );
    while( strpos( $s, '/' ) !== false ){
        $s = implode( current( $arr ), explode( '/', $s, 2 ) ); next( $arr );
    } return $s;
}

Puis appelez-le de n'importe quelle portée:

$s = fill( 'I need to buy /, /, and / from the store.', BREAD, EGGS, MILK );

Vous pouvez utiliser n’importe quel jeton de remplacement, comme un% ou un #. J'ai utilisé la barre oblique ici car il est un peu plus facile de taper.

2
Beejor

Il est amusant de pouvoir utiliser le mot-clé 'const' comme nom pour votre fonction afin d'éviter toute interférence dans l'espace de noms:

define("FOO","foo");
${'const'} = function($a){return $a;};
echo "{$const(FOO)}"; // Prints "foo"
echo const(FOO); // Parse error: syntax error, unexpected T_CONST

Vous pouvez également utiliser $ GLOBALS pour propager la fonction 'const' dans tout le code:

$GLOBALS['const'] = function($a){return $a;};

Je ne sais pas si c'est sûr pour une utilisation future. Et ce qui est pire - c'est toujours aussi moche.

0
user619271