web-dev-qa-db-ja.com

連結せずに文字列に定数を含める

PHPに、連結せずに文字列に定数を含める方法はありますか?

define('MY_CONSTANT', 42);

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

番号。

Stringsでは、PHPが文字列データと定数識別子を区別する方法はありません。これは、heredocを含むPHPの文字列形式のいずれにも当てはまります。

constant()は定数を取得する代替方法ですが、関数呼び出しはできません連結せずに文字列に入れてください。

PHPの定数に関するマニュアル

130
Pekka 웃

はい、そうです(何らかの形で;)):

define('FOO', 'bar');

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

これはおそらくあなたが目指していたものではありませんが、技術的にはこれは連結ではなく置換であり、この仮定から連結せずに文字列に定数を含むと思います。

101
Felix Kling

文字列内で定数を使用するには、次の方法を使用できます。

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

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


これはどのように作動しますか?

任意の文字列関数名と任意のパラメーターを使用できます

任意の関数名を変数に配置し、二重引用符で囲まれた文字列内のパラメーターで呼び出すことができます。複数のパラメーターでも機能します。

$fn = 'substr';

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

生産する

私は亀が好きです

匿名関数も

PHP 5.3+。を実行している場合は、匿名関数を使用することもできます。

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

期待どおりに適切にエスケープされたhtmlを生成します。

コールバック配列は許可されていません!

関数名が任意の呼び出し可能になり得るという印象を受けた場合、そうではありません。is_callableに渡されたときにtrueを返す配列は、文字列内で使用すると致命的なエラーを引き起こします。

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

覚えておいてください

この方法はお勧めしませんが、コードがはるかに読みやすくなる場合があるため、あなた次第です-可能性はあります。

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

本当に連結なしで定数をエコーし​​たい場合ここに解決策があります:

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

:この例では、エコーはいくつかのパラメーターを取ります(カンマを見てください)。したがって、実際の連結ではありません

エコーは関数として動作し、より多くのパラメータを取り、連結よりも効率的です。連結してからエコーする必要がないため、新しい文字列連結オブジェクトを作成することなくすべてをエコーし​​ます:))

[〜#〜] edit [〜#〜]

また、concatenating文字列を考慮する場合、文字列をparametersとして渡すか、"で文字列全体を書く(コンマバージョン)は常に最速で、次は'単一引用符との連結)で、最も遅い文字列構築方法は二重引用符"を使用しますこの方法で記述された式は、宣言された変数と関数に対して評価される必要があります。

12
Juraj Blahunka

できること:

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

他の人が指摘したように、あなたはそれをすることはできません。 PHPには関数constant()があり、文字列で直接呼び出すことはできませんが、これを簡単に回避できます。

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

そしてその使用法の基本的な例:

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

最も簡単な方法は

define('MY_CONSTANT', 42);

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

(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

他の回答に対するいくつかの選択肢がありますが、それらは主に「{$}」トリックに焦点を当てているようです。ただし、速度については保証されていません。これはすべて純粋な構文糖です。これらの例では、以下の定数のセットが定義されていると仮定します。

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

extract()を使用
結果は変数と同一であるため、これは素晴らしいです。最初に、再利用可能な関数を作成します。

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

次に、任意のスコープから呼び出します:

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

ここでは、指を簡単にするために定数を小文字にしていますが、array_change_key_case()を削除してそのまま保持することができます。競合するローカル変数名が既にある場合、定数はそれらをオーバーライドしません。

文字列置換を使用
これはsprintf()に似ていますが、単一の置換トークンを使用し、無制限の数の引数を受け入れます。私はこれを行うより良い方法があると確信していますが、私の不器用さを許し、その背後にあるアイデアに集中しようとします。

前と同様に、再利用可能な関数を作成します。

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

次に、任意のスコープから呼び出します:

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

%や#など、必要な置換トークンを使用できます。入力しやすいので、ここではスラッシュを使用しました。

2
Beejor

名前空間のポイ捨てを防ぐために、関数の名前としてキーワード 'const'を使用できるのは楽しいです。

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

また、$ GLOBALSを使用して、コード全体に「const」関数を伝播することもできます。

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

将来使用しても安全かどうか不明です。さらに悪いことに、それはまだugいようです。

0
user619271