PHP カーネルの定義、パラメータ転送、戻り値を深く理解する (6) 関数
1. 関数の定義
ユーザー関数の定義は次のように関数キーワードから始まります。
<span style="color: #0000ff;">function</span> foo(<span style="color: #800080;">$var</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$var</span><span style="color: #000000;">;}</span>
1. 字句解析
Zend/zend_ language_scanner .l 次のコードが見つかります:
<st_in_scripting><span style="color: #800000;">"</span><span style="color: #800000;">function</span><span style="color: #800000;">"</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> T_FUNCTION;}</span></st_in_scripting>
これは、関数が T_FUNCTION タグを生成することを意味します。このトークンを取得したら、構文解析を開始します。
2. 構文分析
次のように、Zend/zend_ language_parser.y ファイル内の関数の宣言プロセス マークを見つけます。
<span style="color: #000000;">function: T_FUNCTION { $$.u.opline_num </span>=<span style="color: #000000;"> CG(zend_lineno); }; is_reference: </span><span style="color: #008000;">/*</span><span style="color: #008000;"> empty </span><span style="color: #008000;">*/</span> { $$.op_type =<span style="color: #000000;"> ZEND_RETURN_VAL; } </span>| <span style="color: #800000;">'</span><span style="color: #800000;">&</span><span style="color: #800000;">'</span> { $$.op_type =<span style="color: #000000;"> ZEND_RETURN_REF; }; unticked_function_declaration_statement: function is_reference T_STRING {zend_do_begin_function_declaration(</span>&$<span style="color: #800080;">1</span>, &$<span style="color: #800080;">3</span>, <span style="color: #800080;">0</span>, $<span style="color: #800080;">2</span><span style="color: #000000;">.op_type, NULL TSRMLS_CC); } </span><span style="color: #800000;">'</span><span style="color: #800000;">(</span><span style="color: #800000;">'</span> parameter_list <span style="color: #800000;">'</span><span style="color: #800000;">)</span><span style="color: #800000;">'</span> <span style="color: #800000;">'</span><span style="color: #800000;">{</span><span style="color: #800000;">'</span> inner_statement_list <span style="color: #800000;">'</span><span style="color: #800000;">}</span><span style="color: #800000;">'</span><span style="color: #000000;"> { zend_do_end_function_declaration(</span>&$<span style="color: #800080;">1</span><span style="color: #000000;"> TSRMLS_CC); };</span>T_FUNCTION マークは、関数宣言を見つけるためにのみ使用され、これが関数宣言であることを示します。関数であり、パラメーターや戻り値など、この関数に関連する作業がさらに多くなります。
3. 中間コードの生成
構文解析後、実行されたコンパイル済み関数は zend_do_begin_function_declaration であることがわかります。次のように Zend/zend_complie.c ファイル内の実装を見つけます。
<span style="color: #0000ff;">void</span> zend_do_begin_function_declaration(znode *<span style="color: #000000;">function_token, znode </span>*<span style="color: #000000;">function_name, </span><span style="color: #0000ff;">int</span> is_method, <span style="color: #0000ff;">int</span> return_reference, znode *fn_flags_znode TSRMLS_DC) <span style="color: #008000;">/*</span><span style="color: #008000;"> {{{ </span><span style="color: #008000;">*/</span><span style="color: #000000;">{ ...</span><span style="color: #008000;">//</span><span style="color: #008000;">省略</span> function_token->u.op_array =<span style="color: #000000;"> CG(active_op_array); lcname </span>=<span style="color: #000000;"> zend_str_tolower_dup(name, name_len); orig_interactive </span>=<span style="color: #000000;"> CG(interactive); CG(interactive) </span>= <span style="color: #800080;">0</span><span style="color: #000000;">; init_op_array(</span>&<span style="color: #000000;">op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); CG(interactive) </span>=<span style="color: #000000;"> orig_interactive; ...</span><span style="color: #008000;">//</span><span style="color: #008000;">省略</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> (is_method) { ...</span><span style="color: #008000;">//</span><span style="color: #008000;">省略,类方法 在后面的章节介绍</span>?!<span style="color: #000000;">?GH } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { zend_op </span>*opline =<span style="color: #000000;"> get_next_op(CG(active_op_array) TSRMLS_CC); opline</span>->opcode =<span style="color: #000000;"> ZEND_DECLARE_FUNCTION; opline</span>->op1.op_type =<span style="color: #000000;"> IS_CONST; build_runtime_defined_function_key(</span>&opline-><span style="color: #000000;">op1.u.constant, lcname, name_len TSRMLS_CC); opline</span>->op2.op_type =<span style="color: #000000;"> IS_CONST; opline</span>->op2.u.constant.type =<span style="color: #000000;"> IS_STRING; opline</span>->op2.u.constant.value.str.val =<span style="color: #000000;"> lcname; opline</span>->op2.u.constant.value.str.len =<span style="color: #000000;"> name_len; Z_SET_REFCOUNT(opline</span>->op2.u.constant, <span style="color: #800080;">1</span><span style="color: #000000;">); opline</span>->extended_value =<span style="color: #000000;"> ZEND_DECLARE_FUNCTION; zend_hash_update(CG(function_table), opline</span>-><span style="color: #000000;">op1.u.constant.value.str.val, opline</span>->op1.u.constant.value.str.len, &<span style="color: #000000;">op_array, </span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(zend_op_array), (</span><span style="color: #0000ff;">void</span> **) &<span style="color: #000000;">CG(active_op_array)); } }</span><span style="color: #008000;">/*</span><span style="color: #008000;"> }}} </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span>中間コードを生成すると、関数名がすべて小文字に統一されており、関数名の大文字と小文字が区別されていないことがわかります。 この実装を検証するために、コードの一部を見てみましょう。
<span style="color: #000000;">function T() { echo </span><span style="color: #800080;">1</span><span style="color: #000000;">;} function t() { echo </span><span style="color: #800080;">2</span><span style="color: #000000;">;}</span>は、PHP の場合、T と t が同じ関数名であることを意味します。この処理はどこで行われますか?
4. 中間コードを実行します
Zend/zend_vm_execute.h ファイル内の ZEND_DECLARE_FUNCTION 中間コードに対応する実行関数: ZEND_DECLARE_FUNCTION_SPEC_HANDLER を見つけます。この関数は関数 do_bind_function のみを呼び出します。呼び出しコードは次のとおりです:
do_bind_function(EX(opline), EG(function_table), <span style="color: #800080;">0</span>);を使用します。 2. 関数パラメータ
関数の定義は、関数リストに関数名を登録するだけの処理です。
1. ユーザー定義関数のパラメーター
この関数では、関数のパラメーター チェックが zend_do_receive_arg 関数によって実装されていることがわかります。パラメータは次のとおりです:
CG(active_op_array)->arg_info = erealloc(CG(active_op_array)-><span style="color: #000000;">arg_info, </span><span style="color: #0000ff;">sizeof</span>(zend_arg_info)*(CG(active_op_array)-><span style="color: #000000;">num_args));cur_arg_info </span>= &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-<span style="color: #800080;">1</span><span style="color: #000000;">];cur_arg_info</span>->name = estrndup(varname-><span style="color: #000000;">u.constant.value.str.val, varname</span>-><span style="color: #000000;">u.constant.value.str.len);cur_arg_info</span>->name_len = varname-><span style="color: #000000;">u.constant.value.str.len;cur_arg_info</span>->array_type_hint = <span style="color: #800080;">0</span><span style="color: #000000;">;cur_arg_info</span>->allow_null = <span style="color: #800080;">1</span><span style="color: #000000;">;cur_arg_info</span>->pass_by_reference =<span style="color: #000000;"> pass_by_reference;cur_arg_info</span>->class_name =<span style="color: #000000;"> NULL;cur_arg_info</span>->class_name_len = <span style="color: #800080;">0</span>;
typedef <span style="color: #0000ff;">struct</span><span style="color: #000000;"> _zend_arg_info { </span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> *name; <span style="color: #008000;">/*</span><span style="color: #008000;">参数的名称</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_uint name_len; </span><span style="color: #008000;">/*</span><span style="color: #008000;">参数名称的长度</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> *class_name; <span style="color: #008000;">/*</span><span style="color: #008000;"> 类名</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_uint class_name_len; </span><span style="color: #008000;">/*</span><span style="color: #008000;">类名长度</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_bool array_type_hint; </span><span style="color: #008000;">/*</span><span style="color: #008000;">数组类型提示</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_bool allow_null; </span><span style="color: #008000;">/*</span><span style="color: #008000;">是否允许为NULL?</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_bool pass_by_reference; </span><span style="color: #008000;">/*</span><span style="color: #008000;">是否引用传递</span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_bool return_reference; </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> required_num_args; } zend_arg_info;</span>中間コードに含まれる arg_nums フィールドは、**zend_do_receive_argxx が実行されるたびに 1 ずつ増加します。
CG(active_op_array)->num_args++;
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-<span style="color: #800080;">1</span>];
<span style="color: #008000;">/*</span><span style="color: #008000;"> {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function </span><span style="color: #008000;">*/</span><span style="color: #000000;">ZEND_FUNCTION(func_num_args){ zend_execute_data </span>*ex = EG(current_execute_data)-><span style="color: #000000;">prev_execute_data; </span><span style="color: #0000ff;">if</span> (ex && ex-><span style="color: #000000;">function_state.arguments) { RETURN_LONG((</span><span style="color: #0000ff;">long</span>)(zend_uintptr_t)*(ex-><span style="color: #000000;">function_state.arguments)); } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { zend_error(E_WARNING,</span><span style="color: #800000;">"</span><span style="color: #800000;">func_num_args(): Called from the global scope - no function context</span><span style="color: #800000;">"</span><span style="color: #000000;">); RETURN_LONG(</span>-<span style="color: #800080;">1</span><span style="color: #000000;">); }}</span><span style="color: #008000;">/*</span><span style="color: #008000;"> }}} </span><span style="color: #008000;">*/</span>
zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
2. 内部関数のパラメーター
共通カウント関数を例にとると、パラメーター処理部分のコードは次のとおりです。
<span style="color: #008000;">/*</span><span style="color: #008000;"> {{{ proto int count(mixed var [, int mode]) Count the number of elements in a variable (usually an array) </span><span style="color: #008000;">*/</span><span style="color: #000000;">PHP_FUNCTION(count){ zval </span>*<span style="color: #000000;">array; </span><span style="color: #0000ff;">long</span> mode =<span style="color: #000000;"> COUNT_NORMAL; </span><span style="color: #0000ff;">if</span> (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, <span style="color: #800000;">"</span><span style="color: #800000;">z|l</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span>&array, &mode) ==<span style="color: #000000;"> FAILURE) { </span><span style="color: #0000ff;">return</span><span style="color: #000000;">; } ... </span><span style="color: #008000;">//</span><span style="color: #008000;">省略</span>}
(1)取参数的个数
取参数的个数是通过ZEND_NUM_ARGS()宏来实现的,其定义如下:
<span style="color: #0000ff;">#define</span> ZEND_NUM_ARGS() (ht)
ht是在Zend/zend.h文件中定义的宏INTERNAL_FUNCTION_PARAMETERS中的ht,如下
<span style="color: #0000ff;">#define</span> INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value,<span style="color: #000000;">zval </span>**return_value_ptr, zval *this_ptr, <span style="color: #0000ff;">int</span> return_value_used TSRMLS_DC
(2)解析参数列表
PHP内部函数在解析参数时使用的是zend_parse_parameters。它可以大大简化参数的接收处理工作,虽然它在处理可变参数时还有点弱。
其声明如下:
ZEND_API <span style="color: #0000ff;">int</span> zend_parse_parameters(<span style="color: #0000ff;">int</span> num_args TSRMLS_DC, <span style="color: #0000ff;">char</span> *<span style="color: #000000;">type_spec, ...)</span>
- 第一个参数num_args表明表示想要接收的参数个数,我们经常使用ZEND_NUM_ARGS()来表示对传入的参数“有多少要多少”
- 第二个参数应该是宏TSRMLS_CC。
- 第三个参数type_spec是一个字符串,用来指定我们所期待接收的各个参数的类型,有点类似于printf中指定输出格式的那个格式化字符串。
- 剩下的参数就是我们用来接收PHP参数值的变量的指针。
zend_parse_parameters()在解析参数的同时户尽可能的转换参数类型,这样就可以确保我们总是能得到所期望的类型的变量
3、函数的返回值
PHP中函数都有返回值,没return返回null
(1)return语句
从Zend/zend_language_parser.y文件中可以确认其生成中间代码调用的是zend_do_return函数。
<span style="color: #0000ff;">void</span> zend_do_return(znode *expr, <span style="color: #0000ff;">int</span> do_end_vparse TSRMLS_DC) <span style="color: #008000;">/*</span><span style="color: #008000;"> {{{ </span><span style="color: #008000;">*/</span><span style="color: #000000;">{ zend_op </span>*<span style="color: #000000;">opline; </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> start_op_number, end_op_number; </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (do_end_vparse) { </span><span style="color: #0000ff;">if</span> (CG(active_op_array)-><span style="color: #000000;">return_reference </span>&& !<span style="color: #000000;">zend_is_function_or_method_call(expr)) { zend_do_end_variable_parse(expr, BP_VAR_W, </span><span style="color: #800080;">0</span> TSRMLS_CC);<span style="color: #008000;">/*</span><span style="color: #008000;"> 处理返回引用 </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { zend_do_end_variable_parse(expr, BP_VAR_R, </span><span style="color: #800080;">0</span> TSRMLS_CC);<span style="color: #008000;">/*</span><span style="color: #008000;"> 处理常规变量返回 </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } ...</span><span style="color: #008000;">//</span><span style="color: #008000;"> 省略,取其他中间代码操作</span><span style="color: #000000;"> opline</span>->opcode =<span style="color: #000000;"> ZEND_RETURN; </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (expr) { opline</span>->op1 = *<span style="color: #000000;">expr; </span><span style="color: #0000ff;">if</span> (do_end_vparse &&<span style="color: #000000;"> zend_is_function_or_method_call(expr)) { opline</span>->extended_value =<span style="color: #000000;"> ZEND_RETURNS_FUNCTION; } } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { opline</span>->op1.op_type =<span style="color: #000000;"> IS_CONST; INIT_ZVAL(opline</span>-><span style="color: #000000;">op1.u.constant); } SET_UNUSED(opline</span>-><span style="color: #000000;">op2);}</span><span style="color: #008000;">/*</span><span style="color: #008000;"> }}} </span><span style="color: #008000;">*/</span>
生成中间代码为ZEND_RETURN。第一个操作数的类型在返回值为可用的表达式时,其类型为表达式的操作类型,否则类型为IS_CONST。这在后续计算执行中间代码函数时有用到。根据操作数的不同,ZEND_RETURN中间代码会执行ZEND_RETURN_SPEC_CONST_HANDLER,ZEND_RETURN_SPEC_TMP_HANDLER或ZEND_RETURN_SPEC_TMP_HANDLER。这三个函数的执行流程基本类似,包括对一些错误的处理。这里我们以ZEND_RETURN_SPEC_CONST_HANDLER为例说明函数返回值的执行过程:
<span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS){ zend_op </span>*opline =<span style="color: #000000;"> EX(opline); zval </span>*<span style="color: #000000;">retval_ptr; zval </span>**<span style="color: #000000;">retval_ptr_ptr; </span><span style="color: #0000ff;">if</span> (EG(active_op_array)->return_reference ==<span style="color: #000000;"> ZEND_RETURN_REF) { </span><span style="color: #008000;">//</span><span style="color: #008000;"> ?ǔ?sÁ\[email protected]Á??</span> <span style="color: #0000ff;">if</span> (IS_CONST == IS_CONST || IS_CONST ==<span style="color: #000000;"> IS_TMP_VAR) { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> Not supposed to happen, but we'll allow it </span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_error(E_NOTICE, </span><span style="color: #800000;">"</span><span style="color: #800000;">Only variable references \</span> should be returned by reference<span style="color: #800000;">"</span><span style="color: #800000;">);</span> <span style="color: #0000ff;">goto</span><span style="color: #000000;"> return_by_value; } retval_ptr_ptr </span>= NULL; <span style="color: #008000;">//</span><span style="color: #008000;"> ?ǔ?</span> <span style="color: #0000ff;">if</span> (IS_CONST == IS_VAR && !<span style="color: #000000;">retval_ptr_ptr) { zend_error_noreturn(E_ERROR, </span><span style="color: #800000;">"</span><span style="color: #800000;">Cannot return string offsets by </span>reference<span style="color: #800000;">"</span><span style="color: #800000;">);</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">if</span> (IS_CONST == IS_VAR && !<span style="color: #000000;">Z_ISREF_PP(retval_ptr_ptr)) { </span><span style="color: #0000ff;">if</span> (opline->extended_value == ZEND_RETURNS_FUNCTION &&<span style="color: #000000;"> EX_T(opline</span>->op1.u.<span style="color: #0000ff;">var</span>).<span style="color: #0000ff;">var</span><span style="color: #000000;">.fcall_returned_reference) { } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (EX_T(opline->op1.u.<span style="color: #0000ff;">var</span>).<span style="color: #0000ff;">var</span>.ptr_ptr == &EX_T(opline->op1.u.<span style="color: #0000ff;">var</span>).<span style="color: #0000ff;">var</span><span style="color: #000000;">.ptr) { </span><span style="color: #0000ff;">if</span> (IS_CONST == IS_VAR && !<span style="color: #800080;">0</span><span style="color: #000000;">) { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> undo the effect of get_zval_ptr_ptr() </span><span style="color: #008000;">*/</span><span style="color: #000000;"> PZVAL_LOCK(</span>*<span style="color: #000000;">retval_ptr_ptr); } zend_error(E_NOTICE, </span><span style="color: #800000;">"</span><span style="color: #800000;">Only variable references \</span> should be returned by reference<span style="color: #800000;">"</span><span style="color: #800000;">);</span> <span style="color: #0000ff;">goto</span><span style="color: #000000;"> return_by_value; } } </span><span style="color: #0000ff;">if</span> (EG(return_value_ptr_ptr)) { <span style="color: #008000;">//</span><span style="color: #008000;"> ?ǔ?s</span> SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr); <span style="color: #008000;">//</span><span style="color: #008000;"> is_ref__gc???</span><span style="color: #800080;">1</span><span style="color: #000000;"> Z_ADDREF_PP(retval_ptr_ptr); </span><span style="color: #008000;">//</span><span style="color: #008000;"> refcount__gcŒ?×1</span><span style="color: #000000;"> (</span>*EG(return_value_ptr_ptr)) = (*<span style="color: #000000;">retval_ptr_ptr); } } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {return_by_value: retval_ptr </span>= &opline-><span style="color: #000000;">op1.u.constant; </span><span style="color: #0000ff;">if</span> (!<span style="color: #000000;">EG(return_value_ptr_ptr)) { </span><span style="color: #0000ff;">if</span> (IS_CONST ==<span style="color: #000000;"> IS_TMP_VAR) { } } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (!<span style="color: #800080;">0</span>) { <span style="color: #008000;">/*</span><span style="color: #008000;"> Not a temp var </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">if</span> (IS_CONST == IS_CONST ||<span style="color: #000000;"> EG(active_op_array)</span>->return_reference == ZEND_RETURN_REF ||<span style="color: #000000;"> (PZVAL_IS_REF(retval_ptr) </span>&& Z_REFCOUNT_P(retval_ptr) > <span style="color: #800080;">0</span><span style="color: #000000;">)) { zval </span>*<span style="color: #000000;">ret; ALLOC_ZVAL(ret); INIT_PZVAL_COPY(ret, retval_ptr); </span><span style="color: #008000;">//</span><span style="color: #008000;"> ?????ǔ? </span><span style="color: #000000;"> zval_copy_ctor(ret); </span>*EG(return_value_ptr_ptr) =<span style="color: #000000;"> ret; } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span>*EG(return_value_ptr_ptr) = retval_ptr; <span style="color: #008000;">//</span><span style="color: #008000;"> ?6??</span><span style="color: #000000;"> Z_ADDREF_P(retval_ptr); } } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { zval </span>*<span style="color: #000000;">ret; ALLOC_ZVAL(ret); INIT_PZVAL_COPY(ret, retval_ptr); </span><span style="color: #008000;">//</span><span style="color: #008000;"> ?????ǔ? </span> *EG(return_value_ptr_ptr) =<span style="color: #000000;"> ret; } } </span><span style="color: #0000ff;">return</span> zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); <span style="color: #008000;">//</span><span style="color: #008000;"> ?</span><span style="color: #000000;">ǔ????}</span>
函数的返回值在程序执行时存储在*EG(return_value_ptr_ptr)。ZEND内核对值返回和引用返回作了区别,并且在此基础上对常量,临时变量和其他类型的变量在返回时作了不同的处理。在return执行完之后,ZEND内核通过调用zend_leave_helper_SPEC函数,清除函数内部使用的变量等。这也是ZEND内核自动给函数加上NULL返回的原因之一。

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPは死にかけていませんが、常に適応して進化しています。 1)PHPは、1994年以来、新しいテクノロジーの傾向に適応するために複数のバージョンの反復を受けています。 2)現在、電子商取引、コンテンツ管理システム、その他の分野で広く使用されています。 3)PHP8は、パフォーマンスと近代化を改善するために、JITコンパイラおよびその他の機能を導入します。 4)Opcacheを使用してPSR-12標準に従って、パフォーマンスとコードの品質を最適化します。

PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイラと列挙タイプを導入します。 3)パフォーマンスを継続的に最適化し、ベストプラクティスを促進します。

PHPでは、特性は方法が必要な状況に適していますが、継承には適していません。 1)特性により、クラスの多重化方法が複数の継承の複雑さを回避できます。 2)特性を使用する場合、メソッドの競合に注意を払う必要があります。メソッドの競合は、代替およびキーワードとして解決できます。 3)パフォーマンスを最適化し、コードメンテナビリティを改善するために、特性の過剰使用を避け、その単一の責任を維持する必要があります。

依存関係噴射コンテナ(DIC)は、PHPプロジェクトで使用するオブジェクト依存関係を管理および提供するツールです。 DICの主な利点には、次のものが含まれます。1。デカップリング、コンポーネントの独立したもの、およびコードの保守とテストが簡単です。 2。柔軟性、依存関係を交換または変更しやすい。 3.テスト可能性、単体テストのために模擬オブジェクトを注入するのに便利です。

SplfixedArrayは、PHPの固定サイズの配列であり、高性能と低いメモリの使用が必要なシナリオに適しています。 1)動的調整によって引き起こされるオーバーヘッドを回避するために、作成時にサイズを指定する必要があります。 2)C言語アレイに基づいて、メモリと高速アクセス速度を直接動作させます。 3)大規模なデータ処理とメモリに敏感な環境に適していますが、サイズが固定されているため、注意して使用する必要があります。

PHPは、$ \ _ファイル変数を介してファイルのアップロードを処理します。セキュリティを確保するための方法には次のものが含まれます。1。アップロードエラー、2。ファイルの種類とサイズを確認する、3。ファイル上書きを防ぐ、4。ファイルを永続的なストレージの場所に移動します。

JavaScriptでは、nullcoalescingoperator(??)およびnullcoalescingsignmentoperator(?? =)を使用できます。 1.??最初の非潜水金または非未定されたオペランドを返します。 2.??これらの演算子は、コードロジックを簡素化し、読みやすさとパフォーマンスを向上させます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!
