PHP是如何实现弱类型的
C的结构体和联合体
-
C语言的结构(struct):包含多个成员,可能有多种数据类型,并且需要分配几种类型占用空间之和的空间。
-
联合(union):支持多种类型,供使用者使用其中一种数据类型,当然是需要分配其中占用空间最大的数据类型的大小。
结构和联合通常是出现在一块的。
PHP弱类型的实现
PHP是用C语言来实现的,那么思考下为什么PHP可以实现弱类型呢?
答案就在C语言的结构和联合上。从弱类型变量的写入和读取二者分析:
变量写入
有了联合,我们可以定义几种类型,让PHP的变量在写的时候自己在其中选取,这个可以解决变量写入。
变量读取
那怎么解决读取这个变量呢?变量设置后,不知道这个变量使用的联合中哪个类型,也就没法读取。
我们可以在结构体里,设置一个成员专门记录联合中用的哪个类型。这样就ok了。
C实现demo
用一个简单的C例子演示一下:这里只使用了三种类型,整数 浮点数和字符串,php的数组是用hashtable这里就不说了。
#include <stdio.h>
typedef union uval{
long a;
double b;
char c;
} uval;
typedef struct pval{
uval val;
int phptype;
} pval;
//enum
void var_dump(pval);
int main(){
pval pval1 = {{.a = 111}, 1};
var_dump(pval1);// int 111
pval1.phptype = 2;
pval1.val.b = 1.21;
var_dump(pval1);// float 1.210000
pval1.phptype = 3;
pval1.val.c = "abc";
var_dump(pval1);// string abc
}
/**
* @param val
* 根据pval变量类型,决定读取联合体的那个类型
*/
void var_dump(pval val){
if(val.phptype == 1){
printf("%s ", "int");
printf("%ld\n", val.val.a);
} else if(val.phptype == 2){
printf("%s ", "float");
printf("%f\n", val.val.b);
} else if(val.phptype == 3){
printf("%s ", "string");
printf("%s\n", val.val.c);
}
}
可以认为pval这种类型就是php的一个变量的类型。每一个php变量记录了这个值val和类型phptype(实际还有引用计数等)。
每次写入val时,要把其类型也记录下来。这样就实现了弱类型。