При ручной сборке PHP (в данном случае рассматриваю версию 7.0.7) необходимо запустить команду make test перед make install, которая прогоняет все тесты в папке tests, после чего можно из командной строки отправить результат. Если просмотреть данную папку, то в ней сразу бросаются в глаза папки с наименованием classes, func, basic и т.д… Почему это интересно?
Дело в том, что на собеседованиях часто любят задавать вопросы как касающиеся каких — то синтаксических (довольно скучных задач (кросворды), вроде ++$i/$i++ находящихся в общем выражении), так и общих, например, ООП. Популярные моменты — это наследование интерфейсов, абстрактных классов, суть которых в общем то нарушить правильный ООП или выявить на особенностях (возможностях) глубину познания кандидатом. Вот именно эти моменты окрас и проверяют тесты, и поэтому, довольно полезно на мой взгляд просмотреть бегло тесты (в тестах пишется ожидаемый результат). Для большей убедительности попробовать выполнить аналогичный код. Прогуглить и узнать почему именно так реализовано (срабатывает) в PHP, а не по другому.
Вот для примера, базовый вопрос на собеседованиях и тест из исходников.
Как видно из описания, класс Fails упадет в фатальную ошибку, так как наследовал интерфейс MyInterface, но не произвел определение тела функции из интерфейса MyInterfaceFunc(). См. документацию по интерфейсам.
Перейдем, к следующем тесту:
В данном случае этот же интерфейс MyInterface, имеет определение сигнатуры метода, объявленного как static.
Как видно из ожидаемой ошибки, в данном случае, метод также должен быть определен в классе, наследующий данный интерфейс.
Или вот довольно частый вопрос, о том, можно ли в обычном классе определить абстрактный метод.
Или вот один замечательный тест:
Метод show(), не может быть переопределен абстрактным.
Перейдем в каталог тестов func и как, пример, тест с использованием static и постфиксным инкрементом/декрементом.
Напоследок, чтобы не сильно Вас утомлять, приведу интересный тест, по баге 28800
На этом все, спасибо за отнятое время.
Дело в том, что на собеседованиях часто любят задавать вопросы как касающиеся каких — то синтаксических (довольно скучных задач (кросворды), вроде ++$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--
На этом все, спасибо за отнятое время.
