神秘的变量名特性

【入门】时间相减问题 【运算符】 题目描述 【题目描述】 你是个贪睡虫,有一天被老师逮个正着,这个老师很有意思,提出一个问题:“给定入睡时刻和起床时刻,计算一共睡了多长时间”,如果回答正确就可以免于处罚。入睡时刻和起床时刻都采用24小时制表示法(见备注),而且知道睡觉时间最少为1秒,最多为24小时。 输入 【输入格式】 输入第一行描述入睡时刻,第二行描述起床时刻,两个时刻都是采用“HH MM SS”, 阅读详情

    在PHP语言中,变量都是保存在哈希表中,称为变量符号表,其中变量名为哈希表的键,变量名对应的容器zval的指针为哈希表中的值。所有全局变量放在一张主符号表中(也就是数组$GLOBALS对应的哈希表)。PHP语言有个特性,变量在命名时,$变量标识符后不能以数字开头。例如我们在以下代码:

<?php

$111= "my";

?>

会报如下错误:Parse error: syntax error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in...

 

从错误的描叙来看,这是一个语法错误,于是我们推论对变量名合法性的判断应该是在编译时的语法分析阶段。

为了证明观点,我们可以试着在执行阶段定义一个数字字符开头的变量:

<?php

$a   = 111;

$$a = "my"; //以变量$a的值作为变量名

echo $$a;

var_dump($GLOBALS);

?>

运行之后发现不报错,并且在全局符号表$GLOBALS中发现相关符号:

  ["a"]=>
  int(111)
  ["111"]=>
  string(2) "my"

 

这样我们就定义了一个全数字字符命名的变量,似乎违背了PHP的规则,但是确实做到了。

(读者可以试着输出$GLOBALS["111"]的值,虽然有值,但是结果却为NULL,这个是PHP中一个类型转换的特性)

 

在这段代码中,$$a = "my"这条语句具有多态性,只有当实际执行到这条语句的时候,我们才能确定变量名,PHP在语法分析阶段无法知道这个变量名会是什么,所以就不会报错,在执行阶段,PHP语言不判断变量名的合法性,于是就产生了这样一个叛逆的变量。

 

知道了这个特性之后,马上会想到一个另外一个特殊的变量:$this

在类的方法中,$this关键字用来指向当前类的对象实例,如果对$this进行赋值操作,会发生什么事情?

 

 

 执行代码,报错:

Fatal error: Cannot re-assign $this in...

 

PHP对$this变量做了一定保护措施,但是这个保护措施也不是完全的,我们利用前面的方法在执行期改变$this的值, 修改后的getName方法为:

 

然后执行代码,发现能够顺利执行,$this的值变成了123, 由此可以判断对$this关键字的保护也仅限与语法分析阶段。

 

当$this的值变成123之后,按理说$this->_name肯定会报错的,但是居然代码能正常执行,这个确实很让人觉得不可思议。于是推断

$this->_name这样的引用方式和一般的对象变量引用方式在有差异,我们继续对getName做修改:

 

这段代码中,$this和$b的值都等于123,但是$this->getAge()可以顺利执行,$b->getAge()却报错:

Fatal error: Call to a member function getAge() on a non-object...

 

这是一个诡异的问题,于是可以推断$this->getAge()和$b->getAge()在编译之后对应的op handler肯定有所差异,于是查看之。

 

通过vld查看op的信息

$this->getAge()对应的为:

ZEND_INIT_METHOD_CALL    RES[  IS_UNUSED  ]         OP1[  IS_UNUSED  ] OP2[  IS_CONST (8142027) 'getAge' ]

 

$b->getAge()在对应的为:

ZEND_INIT_METHOD_CALL    RES[  IS_UNUSED  ]         OP1[  IS_CV !0 ]      OP2[ ,  IS_CONST (8142039) 'getAge' ]

 

虽然对应了同样的op code,但是由于操作数的不同(前者不使用OP1,后者使用OP1, 且OP1的值!0表示$b),同一个op code对应同一类handler,然后根据操作数的类型确定到此类handler中的某一个handler。

 

$this->getAge()对应的handler处理为:ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER

$b->getAge()    对应的handler处理为:ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER

 

这就是它们的差异了,在执行

$my = new Person();
$name = $my->getName();

 

调用getName的时候,getName()的作用域(scope)已经被设置成$name对象中,语法分析的时候对于getName中$this->getAge()这样的调用时只是在当前作用域(scope)中调用getAge()函数,不会理会$this的具体值,而在$b->getAge()这样的调用时,会关心$b所对应的值。

 

使用dotpeek反编译dll并移除SuppressIldasmAttribute特性 本文详细介绍了如何使用JetBrains dotPeek工具反编译.NET DLL文件,并利用Mono.Cecil库精准移除程序集中的SuppressIldasmAttribute特性。通过分步教程和代码示例,指导开发者完成从代码导出到特性移除的完整流程,解决因该特性导致的兼容性与分析障碍,适用于学习、调试与深度代码研究场景。 阅读详情

相关推荐

从DLL到源码:用dotPeek和Mono.Cecil搞定反编译与特性清理

本文详细介绍了如何使用dotPeek和Mono.Cecil工具进行DLL反编译与特性清理,帮助开发者将黑盒DLL还原为可读源代码。通过实战案例演示了从加载分析DLL到移除编译特性的完整流程,并提供了高级修改技巧和常见问题解决方案,适用于遗留项目维护和第三方库调试等合法场景。

weixin_30872337的博客 577

PHP中的变量命名规则是什么?

某些特定的名称如。

破损的天堂鸟博客 1494

神秘的JavaScript变量:探索前端开发中的不寻常之处

在第一个示例中,JavaScript将数字1隐式地转换为字符串,然后执行字符串的拼接操作。在编写JavaScript代码时,建议始终使用关键字显式地声明变量,注意作用域和变量名的优先级,并小心处理类型转换的情况。当我们在一个作用域中使用一个变量时,JavaScript会按照一定的顺序搜索该变量。作用域链的顺序是从内到外的,它首先搜索当前作用域,然后逐级向上搜索父级作用域,直到找到第一个匹配的变量或达到全局作用域。在JavaScript中,变量提升是一种特殊的行为,它允许在声明之前就可以访问变量。

CflfEditor的博客 65

Java入门-13-【入门】时间相减问题 【运算符】

题目描述 你是个贪睡虫,有一天被老师逮个正着,这个老师很有意思,提出一个问题:“给定入睡时刻和起床时刻,计算一共睡了多长时间”,如果回答正确就可以免于处罚。入睡时刻和起床时刻都采用24小时制表示法(见备注),而且知道睡觉时间最少为1秒,最多为24小时。 输入 【输入格式】 输入第一行描述入睡时刻,第二行描述起床时刻,两个时刻都是采用“HH MM SS”,其中“HH”表示时,范围为0到23,“MM”...

adrion_aaron的博客 1809

解密JavaScript的神秘之处

在本文中,我们将揭秘JavaScript中一些有趣和神秘的特性,并提供相应的源代码示例。在JavaScript中,函数可以被视为一等公民,这意味着函数可以像其他数据类型一样被赋值给变量、作为参数传递给其他函数,甚至可以作为函数的返回值。JavaScript是一种事件驱动的语言,它可以对用户的交互和其他事件做出响应。通过使用事件处理器,我们可以注册特定事件的回调函数,以便在事件发生时执行相应的操作。这样,通过该对象访问的属性和方法会首先在对象本身查找,如果找不到,就会沿着原型链向上查找。

EuForth的博客 67

Audio2Face进阶玩法:结合LiveLink在UE5中实现MetaHuman全身动画+语音驱动(保姆级配置指南)

本文提供了一份详尽的保姆级教程,指导如何将NVIDIA Audio2Face与Unreal Engine 5的LiveLink功能结合,实现驱动MetaHuman数字人面部表情的同时,无缝融合身体动画。文章详细讲解了从环境准备、插件部署、基础面部驱动测试,到动画蓝图高级配置与多数据流融合的全流程,并分享了性能优化与问题排查的实战经验,旨在帮助创作者打造表情与肢体动作协调统一的生动数字人。

q9w8e7r6t5的博客 197

今天数据结构老师提到一个问题……

        世界地图上如此多的国家,实践证明,我们只要四种颜色,就可以标出,而且相邻国家不同色,值得注意的是这个问题,目前还没有人证明,同时有关图问题,目前世界上还存在许多为解决的问题……我认为这个在逻辑上肯定能找到答案……我们共同期待吧……

Supercaller的专栏 663

简单易懂的AXI_Lite 总线详解

简单易懂的AXI_Lite 总线详解 1、前言 AXI_LITE协议主要应用于Xilinx的ZYNQ芯片构架下的ARM和FPGA之间的数据读写,更偏向于单个寄存器的读写。 2、AXI总线与ZYNQ的关系 AXI(Advanced eXtensible Interface)本是由ARM公司提出的一种总线协议,Xilinx从6系列的FPGA开始对AXI总线提供支持,此时AXI已经发展到了AXI4这个版本,所以当你用到Xilinx的软件的时候看到的都是“AIX4”的IP,如Vivado打包一个AXI IP的时候,

m0_46642108的博客 8495

一个很有意思的写法

#include #include #include #include typedef long long ll; using namespace std; ll s[1000100]; int main(){ int a,n; while(scanf("%d %d",&a,&n)){ priority_queue,greater > q; int pos=0; q.pu

Twoutopians 444

AI量化交易工作台Vibe-Trading:用自然语言驱动策略回测与多智能体研究

量化交易通过数学模型和计算机程序执行投资决策,其核心在于将市场规律转化为可验证的策略。传统量化开发涉及数据获取、策略编写、回测验证等复杂工程,对非编程背景的从业者构成较高门槛。随着大语言模型技术的发展,自然语言交互正成为降低技术使用难度的关键。Vibe-Trading项目正是这一趋势的实践,它将金融工程任务封装为可调用的工具与技能,允许用户通过自然语言指令直接驱动策略回测、因子研究和投资组合分析。其技术价值在于构建了一个模块化的AI Agent框架,通过ReAct推理框架协调多个专项技能,并创新性地引入多智

weixin_28695161的博客 1567

UE5垃圾回收优化实战:定位GC卡顿与内存泄漏

垃圾回收(GC)是Unreal Engine 5中保障UObject内存安全的核心机制,其基于引用图的标记-清除原理决定了性能高度依赖引用结构合理性。当GC频繁触发或单次耗时突增,往往映射出蓝图强引用冗余、C++根对象管理失控或资源生命周期设计缺陷等底层问题。技术价值在于降低主线程阻塞、稳定60帧体验、抑制内存异常增长;典型应用场景包括关卡切换卡顿、UI打开后持续GC、打包后内存不释放等。本文聚焦UE5特有的Full GC模式、UObject生命周期约束及GC触发时机不可见性,提供从蓝图变量规范、TSoft

weixin_31995251的博客 362

三十九、PHP内核探索:诡异的变量名 ☞ 神秘的变量名特性

在PHP语言中,变量都是保存在哈希表中,称为变量符号表,其中变量名为哈希表的键,变量名对应的容器zval的指针为哈希表中的值。所有全局变量放在一张主符号表中(也就是数组$GLOBALS对应的哈希表)。PHP语言有个特性,变量在命名时,$变量标识符后不能以数字开头。例如我们在以下代码: <?php $111= "nowamagic"; ?> 会报如下错误:Parse error:...

进阶之旅 380

021、反激变换器的软启动设计

本文分享了反激变换器软启动设计的实践经验。作者通过一次上电炸机事故引出软启动的重要性,分析了启动瞬间电流冲击和环路饱和问题。介绍了三种软启动方案:效果差的RC电路、推荐使用的数字芯片方案以及分立元件实现方法,重点指出数字方案的一致性优势。文章还探讨了软启动与过流保护的配合问题,提供了实测波形、温度影响等调试要点,并总结出软启动时间选择、批量生产一致性等实用建议。最后强调软启动是电源可靠性的关键设计,不应为节省成本而忽略。全文包含多个工程实践细节,对电源设计人员具有重要参考价值。(149字)

Jack010169的博客 176

python中类的神秘面纱

看完篇你就可以飘起来了 一:实例化过程: 实例化:其实就是以People类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名 class People(object): def __init__(self, name, sex='F'): self.name = name self.sex = sex def people_name...

ahjd123czy的博客 284

纳米尺度仿真软件:GROMACS_(3).分子动力学模拟原理

分子动力学(MD)模拟是一种强大的计算方法,通过数值积分牛顿运动方程,追踪粒子在时间上的位置和速度变化,提供关于体系动力学行为的详细信息。选择合适的力场、设置初始条件、应用边界条件、控制温度和压力、选择合适的时间步长、计算能量和力,是 MD 模拟的关键步骤。通过这些步骤,可以对各种化学、生物和材料体系进行模拟和分析,揭示其结构、动力学和热力学性质。高级应用如反应路径模拟和蛋白质折叠研究,进一步扩展了 MD 模拟的应用范围。

kkchenjj的博客 1100

汽车IVI中控开发入门及进阶(三十八):手机投屏HiCar开发

为了兼容这部分手机,车机端在向手机端发送USB控制命令字的同时,需要启动mDNS Server,广播车机端IP地址和HiCar SDK侦听的Server Socket端口(IP地址和端口在HiCar SDK初始化USB driver时,告知车机),在检测到手机断开USB连接时关闭mDNS Server。厂商在集成HiCar SDK开发HMI应用时,不可避免会使用到智能座舱的敏感权限,例如位置权限、摄像头权限、麦克风权限等,SDK初始化时,厂商HMI应用需要设置必要的车机参数供SDK使用。

码农17年的博客 1075

改良程序的11技巧

有很多理由都能说明为什么我们应该写出清晰、可读性好的程序。 最重要的一点, 程序你只写一次,但以后会无数次的阅读。 当你第二天回头来看你的代码时,你就要开始阅读它了。 当你把代码拿给其他人看时,他必须阅读你的代码。 因此,在编写时多花一点时间,你会在阅读它时节省大量的时间。 让我们看一些基本的编程技巧: 尽量保持方法简短.永远永远不要把同一个变量用于多个不同的目的.使用自描述的变

CTO=开发管理+架构+技术专栏 481

【小白CV教程】YOLOv5+Deepsort实现车辆行人的检测、追踪和计数

【小白CV教程】YOLOv5+Deepsort实现车辆行人的检测、追踪和计数本文禁止转载!项目简介:YOLOv5检测器:DeepSort追踪器:运行demo:训练自己的模型:调用接口:创建检测器:调用检测接口: 本文禁止转载! 项目简介: 使用YOLOv5+Deepsort实现车辆行人追踪和计数,代码封装成一个Detector类,更容易嵌入到自己的项目中。 代码地址(欢迎star): https://github.com/Sharpiless/Yolov5-deepsort-inference 最终效果:

梁瑛平的博客 5万+

ThinkPHP 控制器高级特性

ThinkPHP的控制器层由核心控制器和业务控制器组成,核心控制器由系统内部的App类完成,负责应用(包括模块和操作)的调度控制,包括HTTP请求拦截和转发、加载配置等,业务控制器则由用户定义的Action类或者其他控制器类完成。 我们通过前面的学习,已经了解了基本的控制器用法,这一篇我们来讲述下控制器的一些特性和高级用法,来探索ThinkPHP控制器的神秘外衣。[-more-] Ac

dianas 1200

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

揭开 JavaScript 作用域的神秘面纱(下)

闭包是指在函数内部创建一个独立的作用域,该作用域中的变量和函数可以在函数外部被访问。即使函数执行完毕,闭包中的变量和函数仍然可以被访问。闭包具有以下特点:函数嵌套函数:闭包必须有函数嵌套函数的结构。内部函数可以访问外部函数的变量:内部函数可以访问外部函数中的变量,即使外部函数已经执行完毕。外部函数返回内部函数:外部函数必须返回内部函数,才能形成闭包。JavaScript 作用域是指变量和函数在程序中的可访问范围。全局作用域:在 JavaScript 中,变量和函数可以在全局作用域中定义。

你若盛开,清风自来 969

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

猫抓 cat-catch 完整指南:浏览器资源嗅探与视频下载 5 步上手

猫抓(cat-catch)是一款开源的浏览器扩展,核心是资源嗅探:它监听网页加载过程中的网络请求,把视频、音频等媒体资源整理成可预览、可勾选的列表,直接完成网页视频下载,不依赖第三方中转网站。它适合保存网页视频、解析 m3u8 流媒体、离线下载在线课程的用户。本文按"安装 → 上手 → 能力拆解 → 进阶 → 排错"的顺序展开。 ## 🚀 从安装到首次下载 ### 猫抓扩展安装步骤 应用商

gitblog_00902的博客 280

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【C++11】其他一些新特性 | 右值引用 | 完美转发

我们已经掌握了C++的大部分语法,并已经能对其熟练使用,但是时代是在发展的,C++11有更新了很多新特性,其中有一些可以极大的提升效率,我们本篇来学习一下。什么是左值?什么是左值引用?左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。//左值 右值int main()

weixin_64132124的博客 1091

字母组合如何用python实现_在Python中对数字和字母的组合列表进行排序

你的问题并不是很清楚,但我假设你忽略了每个元组中的第一项,而只在第二项中对列表进行排序。我还假设只有从'a'到'I'的字母可以出现在这个列表中。在转换A-&gt;1,b-&gt;2,c-&gt;3。。。i-&gt;9是利用数字字符的ASCII码和小写字母是连续的这一事实。因此,在每个字母和它的等效数字之间有一个恒定的偏移量48。在因此,要将字符串列表转换为键,我们可以将所有字符串合并为单个字符串,...

weixin_39878247的博客 959

神秘的 sizeof(union) 、sizeof(struct) 和内存对齐技术

【C++ Primer】 神秘的 sizeof(union) 、sizeof(struct) 和内存对齐技术 标签: structc++编译器平台数据结构c 2012-05-17 15:30 4368人阅读 评论(5) 收藏 举报 本文章已收录于: 分类: 【C++ Primer】(32) 作者同类文章X

cai_niao_123的博客 506

Java8的新特性以及使用

我们通常需要对列表的每个元素使用某个函数,例如逐一乘以某个数、除以某个数或者做其它操作。// filter更好的办法--filter方法改进。获取数字的个数、最小值、最大值、总和以及平均。表达式返回值可以是任何类型,但是返回值会包装。开始,长度为四个字母的名字,你可以合并两。实例,也可以通过方法返回值得到。实例,否则返回传入的错误信息。)非常类似,区别在于传入方法。类似,区别在于传入的默认值。的方法引用更方便,方法引用。方法类似,区别在于返回值。式返回值可以是任意类型,创建一个字符串列表,

2301_78145669的博客 1690
上一篇: PHP新的垃圾回收机制:Zend GC详解
下一篇: KalonDaemon - 守护进程PHP版
phpkernel
博客等级 码龄16年 96粉丝 13原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值