Новые объектно-ориентированные средства в РНР 5
Версия РНР 3 вышла в середине 1998 года. В нее уже были включены не которые объектно-ориентированные механизмы, но скорее как дополнения, имеющие целью "дать новые средства доступа к массивам". Никаких значимых изменений в эту объектную модель не было внесено и в версии 4, которая появилась в середине 2000 года. Основа объектно-ориентированного программирования была уже заложена - в ней и тогда можно было создавать классы и поддерживалось одиночное наследование.
С выходом в 2004 году версии РНР 5 открылся простор для усовершенствования объектно-ориентированных механизмов РНР. К тому времени Java, наиболее популярный объектно-ориентированный язык, существовал уже почти 10 лет. Почему РНР понадобилось так много времени, чтобы стать полноценным ОО-языком? Краткий ответ заключается в том, что РНР предназначен исключительно для разработки Web-приложений, а эта область лишь сравнительно недавно получила импульс к развитию в указанном направлении.
Язык был дополнен поддержкой объектов, но разработчик волен был ими пользоваться или оставаться в рамках процедурного программирования. Тот факт, что РНР является гибридным языком, следует считать скорее достоинством, чем недостатком. Ведь есть ситуации, когда нужно всего лишь вставить небольшой фрагмент кода, а есть такие, когда имеет смысл прибегнуть ко всему арсеналу средств ООП.
В статье "ООП в php" я уже отмечал, что иногда единственно возможным является объектно-ориентированное решение. В РНР 5 это учтено, поэтому в язык встроена полноценная объектная модель, упрочившая позиции РНР как лидирующего языка серверных сценариев.
Как и в статье "Основы объектно-ориентированного программирования", мы ограничимся здесь лишь общими набросками. Я вкратце расскажу вам о том, как была улучшена объектная модель, а детали будут рассмотрены на конкретных примерах в последующих главах. Коснемся мы и вопроса обратной совместимости.
Модификаторы доступа
В предыдущей статье модификаторы доступа были названы важным составным элементом любого объектно-ориентированного языка. И РНР 5 содержит все, что от них обычно ожидают. В предыдущих версиях РНР никакой поддержки для защиты данных реализовано не было, то есть все члены класса считались открытыми. Этот недостаток, возможно, являлся самым серьезным препятствием на пути использования объектов в РНР 4.
Встроенные классы
Любой объектно-ориентированный язык поставляется с библиотекой встроенных классов, и РНР не является исключением. РНР 5 содержит стандартную библиотеку Standard РНР Library (SPL), в которую входит большое число готовых классов и интерфейсов. В версии 5.1 в зависимости от конфигурации имеется свыше 100 встроенных классов и интерфейсов - это заметное увеличение по сравнению с 5.0.
Наличие готовых классов ускоряет разработку, а будучи написаны на языке С, они существенно повышают производительность. Но даже если встреченный класс делает не совсем то, что вам нужно, его без труда можно расширить под свои задачи.
Исключения
Во всех объектно-ориентированных языках поддерживаются исключения - особый способ обработки ошибок. Для работы с исключениями понадобятся ключевые слова try, catch и throw. Блок try объемлет код, в котором может возникнуть ошибка. Если ошибка возникает, то возбуждается исключение, которое может быть перехвачено в блоке catch. Преимущество исключений по сравнению с кодами ошибок состоит в том, что исключения можно обрабатывать централизованно, а это позволяет создавать более элегантный код. Кроме того, исключения заметно сокращают объем кода обработки ошибок, писать который скучно и утомительно. Наконец, наличие встроенного класса сильно упрощает создание собственных классов исключений путем наследования.
Классы для работы с базами данных
Поскольку язык РНР предназначен для создания динамических Web-страниц, наличие поддержки для работы с базами данных невозможно переоценить. В РНР 5 включено расширение mysqli (MySQL Improved), ориентированное на версии MySQL начиная с 4.1. Теперь можно пользоваться имеющимся в MySQL механизмом подготовки запросов, причем для этой цели предлагается объектно-ориентированный интерфейс, который позволяет делать все то, что раньше выполнялось процедурно.
SQLite - это база данных, встроенная непосредственно в РНР. Она не настолько универсальна, как MySQL, но является идеальным решением в некоторых ситуациях и зачастую позволяет создавать более быстрые и гибкие приложения, потребляющие мало памяти. И для нее тоже имеется полностью объектно-ориентированный интерфейс.
РНР версии 5.1 и старше поставляется с пакетом РНР Data Objects (PDO). Если вам нужно обращаться к нескольким разным СУБД, то этот пакет станет идеальным решением. Общий для разных баз данных интерфейс PDO стал возможен только с появлением новой объектной модели.
Web-сервисы
В РНР 5 поддержка языка XML (Extensible Markup Language) обеспечивается библиотекой libxml2. Код, реализующий Simple API for XML (SAX) и объектную модель документа (DOM - Document Object Model), был полностью переписан, а поддержка DOM приведена в соответствие со стандартом, принятым консорциумом World Wide Web Consortium.
Унификация работы с XML за счет использования libxml2 позволила сделать реализацию более эффективной и простой для сопровождения. Это особенно важно, так как поддержка XML в РНР 4 довольно слабая, а при реализации Web-сервисов возникает много проблем, для решения которых необходим объектно-ориентированный подход.
В РНР 4 создание SOAP-клиента и чтение из RSS-канала являются нетривиальными задачами, для решения которых надо создавать собственные классы или пользоваться внешними, например NuSOAP. В РНР 5 это уже не нужно. Эти задачи решаются с помощью встроенных классов SOAPClient и SimpleXMLElement. И в этом случае простота обусловлена улучшенной объектной моделью.
Итератор
Помимо встроенных классов, РНР 5 предлагает еще и ряд встроенных интерфейсов. Самым важным из них является Iterator, поскольку его наследуют многие другие классы и интерфейсы.
Обратная совместимость
Проблема обратной совместимости может возникнуть, если в вашей программе уже используются объекты. В РНР 5 появилось много новых «волшебных» методов. Имена волшебных методов начинаются с двух символов подчеркивания, поэтому все определенные пользователями методы или функции с аналогичными именами должны быть переименованы. Наиболее важны методы, связанные с созданием и удалением объектов. И хотя создание объектов в духе РНР 4 пока поддерживается, но настоятельно рекомендуется пользоваться новым способом, который основан на волшебных методах.
В РНР 5 некоторые существующие функции, имеющие отношение к объектам, объявлены устаревшими. Например, функция is_a заменена оператором instanceof. Впрочем, это конкретное изменение не окажет влияния на работу вашей программы в среде РНР 5. Если вы воспользуетесь устаревшей функцией, то получите предупреждение при условии, что уровень диагностики ошибок равен E_STRICT (полезный прием, позволяющий выяснить, какие части кода следует модернизировать). Другой пример: функции get_parent_class, get_class и get_class_methods теперь возвращают чувствительный к регистру результат (хотя в параметре по-прежнему не различаются большие и маленькие буквы). Если вы сравнивали полученный результат с помощью функции сравнения с учетом регистра, то, возможно, вам придется внести изменения.
Передача по ссылке
Выше были приведены не слишком существенные изменения, которые довольно легко обнаружить и учесть в коде. Но есть одно изменение, которое способно оказать огромное влияние на программу.
Об основной модификации в РНР 5 в отношении объектов обычно говорят, что объекты теперь передаются по ссылке. Это правда, которая, впрочем, маскирует действительную проблему - изменение семантики оператора присваивания в применении к объектам.
Конечно, оператор присваивания часто вызывается неявно, когда объект передается функции или методу, но именно в связи с этим объекты и передаются по ссылке. В предыдущих версиях РНР по умолчанию объекты присваивались и передавались функциям по значению. Такое поведение идеально для примитивных типов, но в случае объектов накладные расходы оказываются слишком велики. Создание копии большого объекта для того, чтобы передать его по значению, потребляет много памяти, а зачастую нужна лишь ссылка на исходный объект, а не его копия. Изменение семантики оператора присваивания - весьма заметная модификация. По сути дела, весь интерпретатор Zend, лежащий в основе РНР, был полностью переписан для РНР 5.
Прогноз
Простое перечисление деталей, касающихся обратной совместимости, оставляет в тени действительно важный вопрос. При модернизации любого устоявшегося языка имеются конфликтующие интересы. Часто вас будут проклинать и за то, что вы нечто сделали, и за то, что вы этого не сделали. Например, для поддержания обратной совместимости может оказаться необходимым сохранить непоследовательную схему именования функций, но тогда вы подвергнетесь критике именно за непоследовательность.
Конечно, неполная обратная совместимость означает, что некоторые написанные программы перестанут работать. Часто нелегко решить, где и когда пожертвовать совместимостью, но передачу объектов по ссылке можно оправдать, несмотря на все неудобства. Единственное, в чем можно быть уверенным, так это в том, что любое изменение кому-то не понравится. Объявление функций устаревшими и выдача соответствующих предупреждений - неплохой способ предупредить заранее и дать разработчикам шанс подготовиться к грядущим изменениям.
Автор: Питер Ловэйн. Переводчик: А. Слинкин