php回傳值return語句用法詳解
在程式語言中,一個函數或一個方法一般都有返回值,但也存在不返回值的情況,此時,這些函數只是處理一些事務, 沒有返回,或者說沒有明確的回傳值,在pascal語言中它有一個專有的關鍵字 procedure 。 在PHP中,函數都有回傳值,分成兩種情況,使用return語句明確的回傳和沒有return語句傳回NULL。
return語句
當使用return語句時,PHP給使用者自訂的函數傳回指定類型的變數。 依舊我們查看原始碼的方式,對return 關鍵字進行詞法分析和語法分析後,產生中間代碼。 從 Zend/zend_language_parser.y檔案中可以確認其產生中間程式碼呼叫的是 zend_do_return 函數。
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */{ zend_op *opline; int start_op_number, end_op_number; if (do_end_vparse) { if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) { zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);/* 处理返回引用 */ } else { zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);/* 处理常规变量返回 */ } } ...// 省略 取其它中间代码操作 opline->opcode = ZEND_RETURN; if (expr) { opline->op1 = *expr; if (do_end_vparse && zend_is_function_or_method_call(expr)) { opline->extended_value = ZEND_RETURNS_FUNCTION; } } else { opline->op1.op_type = IS_CONST; INIT_ZVAL(opline->op1.u.constant); } SET_UNUSED(opline->op2);}/* }}} */
產生中間程式碼為 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為例說明函數傳回值的執行過程:
static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS){ zend_op *opline = EX(opline); zval *retval_ptr; zval **retval_ptr_ptr; if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) { // 返回引用时不允许常量和临时变量 if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references \ should be returned by reference"); goto return_by_value; } retval_ptr_ptr = NULL; // 返回值 if (IS_CONST == IS_VAR && !retval_ptr_ptr) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } if (IS_CONST == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) { if (opline->extended_value == ZEND_RETURNS_FUNCTION && EX_T(opline->op1.u.var).var.fcall_returned_reference) { } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) { if (IS_CONST == IS_VAR && !0) { /* undo the effect of get_zval_ptr_ptr() */ PZVAL_LOCK(*retval_ptr_ptr); } zend_error(E_NOTICE, "Only variable references \ should be returned by reference"); goto return_by_value; } } if (EG(return_value_ptr_ptr)) { // 返回引用 SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr); // is_refgc设置为1 Z_ADDREF_PP(retval_ptr_ptr); // refcountgc计数加1 (*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr); } } else {return_by_value: retval_ptr = &opline->op1.u.constant; if (!EG(return_value_ptr_ptr)) { if (IS_CONST == IS_TMP_VAR) { } } else if (!0) { /* Not a temp var */ if (IS_CONST == IS_CONST || EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) { zval *ret; ALLOC_ZVAL(ret); INIT_PZVAL_COPY(ret, retval_ptr); // 复制一份给返回值 zval_copy_ctor(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; // 直接赋值 Z_ADDREF_P(retval_ptr); } } else { zval *ret; ALLOC_ZVAL(ret); INIT_PZVAL_COPY(ret, retval_ptr); // 复制一份给返回值 *EG(return_value_ptr_ptr) = ret; } } return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); // 返回前执行收尾工作}
函數的回傳值在程式執行時儲存在 *EG(return_value_ptr_ptr)。 ZE內核對值返回和引用返回作了區分, 並且在此基礎上對常數,臨時變數和其它類型的變數在返回時進行了不同的處理。在return執行完之前, ZE核心透過呼叫zend_leave_helper_SPEC函數,清除函數內部使用的變數等。 這也是ZE內核自動為函數加上NULL回傳的原因之一。
沒有return語句的函數
在PHP中,沒有過程這個概念,只有沒有回傳值的函數。但是對於沒有回傳值的函數,PHP內核會「幫你「加上一個NULL來做為回傳值。 這個「幫你」的操作也是在產生中間程式碼時進行的。在每個函數解析時都需要執行函數zend_do_end_function_declaration, 在此函數中有一條語句:
zend_do_return(NULL, 0 TSRMLS_CC);
結合前面的內容,我們知道這語句的作用就是回傳NULL。這就是沒有return語句的函數傳回NULL的原因。
內部函數的回傳值都是透過一個名為 return_value 的變數傳遞的。 這個變數同時也是函數中的一個參數,在PHP_FUNCTION函數擴展開來後可以看到。 這個參數總是包含有一個事先申請好空間的 zval 容器,因此你可以直接存取其成員並對其進行修改而無需先對 return_value 執行一下 MAKE_STD_ZVAL 巨集指令。 為了能夠更方便從函數中傳回結果,也為了省卻直接存取 zval 容器內部結構的麻煩,ZEND 提供了一大套巨集指令來完成相關的這些操作。 這些巨集命令會自動設定好類型和數值。
從函數直接傳回值的巨集:
RETURN_RESOURCE(resource) 傳回一個資源。
RETURN_BOOL(bool) 傳回一個布林值。
RETURN_NULL() 傳回一個空值。
RETURN_LONG(long) 傳回一個長整數。
RETURN_DOUBLE(double) 傳回一個雙精確度浮點數。
RETURN_STRING(string, duplicate) 傳回一個字串。 duplicate 表示這個字元是否使用 estrdup() 進行複製。
RETURN_STRINGL(string, length, duplicate) 傳回一個定長的字串。其餘跟 RETURN_STRING 相同。這個巨集速度更快而且是二進位安全的。
RETURN_EMPTY_STRING() 傳回一個空字串。
RETURN_FALSE 傳回一個布林值假。
RETURN_TRUE 傳回一個布林值真。
設定函數傳回值的巨集:
RETVAL_RESOURCE(resource) 設定回傳值為指定的資源。
RETVAL_BOOL(bool) 設定傳回值為指定的一個布林值。
RETVAL_NULL 設定傳回值為空值
RETVAL_LONG(long) 設定傳回值為指定的一個長整數。
RETVAL_DOUBLE(double) 設定傳回值為指定的一個雙精確度浮點數。
RETVAL_STRING(string, duplicate) 設定傳回值為指定的一個字串,duplicate 意義同 RETURN_STRING。
RETVAL_STRINGL(string, length, duplicate) 設定傳回值為指定的一個定長的字串。其餘跟 RETVAL_STRING 相同。這個巨集速度更快而且是二進位安全的。
RETVAL_EMPTY_STRING 設定回傳值為空字串。
RETVAL_FALSE 設定回傳值為布林值假。
RETVAL_TRUE 設定回傳值為布林值真。
如果需要返回的是像數組和物件這樣的複雜類型的數據,那就需要先呼叫 array_init() 和 object_init(), 也可以使用相應的 hash 函數直接操作 return_value。 由於這些類型主要是由一些雜七雜八的東西構成,所以對它們就沒有了相應的宏。
以上是php回傳值return語句用法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
