<?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. part1:1-embeded学习心态

    遇到问题,要冷静分析问题,采用排除法,个个排除查找问题之所在!切记!在没分析完自己问题之前,别把问题所在指向他人!

  2. 函数数组demo

    #include <stdio.h> #include <string.h> typedef int(*service_func)(char *,char *); struct ...

  3. 自然语言处理--中文文本向量化counterVectorizer()

    1.载入文档 #!/usr/bin/python # -*- coding: utf-8 -*- import pandas as pd import re import jieba from skl ...

  4. 2018.07.20 bzoj2152: 聪聪可可(点分治)

    传送门 本蒟蒻AC的第二道点分治,调了30min" role="presentation" style="position: relative;"&g ...

  5. 2018.07.08 hdu6183 Color it(线段树)

    Color it Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Proble ...

  6. SIM900 AT来电显示开启,一些代码

    /*Note: this code is a demo for how to using gprs shield to send sms message, dial a voice call and ...

  7. 【redis】linux上的安装与配置(详细图解)

    转载自:https://blog.csdn.net/yjqyyjw/article/details/73293455:经过个人测试也适用于当前最新稳定的3.x的版本,顺便填了几个坑. 1.下载 htt ...

  8. Ubuntu14.04下安装Cuda8.0

    https://blog.csdn.net/sinat_19628145/article/details/60475696 https://developer.nvidia.com/cuda-down ...

  9. (求树的直径)Warm up -- HDU -- 4612

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 给一个无向图, 加上一条边后,求桥至少有几个: 那我们加的那条边的两个顶点u,v:一定是u,v之 ...

  10. Oracle实现递归查询

    前几天在开发的过程中遇到一个递归查询的问题,java代码大致是这样的: // 递归得到四级机构对象 public UserManagerDept getuserManagerDeptBy(String ...