php是弱型別,動態的語言指令碼。在申明乙個變數的時候,並不需要指明它儲存的資料型別。
<?php
$var = 1;
$var = "variable";
$var = 1.00;
$var = array();
$var = new object();
?>
動態變數,在執行期間是可以改變的,並且在使用前無需宣告變數型別。
那麼,問題一、zend引擎是如何用c實現這種弱型別的呢?
實際上,在php中宣告的變數,在ze中都是用結構體zval來儲存的。首先我們開啟zend/zend.h來看zval的定義:
typedef struct _zval_struct zval;
struct _zval_struct ;
typedef union _zvalue_value str;
hashtable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
zend/zend_types.h:
typedef unsigned char zend_bool;
typedef unsigned char zend_uchar;
typedef unsigned int zend_uint;
typedef unsigned long zend_ulong;
typedef unsigned short zend_ushort;
從上述**中,可以看到_zvalue_value是真正儲存資料的關鍵部分。通過共用體實現的弱型別變數宣告。
問題二、zend引擎是如何判別、儲存php中的多種資料型別的呢?
_zval_struct.type中儲存著乙個變數的真正型別,根據type來選擇如何獲取zvalue_value的值。
type值列表(zend/zend.h):
#define is_null 0
#define is_long 1
#define is_double 2
#define is_bool 3
#define is_array 4
#define is_object 5
#define is_string 6
#define is_resource 7
#define is_constant 8
#define is_constant_array 9
來看乙個簡單的例子:
<?php
$a = 1;
//此時zval.type = is_long,那麼zval.value就去取lval.
$a = array();
//此時zval.type = is_array,那麼zval.value就去取ht.
?>
這其中最複雜的,並且在開發第三方擴充套件中經常需要用到的是」資源型別」。在php中,任何不屬於php的內建的變數型別的變數,都會被看作資源來進行儲存。比如:資料庫控制代碼、開啟的檔案控制代碼、開啟的socket控制代碼。
資源型別,需要使用ze提供的api函式來註冊,資源變數的宣告和使用將在單獨的篇目中進行詳細介紹。正是因為ze這樣的處理方式,使php就實現了弱型別,而對於ze的來說,它所面對的永遠都是同一種型別zval。
PHP弱資料型別的內部實現
php那個該死的若型別是怎麼實現的 開啟php 中zend.h和zend types.h可以看到有如下定義 typedef union zvalue value str 字串 hashtable ht hash表 zend object obj php物件儲存結構 zvalue value stru...
PHP弱資料型別的內部實現
php那個該死的若型別是怎麼實現的 開啟php 中zend.h和zend types.h可以看到有如下定義 typedef union zvalue value str 字串 hashtable ht hash表 zend object obj php物件儲存結構 zvalue value stru...
PHP弱型別的學習
下面為學習過程中搜查的內容 總結 補充 md5碰撞 這兩個部落格很詳細,下面為學習過程中第乙個部落格搜查的內容 建議看完第乙個保留疑問然後再看第二個再做複習 1.get 變數 2.ctype alpha 3.md5 函式 4.json decode函式 5.intval 函式 6.array sea...