精华内容
下载资源
问答
  • PHP作为一门简单而强大的语言,能够提供很多Web适用的语言特性,而从本期《问底》开始,王帅将从实践出发,带你弄清PHP内核中一些常用的部分,比如这里的“弱类型变量原理”。PHP是一门简单而强大的语言,提供了很多...
  • 33-弱类型变量的实现

    2016-04-25 12:25:14
    33-弱类型变量的实现PHP是弱类型,动态的语言脚本。在申明一个变量的时候,并不需要指明它保存的数据类型。 $var = 1; $var = "variable"; $var = 1.00; $var = array(); $var = new Object(); ?> 动态变量,在...

    33-弱类型变量的实现

    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 {  
        /* 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;  
    

    从上述代码中,可以看到_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弱类型变量是如何实现的

    千次阅读 2017-06-07 10:10:59
    PHP是弱类型,动态的语言脚本。在申明一个变量的时候,并不需要指明它保存的数据类型。例如: $var = 1;  $var = "variable";  $var = 1.00;  $var = array();  $var = ...

    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 {  
         /* 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;

    从上述代码中,可以看到_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句柄。


    资源类型,会用lval,此时它是一个整型指示器, 然后PHP会再根据这个指示器在PHP内建的一个资源列表中查询相对应的资源。


    正是因为ZE这样的处理方式,使PHP就实现了弱类型,而对于ZE的来说,它所面对的永远都是同一种类型zval。

    展开全文
  • PHP是弱类型,动态的语言脚本。在申明一个变量的时候,并不需要指明它保存的数据类型。 例如: [php] view plaincopy $var = 1;  $var = "variable";  $var = 1.00;  $var = array();  $...
     
    

    PHP是弱类型,动态的语言脚本。在申明一个变量的时候,并不需要指明它保存的数据类型。

    例如:

    [php]  view plain copy
    1. <?php  
    2. $var = 1;  
    3. $var = "variable";  
    4. $var = 1.00;  
    5. $var = array();  
    6. $var = new Object();  
    动态变量,在运行期间是可以改变的,并且在使用前无需声明变量类型。


    那么,问题一、Zend引擎是如何用C实现这种弱类型的呢?

    实际上,在PHP中声明的变量,在ZE中都是用结构体zval来保存的。

    首先我们打开Zend/zend.h来看zval的定义:

    [cpp]  view plain copy
    1. typedef struct _zval_struct zval;  
    2.   
    3. struct _zval_struct {  
    4.     /* Variable information */  
    5.     zvalue_value value;     /* value */  
    6.     zend_uint refcount__gc;  
    7.     zend_uchar type;    /* active type */  
    8.     zend_uchar is_ref__gc;  
    9. };  
    10.   
    11. typedef union _zvalue_value {  
    12.     long lval;  /* long value */  
    13.     double dval;    /* double value */  
    14.     struct {  
    15.         char *val;  
    16.         int len;  
    17.     } str;  
    18.     HashTable *ht;  /* hash table value */  
    19.     zend_object_value obj;  
    20. } zvalue_value;  

    Zend/zend_types.h:

    [cpp]  view plain copy
    1. typedef unsigned char zend_bool;  
    2. typedef unsigned char zend_uchar;  
    3. typedef unsigned int zend_uint;  
    4. typedef unsigned long zend_ulong;  
    5. typedef unsigned short zend_ushort;  

    从上述代码中,可以看到_zvalue_value是真正保存数据的关键部分。通过共用体实现的弱类型变量声明


    问题二、Zend引擎是如何判别、存储PHP中的多种数据类型的呢?

    _zval_struct.type中存储着一个变量的真正类型,根据type来选择如何获取zvalue_value的值。
    [cpp]  view plain copy
    1. type值列表(Zend/zend.h):  
    2. #define IS_NULL     0  
    3. #define IS_LONG     1  
    4. #define IS_DOUBLE   2  
    5. #define IS_BOOL     3  
    6. #define IS_ARRAY    4  
    7. #define IS_OBJECT   5  
    8. #define IS_STRING   6  
    9. #define IS_RESOURCE 7  
    10. #define IS_CONSTANT 8  
    11. #define IS_CONSTANT_ARRAY   9  

    来看一个简单的例子:
    [php]  view plain copy
    1. <?php  
    2.     $a = 1;  
    3.     //此时zval.type = IS_LONG,那么zval.value就去取lval.  
    4.     $a = array();  
    5.     //此时zval.type = IS_ARRAY,那么zval.value就去取ht.  

    这其中最复杂的,并且在开发第三方扩展中经常需要用到的是"资源类型".
    在PHP中,任何不属于PHP的内建的变量类型的变量,都会被看作资源来进行保存。
    比如:数据库句柄、打开的文件句柄、打开的socket句柄。

    资源类型,需要使用ZE提供的API函数来注册,资源变量的声明和使用将在单独的篇目中进行详细介绍。

    正是因为ZE这样的处理方式,使PHP就实现了弱类型,而对于ZE的来说,它所面对的永远都是同一种类型zval

    展开全文
  • PHP是一门简单而强大的语言,提供了很多Web适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。  PHP的执行是通过Zend Engine(下面简称ZE),ZE是使用C编写,在底层...

    PHP是一门简单而强大的语言,提供了很多Web适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。 

    PHP的执行是通过Zend Engine(下面简称ZE),ZE是使用C编写,在底层实现了一套弱类型机制。ZE的内存管理使用写时拷贝、引用计数等优化策略,减少再变量赋值时候的内存拷贝。

    下面不光带你探索PHP弱类型的原理,也会在写PHP扩展角度,介绍如何操作PHP的变量。 

    1. PHP的变量类型

    PHP的变量类型有8种:

    • 标准类型:布尔boolen,整型integer,浮点float,字符string
    • 复杂类型:数组array,对象object
    • 特殊类型:资源resource  

    PHP不会严格检验变量类型,变量可以不显示的声明其类型,而在运行期间直接赋值。也可以将变量自由的转换类型。如下例,没有实现声明的情况下,$i可以赋任意类型的值。

    [php]  view plain copy
    1. <? php  $i = 1;   //int $i = 'show me the money';  //string $i = 0.02;  // float $i = array(1, 2, 3);  // array $i = new Exception('test', 123); // object $i = fopen('/tmp/aaa.txt', 'a') // resource ?>   

    如果你对弱类型原理理解不深刻,在变量比较时候,会出现“超出预期”的惊喜。

    [php]  view plain copy
    1. <? PHP $str1 = null;  $str2 = false;  echo $str1==$str2 ? '相等' : '不相等';  $str3 = '';  $str4 = 0;  echo $str3==$str4 ? '相等' : '不相等';  $str5 = 0;  $str6 = '0';  echo $str5==$str6 ? '相等' : '不相等';  ?>   

    以上三个结果全部是相等,因为在变量比较的时候,PHP内部做了变量转换。如果希望值和类型同时判断,请使用三个=(如,$a===0)来判断。也许你会觉得司空见惯,也许你会觉得很神奇,那么请跟我一起深入PHP内核,探索PHP变量原理。

    2. 变量的存储及标准类型介绍

    PHP的所有变量,都是以结构体zval来实现,在Zend/zend.h中我们能看到zval的定义:

    [php]  view plain copy
    1. typedef union _zvalue_value {     long lval;                 /* long value */     double dval;               /* double value */     struct {                            char *val;         int len;               /* this will always be set for strings */     } str;                     /* string (always has length) */     HashTable *ht;             /* an array */     zend_object_value obj;     /* stores an object store handle, and handlers */  } zvalue_value;   

    属性名 含义 默认值
    refcount__gc 表示引用计数 1
    is_ref__gc 表示是否为引用 0
    value 存储变量的值  
    type 变量具体的类型  

    其中refcount__gc和is_ref__gc表示变量是否是一个引用。type字段标识变量的类型,type的值可以是:IS_NULL,IS_BOOL,IS_LONG,IS_FLOAT,IS_STRING,IS_ARRAY,IS_OBJECT,IS_RESOURCE。PHP根据type的类型,来选择如何存储到zvalue_value。 

    zvalue_value能够实现变量弱类型的核心,定义如下:

    [php]  view plain copy
    1. typedef union _zvalue_value {     long lval;                 /* long value */     double dval;               /* double value */     struct {                            char *val;         int len;               /* this will always be set for strings */     } str;                     /* string (always has length) */     HashTable *ht;             /* an array */     zend_object_value obj;     /* stores an object store handle, and handlers */  } zvalue_value;   

    布尔型,zval.type=IS_BOOL,会读取zval.value.lval字段,值为1/0。如果是字符串,zval.type=IS_STRING,会读取zval.value.str,这是一个结构体,存储了字符串指针和长度。

    C语言中,用"\0"作为字符串结束符。也就是说一个字符串"Hello\0World"在C语言中,用printf来输出的话,只能输出hello,因为"\0"会认为字符已经结束。PHP中是通过结构体的_zval_value.str.len来控制字符串长度,相关函数不会遇到"\0"结束。所以PHP的字符串是二进制安全的。

    如果是NULL,只需要zval.type=IS_NULL,不需要读取值。

    通过对zval的封装,PHP实现了弱类型,对于ZE来说,通过zval可以存取任何类型。

    3. 高级类型Array和Object数组Array

    数组是PHP语言中非常强大的一个数据结构,分为索引数组和关联数组,zval.type=IS_ARRAY。在关联数组中每个key可以存储任意类型的数据。PHP的数组是用Hash Table实现的,数组的值存在zval.value.ht中。 

    后面会专门讲到PHP哈希表的实现。

    对象类型的zval.type=IS_OBJECT,值存在zval.value.obj中。

    4. 特殊类型——资源类型(Resource)介绍

    资源类型是个很特殊的类型,zval.type=IS_RESOURCE,在PHP中有一些很难用常规类型描述的数据结构,比如文件句柄,对于C语言来说是一个指针,不过PHP中没有指针的概念,也不能用常规类型来约束,因此PHP通过资源类型概念,把C语言中类似文件指针的变量,用zval结构来封装。资源类型值是一个整数,ZE会根据这个值去资源的哈希表中获取。  

    资源类型的定义:

    [php]  view plain copy
    1. typedefstruct_zend_rsrc_list_entry {     void *ptr;     int type;     int refcount;  }zend_rsrc_list_entry;   

    其中,ptr是一个指向资源的最终实现的指针,例如一个文件句柄,或者一个数据库连接结构。type是一个类型标记,用于区分不同的资源类型。refcount用于资源的引用计数。

    内核中,资源类型是通过函数ZEND_FETCH_RESOURCE获取的。

    [php]  view plain copy
    1. ZEND_FETCH_RESOURCE(con, type, zval *, default, resource_name, resource_type);   

    5. 变量类型的转换

    按照现在我们对PHP语言的了解,变量的类型依赖于zval.type字段指示,变量的内容按照zval.type存储到zval.value。当PHP中需要变量的时候,只需要两个步骤:把zval.value的值或指针改变,再改变zval.type的类型。不过对于PHP的一些高级变量Array/Object/Resource,变量转换要进行更多操作。

    变量转换原理分为3种:

    5.1 标准类型相互转换

    比较简单,按照上述的步骤转化即可。

    5.2 标准类型与资源类型转换

    资源类型可以理解为是int,比较方便转换标准类型。转换后资源会被close或回收。

    [php]  view plain copy
    1. <? php $var = fopen('/tmp/aaa.txt''a'); // 资源 #1 $var = (int) $var; var_dump($var);  // 输出1 ?>  

    5.3 标准类型与复杂类型转换

    Array转换整型int/浮点型float会返回元素个数;转换bool返回Array中是否有元素;转换成string返回'Array',并抛出warning。 
    详细内容取决于经验,请阅读PHP手册: http://php.net/manual/en/language.types.type-juggling.php 

    5.4 复杂类型相互转换

    array和object可以互转。如果其它任何类型的值被转换成对象,将会创建一个内置类stdClass的实例。

    在我们写PHP扩展的时候,PHP内核提供了一组函数用于类型转换:  

    void convert_to_long(zval* pzval)
    void convert_to_double(zval* pzval)
    void convert_to_long_base(zval* pzval, int base)
    void convert_to_null(zval* pzval)
    void convert_to_boolean(zval* pzval)
    void convert_to_array(zval* pzval)
    void convert_to_object(zval* pzval)
    void convert_object_to_type(zval* pzval, convert_func_t converter)

    PHP内核提供的一组宏来方便的访问zval,用于更细粒度的获取zval的值:

    内核访问zval容器的API
    访问变量
    Z_LVAL(zval) (zval).value.lval
    Z_DVAL(zval) (zval).value.dval
    Z_STRVAL(zval) (zval).value.str.val
    Z_STRLEN(zval) (zval).value.str.len
    Z_ARRVAL(zval) (zval). value.ht
    Z_TYPE(zval) (zval).type
    Z_LVAL_P(zval) (*zval).value.lval
    Z_DVAL_P(zval) (*zval).value.dval
    Z_STRVAL_P(zval_p) (*zval).value.str.val
    Z_STRLEN_P(zval_p) (*zval).value.str.len
    Z_ARRVAL_P(zval_p) (*zval). value.ht
    Z_OBJ_HT_P(zval_p) (*zval).value.obj.handlers
    Z_LVAL_PP(zval_pp) (**zval).value.lval
    Z_DVAL_PP(zval_pp) (**zval).value.dval
    Z_STRVAL_PP(zval_pp) (**zval).value.str.val
    Z_STRLEN_PP(zval_pp) (**zval).value.str.len
    Z_ARRVAL_PP(zval_pp) (**zval). value.ht

    6. 变量的符号表与作用域

    PHP的变量符号表与zval值的映射,是通过HashTable(哈希表,又叫做散列表,下面简称HT),HashTable在ZE中广泛使用,包括常量、变量、函数等语言特性都是HT来组织,在PHP的数组类型也是通过HashTable来实现。 
    举个例子:

    [php]  view plain copy
    1. <? php $var = 'Hello World'; ?>   

    $var的变量名会存储在变量符号表中,代表$var的类型和值的zval结构存储在哈希表中。内核通过变量符号表与zval地址的哈希映射,来实现PHP变量的存取。

    为什么要提作用域呢?因为函数内部变量保护。按照作用域PHP的变量分为全局变量和局部变量,每种作用域PHP都会维护一个符号表的HashTable。当在PHP中创建一个函数或类的时候,ZE会创建一个新的符号表,表明函数或类中的变量是局部变量,这样就实现了局部变量的保护--外部无法访问函数内部的变量。当创建一个PHP变量的时候,ZE会分配一个zval,并设置相应type和初始值,把这个变量加入当前作用域的符号表,这样用户才能使用这个变量。 
    内核中使用ZEND_SET_SYMBOL来设置变量:

    [php]  view plain copy
    1. ZEND_SET_SYMBOL( EG(active_symbol_table), "foo", foo);  

    查看_zend_executor_globals结构

    [php]  view plain copy
    1. Zend/zend_globals.h  
    2.  struct _zend_executor_globals {          //略        HashTable symbol_table;//全局变量的符号表        HashTable *active_symbol_table;//局部变量的符号表        //略  };   

    在写PHP扩展时候,可以通过EG宏来访问PHP的变量符号表。EG(symbol_table)访问全局作用域的变量符号表,EG(active_symbol_table)访问当前作用域的变量符号表,局部变量存储的是指针,在对HashTable进行操作的时候传递给相应函数。

    为了更好的理解变量的哈希表与作用域,举个简单的例子:

    [php]  view plain copy
    1. <? php $temp = 'global'function test() {     $temp = 'active'; } test(); var_dump($temp); ?>   

    创建函数外的变量$temp,会把这个它加入全局符号表,同时在全局符号表的HashTable中,分配一个字符类型的zval,值为‘global‘。创建函数test内部变量$temp,会把它加入属于函数test的符号表,分配字符型zval,值为’active' 。

    7. PHP扩展中变量操作

    创建PHP变量

    我们可以在扩展中调用函数MAKE_STD_ZVAL(pzv)来创建一个PHP可调用的变量,MAKE_STD_ZVAL应用到的宏有:

    [php]  view plain copy
    1. #define     MAKE_STD_ZVAL(zv)               ALLOC_ZVAL(zv);INIT_PZVAL(zv)   #define     ALLOC_ZVAL(z)                   ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)   #define     ZEND_FAST_ALLOC(p, type, fc_type)       (p) = (type *) emalloc(sizeof(type))   #define     INIT_PZVAL(z)                       (z)->refcount__gc = 1;(z)->is_ref__gc = 0;   

    MAKE_STD_ZVAL(foo)展开后得到:

    [php]  view plain copy
    1. (foo) = (zval *) emalloc(sizeof(zval));   (foo)->refcount__gc = 1;   (foo)->is_ref__gc = 0;   

    可以看出,MAKE_STD_ZVAL做了三件事:分配内存、初始化zval结构中的refcount、is_ref。 

    内核中提供一些宏来简化我们的操作,可以只用一步便设置好zval的类型和值。

    API Macros for Accessing zval 
    实现方法
    ZVAL_NULL(pvz) Z_TYPE_P(pzv) = IS_NULL
    ZVAL_BOOL(pvz) Z_TYPE_P(pzv) = IS_BOOL; 
    Z_BVAL_P(pzv) = b ? 1 : 0;
    ZVAL_TRUE(pvz) ZVAL_BOOL(pzv, 1);
    ZVAL_FALSE(pvz) ZVAL_BOOL(pzv, 0);
    ZVAL_LONG(pvz, l)(l 是值) Z_TYPE_P(pzv) = IS_LONG;Z_LVAL_P(pzv) = l;
    ZVAL_DOUBLE(pvz, d) Z_TYPE_P(pzv) = IS_DOUBLE;Z_LVAL_P(pzv) = d;
    ZVAL_STRINGL(pvz, str, len, dup) Z_TYPE_P(pzv) = IS_STRING;Z_STRLEN_P(pzv) = len; 
    if (dup) { 
        {Z_STRVAL_P(pzv) =estrndup(str, len + 1);}  
    }else { 
        {Z_STRVAL_P(pzv) = str;} 
    }
    ZVAL_STRING(pvz, str, len) ZVAL_STRINGL(pzv, str,strlen(str), dup);
    ZVAL_RESOURCE(pvz, res) Z_TYPE_P(pzv) = IS_RESOURCE;Z_RESVAL_P(pzv) = res; 


    ZVAL_STRINGL(pzv,str,len,dup)中的dup参数

    先阐述一下ZVAL_STRINGL(pzv,str,len,dup); str和len两个参数很好理解,因为我们知道内核中保存了字符串的地址和它的长度,后面的dup的意思其实很简单,它指明了该字符串是否需要被复制。值为 1 将先申请一块新内存并赋值该字符串,然后把新内存的地址复制给pzv,为 0 时则是直接把str的地址赋值给zval。

    ZVAL_STRINGL与ZVAL_STRING的区别

    如果你想在某一位置截取该字符串或已经知道了这个字符串的长度,那么可以使用宏 ZVAL_STRINGL(zval, string, length, duplicate) ,它显式的指定字符串长度,而不是使用strlen()。这个宏该字符串长度作为参数。但它是二进制安全的,而且速度也比ZVAL_STRING快,因为少了个strlen。 

    ZVAL_RESOURCE约等于ZVAL_LONG

    在章节4中我们说过,PHP中的资源类型的值是一个整数,所以ZVAL_RESOURCE和ZVAL_LONG的工作差不多,只不过它会把zval的类型设置为 IS_RESOURCE。

    8. 总结

    PHP的弱类型是通过ZE的zval容器转换完成,通过哈希表来存储变量名和zval数据,在运行效率方面有一定牺牲。另外因为变量类型的隐性转换,在开发过程中对变量类型检测力度不够,可能会导致问题出现。 

    不过PHP的弱类型、数组、内存托管、扩展等语言特性,非常适合Web开发场景,开发效率很高,能够加快产品迭代周期。在海量服务中,通常瓶颈存在于数据访问层,而不是语言本身。在实际使用PHP不仅担任逻辑层和展现层的任务,我们甚至用PHP开发的UDPServer/TCPServer作为数据和cache的中间层。

    展开全文
  • javascript变量弱类型

    2017-09-21 12:57:09
    javascript变量弱类型 计算从左到右顺序。 符号“+”,可能是数字相加、也可能是字符串拼接,情况如下: 1. 数字 + 字符串 (1 + "2" = "12"): 字符串拼接 2. 字符串 + 数字 ("1" + 2 = "12"): 字符串拼接 ...
  • JavaScript 是一种弱类型语言,也就是说不需要指定变量的类型,JavaScript的变量类型由它的值来决定, 定义变量需要用关键字 ‘var’, 一条JavaScript语句应该以“;”结尾 定义变量的语法格式: var 变量名 = 值; ...
  • 主要介绍了弱类型语言javascript开发中的一些坑,结合实例形式总结分析了javascript开发中关于变量、函数、数组、对象、作用域等相关知识点常见易错问题,需要的朋友可以参考下
  • PHP弱类型安全

    千次阅读 2019-03-24 10:47:18
    PHP 中在使用 == 比较不同类型变量时会存在变量转换。如: $a = null, $b = false; # true $a = '', $b = null; # true # 数字比较时,会提取字符串中的第一个数字及其相邻数字 intval('abcd...
  • 强类型语言与弱类型语言

    千次阅读 2018-02-01 22:57:19
    弱类型语言允许将一块内存看做多种类型。比如直接将整型变量与字符变量相加。C and C++ 是静态语言,也是弱类型语言;Perl and PHP 是动态语言,但也是弱类型语言。 强类型语言在没有强制类型转化前,不允许两种...
  • 首先强弱是相对的。 强类型: ...通俗地说,弱类型偏向于容忍隐式转换,把不同类型的变量放在一起运算。 静态类型: 编译的时候就知道每一个变量的类型,因为类型错误而不能做的事情是语法错误。...
  • 编程语言一般分为动态类型、静态类型和强类型、弱类型,例如Java是静态、强类型编程语言,而JavaScript是动态、弱类型编程语言。 一、动态类型与静态类型 动态类型语言是运行期间才做数据类型检查的语言,...
  • 强类型语言 ...弱类型定义的语言,某一个变量被定义类型,该变量可以根据环境变化自动。弱类型语言包括:VB,PHP,JavaScript等语言。其中VBScript是动态语言,是一种类型不安全的原因。 举个栗子吧: var
  • declare begin for i in 0..5 loop for k in 1..i loop dbms_output.put(' '); end loop; for j in 1..11-2*i loop dbms_output.put('*');... cursor cur_info is select ename,dname from emp,dept where emp...
  • 松散比较:==比较时先转数据类型再进行比较 严格比较:=== 比较时先判断两种字符串类型是否相等,再进行比较 例: "admin"==0 #ture "1admin"==1 #ture "admin1"==1 #false 如果该字符串没有包含’.’ ‘e’ 'E’...
  • 1.区分大小写 ...2.弱类型变量  全部的变量都用var关键字标示,JavaScript解释器会自动分配 3.句子的尾部分号是可选的  如:var name=23; or var name=23都可以  <script language=’javascript’
  • 浅谈PHP弱类型安全

    万次阅读 2015-01-14 11:54:07
    0x00 弱类型初探 没有人质疑php的简单强大,它提供了很多特性供开发者使用,其中一个就是弱类型机制。 在弱类型机制下 你能够执行这样的操作 1 2 3 4 5 $var = 1; $var = array(); $var = "string"; ?...
  • C语言中强类型&弱类型

    千次阅读 2017-10-22 14:10:53
    强类型:以初始化的全局数据...弱类型:未初始化的全局数据; main.c #include short x = 10; short y = 10; void func(); int main() { fun(); printf("x=%d\n,y=%d\n"); return 0; }test.c int x ; void func

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,528
精华内容 55,011
关键字:

弱类型变量