<?php
$a="abc";
$b="def";
unset($a,$b);
echo $a."\n";
echo $b."\n";

1)词法分析

<ST_IN_SCRIPTING>"unset" {
return T_UNSET;
}

2)语法分析

unticked_statement:

|    T_UNSET '(' unset_variables ')' ';'          //unset($a,$b) 还能这么用呢,第一次知道

unset_variables:
        unset_variable

|    unset_variables ',' unset_variable

;

unset_variable:

        variable    { zend_do_end_variable_parse(&$1, BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1 TSRMLS_CC); }

;

3)生成opcode

void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */
{
zend_op *last_op; zend_check_writable_variable(variable); if (variable->op_type == IS_CV) {
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_UNSET_VAR;
SET_NODE(opline->op1, variable);
SET_UNUSED(opline->op2);
SET_UNUSED(opline->result);
opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
} else {
//不是IS_CV类型的处理
}
}

4)执行opcode

static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval tmp, *varname;
HashTable *target_symbol_table; SAVE_OPLINE();
if (IS_CV == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
if (EG(active_symbol_table)) {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var); zend_delete_variable(EX(prev_execute_data), EG(active_symbol_table), cv->name, cv->name_len+, cv->hash_value TSRMLS_CC); //从active_symbol_table中清除cv->name以及相应值,再从CV数组中清除此值
EX_CV(opline->op1.var) = NULL;
} else if (EX_CV(opline->op1.var)) {
zval_ptr_dtor(EX_CV(opline->op1.var));
EX_CV(opline->op1.var) = NULL;
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
//不会被执行了
}
 
#define CV_DEF_OF(i) (EG(active_op_array)->vars[i])

#undef EX_CV
#define EX_CV(var) EX(CVs)[var]

#undef EX_CVs

#define EX_CVs() EX(CVs)

#undef EX_T

#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))

#undef EX_Ts

#define EX_Ts() EX(Ts)

 

ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
{

if (zend_hash_quick_del(ht, name, name_len, hash_value) == SUCCESS) {

name_len--;

while (ex && ex->symbol_table == ht) {

int i;

if (ex->op_array) {

                for (i = 0; i < ex->op_array->last_var; i++) {

if (ex->op_array->vars[i].hash_value == hash_value &&

ex->op_array->vars[i].name_len == name_len &&

!memcmp(ex->op_array->vars[i].name, name, name_len)) {

ex->CVs[i] = NULL;

break;

}

}

}

ex = ex->prev_execute_data;

}

}

}

ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag)

{

uint nIndex;

Bucket *p;

#ifdef ZEND_SIGNALS

TSRMLS_FETCH();

#endif

IS_CONSISTENT(ht);

if (flag == HASH_DEL_KEY) {

        h = zend_inline_hash_func(arKey, nKeyLength);

}

nIndex = h & ht->nTableMask;

p = ht->arBuckets[nIndex];

    while (p != NULL) {

if ((p->h == h)

&& (p->nKeyLength == nKeyLength)

&& ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */

|| !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */

HANDLE_BLOCK_INTERRUPTIONS();

if (p == ht->arBuckets[nIndex]) {

ht->arBuckets[nIndex] = p->pNext;

} else {

p->pLast->pNext = p->pNext;

}

if (p->pNext) k{

p->pNext->pLast = p->pLast;

}

if (p->pListLast != NULL) {

p->pListLast->pListNext = p->pListNext;

} else {

/* Deleting the head of the list */

ht->pListHead = p->pListNext;

}

if (p->pListNext != NULL) {

p->pListNext->pListLast = p->pListLast;

} else {

ht->pListTail = p->pListLast;

}

if (ht->pInternalPointer == p) {

ht->pInternalPointer = p->pListNext;

}

if (ht->pDestructor) {

ht->pDestructor(p->pData);

}

if (p->pData != &p->pDataPtr) {

pefree(p->pData, ht->persistent);

}

pefree(p, ht->persistent);

HANDLE_UNBLOCK_INTERRUPTIONS();

ht->nNumOfElements--;

return SUCCESS;

}

p = p->pNext;

}

return FAILURE;

}

php unset变量的更多相关文章

  1. php面试题7(1、unset变量是删除栈变量,并不删除堆变量)(2、php爬虫特别简单: 可以file_get_contents和直接fopen)

    php面试题7(1.unset变量是删除栈变量,并不删除堆变量)(2.php爬虫特别简单: 可以file_get_contents和直接fopen) 一.总结 1.unset变量是删除栈变量,并不删除 ...

  2. unset变量释放内存不起作用

    unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间. 只有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存.

  3. linux学习之十、变量的取用与配置:echo, 变量配置守则, unset

    vim vim 的环境设定参数 :set nu :set nonu 就是设定与取消行号啊! :set hlsearch :set nohlsearch hlsearch 就是 high light s ...

  4. thinkphp 控制器unset删除对象变量失败。。

    今儿开发过程中发现 tp是unset 变量失败..具体代码 foreach( $this->menu as $k => $v){ if(0 == $v['flag']) unset($th ...

  5. 第9章 Shell基础(3)_Bash的变量

    4. Bash的变量 4.1 用户自定义变量 4.1.1 什么是变量 变量是计算机的内存单元,其中存放的值可以改变.当Shell脚本需要保存一些信息时,如一个文件名或是一个数字,就把它存放在一个变量中 ...

  6. 三、Shell变量类型和运算符

    一.Shell变量的应用 1.Shell变量的种类     ·用户自定义变量:由用户自己定义.修改和使用     ·预定义变量:Bash预定义的特殊变量,不能直接修改     ·位置变量:通过命令行给 ...

  7. shell编程之变量

    变量: 变量由字母.数字._ 组成,不能以数字开头 长度不能超过255个字符 在bash中,变量的默认类型是字符串类型 变量分类: 1.用户自定义变量:只在当前shell生效,是局部变量 定义方法: ...

  8. Shell 的变量功能

    搜寻路径PATH(系统预设变量) 执行命令时,系统透过PATH得路径顺序搜寻指令,如果再搜寻完后还找不到该指令,就会打印错误讯息[command not fount].   环境变量 进入shell之 ...

  9. Linux中的输入重定向,变量

    1 :分号 格式:命令1:命令2;命令3 说明:命令之间用分号隔开是顺序执行,命令之间没有任何逻辑关系 2  &&  逻辑与 格式:命令1 && 命令2 说明:命令1正 ...

随机推荐

  1. SVN中检出 和 导出 的区别

    SVN中检出 和 导出 的区别:检出得到的文件夹中,是受SVN客户端控制的,对其进行文件或文件夹的增删改操作都会被SVN客户端识别出来,对其可以进行update.commit操作.其中含有.svn隐藏 ...

  2. 常见的web服务器软件分类

    (1)ApacheApache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上.Apache源于NCSAhttpd服务器,经过多次修改,成为世界上最流行的Web服务器软 ...

  3. 2018.09.14 洛谷P3567 [POI2014]KUR-Couriers(主席树)

    传送门 简单主席树啊. 但听说有随机算法可以秒掉%%%(本蒟蒻并不会) 直接维护值域内所有数的出现次数之和. 当这个值不大于区间总长度的一半时显然不存在合法的数. 这样在主席树上二分查值就行了. 代码 ...

  4. hdu-1141

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1141 参考文章:https://blog.csdn.net/fei____fei/article/de ...

  5. 基于beego orm 针对oracle定制

    目前golang的ORM对oracle支持都没有mysql那样完整,一个orm要同时兼容mysql和oracle由于在sql语法上区别,会使整orm变的非常臃肿. 本项目是在beego orm上修改, ...

  6. (匹配 最小路径覆盖)Air Raid --hdu --1151

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1151 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  7. OpenGl 坐标转换 (转载)

    OpenGl 坐标转换 (转载) 1. OpenGL 渲染管线 OpenGL渲染管线分为两大部分,模型观测变换(ModelView Transformation)和投影变换(Projection Tr ...

  8. hdu 5067 遍历指定点集最小时间

    http://acm.hdu.edu.cn/showproblem.php?pid=5067 贴题解 由于Harry的dig machine是无限大的,而装载石头和卸载石头是不费时间的,所以问题可以转 ...

  9. web问题

    模拟form提交过程中form(hidden)时:The frame requesting access has a protocol of "http", the frame b ...

  10. Hibernate 注解和配置文件两种方法的对比(有实例)

    hibernate多对多形式(User类<---->Educate类) 1.基于注解的形式: User类: package com.ssh.entities; import java.ut ...