php unset变量
<?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变量的更多相关文章
- php面试题7(1、unset变量是删除栈变量,并不删除堆变量)(2、php爬虫特别简单: 可以file_get_contents和直接fopen)
php面试题7(1.unset变量是删除栈变量,并不删除堆变量)(2.php爬虫特别简单: 可以file_get_contents和直接fopen) 一.总结 1.unset变量是删除栈变量,并不删除 ...
- unset变量释放内存不起作用
unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间. 只有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存.
- linux学习之十、变量的取用与配置:echo, 变量配置守则, unset
vim vim 的环境设定参数 :set nu :set nonu 就是设定与取消行号啊! :set hlsearch :set nohlsearch hlsearch 就是 high light s ...
- thinkphp 控制器unset删除对象变量失败。。
今儿开发过程中发现 tp是unset 变量失败..具体代码 foreach( $this->menu as $k => $v){ if(0 == $v['flag']) unset($th ...
- 第9章 Shell基础(3)_Bash的变量
4. Bash的变量 4.1 用户自定义变量 4.1.1 什么是变量 变量是计算机的内存单元,其中存放的值可以改变.当Shell脚本需要保存一些信息时,如一个文件名或是一个数字,就把它存放在一个变量中 ...
- 三、Shell变量类型和运算符
一.Shell变量的应用 1.Shell变量的种类 ·用户自定义变量:由用户自己定义.修改和使用 ·预定义变量:Bash预定义的特殊变量,不能直接修改 ·位置变量:通过命令行给 ...
- shell编程之变量
变量: 变量由字母.数字._ 组成,不能以数字开头 长度不能超过255个字符 在bash中,变量的默认类型是字符串类型 变量分类: 1.用户自定义变量:只在当前shell生效,是局部变量 定义方法: ...
- Shell 的变量功能
搜寻路径PATH(系统预设变量) 执行命令时,系统透过PATH得路径顺序搜寻指令,如果再搜寻完后还找不到该指令,就会打印错误讯息[command not fount]. 环境变量 进入shell之 ...
- Linux中的输入重定向,变量
1 :分号 格式:命令1:命令2;命令3 说明:命令之间用分号隔开是顺序执行,命令之间没有任何逻辑关系 2 && 逻辑与 格式:命令1 && 命令2 说明:命令1正 ...
随机推荐
- 学习bn算法
好处: 1.归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低: 2.另外一方面,一旦每批训练数据的分布各不相同(b ...
- client.HConnectionManager$HConnectionImplementation: Can't get connection to ZooKeeper: KeeperErrorCode = ConnectionLoss for /hbase
解决方法:hbase 未成功启动 1.关闭防火墙:service iptables stop 2.start-hbase.sh
- Python特殊方法
# __slots__如果要限制添加的属性,例如,Student类只允许添加 name.gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现. # __sl ...
- Django入门与实践-第13章:表单处理(完结)
http://127.0.0.1:8000/boards/1/ http://127.0.0.1:8000/boards/2/ http://127.0.0.1:8000/boards/3/ http ...
- 静态代码块和this
/* 静态代码块.随着类的加载而执行.而且只执行一次. 作用: 用于给类进行初始化. */class StaticCode{ static int num ; static { num = 10;// ...
- 常用的SLAM解决方案
ORB SLAM 可以去Github上自己搜索现成的SLAM程序包 在此基础上做优化 视觉SLAM的分类方法:按摄像头的多少分为单目和双目,按是否使用概率方法分为概率法和图法 链接 学习SLAM重要的 ...
- B-tree B+tree适合文件系统索引和MySQL索引
B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点.下图是 B-树的简化图. B-树 ...
- java.util.Date与java.sql.Date的关系和转换方法(转)
在ResultSet中我们经常使用的setDate或getDate的数据类型是java.sql.Date,而在平时java程序中我们一般习惯使用 java.util.Date. 因此在DAO层我们经常 ...
- java web开发过程中的“\”指的是什么,如何区分
- Android-fragment-ListView展示-v4支持包
昨天写的这几篇博客,Android-fragment简介-fragment的简单使用,Activity-fragment-ListView展示,Android-fragment生命周期,Android ...