我怎样才能立即停止程序,就像在 C 语言的 PHP 扩展中的常规 PHP 中一样?

How can I immediately stop the program as in regular PHP in PHP extension in C?

提问人:Mark Smith 提问时间:6/26/2023 更新时间:6/26/2023 访问量:62

问:

在常规PHP中,当我连接到数据库并执行错误的SQL语句时,PHP会立即停止程序并显示错误。

$conn = new PDO();
$sth = $conn->prepare('select2 * from block');
$sth->execute();
$result = $sth->fetchAll();
var_dump($result);

但是,在带有 C 的 PHP 扩展中,行为似乎存在差异。

如果我执行了不正确的 SQL 语句,程序仍然会抛出致命的错误异常,但执行后的代码会继续:

zval sql, model, result, tmp;
object_init_ex(&model, modelCe);
zend_call_method(Z_OBJ(model), Z_OBJCE(model), NULL, ZEND_STRL("__construct"), NULL, 0, NULL, NULL);
ZVAL_STRING(&sql, "select2 * from table");
zend_call_method(Z_OBJ(model), Z_OBJCE(model), NULL, ZEND_STRL("findAllBySql"), &result, 1, &sql, NULL); // Error here
zval_ptr_dtor(&sql);
zval_ptr_dtor(&model);
zval_ptr_dtor(&result);

zend_string *key = zend_string_init(ZEND_STRL("backendUrl"), 0);
zval *view = zend_read_property(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), ZEND_STRL("view"), ZEND_FETCH_CLASS_SILENT, NULL);
zval *backendUrl = Z_OBJ_HT_P(view)->read_property(Z_OBJ_P(view), key, BP_VAR_IS, NULL, &tmp); // Trying to retrieve value from object but seems the view object does not have value anymore.
zend_string_release(key);
zval_ptr_dtor(&tmp);

char *link = globalConcatenateString((char *[]) { Z_STRVAL_P(backendUrl), "/instance/data" }, 2);
free(link);

RETURN_TRUE;

但是,似乎当抛出异常时,错误语句之后的变量值似乎被清除了,此时,程序崩溃并出现 Segmentation 错误。

如果我尝试在 findAllBySql 函数中捕获异常,然后重新抛出错误,它会无意中使程序变得更加复杂,因为我需要为每个数据库查询(或任何其他引发异常的函数)添加异常检查:

zend_call_method(Z_OBJ(model), Z_OBJCE(model), NULL, ZEND_STRL("findAllBySql"), &result, 1, &sql, NULL); // Error here

// Check exception:
if (EG(exception)) {
    // Handle error
}

// Call other query
zend_call_method(Z_OBJ(model), Z_OBJCE(model), NULL, ZEND_STRL("findAllBySql"), &result, 1, &sql, NULL); // Error here

if (EG(exception)) {
    // Handle error
}

如何像在常规PHP中一样立即停止程序?

PHP C 异常

评论

0赞 shingo 6/26/2023
立即停止?那么谁来打电话,,,等等?zval_ptr_dtorzend_string_releasefree
0赞 Mark Smith 6/26/2023
为什么我无法正常获取对象的属性值?为什么系统会清除对象值?如果系统清除了变量值,那么它如何才能正确调用 zval_ptr_dtor、zend_string_release、free 等呢?
0赞 shingo 6/26/2023
我无法回答第一个问题,这似乎是另一个新问题。至于第二个,对象指的是什么??clear 是什么意思?根据您提供的代码,我认为无法将这些变量设置为 NULL。modelzend_call_method
0赞 Mark Smith 6/26/2023
@shingo,这一行,zval *backendUrl = Z_OBJ_HT_P(view)->read_property(Z_OBJ_P(view), key, BP_VAR_IS, NULL, &tmp);如果我在调用 zend_call_method 之前获取 backendUrl 属性,则有一个不为空的字符串,但如果我在调用之后获取,它将返回 NULL。我不认为zend_call_method做到了。
0赞 Mark Smith 6/26/2023
@ikegami,确实如此。它仍然在错误发生后执行代码。

答: 暂无答案