在使用 PDO 实例执行查询时出现分段错误



使用 PDO 实例执行查询时,脚本会产生分段错误。在验证 PDO 对象确实是 PDO 类的实例后,会发生这种情况:

var_dump($db)

这导致:

Object(PDO)#16 {
}

它还会在实例化对象后立即成功执行没有分段错误的查询,但不会在脚本中稍后执行。

这个问题最终变成了PHP对象的怪癖,以及一个试图变得过于聪明的开发人员。

在 PHP 中,对象通过引用(排序)传递到所有作用域。这意味着子作用域可以更改父作用域中的对象。为了避免这种情况,我正在使用的程序将对象存储在值存储中,如果它是对象,则此值存储将在返回变量之前克隆变量:

public function getConfig(string $key)
{
if ($this->hasConfig($key) === true) {
if (is_object($this->configValues[$key]) === true) {
return clone $this->configValues[$key];
} else {
return $this->configValues[$key];
}
} else {
return null;
}
}

clone关键字(详见此处)创建对象及其属性的浅表副本,同时保留作为引用的所有属性。

但是,当克隆 PDO 对象时,它不会维护允许它连接到数据库的流处理程序,但它维护引用。

不幸的是,这会导致分段错误。

我怀疑这是因为在内部访问了超出范围(受保护)的内存,或者因为实际上允许 PHP 使用 PDO 与 MySQL/数据库通信的库不允许以这种方式传递流处理程序。

无论原因如何,如果克隆 PDO 对象,然后使用它进行查询,都会导致分段错误,该错误不会产生错误或异常,从而允许您调试问题。

必须始终传递和使用实际的数据库对象。

我创建了这个问题和答案来记录这个特定的怪癖,因为我最初尝试调试问题时无法在 Google 上找到对此特定行为的任何引用。

在 PHP 7.2.16 中观察到了这种行为,我还没有验证它是否会在其他版本的 PHP 中产生类似的行为。

如果无法以这种方式安全地克隆流处理程序,则预期行为是clone关键字在 PDO 对象上使用时引发异常。

编辑:

另一个可能有所贡献的因素(同样,这不是我广泛测试的东西)是这个特定的连接使用PDO::MYSQL_ATTR_SSL_CA属性来设置 SSL 证书 .pem 文件。

最新更新