37

次のコードは完全に機能しています。

${0x0} = 'test';
echo ${0x0}; // prints "test"

しかし、その理由はわかりません。0x0(または0、非16進の人々がそれを呼ぶように)それはランダムなコンテナであり、それは任意の数である可能性がありますが、php変数は数で始めることはできません。ここで使用されることの何が特別なの{ }か、そしてそれらの制限は何ですか?

4

5 に答える 5

31

まず第一に、変数変数構文で使用されると文字列にキャストされる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つの要素で構成されています。たとえば、シンボルテーブルのエントリであるラベルと、実際の変数コンテナです。

ラベルの有効な文字列を受け取る限り、それは幸せです。

于 2013-03-07T12:20:11.827 に答える
25

ドキュメントから:

プロパティ名を明確に区切るために、中括弧を使用することもできます。これらは、配列を含むプロパティ内の値にアクセスする場合、プロパティ名が複数の部分で構成されている場合、またはプロパティ名に有効でない文字が含まれている場合(例: json_decode() または SimpleXML から) に最も役立ちます。

${...}これは、 を使用する場合、変数名に使用できる文字に関して制限がないことを意味します。しかし、そうすべきかどうか...

于 2013-03-07T12:01:28.420 に答える
4

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

0x00リテラルの 16 進表現です。

于 2013-03-07T12:02:48.440 に答える
4

言い換えれば、そのような場合の中括弧内のすべてが文字列です!

つまり、s0x0は確かに の 16 進バージョンです0が、ここでは両方とも文字列です! だからこそ働ける${0x0}か、働かないか!${0}$0$0x0

于 2013-03-07T12:09:04.020 に答える
3

@Michael Robinsonが言ったことに加えて、あなたの例ではこれも有効です:

${0x0} = 'test';
$var = "0";
echo $$var; // prints "test"
于 2013-03-07T12:03:52.903 に答える