Интервью со Стерлингом Хьюз о PHP5

:

Оригинал интервью доступен по адресу
http://www.php-con.com/2003/east/interviews/hughes.php

PHP-Con (http://www.php-con.com) недавно записали интервью с участником PHPCon Стерлингом Хьюзом, который выкроил немного времени между своими выступлениями по темам "PHP и XML"("PHP & XML") и "7 главных ошибок в PHP программировании"("Top 7 Mistakes in PHP Programming"), чтобы рассказать о предстоящем релизе PHP5. Брайан Ричард (Bryan Richard), директор конференции из QuarterPower Media проводил интервью посредством электронной почты.

Брайан Ричард (БР): Пожалуйста, представьтесь и поведайте людям, почему именно с вами мы говорим о PHP.

Стерлинг Хьюз (СХ): Привет, я Стерлинг. Я автор книги "Книга рецептов для PHP-программиста"("PHP Developer's Cookbook"), я программирую на PHP, начиная с 3 версии, а с первых бета-версий PHP4 являюсь ещё и разработчиком PHP. Вы также можете знать меня как одного из авторов таких расширений как, URL, XSLT, Bzip2, Zip, Sockets, Cyrus, SWF, ADT, Mono и dio.

БР: Недавно на NYPHP вы провели презентацию новинок PHP5. Эта версия PHP действительно то, чем можно восхищаться? Насколько велики изменения?

СХ: Ну, это на самом деле зависит от конкретного человека. Например, я, несмотря на то, что программировал и на C++, и на Java, — люблю использовать процедуры. У меня такое чувство, что всё ООП состоит из превращения уже имеющихся задач в новые. И уже только потом дело доходит до их решения. Конечно, такой подход многое упрощает, но он ужасно неэффективен для разработки небольшого набора взаимосвязанных программ, что, собственно, и является сутью программных разработок для Web.

Я вовсе не пытаюсь этим сказать, что мне не нравится PHP5. По большей части PHP5 просто замечательный, особенно, что касается исключений (exceptions). Безусловно, множество новых свойств Zend Engine 2 дают много преимуществ. Но большая часть моего кода — процедурная, а Zend Engine 2 в основном подвергся изменениям в области ООП.

Но это касается меня.

А если вы программист, разрабатывающий объектно- ориентированные решения, то выход PHP5 — это действительно повод для радости. У PHP4 на самом деле не было объектной модели. Объекты были лишь базовыми типами, внутри состоящими из двух таблиц имён: таблицы функций и таблицы переменных. Это делало объекты непредсказуемыми, непонятными и неэффективными. А самым отвратительным было то, что где бы вы не использовали объекты, вы должны были передавать их по ссылке.

Посмотрим на следующий код:

<?php
class Slowpoke {
var 
$feet;
var 
$arms;
}
$s = new Slowpoke;
?>

В PHP4 этот код привёл бы к появлению двух копий объекта ещё на этапе его создания. Чтобы правильно создать объект, вы должны были использовать символ '&':

 $s = &new Slowpoke

То же самое относится и к использованию объекта:

<?php
function add_feet($s) {
$s->feet 2;
}
$s = &new Slowpoke;
var_dump($s->feet);
add_feet($s);
var_dump($s->feet);
?>

На самом деле здесь вы бы не изменили объект Slowpoke, когда присваивали значение '2' свойству 'feet' в функции 'add_feet'. Поскольку в PHP при изменении значения переменных действия производятся с их копиями, то всегда, когда вы не передаёте объект по ссылке при изменении объекта или его свойств, происходит его копирование в новый объект.

В PHP5 объекты изначально являются ссылками, и это всё упрощает. Вместо передачи самого объекта, вы передаёте интерпретатору число, идентифицирующее этот объект. Когда осуществляется доступ к объекту, возвращается объект, соответствующий этому числу. Это поможет повысить производительность огромного количества скриптов, в которых неправильно использовалась объектная модель PHP4. Приведенные выше простые примеры замечательно работают в PHP5.

БР: Если Вы считаете, что ООП неэффективно в решении задач для Web, то почему же именно изменения в объектной модели является главными особенностями новой версии? Нет ли в этом попытки сделать PHP многоцелевым языком, таким как Perl, Python или Ruby?

СХ: У каждого есть свои предпочтения. Я предпочитаю использовать процедурную логику, кроме случаев инкапсуляции сущностей. Другими словами, когда я хочу описать объект, я использую именно объект. Я против того, чтобы использовать ООП для создания огромных, абсолютно абстрактных моделей, вкладывая всю логику в сам объект.

Такие модели, особенно применительно к Web, получаются намного более сложными сами по себе, чем проблемы, для решения которых они создавались.

Говоря это, я надеюсь, что объектная ориентация PHP5 имеет две причины:

  • Объекты плохо работали в PHP4. PHP4 безупречно работает с процедурами, и поэтому что-то менять в этой сфере не было необходимости. Однако, как я уже говорил, в PHP4 на самом деле не было объектной модели. Zeev рассказывает о задумке и воплощении объектной модели PHP4 как о результате "одной бессонной ночи".
  • Некоторые люди всё-таки любят создавать большие объектно- ориентированные скрипты. Теперь и у них будут надёжные инструменты для работы.

БР: Разработчики и администраторы вынуждены были пережить большие изменения в прошлом — на ум приходят отключенные по умолчанию "register globals". Не вызовут ли очередные значительные изменения в языке негативной реакции так, как это случилось с Visual Basic, когда Microsoft попытались перевести разработчиков на VB.NET?

СХ: Появление PHP5 — эволюционное, а не революционное событие. Наверное, есть кое-что, чем гордятся все PHP- программисты — это собственный прагматизм. В отличие от других языков, в PHP первоочередное внимание уделяется обратной совместимости. В конфигурационном файле есть настройки, которые практически снимают все проблемы обратной совместимости. Кроме того, все изменения осуществлены практически незаметно. Старый синтаксис будет работать.

БР: Ваша презентация новых возможностей языка действительно очень полезна, но я хотел бы знать ваше личное мнение о некоторых из них. Действительно ли PHP стал объектно- ориентированным? Нравится ли вам, как реализован этот механизм?

СХ: Тяжело определить "настоящую объектность", так как у каждого есть своё мнение на этот счёт. Кроме хорошего, про новую объектную модель и её реализацию мне сказать нечего. Когда я писал расширение "Mono", у меня была возможность увидеть, как далеко зашла объектная модель. Andi, Stas и Zeev проделали огромную работу с Zend Engine 2.

БР: А что насчёт try/catch/throw?

СХ: Try, catch и throw будут, по моему мнению, самыми полезными свойствами PHP5. При разработке веб-приложений постоянно имеешь дело с внешними источниками информации: RDBM, SOAP-транзакции, файловая система. Это вынуждает постоянно отслеживать ошибки.

<?php
$fp 
fopen("somefile""w");
if (!
is_resource($fp)) {
die(
"Couldn't open somefile!");
}
fwrite($fp"foo");
if (!
fclose($fp)) {
die(
"Couldn't close somefile!");
}
?>

В PHP5 исключения позволят упростить код, разместив все механизмы обработки ошибок в одном месте:

<?php
try {
$fp fopen("somefile""w");
fwrite($fp"foo");
fclose($fp);
} catch (
Exception $e) {
echo 
$e->getMessage();
}
?>

БР: А автозагрузка?

СХ: Автозагрузка — хорошая вещь. Другое дело, что я не уверен, насколько она полезна.

БР: SPL?

СХ: SPL является свидетельством расширяемости Zend Engine 2. SPL - это альтернативное расширение для Zend Engine 2, которое определяет стандартный набор интерфейсов. Ваш объект использует интерфейс из SPL, и, когда осуществляется доступ к этому объекту через встроенные конструкции PHP, вызываются различные методы, определённые интерфейсом.

SPL как синтаксический сахар. Он не сделает за вас вашу работу, и, вероятно, усложнит работу других программистов с вашим кодом. Но SPL является замечательным примером расширения, использующего преимущества новых внутренних свойств Zend Engine 2, создающего собственные и перезаписывающего существующие машинные коды (opcodes). Машинные коды — это наборы инструкций, в которые компилируется ваш PHP-скрипт. Посмотрите на этот пример:

<?php
$a 
"Hello";
$b "World";
echo 
$a;
echo 
$b;
?>

Этот код транслируется в следующий набор внутренних инструкций:

0 FETCH_W $0, 'a'
1 ASSIGN $0, 'Hello'
2 FETCH_W $72, 'b'
3 ASSIGN $72, 'World'
4 FETCH_R $144, 'a'
5 ECHO $144
6 FETCH_R $180, 'b'
7 ECHO $180
8 RETURN 1

Машинные коды PHP — это трехадресные коды (P-Code), в которых каждая операция соответствует двум операндам и результату. В архитектуре PHP4 всё происходило внутри огромного switch-цикла, в котором каждый вариант соответствовал коду, такому как RETURN, ASSIGN или ECHO. И, так как все коды были чётко определены внутри цикла, перезаписывать и добавлять новые коды было невозможно.

В PHP5 машинные коды хранятся в массиве, и, таким образом, вы можете их перезаписывать и регистрировать новые. Это даёт расширениям большую силу, независимо от того, разрабатываете ли вы отладчик и что-то наподобие SPL, что переопределяет стандартные операторы массивов, такие как foreach или [].

БР: Вы рассказали о перезагрузках в процессе выполнения программы с использованием __call() и об интерфейсах, но ничего не сказали о простом и множественном наследовании. Появилась ли поддержка множественного наследования?

СХ: Классы могут наследовать множественные контракты через интерфейсы, таким образом, я думаю, вы можете назвать это и множественным наследованием (программисты Java точно могут). Однако множественное наследование в стиле C++ не поддерживается. Мне лично нравится идея наследования функциональности, но надо помнить, что мы всё-таки говорим о программировании для Web. Интерфейсы дают то, что требуется 95% разработчиков, и при этом сохраняется простота использования, что тоже немаловажно.

БР: С чем, вы думаете, у разработчиков возникнут наибольшие проблемы при переходе с PHP4 на PHP5?

СХ: PHP5 во многом совместим с PHP4, однако есть кое-что, о чём следует знать:

  1. В PHP5 объекты изначально являются ссылками. С кодом, написанным с учётом копирования объектов, возникнут проблемы. К счастью, это затронет относительно небольшие объёмы кода, так как работа с копиями объектов — это не совсем то, что нужно разработчикам.

    При портировании на PHP5 у вас есть два варианта. Первый и предпочтительный способ — использовать __clone(), что приводит к копированию объекта.

     $o2 $o1->__clone(); 

    Следует отметить, что использование clone — наиболее надежный способ копирования объектов. В PHP4 возникало множество непонятных проблем в случае неверного копирования объектов. Вы должны были хорошо разбираться в ссылках и механизме "copy-on-write" для правильного клонирования объектов.

    Если же вы хотите оставить свой старый код неизменным у PHP5 в php.ini есть опция называемая "ze2.implicit_clone". Когда она установлена в значение "истина", объекты PHP5 ведут себя так же, как в PHP4, но в тоже время у вас всё ещё остаётся возможность использовать свойства PHP5, такие как унифицированные конструкторы, пространства имён, исключения, и т.д.

  2. Свойства объекта должны быть предопределены. В PHP4 запросто работал следующий код:

    <?php
    class Container {
    }
    $c = &new Container;
    $c->name "Sterling";
    echo 
    $c->name;
    ?>

    Однако в PHP5 вышеприведенное стало невозможным. Такое решение было принято, потому что продолжать реализовывать поддержку таких механизмов достаточно сложно, да и вообще это дурной тон.

    Для преодоления подобных изменений в двоичном коде вам необходимо переписать ваши объекты под использование перезагрузок. Динамическое назначение свойств в PHP может быть легко имитировано именно через перезагрузки объектов.

    <?php
    class Container {
    private 
    $props;
    function 
    __get($name) {
    return 
    $this->props[$name];
    }
    function 
    __set($name$value) {
    $this->props[$name] = $value;
    }
    }
    $c = new Container;
    $c->name "Sterling";
    echo 
    $c->name;
    ?>

  3. Вы должны объявлять классы до их наследования. В PHP4 следующее:

    <?php
    class foo extends bar { }
    class 
    bar { }
    ?>

    было возможно. В PHP5 вы всегда должны объявлять классы до их наследования:

    <?php
    class bar { }
    class 
    foo extends bar { }
    ?>

  4. Следующие слова теперь зарезервированы:

    try, catch, throw, exception, public, private, protected, abstract, interface, final.

  5. При объявлении класса следующие имена функций теперь также зарезервированы:

    __call, __get, __set, __clone, __construct, __destruct.

БР: Ранее разработчики не особенно заботились о контроле доступа. Не думаете ли вы, что переменные типа public, private и protected станут камнем преткновения?

СХ: Я так не думаю. Private, Protected и Public касаются сокрытия информации (создания контракта), и PHP- разработчики уже давно разработали несколько методов указания таких контрактов: добавление подчёркивания в начало имён private- переменных и функций или добавление комментариев, указывающих на уровень доступа.

Ключевые слова private, protected и public теперь дают возможность программно создавать контракты, хотя контракты, как таковые, и так всегда существовали. По умолчанию (если вы не указываете public, private или protected) всё будет работать так же, как работало в PHP4.

БР: Ваш blog недавно падал. Должно быть, это было весело. У вас там была установлена пятёрка?

СХ: Нет, мой weblog работает на MovableType (вскоре будет изменён на serendipity), и на веб-сервере установлен PHP 4.2.2. А на презентационной системе был установлен PHP5.

БР: Вы упоминали в своём blog'е, что у пятёрки есть какие-то проблемы с памятью. Насколько они серьёзны?

СХ: Очень серьезные. Хостинг для презентации был любезно предоставлен NYPHP, но мы были вынуждены её закрыть на время решения проблем с сервером. PHP5 съедал столько памяти, что пришлось изменить опцию Apache "MaxClients" на 25, иначе каждый дочерний процесс Apache забирал более 40Мб.

PHP5 в настоящее время — это лишь ранняя бета-версия1. Так что утечка памяти, сбои и другие ошибки вполне возможны. PHP5 пройдёт долгий процесс контроля качества, и, я надеюсь, избавится от главных багов до выхода финальной версии.

БР: Как проходит процесс контроля качества? Как в этом можно поучаствовать?

СХ: В скором времени мы планируем выпустить бета-версию PHP5, и после этого начнётся процесс тестирования и заполнения отчётов об обнаруженных ошибках с небольшими легко воспроизводимыми примерами, иллюстрирующими эти ошибки. Если вы хотите помочь в тестировании и исправлении ошибок присоединяйтесь к команде контроля качества PHP (PHP QA team).

Процесс выпуска релиза проходит следующим образом (всё происходит после окончания периода бета-тестирования):

  1. Кто-нибудь решает, что пришло время выпустить новую версию, и отправляет сообщение в список рассылки разработчиков, указав в нём свои намерения. Если достигнуто согласие, то создаётся ветка разработки нового релиза. Эта ветка может содержать только исправления ошибок.
  2. Выпускается release candidate. Release candidate (в отличие от бета-версии) - это финальная версия, которая всё-таки ещё может содержать ошибки. Эта версия интенсивно тестируется командой контроля качества, а также любым из энтузиастов (о выходе release candidate сообщается на главной странице PHP.net). Ошибки, которые должны быть исправлены до выпуска релиза, обозначаются как критические, и именно их исправлением занимаются на этой стадии.
  3. После выпуска нескольких release candidates и исправления критических ошибок кто-нибудь инициирует выпуск финального release candidate. Этот release candidate является финальной версией PHP5, если все критические ошибки исправлены. Финальный release candidate тестируется ещё более тщательно разработчиками и командой контроля качества. Если серьёзные ошибки не будут найдены, релиз переименовывается и выпускается как PHP5.

БР: Реализация объектной модели пятёрки снизит производительность или мы, наоборот, можем ожидать её прироста?

СХ: И то, и другое. Строго говоря, объектный код PHP5 будет работать медленнее, чем код PHP4. Частично это связано с идентификаторами объектов, а частично с появлением дополнительных новых свойств (таких как интерфейсы). Однако ООП в PHP5 станет более правильным и понятным. Большая часть кода PHP4 будет работать лучше и быстрее в PHP5, потому что мало, кто точно знал, как работать с объектами в PHP4.

БР: Библиотека cURL теперь будет встроенной. Вы, должно быть, рады этому?

СХ: Да уж, не жалуюсь. :)

БР: У Бена Шеферда из DevArticles.com в его статье "Чего ожидать от PHP 5.0"("What to Expect in PHP 5.0") был раздел "PHP 5.0 взбудоражит мир"("PHP 5.0 Will Take the World by Storm"). Я думаю, что PHP и так уже сыграл большую роль, а вы согласны с заявлением Шеферда? Соблазнит ли пятёрка программистов Java, C# или Perl?

СХ: Я согласен с вами, PHP4 и так уже взбудоражил мир. А PHP5 — это его функциональный апгрейд, необходимый людям, нуждающимся в большей объектности. Я думаю, главное, что вы заметите в PHP5 — это рост PEAR. PEAR всегда основывался на множестве ляпов в PHP, чтобы сохранить целостность объектной модели. PHP5 дополнен свойствами, необходимыми для чёткой реализации структуры PEAR и связанной с ним функциональности.

БР: Что ещё нового вы хотели бы видеть в пятой версии?

СХ: Лучшее XML расширение.

Большое спасибо Стерлингу за его детальные ответы. Хотите задать Стерлингу свои собственные вопросы? Хотите знать, когда появляются свежие интервью? Подпишитесь на PHPCon Announce list, и вы всегда будете в курсе событий.


For comment register here
   2004-05-11 18:26
Так получается, что если я не использую ооп в своих программах, то мне 5 версия не нужна?
Да классно. ООП-рулит!!! :-)

Я так понял это из вышеприведенной статьи?


   2004-07-23 11:43
2silya: нет, это получается, что ты по назначению используешь php :) "ООП... такой подход многое упрощает, но он ужасно неэффективен для разработки небольшого..." (с) СХ

Я тоже до некоторого времени програмировал процедурно, но все же пришел к классам, как к способу раздилить работу с данными, кодом html и логикой. При таком подходе, слово "сценарий" относительно php обрело для меня тот смысл, который я в него вкладывал - я описываю события, а не занимаюсь постоянно их реализацией.
Так что ООП рулит!
В итоге: эволюция php - это перманентно приятно! :)
P.s. К тому же познавательно, я не знал что new и &new разные вещи, только не понял - $s = new Slowpoke; одна копия в $s а где другая?