将spread运算符应用于对象时的PHP段错误

时间:2017-11-09 16:31:15

标签: php segmentation-fault php-7.1

最终编辑::看答案

好的,给出这段代码

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解决了这个问题。从某种意义上说,我可以创建一个新的阵列,这个阵列不会移动。 $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)",更多测试显示我改变{{1}时在if $format%s $format = '%s.中进行分配我仍然会遇到段错误。

最奇怪的是,昨天当我做了指针我得到了所有...虽然输入这个PHP似乎已经确定这个代码现在是正确的..我试图说,昨天它没有& #39; t段错误直到zf3内'被调用...

我真的迷失在哪里看......

1 个答案:

答案 0 :(得分:0)

好吧,长话短说,它与正则表达式或数组移位无关。事实证明...(spread)运算符应用于具有ArrayAccess,IteratorAggregate等的对象,使该对象作为数组工作的所有内容在使用...运算符调用时随机似乎是段错误。 / p>

即。给定这个类签名,我们能够处理这个类,就好像它是一个数组(这里没有实现细节来节省解释中的空间)

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包含树添加的项目。如果$fooarray我们可以执行function(...$foo),这将导致函数调用function('one', 'two', 'three')。对?好吧那么,当我在我的代码中用我的Collection类(在某种意义上我的Foo)这样做时,它会发生段错误(并非总是如此,只是某些实例,而且没有;没有定义键,我测试了它,以及一个数组,它会给出一个错误“无法用键解压缩数组”。)

我仍然不知道为什么我的解决办法就是将我的Collection投射到array。我也不知道这是否是PHP中的已知错误,也不知道如何真正搜索它。

TL; DR ::当使用...运算符解包时,请确保您尝试解包的内容是array;)