[問題]
以前のプログラミング経験にもかかわらず、初心者PHP では、属性のデフォルト エラーによって困惑しています。コード:
class Foo {
public $path = array(
realpath(".")
);
}
では構文エラーが発生します。ただし、次の場合はシームレスに機能します:
$path = array(
realpath(".")
);
次のような疑問が生じます。なぜ属性のデフォルトでは関数を呼び出すことができないのでしょうか?これは意図的なものですか、それとも実装上の欠陥ですか?
[Answer]
PHP コンパイラー コードは、この制限が意図的であることを示していますが、公式の根拠はありません。 PHP の現在の実装の制限によって明らかなように、この機能を確実に実装するには、特定の課題が生じます。
コンパイラの文法は、クラス変数宣言を次のように定義します。
class_variable_declaration: //... | T_VARIABLE '=' static_scalar //... ;
したがって、$path のような変数値を割り当てるには、期待値が静的スカラーと一致する必要があります。これには、静的スカラーでもある値を持つ配列が含まれます:
static_scalar: /* compile-time evaluated scalars */ //... | T_ARRAY '(' static_array_pair_list ')' // ... //... ;
コード サンプルと一致する次の構文が文法で許可されている場合、スクリプトでは「無効なバインディング タイプ」エラーが発生します:
class_variable_declaration: //... | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ... ;
指定されたコード サンプルを解析すると、次の手順がわかります:
zend_do_begin_class_declaration() // Adds an opcode array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties zend_do_declare_property() // Declares the property zend_do_early_binding() // Consumes the last opcode and evaluates it
オペコードが予期されていない場合 (関数またはメソッドに関連する場合など)、エラーがスローされます。
非静的配列の許可INIT_ARRAY オペコードを生成し、zend_do_early_binding():
DECLARE_CLASS 'Foo' SEND_VAL '.' DO_FCALL 'realpath' INIT_ARRAY
属性のデフォルトで関数呼び出しに対応するには、メソッド定義と同様に、クラス変数宣言をスコープとする新しいオペコード配列が必要になります。ただし、そのような評価のタイミングを決定することには、さらなる課題が伴います。
他の動的言語はこの問題を解決できていますが、PHP には依然としてこの機能が存在しません。これは、その複雑さと優先度の低さが原因である可能性があります。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3