開発プロセスでは、関数の戻り値の型を決定して変更する必要がありますが、PHP は型付けが弱い言語であるため、このような構文検証が行われず、多くの落とし穴が発生しました。
たとえば、次のコード:
<?phpfunction getArticles(...){ $arrData = array(); if($exp1){ return $arrData; }else if($exp2){ return 1; }else{ return false; }}$arrData =getArticles(...);foreach($arrData as $record){//do something.....}?>
getArticles 関数は、bool、int、配列など、さまざまな条件に従ってさまざまなタイプの値を返します。通常、このタイプの関数は配列を返し、それを使用します。しかし、関数の戻り値の型が固定されていないため、呼び出し時にさまざまな思わぬ落とし穴が発生する可能性があり、標準化できないので、それを強制的に実行する必要があると考えました。
関数/メソッドの戻り値の型を強制できます:
int function a(){ ...... return 1;}bool function b(){ ...... return false;}array function c(){ ...... return array();}object function d(){ ...... return new a();}
4 つの必須の型制限をサポートします: int、array、bool、object 戻り値が関数宣言の型と一致しない場合、警告がスローされます。本来はエラーをスローする予定でしたが、これは厳しすぎてエラーではなく例外としか考えられないので、警告を使用します。
PHP 自体は int 関数のような構文をサポートしていないため、それをサポートしたい場合は、まず構文パーサーを修正する必要があります。詳しくは説明しません。詳細はこちらを参照してください。最初に構文を変更します。Zend/zend_ language_scanner.l ファイルをスキャンします。
次のコードを追加します。
<ST_IN_SCRIPTING>"int" { return T_FUNCTION_RETURN_INT;}<ST_IN_SCRIPTING>"bool" { return T_FUNCTION_RETURN_OBJECT;}<ST_IN_SCRIPTING>"object" { return T_FUNCTION_RETURN_OBJECT;}<ST_IN_SCRIPTING>"resource" { return T_FUNCTION_RETURN_RESOURCE;}
..........%token T_FUNCTION_RETURN_INT%token T_FUNCTION_RETURN_BOOL%token T_FUNCTION_RETURN_STRING%token T_FUNCTION_RETURN_OBJECT%token T_FUNCTION_RETURN_RESOURCE1然后增加token处理逻辑:1function: T_FUNCTION { \(.u.opline_num = CG(zend_lineno);\).u.EA.var = 0; } | T_FUNCTION_RETURN_INT T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_LONG; } | T_FUNCTION_RETURN_BOOL T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_BOOL; } | T_FUNCTION_RETURN_STRING T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_STRING; } | T_FUNCTION_RETURN_OBJECT T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_OBJECT; } | T_FUNCTION_RETURN_RESOURCE T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_RESOURCE; } | T_ARRAY T_FUNCTION { \(.u.opline_num = CG(zend_lineno); \).u.EA.var = IS_ARRAY; }
......zend_op_array op_array;char *name = function_name->u.constant.value.str.val;int name_len = function_name->u.constant.value.str.len;int function_type = function_token->u.EA.var; //保存函数类型,在语法解释器中增加的int function_begin_line = function_token->u.opline_num;......op_array.function_name = name;op_array.fn_type = function_type; //将类型保存到op_array中,op_array.return_reference = return_reference;op_array.fn_flags |= fn_flags;op_array.pass_rest_by_reference = 0;..........
コールバック関数 return の前に次のコードを追加します。
ZEND_RETURN_SPEC_CONST_HANDLERZEND_RETURN_SPEC_TMP_HANDLERZEND_RETURN_SPEC_VAR_HANDLER
パッチをダウンロードします: php-syntax.patch
続き: その後、私はバード兄弟と話しましたが、彼の答えは次のとおりです: 「このトピックは基本的にメールグループの生理的な投稿です... 1. PHP は型であるため, 多くの型は相互に変換できるので、暗黙的な変換が必要ですか? 変換にさまざまな変換ルールが含まれる場合、これは制限されすぎます。十分ではありません (さまざまなカスタム クラスと継承クラス) 3. 将来的に JIT を実行したい場合は、サポートすることを検討してください。」 この観点からすると、公式もこの問題にかなり巻き込まれています。変換を強制するのではなく、警告をスローして、変換するかどうかを開発者に決定させる方が良いでしょうか?