Как стать автором
Обновить

Подготовка к собеседованиям по PHP с использованием тестов (phpt) из исходников PHP

Время на прочтение3 мин
Количество просмотров20K
При ручной сборке PHP (в данном случае рассматриваю версию 7.0.7) необходимо запустить команду make test перед make install, которая прогоняет все тесты в папке tests, после чего можно из командной строки отправить результат. Если просмотреть данную папку, то в ней сразу бросаются в глаза папки с наименованием classes, func, basic и т.д… Почему это интересно?

Дело в том, что на собеседованиях часто любят задавать вопросы как касающиеся каких — то синтаксических (довольно скучных задач (кросворды), вроде ++$i/$i++ находящихся в общем выражении), так и общих, например, ООП. Популярные моменты — это наследование интерфейсов, абстрактных классов, суть которых в общем то нарушить правильный ООП или выявить на особенностях (возможностях) глубину познания кандидатом. Вот именно эти моменты окрас и проверяют тесты, и поэтому, довольно полезно на мой взгляд просмотреть бегло тесты (в тестах пишется ожидаемый результат). Для большей убедительности попробовать выполнить аналогичный код. Прогуглить и узнать почему именно так реализовано (срабатывает) в PHP, а не по другому.

Вот для примера, базовый вопрос на собеседованиях и тест из исходников.

Файл: tests/classes/abstract_by_interface_001.phpt


--TEST--
ZE2 An abstract method may not be called
--FILE--
<?php

class Root {
}

interface MyInterface
{
        function MyInterfaceFunc();
}

abstract class Derived extends Root implements MyInterface {
}

class Leaf extends Derived
{
        function MyInterfaceFunc() {}
}

var_dump(new Leaf);

class Fails extends Root implements MyInterface {
}

?>
===DONE===
--EXPECTF--
object(Leaf)#%d (0) {
}

Fatal error: Class Fails contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (MyInterface::MyInterfaceFunc) in %sabstract_by_interface_001.php on line %d


Как видно из описания, класс Fails упадет в фатальную ошибку, так как наследовал интерфейс MyInterface, но не произвел определение тела функции из интерфейса MyInterfaceFunc(). См. документацию по интерфейсам.

Перейдем, к следующем тесту:

Файл: tests/classes/abstract_by_interface_002.phpt


В данном случае этот же интерфейс MyInterface, имеет определение сигнатуры метода, объявленного как static.

interface MyInterface
{
        static function MyInterfaceFunc();
}

....

class Fails extends Root implements MyInterface {
}

?>
===DONE===
--EXPECTF--
object(Leaf)#%d (0) {
}

Fatal error: Class Fails contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (MyInterface::MyInterfaceFunc) in %sabstract_by_interface_002.php on line %d


Как видно из ожидаемой ошибки, в данном случае, метод также должен быть определен в классе, наследующий данный интерфейс.

Или вот довольно частый вопрос, о том, можно ли в обычном классе определить абстрактный метод.

Файл: tests/classes/abstract_derived.phpt


--TEST--
ZE2 A derived class with an abstract method must be abstract
Производный класс с абстрактным методом должен быть абстрактным
--SKIPIF--
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
--FILE--
<?php

class base {
}

class derived extends base {
        abstract function show();
}

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--

Fatal error: Class derived contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (derived::show) in %sabstract_derived.php on line %d



Или вот один замечательный тест:

Файл: tests/classes/abstract_redeclare.phpt


<?php

class pass {
        function show() {
                echo "Call to function show()\n";
        }
}

class fail extends pass {
        abstract function show();
}

echo "Done\n"; // Shouldn't be displayed
?>


Метод show(), не может быть переопределен абстрактным.

Перейдем в каталог тестов func и как, пример, тест с использованием static и постфиксным инкрементом/декрементом.

Файл: tests/func/002.phpt


--TEST--
Static variables in functions
--FILE--
<?php
function blah()
{
  static $hey=0,$yo=0;

  echo "hey=".$hey++.", ",$yo--."\n";
}

blah();
blah();
blah();
if (isset($hey) || isset($yo)) {
  echo "Local variables became global :(\n";
}
--EXPECT--
hey=0, 0
hey=1, -1
hey=2, -2


Напоследок, чтобы не сильно Вас утомлять, приведу интересный тест, по баге 28800

--TEST--
Bug #28800 (Incorrect string to number conversion for strings starting with 'inf')
--FILE--
<?php
        $strings = array('into', 'info', 'inf', 'infinity', 'infin', 'inflammable');
        foreach ($strings as $v) {
                echo ($v+0)."\n";
        }
?>
--EXPECT--


На этом все, спасибо за отнятое время.
Теги:
Хабы:
+6
Комментарии48

Публикации

Изменить настройки темы

Истории

Работа

PHP программист
155 вакансий

Ближайшие события