程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP基礎知識 >> PHP源碼 — 函數返回值

PHP源碼 — 函數返回值

編輯:PHP基礎知識
 

在正常的開發思維裡,固有的返回值都應該是如下邏輯

Int a(){
  Return 1;
}

然而,Php返回值是返回一個zval* 數據結構。

而且不能直接使用return操作,而是通過一個神奇的指針retuen_value 來存儲。看是沒有定義,其實不然。

這個神奇的retuen_value處理過程,先看正確的返回值操作
PHP_FUNCTION(hello)
{
  ZVAL_STRING(return_value,“hello”, 1); //RETVAL_STRING(“hello”, 1);
  Return ;
}

刨根問底,必須從 PHP_FUNCTION 這個定義開始,要習慣了PHP和ZEND 的關系

PHP還是一貫的重新命名zend 的宏
#define PHP_FUNCTION ZEND_FUNCTION

一路追蹤

#define ZEND_FN(name) zif_##name
#define ZEND_MN(name) zim_##name
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))

關鍵地方:

#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)

在 INTERNAL_FUNCTION_PARAMETERS 宏定義

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC

包括成員:

/*
等價與ZEND_NUM_ARGS() ,表示參數的個數
*/
int ht
/*
存儲值,關鍵是_zval_struct 數據結構
*/
zval *return_value
/*
引用地址
*/
zval **return_value_ptr,
/*
對象
*/
zval *this_ptr,
/*
表示是否返回值
*/
int return_value_used

下面在做個例子,演示下return_value_used 的作用
PHP_FUNCTION(retuen_value_used_test)
{
char *arg = NULL;
zval *a,*b,*c;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &a,&b,&c) == FAILURE) {
return;
}
/*關鍵點*/
php_printf("%d",return_value_used);

RETURN_STRINGL(Z_STRVAL_P(a), Z_STRLEN_P(a), 0);
}

這是1個很簡單函數定義,實現傳入3個參數(我為了方便,直接定義成z類型)
PHP調用方法
<?php
retuen_value_used_test("2","v","dd");
?>

當PHP程序retuen_value_used_test函數沒有用到返回值的時候,結果是:
0

<?php
$log = retuen_value_used_test("2","v","dd");
?>

當PHP程序retuen_value_used_test函數使用到返回值的時候,結果是:
1

返回值類型
#define RETVAL_RESOURCE(l) ZVAL_RESOURCE(return_value, l)
#define RETVAL_BOOL(b) ZVAL_BOOL(return_value, b)
#define RETVAL_NULL() ZVAL_NULL(return_value)
#define RETVAL_LONG(l) ZVAL_LONG(return_value, l)
#define RETVAL_DOUBLE(d) ZVAL_DOUBLE(return_value, d)
#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate)
#define RETVAL_STRINGL(s, l, duplicate) ZVAL_STRINGL(return_value, s, l, duplicate)
#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value)
#define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor)
#define RETVAL_FALSE ZVAL_BOOL(return_value, 0)
#define RETVAL_TRUE ZVAL_BOOL(return_value, 1)

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved