Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

PHP 5.6alpha3

Я уже писал о том что появилось в ПХП 5.6. Четыре дня назад вышла новая альфа, а с её появлением в языке одним магическим методом стало больше. Добавился метод «__debugInfo», теперь он вызывается функцией var_dump выводится объект.

У объектов и ранее была возможность влиять на вывод этой функцией, но тогда это было доступно только для экземпляров, классы которых были написаны на Си, теперь же эта возможность есть в ПХП.

Пример использования:

class File {
  // «ресурс (поток)» — не очень-то информативно…
  private $fp;

  // …в отличие от его метаданных
  public function __debugInfo() {
    return $this->fp ? stream_get_meta_data($fp) : [];
  }

  public function open($filename, $mode = 'r'){
    $this->fp = fopen($filename, $mode);
  }  
}

$f = new File;
var_dump($f); // object(File)#1 { }
$f->open('http://php.net');
var_dump($f);
/*
object(File)#1 {
  ["wrapper_type"]=>
  string(4) "http"
  ["stream_type"]=>
  string(10) "tcp_socket"
  и так далее...
*/

Мне тут же стало интересно — можно ли сделать метод __debugInfo приватным? Оказывается нельзя, интерператор ругается:

Warning: The magic method __debugInfo() must have public visibility and cannot be static in /Users/bolk/example.php on line 3
object(Dumb)#1 (0) {
}

И, кстати, сразу нашёл баг — стоит в этом магическом методе вернуть себя же (массив, состоящий из переменной $this), как var_dump зацикливается, а если вернуть $GLOBALS получим Segmentation fault: 11.

В принципе, это закономерно — ведь это альфа-версия.

7 комментариев
SunChaser (sunchaser.info) 2014

Меня в новом PHP несколько смущает поведение многоточия

function func($a, $b, ...$params)
{
   var_dump($a, $b, $params);
}

$b = [];
$b[1] = 1;
$b[4] = 4;
$b[2] = 2;
$b[5] = 5;
$b[3] = 3;
 
func(...$b);
// int(1)
// int(4)
// array(3) {
// [0]=>
// int(2)
// [1]=>
// int(5)
// [2]=>
// int(3)
// }
// WAT?

даже не знаю, баг это или фича

Евгений Степанищев (bolknote.ru) 2014

Комментарий для sunchaser.info:

А зачем так сложно, почему не

var_dump([1 => 1, 4 => 4, 2 => 2, 5 => 5, 3 => 3]);

Как будет видно сразу — значения тут идут не по порядку ключей. В общем-то, ничего удивительного и нет. Поскольку в PHP успешно существуют и частенько применяются разряженные массивы, то можно предположить, что массивы даже с числовыми ключами это не тип данных, где ключи по порядку отображаются в значения.

Смысла в сортированном типе в ПХП нет — мы не знаем размерность значений, значит вычислить положение в памяти простым прибавлением индекса умноженного на размер тоже не можем. Никаких преимуществ, следовательно, сортированный тип нам не несёт, а недостаток есть — каждая последующая вставка была бы сильно медленнее предыдущей, если данные шли бы несортированными. Так как нужно было найти место для вставки и сдвинуть хвост.

Одни проблемы без достоинств.

SunChaser (sunchaser.info) 2014

Комментарий для Евгения Степанищева:

Я бы даже принял такой вариант за норму, если бы он не кидал «PHP Catchable fatal error: Cannot unpack array with string keys» на массив со строковыми ключами

т. е. он просит числа и игнорирует их

проблема не в массивах ПХП, с ними давно всё понятно, а с несколько неожиданным поведением ’...’

Евгений Степанищев (bolknote.ru) 2014

Комментарий для sunchaser.info:

Я бы даже принял такой вариант за норму, если бы он не кидал «PHP Catchable fatal error: Cannot unpack array with string keys» на массив со строковыми ключами
т. е. он просит числа и игнорирует их

А можно об этом подробнее?

SunChaser (sunchaser.info) 2014

Комментарий для Евгения Степанищева:

[sunchaser@asgard tmp]$ cat test.php
<?php
function func($a, $b, ...$params)
{
 var_dump($a, $b, $params);
}
$array = [’q’ => ’q’, ’w’ => ’w’, ’e’ => ’e’];
func(...$array);

[sunchaser@asgard tmp]$ php test.php
PHP Catchable fatal error: Cannot unpack array with string keys in /tmp/test.php on line 10
PHP Stack trace:
PHP 1. {main}() /tmp/test.php:0

[sunchaser@asgard tmp]$ php -v
PHP 5.6.0alpha3 (cli) (built: Feb 28 2014 13:31:50)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0-dev, Copyright (c) 1998-2014 Zend Technologies
    with Xdebug v2.2.4, Copyright (c) 2002-2014, by Derick Rethans

Евгений Степанищев (bolknote.ru) 2014

Комментарий для sunchaser.info:

Ну так логично же? Или в чём проблема?

SunChaser (sunchaser.info) 2014

Комментарий для Евгения Степанищева:

на мой вкус логично одно из двух

(1) он просто игнорит ключи у массива — тогда лишний фатал еррор
(2) он требует числовые ключи и выстраивает массив по порядку ключей

текущее поведение выглядит какой-то полумерой