次のコードは完全に機能しています。
${0x0} = 'test';
echo ${0x0}; // prints "test"
しかし、その理由はわかりません。0x0
(または0
、非16進の人々がそれを呼ぶように)それはランダムなコンテナであり、それは任意の数である可能性がありますが、php変数は数で始めることはできません。ここで使用されることの何が特別なの{ }
か、そしてそれらの制限は何ですか?
次のコードは完全に機能しています。
${0x0} = 'test';
echo ${0x0}; // prints "test"
しかし、その理由はわかりません。0x0
(または0
、非16進の人々がそれを呼ぶように)それはランダムなコンテナであり、それは任意の数である可能性がありますが、php変数は数で始めることはできません。ここで使用されることの何が特別なの{ }
か、そしてそれらの制限は何ですか?
まず第一に、変数変数構文で使用されると文字列にキャストされる16進表現0x0
の単なる規則です。0
'0'
var_dump(0x0===0); // prints "bool(true)"
${0x0} = 'test';
echo ${0x0}; // prints "test"
echo ${'0'}; // prints "test" as well
var_dump(get_defined_vars()); // contains ["0"] => string(4) "test"
あなたはそれが有効な変数名ではないとあなたが言う正しいホエーです:
変数名は、PHPの他のラベルと同じ規則に従います。有効な変数名は、文字またはアンダースコアで始まり、その後に任意の数の文字、数字、またはアンダースコアが続きます。正規表現としては、次のように表現されます。'[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] *'
$0foo = 'Test';
これが、解析エラーをトリガーする理由です。
変数変数の構文を使った簡単なテストでは、実際、PHPは、文字列である限り、変数名を実際には気にしていないように見えることがわかります。
${'123 abc xyz '} = 'Test';
echo ${'123 abc xyz '}; // Test
echo ${'123 abc xyz '}; // PHP Notice: Undefined variable: 123 abc xyz in ...
var_dump(get_defined_vars()); // ["123 abc xyz "] => string(4) "Test"
私の推測では、前述の命名制限は、言語コアではなくソースコードパーサーによって課せられています。PHPコードを分析するときに変数を区別するには、このようなルールが必要です。内部的には、PHPを強化するZendエンジンは、変数をハッシュマップとして処理します。
PHP変数は、一般に2つの要素で構成されています。たとえば、シンボルテーブルのエントリであるラベルと、実際の変数コンテナです。
ラベルの有効な文字列を受け取る限り、それは幸せです。
ドキュメントから:
プロパティ名を明確に区切るために、中括弧を使用することもできます。これらは、配列を含むプロパティ内の値にアクセスする場合、プロパティ名が複数の部分で構成されている場合、またはプロパティ名に有効でない文字が含まれている場合(例: json_decode() または SimpleXML から) に最も役立ちます。
${...}
これは、 を使用する場合、変数名に使用できる文字に関して制限がないことを意味します。しかし、そうすべきかどうか...
PHP パーサーは、文字列を返す (または文字列にキャストできる) 任意の式から変数名を作成するための特別な構文を提供します。
<?php
define('A', 'aaa');
${' _ '} = 'blah';
${'test' . A . (2 + 6)} = 'var';
echo ${' _ '}; // blah
echo ${'testaaa8'}; // var
${'123'} = 'blah';
echo ${100 + 23}; // blah
function returnVarName() {
return 'myVar';
}
$myVar = 12;
echo ${returnVarName()}; // 12
この構文は、オブジェクト プロパティにも使用できます。
$object->{' some property ... with strage name'};
0x0
0
リテラルの 16 進表現です。
言い換えれば、そのような場合の中括弧内のすべてが文字列です!
つまり、s0x0
は確かに の 16 進バージョンです0
が、ここでは両方とも文字列です! だからこそ働ける${0x0}
か、働かないか!${0}
$0
$0x0
@Michael Robinsonが言ったことに加えて、あなたの例ではこれも有効です:
${0x0} = 'test';
$var = "0";
echo $$var; // prints "test"