Include constant in string without concatenating

2020-01-24 02:40发布

Is there a way in PHP to include a constant in a string without concatenating?

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";

12条回答
▲ chillily
2楼-- · 2020-01-24 03:08

As others have pointed out you can not do that. PHP has a function constant() which cant be called directly in a string but we can easily work around this.

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

and a basic example on its usage:

define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}"; 
查看更多
Root(大扎)
3楼-- · 2020-01-24 03:10

Here are some alternatives to the other answers, which seem to be focused mostly on the "{$}" trick. Though no guarantees are made on their speed; this is all pure syntactic sugar. For these examples, we'll assume the set of constants below were defined.

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

Using extract()
This one is nice because the result is identical to variables. First you create a reusable function:

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

Then call it from any scope:

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

Here, it lowercases the constants to be easier on your fingers, but you can remove the array_change_key_case() to keep them as-is. If you already have conflicting local variable names, the constants won't override them.

Using string replacement
This one is similar to sprintf(), but uses a single replacement token and accepts an unlimited number of arguments. I'm sure there are better ways to do this, but forgive my clunkiness and try to focus on the idea behind it.

Like before, you create a reusable function:

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

Then call it from any scope:

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

You can use any replacement token you want, like a % or #. I used the slash here since it's a bit easier to type.

查看更多
4楼-- · 2020-01-24 03:11

To use constants inside strings you can use the following method:

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

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


How does this work?

You can use any string function name and arbitrary parameters

One can place any function name in a variable and call it with parameters inside a double-quoted string. Works with multiple parameters too.

$fn = 'substr';

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

Produces

I like turtles

Anonymous functions too

You can also use anonymous functions provided you're running PHP 5.3+.

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

Produces properly escaped html as expected.

Callback arrays not allowed!

If by now you are under the impression that the function name can be any callable, that's not the case, as an array that returns true when passed to is_callable would cause a fatal error when used inside a string:

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

Keep in mind

This practice is ill-advised, but sometimes results in much more readable code, so it's up to you - the possibility is there.

查看更多
SAY GOODBYE
5楼-- · 2020-01-24 03:12
define( 'FOO', 'bar');  
$FOO = FOO;  
$string = "I am too lazy to concatenate $FOO in my string";
查看更多
Lonely孤独者°
6楼-- · 2020-01-24 03:14

It is fun that you can use keyword 'const' as a name for your function to prevent namespace littering:

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

You can also use $GLOBALS to propagate 'const' function all over the code:

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

Unsure is it safe for future using. And what is worse - it's still looks ugly.

查看更多
7楼-- · 2020-01-24 03:16

No.

With Strings, there is no way for PHP to tell string data apart from constant identifiers. This goes for any of the string formats in PHP, including heredoc.

constant() is an alternative way to get hold of a constant, but a function call can't be put into a string without concatenation either.

Manual on constants in PHP

查看更多
登录 后发表回答