程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP源碼分析-弱類型變量實現

PHP源碼分析-弱類型變量實現

編輯:關於PHP編程

PHP是弱類型,動態的語言腳本。在申明一個變量的時候,並不需要指明它保存的數據類型。

例如:

<?php 
$var = 1; 
$var = "variable"; 
$var = 1.00; 
$var = array(); 
$var = new Object(); 
<?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 { 
    /* Variable information */ 
    zvalue_value value;     /* value */ 
    zend_uint refcount__gc; 
    zend_uchar type;    /* active type */ 
    zend_uchar is_ref__gc; 
}; 
 
typedef union _zvalue_value { 
    long lval;  /* long value */ 
    double dval;    /* double value */ 
    struct { 
        char *val; 
        int len; 
    } str; 
    HashTable *ht;  /* hash table value */ 
    zend_object_value obj; 
} zvalue_value; 
typedef struct _zval_struct zval;

struct _zval_struct {
 /* Variable information */
 zvalue_value value;  /* value */
 zend_uint refcount__gc;
 zend_uchar type; /* active type */
 zend_uchar is_ref__gc;
};

typedef union _zvalue_value {
 long lval; /* long value */
 double dval; /* double value */
 struct {
  char *val;
  int len;
 } 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; 
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 
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
來看一個簡單的例子:www.2cto.com
<?php 
    $a = 1; 
    //此時zval.type = IS_LONG,那麼zval.value就去取lval.  
    $a = array(); 
    //此時zval.type = IS_ARRAY,那麼zval.value就去取ht. 
<?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

 

摘自 God's blog

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