问题标签 [php-internals]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
php - PHP 操作码与实际执行的二进制代码有何关系?
test.php 作为纯文本:
test.php 作为操作码:
test.php 作为二进制表示:
(跳过 test.php 的回声输出)
现在我想了解更多关于操作码如何转换为二进制表示的信息。
编辑和澄清的问题:
操作码如何翻译成二进制版本?你能看到 'a' 到 !0 的分配吗?ECHO 语句是否在某处以及它的输出?
我在二进制版本中发现很少有模式暗示操作码的逐行表示。
(“2f726f6f742f746573742e706870”是“/root/test.php”的十六进制表示)
编辑:
当行长度设置为 4 字节并在不同程序之间进行比较时,十六进制表示揭示了模式。
但是我对虚拟机如何在这种级别上工作的知识太薄弱,无法真正正确地分析并将其链接到 C 代码。
编辑:
php - 什么时候在 PHP 中创建“符号”/“变量名”?
这是我的设置:
display_startup_errors = on
display_errors = On
error_reporting = E_ALL | E_STRICT
上面的代码行将创建一个 zval 容器并将其与符号 a' 相关联。并会给出以下 o/p。
现在考虑以下代码:
将生成 o/p;
来自 PHP 手册的Reference Counting Basics :当使用常量值创建新变量时会创建 zval 容器
这是否意味着,
1] 遇到类似于code2 的第 1 行的代码时不创建符号ie
$a;
。由于 xdebug_debug_zval 没有找到符号/变量名称“a”。根据 Reference Counting Basics中的声明,没有创建 zval 容器。2] 只有在遇到类似于code2 ie的第 3 行的
代码时才会创建符号。即,仅当变量与常量值相关联时才会创建符号,并且根据引用计数基础中的语句创建 zval 容器并与符号“a”相关联。而code2 的第 1 行即是一段无用的代码。$a = "abcd";
$a;
有关 xdebug_debug_zval 的信息,请访问此处。
php - array_keys 如何进行值搜索?
PHP array_keys 如何进行值搜索?
例子:
因为它们是键值对。我猜 PHP 会基于哈希进行搜索,而不是遍历数组中的每个密钥对。
对此有任何“明确的想法”吗?
受此问题启发的问题:如果类似大小的数组中的相应元素是数字(没有迭代),如何获取数组中空元素的键?
php - 用“新”实例化时到底发生了什么?
让我们考虑以下代码:
输出:
实例化成 $obj1 后:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }将“Hello”分配给 $obj->var1 后:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='你好' }
逐个:
实例化成 $obj1 后:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }
为什么$obj1->var1
只有refcount=2
一个a类对象时有?
是因为new
操作员如何赋值吗?PHP 使用引用进行赋值。当用 实例化时new
,没有符号/变量名称与该实例相关联。但是,类属性确实有名称。是recount=2
因为这个吗?
如果是这种情况,则使用浅拷贝 WRT 类实例会发生 COW(写入时复制)。虽然属性仍然指向在实例化期间使用new
.
现在,
将“Hello”分配给 $obj->var1 后:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='你好' }
因此,当我为该属性分配一个值时,该属性$obj1->var1
的新 zval 容器,因此refcount=1
?
这是否意味着在使用实例化期间创建的 zval 容器new
仍然存在但由于没有与之关联的符号/变量名称而无法访问?
请注意(来自xdebug:Variable Display Features):
debug_zval_dump()
不同于xdebug_debug_zval()
.
void xdebug_debug_zval( [字符串变量名 [, ...]] )
显示有关变量的信息。
此函数显示有关一个或多个变量的结构化信息,包括其类型、值和引用计数信息。使用值递归地探索数组。该函数的实现方式与 PHP 的debug_zval_dump()函数不同,以便解决该函数所存在的问题,因为变量本身实际上是传递给函数的。Xdebug 的版本更好,因为它使用变量名在内部符号表中查找变量并直接访问所有属性,而无需处理实际将变量传递给函数。结果是这个函数返回的信息比 PHP 自己的显示 zval 信息的函数要准确得多。
UPDATE
:Dec 31th 2011:
我正在尝试查看使用new时如何进行内存分配。但是我现在要做的事情太多了。我希望我能尽快发布有用的更新。在那之前,这里是我正在查看的代码的链接:
php - 为什么在“写入属性”/“将属性注入类的对象”时不会发生 COW?
输出:
echo1: 实例化后:
t1: (refcount=1, is_ref=0)=class a { public $test = (refcount=2, is_ref=0)='msg1' }echo2: 将 $t1 分配给 $t2 后:
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=2, is_ref=0)='msg1' }echo3: 分配后 $t1->test = "msg2" :
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
t2: ( refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }echo4: 分配后 $t2->test="msg3" :
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
t2: ( refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }echo5: 将 $test2 注入 $t2 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3'; public $test2 = (refcount=1, is_ref=0)='c ap!' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3'; public $test2 = (refcount=1, is_ref=0)='c ap!' }
忽略echo1
&echo2
因为这个:用“新”实例化时到底发生了什么?& 预期的行为。
考虑echo3
:
echo3: 分配后 $t1->test = "msg2" :
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
t2: ( refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
这是可以理解的,因为我只是更改$t1->test
变量而不直接更改&t2->test
.
考虑到echo4
,在哪里进行直接更改$t2->test
:
echo4: 分配后 $t2->test="msg3" :
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
t2: ( refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
没有奶牛发生!$t1
即使is_ref
未设置,更改也会反映到。
考虑echo5
到变量$test2
被注入的位置$t2
:
echo5: 将 $test2 注入 $t2 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg4'; public $test2 = (refcount=1, is_ref=0)='c ap!' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg4'; public $test2 = (refcount=1, is_ref=0)='c ap!' }
再一次,没有奶牛发生!$t1
即使is_ref
未设置,更改也会反映到。
Why is this behaviour!?
php - 什么是 #在对象的 var_dump 中的对象(someClass)旁边?我有一个推断。我对吗?
这是我用来得出以下推论的代码及其输出:
输出:
对象的line in#<some-number>
旁边实际上是. 在哪里,object(someClass)
var_dump
#<count>
count 是对象的对象/ zval 的数量,无论它属于哪个类,到目前为止已创建。当 zval 的引用计数达到零(即垃圾收集)时,它会为每个创建的对象不断增加并减 1。
我对吗?
php - 如何从 PHP 扩展中重载函数?
我一直在阅读一些 PHP 扩展教程,但我找不到任何有关如何重载现有函数的信息。
例如,我想将 fopen() 更改为类似
我怎么能那样做?谢谢
PS。我的意思是扩展名(用 C 编写,编译为 .so 并包含在 httpd.conf 中,而不是 .php 程序)
编辑:找到解决方案,感谢 Gordon 链接。
我已经下载了功能的 PECL 包rename_function
。它的源代码使我得出了必要的结论:
有一个全局哈希表
function_table
,它根据函数的名称保存函数的所有指针。zend_hash_find
//将允许我在这个表中做任何我想做的改变zend_hash_add
。zend_hash_del
php - php 扩展:无法使用 zend_hash_update 更新类字段
我想将这个类实现为 php 扩展:
我已经实现了 __constructor、$attrs 字段和 __get 方法。现在我想不通__set。
有我的c代码:
其中 attrs - 在 init 函数中声明受保护的属性(我已将属性声明为 null,但是当我在构造函数中向 $attrs 添加数据时 - 属性更新为数组)
所以我的问题是:我需要如何在 c 中更新我的 attr 字段?我的扩展成功编译,我可以定义属性,读取它们,但我无法设置它们 - 因为设置的值变为空,例如:
我是 c 开发的新手,我真的需要帮助。
UPD 1.我尝试将 __set 正文更改为:
现在我可以设置字符串值了。如果我需要打开每种类型的 zval??
php - 为什么 file_get_contents 比 memcache_get 快?
我正在使用 file_get_contents 从磁盘加载 XML 文件,作为测试,我发现我可以file_get_contents()
在 3.99 秒内使用 1,000 次加载 156K 文件。我已经对执行加载的部分进行了子类化,并将其替换为 memcache 层,在我的开发机器上发现我可以在 4.54 秒内完成 1000 次相同文档的加载。
我很欣赏 file_get_contents() 会做一些缓存,但看起来它实际上比众所周知的缓存技术更快。在单个服务器上,性能是否file_get_contents()
达到了可以达到的水平?
我通过 Macports、OS X 10.6.8 使用 PHP 5.2.17。
编辑:我在这种大小的 XML 文档中发现,使用该MEMCACHE_COMPRESSED
标志有一点好处。通过 memcache 加载 1,500 次在 6.44 秒(压缩)而不是 6.74 秒(不压缩)内完成。但是,两者都比 慢file_get_contents
,后者在 5.71 秒内完成相同数量的加载。
php - 从扩展返回“本机”PHP 对象
我正在为个人项目创建一个 PHP 扩展。除了上面文章中的链接之外,我对 zend_engine 没有任何了解,而且我的 C 技能已经过时了 10 年,而且只是学术性的。所有这些都是在说“如果看起来我在问一个愚蠢的问题,我可能是”。
是否可以在我自己的扩展中调用其他 PHP 扩展中的函数,或者每个 PHP 扩展都被视为一个孤岛,对系统的其他部分没有洞察力?如果这是可能的,这是常见的做法,还是一个坏主意™?
也就是说,我知道我可以返回一个类似这样的字符串。
我希望能够返回一个 SimpleXML 元素或一个 DomDocument 元素。谷歌搜索已被证明是困难的,因为没有大量关于扩展开发的内容,而且有大量关于标准 PHP 使用的内容。