PHP 将扩展运算符应用于对象时出现段错误
PHP segfault when spread operator is applied to object
最终编辑 :: 查看答案
好的,给定这段代码
private function select(string $key, string ...$keys): Model
{
\array_unshift($keys, $key);
foreach($keys as &$key)
{
$key = \preg_replace_callback('/([a-zA-Z]+)\((.*)\)/', function($match){
return \sprintf('%s(%s)', $match[1], $this->primaryFields()->keys()->first());
}, $key);
}
在这种情况下,写入密钥的行出现段错误,起初我认为这是因为Prce发生了一些奇怪的事情。但是,当我用字符串文字设置它时,会发生同样的情况。最后我通过注释掉 array_unshift
解决了这个问题。从某种意义上说,我可以创建一个新数组,其中 'unshifts' $key
参数,但我认为这不是必需的,有没有人知道这是 PHP 怪癖,还是我是不是误会了什么?
顺便说一句,我是 运行 php7.1 作为 fpm
编辑::
好吧,我正在写我正在开发的整个故事,但我似乎已经查明了原因,它是一个 sprintf
特别是这个块
$keys = \array_map(function($key){
$matches = Regex::match('/([a-zA-Z]+)\((.*)\)/', $key);
$string = \key_exists(2, $matches)
? $matches[2]
: $key;
if(\count($matches) > 0)
{
$format = \sprintf('%s(%%s.`%%s`)', $matches[1]);
}
else
{
$format = $string === '*'
? '%s.%s'
: '%s.`%s`';
}
return \sprintf($format, $this->owner->getTarget(), $string);
}, $this->keys);
回调最后一行的 sprintf
是什么段错误,当且仅当格式由 if 创建时,当它通过 else 时工作正常。
我创建格式的方式不被允许?据我所知,它确实为“'count(%s.%s
)”创建了一个有效格式,更多测试表明,当我将 if 中的 $format
赋值更改为 $format = '%s.
%s'
我仍然遇到段错误。
最奇怪的是,昨天当我进行精确定位时,我得到了所有...虽然输入此 php 似乎已经确定此代码现在是正确的..我正在尝试的可以说昨天它没有出现段错误,直到在 zf3 中 new PDO
被调用...
我真的不知道去哪里看...
好吧,长话短说,它与正则表达式或数组移位无关。事实证明,应用于具有 ArrayAccess、IteratorAggregate 等对象的 ...
(spread) 运算符,使该对象作为数组工作的所有内容,在使用 ...
运算符调用时似乎随机出现段错误。
即鉴于此 class 签名,我们能够像处理数组一样处理此 class(此处没有实现细节以在解释中保存 space)
class Foo implements \ArrayAccess, \IteratorAggregate
{
public function getIterator()
public function offsetExists($offset)
public function offsetGet($offset)
public function offsetSet($offset, $value)
public function offsetUnset($offset)
}
$foo = new Foo;
$foo[] = 'one';
$foo[] = 'two';
$foo[] = 'three';
好吧,让我们同意 $foo
包含树添加的项目。如果 $foo
是 array
,我们可以做 function(...$foo)
,这将导致函数调用 function('one', 'two', 'three')
。正确的?好吧,当我在我的代码中用我的 Collection
class(我的 Foo
在某种意义上)这样做时,它会出现段错误(不总是,只是在某些情况下,没有;有没有定义键,我测试了它,以及一个数组它会给出一个错误 "can't unpack array with keys").
我仍然不知道为什么会出现段错误,只是我的解决方法是将我的 Collection
转换为 array
。我也不知道这是否是 PHP 上的已知错误,也不知道如何真正搜索它。
TL;DR :: 使用 ...
运算符解包时,请确保您尝试解包的内容是 array
;)
最终编辑 :: 查看答案
好的,给定这段代码
private function select(string $key, string ...$keys): Model
{
\array_unshift($keys, $key);
foreach($keys as &$key)
{
$key = \preg_replace_callback('/([a-zA-Z]+)\((.*)\)/', function($match){
return \sprintf('%s(%s)', $match[1], $this->primaryFields()->keys()->first());
}, $key);
}
在这种情况下,写入密钥的行出现段错误,起初我认为这是因为Prce发生了一些奇怪的事情。但是,当我用字符串文字设置它时,会发生同样的情况。最后我通过注释掉 array_unshift
解决了这个问题。从某种意义上说,我可以创建一个新数组,其中 'unshifts' $key
参数,但我认为这不是必需的,有没有人知道这是 PHP 怪癖,还是我是不是误会了什么?
顺便说一句,我是 运行 php7.1 作为 fpm
编辑::
好吧,我正在写我正在开发的整个故事,但我似乎已经查明了原因,它是一个 sprintf
特别是这个块
$keys = \array_map(function($key){
$matches = Regex::match('/([a-zA-Z]+)\((.*)\)/', $key);
$string = \key_exists(2, $matches)
? $matches[2]
: $key;
if(\count($matches) > 0)
{
$format = \sprintf('%s(%%s.`%%s`)', $matches[1]);
}
else
{
$format = $string === '*'
? '%s.%s'
: '%s.`%s`';
}
return \sprintf($format, $this->owner->getTarget(), $string);
}, $this->keys);
回调最后一行的 sprintf
是什么段错误,当且仅当格式由 if 创建时,当它通过 else 时工作正常。
我创建格式的方式不被允许?据我所知,它确实为“'count(%s.%s
)”创建了一个有效格式,更多测试表明,当我将 if 中的 $format
赋值更改为 $format = '%s.
%s'
我仍然遇到段错误。
最奇怪的是,昨天当我进行精确定位时,我得到了所有...虽然输入此 php 似乎已经确定此代码现在是正确的..我正在尝试的可以说昨天它没有出现段错误,直到在 zf3 中 new PDO
被调用...
我真的不知道去哪里看...
好吧,长话短说,它与正则表达式或数组移位无关。事实证明,应用于具有 ArrayAccess、IteratorAggregate 等对象的 ...
(spread) 运算符,使该对象作为数组工作的所有内容,在使用 ...
运算符调用时似乎随机出现段错误。
即鉴于此 class 签名,我们能够像处理数组一样处理此 class(此处没有实现细节以在解释中保存 space)
class Foo implements \ArrayAccess, \IteratorAggregate
{
public function getIterator()
public function offsetExists($offset)
public function offsetGet($offset)
public function offsetSet($offset, $value)
public function offsetUnset($offset)
}
$foo = new Foo;
$foo[] = 'one';
$foo[] = 'two';
$foo[] = 'three';
好吧,让我们同意 $foo
包含树添加的项目。如果 $foo
是 array
,我们可以做 function(...$foo)
,这将导致函数调用 function('one', 'two', 'three')
。正确的?好吧,当我在我的代码中用我的 Collection
class(我的 Foo
在某种意义上)这样做时,它会出现段错误(不总是,只是在某些情况下,没有;有没有定义键,我测试了它,以及一个数组它会给出一个错误 "can't unpack array with keys").
我仍然不知道为什么会出现段错误,只是我的解决方法是将我的 Collection
转换为 array
。我也不知道这是否是 PHP 上的已知错误,也不知道如何真正搜索它。
TL;DR :: 使用 ...
运算符解包时,请确保您尝试解包的内容是 array
;)