标签: php-internals

究竟是什么原因导致 E_CORE_ERROR 和 E_CORE_WARNING?

PHP 手册指出 E_CORE_ERROR 是 PHP 初始启动期间发生的致命错误:

这类似于 E_ERROR,只不过它是由 PHP 核心生成的。

另外,它指出 E_CORE_WARNING 是 PHP 初始启动期间发生的警告:

这类似于 E_WARNING,只不过它是由 PHP 核心生成的。

E_CORE_ERROR和E_CORE_WARNING到底是如何发生的?

具体来说,是什么原因造成的呢?

php error-handling php-internals

5
推荐指数
1
解决办法
1715
查看次数

在 __destruct() 中,如何查看当前是否存在异常?

我如何查看当前是否存在异常,即堆栈正在展开?

在下面的示例中,您将如何实施isExceptionInFlight()

<?php

class Destroyer
{
    function __destruct()   {
        if (isExceptionInFlight()) {
            echo 'failure';
        } else {
            echo 'success';
        }
    }
}

function isExceptionInFlight() {
    // ?????
}

function createAndThrow()
{
    $var = new Destroyer;
    throw new \Exception;
}

createAndThrow();
Run Code Online (Sandbox Code Playgroud)

这样做的目的是实现 D 的scope语句,该语句可作为多种其他语言的库使用。这使您可以摆脱嵌套的 try-catch 块,从而更轻松地正确执行回滚事务。

附录1:

我环顾过 Zend PHP 引擎,executor_globals.exception似乎就是我正在寻找的东西(https://github.com/php/php-src/blob/master/Zend/zend_globals.h)。然而,nullptr当我在 __destruct() 期间检查它时,该值始终是。知道我接下来应该看哪里吗?

附录2:

检查executor_globals.opline_before_exception取得了一些进展。但是,它不会重置为nullptr捕获异常时的值。

附录3:

我找到了以下代码(第135行)

/* Make sure that destructors are protected from previously …
Run Code Online (Sandbox Code Playgroud)

php destructor exception php-internals

5
推荐指数
1
解决办法
367
查看次数

PHP,编译 foreach 和 opline

我试图弄清楚 PHP 如何解释 foreach 语句。这导致我gdb在执行虚拟 foreach 脚本时使用。

我最终在zend_compile_foreach()函数中的 zend_compile.c 中。我看到对宏 ZEND_FE_FETCH_R 的调用移动了我们循环的数组/对象的内部指针。

有几件事我不明白:

  • 值如何实际返回到zend_compile_foreach上下文
  • 我们是否嵌套调用zend_compile_stmt(因此zend_compile_foreach)以进行迭代?那么代码编译 N 次了吗?N 是数组/对象中的元素数
  • 什么是opline??我到处都看到,但我不知道这一点

php arrays compiler-construction php-internals

5
推荐指数
0
解决办法
230
查看次数

PHP 内部原理:TSRMLS_FETCH 如何工作?

PHP InternalsTSRMLS_FETCH宏是如何工作的?

根据PHP 手册

在开发扩展时,包含“tsrm_ls 未定义”的构建错误或导致该结果的错误源于 TSRMLS 在当前范围内未定义的事实,要解决此问题,请使用适当的宏声明函数以接受 TSRMLS,如果有问题的函数不能更改,您必须在函数体内调用 TSRMLS_FETCH。

我了解声明函数以使用适当的宏接受 TSRMLS意味着使用TSRMLS_C、TSRMLS_D、TSRMLS_CC 和 TSRMLS_DC来定义或调用具有额外参数/参数的函数。

但是,如果相关函数的原型无法更改,则必须在函数体内调用 TSRMLS_FETCH使我有点困惑。如果我在PHP-SRC看起来既这里这里TSRMLS_FETCH 似乎是一个空的宏。

所以这给我留下了一个问题——它TSRMLS_FETCH是如何工作的?在编译时是否有其他东西填充这个宏?

php c macros php-internals

5
推荐指数
1
解决办法
607
查看次数

哪些 PHP 函数受 allow_url_fopen 影响?

在 PHP 中,该allow_url_fopen标志控制各种文件系统功能是否可以使用远程 URL ,以便访问远程文件。

现在建议安全最佳实践禁用此选项,因为它是潜在的攻击媒介。但是,如果禁用该设置,任何依赖此功能才能工作的代码都将被破坏。例如,我知道至少有一个 reCaptcha 插件file_get_contents()用于访问 Google API,因此依赖于这个标志。

为了检查我们应用程序中的代码以确定禁用此标志是否安全(以便在必要时进行重写),我需要它影响的 PHP 函数的规范列表。但是,我一直找不到这样的列表 - PHP 网站上似乎没有,而且 Google 搜索也没有找到任何内容。

  • 任何人都可以提供其行为受到影响的所有 PHP 函数的列表allow_url_fopen吗?

接受的答案应参考权威来源或提供有关用于编制列表的方法的详细信息,以证明其正确性和完整性。

php php-internals

5
推荐指数
1
解决办法
186
查看次数

如何将数组作为Object属性添加到PHP扩展中声明的类?

我希望我的PHP扩展声明一个等效于以下PHP的类:

class MyClass
{
    public $MyMemberArray;

    __construct()
    {
        $this->MyMemberArray = array();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在按照" 高级PHP编程 "和" 扩展和嵌入PHP "中的示例进行操作,并且我能够声明一个具有整数属性的类PHP_MINIT_FUNCTION.

但是,当我使用相同的方法声明一个数组属性时PHP_MINIT_FUNCTION,我在运行时收到以下错误消息:

PHP Fatal error:  Internal zval's can't be arrays, objects or resources in Unknown on line 0
Run Code Online (Sandbox Code Playgroud)

高级PHP编程的第557页有一个例子,说明如何声明一个创建数组属性的构造函数,但是示例代码没有编译(第二个"对象"似乎是多余的).

我修复了错误并将其修改为我的代码:

PHP_METHOD(MyClass, __construct)
{
    zval *myarray;
    zval *pThis;

    pThis = getThis();

    MAKE_STD_ZVAL(myarray);

    array_init(myarray);
    zend_declare_property(Z_OBJCE_P(pThis), "MyMemberArray", sizeof("MyMemberArray"), myarray, ZEND_ACC_PUBLIC TSRMLS_DC);
}
Run Code Online (Sandbox Code Playgroud)

这会编译,但它在构造时会产生相同的运行时错误.

php c php-extension php-internals

4
推荐指数
1
解决办法
1373
查看次数

Zend引擎是否可以在PHP之外嵌入?

如果我记得的话,Zend引擎的原始设计之一是,它可能相对容易嵌入其他人可能希望创建的语言.基本上,没有所有PHP模块的PHP语法.这仍然是这样吗?

php php-internals

4
推荐指数
1
解决办法
442
查看次数

PHP字符串长度

PHP编码标准说:

... PHP保留每个字符串的length属性,并且不应使用strlen()计算它。以这种方式编写函数,以便它们可以利用length属性,从而提高效率并使其成为二进制安全的。...

如何访问此length属性?还是我误会了?

php string standards php-internals

4
推荐指数
1
解决办法
4281
查看次数

存储整数的实际内存开销是多少?

我想说我就是这样做的

$arr = array();
for ($i = 0; $i < 10; $i++) $arr[] = $i;
Run Code Online (Sandbox Code Playgroud)

所以我将10个整数存储在一个数组中.如果整数是32b,则内存开销应为40字节.问题是,我没有告诉php它是一个整数所以它要么必须将其存储为其他东西?(例如,js喜欢制作双打)或者保留额外的数据以提醒自己它是什么?这10个数字+数组实际占用系统内存多少内存?

它很重要,因为我正在尝试评估算法的可行性,我想移植到php并且它在内存上有点沉重.

php php-internals

4
推荐指数
1
解决办法
179
查看次数

什么是zend扩展?

如果你看一下这个文档,第一个参数只返回Zend扩展.与PHP("简单")扩展相比,什么是Zend扩展?

php php-extension php-internals

4
推荐指数
1
解决办法
3329
查看次数