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

При ручній збірці 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 class derived with an abstract method must be abstract
Похідний клас з абстрактним методом повинен бути абстрактним
--SKIPIF--
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip zend engine 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--


На цьому все, спасибі за забране час.
Джерело: Хабрахабр
  • avatar
  • 0

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.