ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ :: Посмотрите на ответ
хорошо, учитывая этот фрагмент кода
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);
}
Строка, где в этом случае пишется ключ segfaults, сначала я подумал, что это произошло потому, что с 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
в последней строке обратного вызова есть то, что segfaults, когда и только когда формат создается с помощью if, когда он проходит через else, работает нормально.
Я так, как создать свой формат не допускается? is создает действительный формат для насколько я знаю «‘count (% s.%s
), еще несколько тестов показывают мне, что когда я меняю $format
назначение в случае если $format = '%s.
% s'
Я все еще получаю сегфо.
Самое странное, что вчера, когда я сделал указание булавки, я получил все … Хотя, набирая этот php, похоже, решил, что этот код сейчас правильный … То, что я пытался сказать, что вчера это не было segfault пока в пределах ZF3 new PDO
назывался…
Я действительно потерян, где искать …
Хорошо, короче говоря, это не имеет ничего общего с регулярными выражениями или изменениями массива. Оказывается, что ...
(распространение) оператор применяется к объекту, который имеет ArrayAccess, IteratorAggregate и т. д., все, что делает этот объект работать как массив, случайным образом кажется segfault при вызове с ...
оператор.
т.е. с учетом этой сигнатуры класса мы способны обрабатывать этот класс, как если бы он был массивом (здесь нет подробностей реализации, чтобы сэкономить место в объяснении)
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
класс (мой Foo
в некотором смысле) это будет segfault (не всегда, только с определенными экземплярами, и нет; ключи не определены, я это проверял, и, как и с массивом, выдает ошибку «не могу распаковать массив с ключами»). ).
Я до сих пор понятия не имею, почему это Segfault просто, что мой обходной путь должен бросить мой Collection
для array
, Я также не знаю, является ли это известной ошибкой в PHP, и как на самом деле ее искать.
TL; DR :: при использовании ...
Оператор распаковки убедитесь, что вы пытаетесь распаковать array
😉
Других решений пока нет …