<?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. 百度词汇检索,计算PMI值

    '''词汇检索百度返回值,并且计算PMI值的类''' from bs4 import BeautifulSoup import requests import re import pandas as ...

  2. 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)

    传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...

  3. test 测试spring容器类

  4. redis与ssm整合(用 redis 替代mybatis二级缓存)

    SSM+redis整合 这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷新已有缓存,如果不存在就会新建缓存,所有的insert,update操作都 ...

  5. Cygwin工具的简单使用

    简介 从使用角度来看:Cygwin就是一个windows软件,该软件就是在windows上仿真linux操作系统.简言之,cygwin是一个在windows平台上运行的 linux模拟环境,使用一个D ...

  6. Linux 随记

    通配符和文件名变量:* ? [] * 查询 $ ls doc1 doc2 document mydoc monday $ ls doc* doc1 doc2 document $ ls  *day m ...

  7. 优秀前端工程师必备:" checkbox & radio--单钩 & 多钩 "大比较:你是♂||♀ , 还是 ♂&♀

    1 单选: type="radio"  需求: 男女input只能选择一个 <input type="radio" name="sex" ...

  8. SPSS-两变量相关性分析

    两个变量之间存在确定性:关系和不确定关系(会存在一定的波动范围),就好比你的亲生母亲绝对只有一个,而你的亲叔叔可能有好几个(可以在1叔—4叔之间波动) 相关性一般分为   1:强正相关关系  (一个值 ...

  9. (线段树 区间查询更新) Can you answer these queries? -- hdu--4027

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4027 分析:因为这个操作是把一个数变成平方根,所以显得略棘手,不过如果仔细演算的话会发现一个2^64数的 ...

  10. Gridview的RowDataBound事件可以做很多事情

    protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)        {            //如果是绑 ...