Статьи

Что нового в PHP 5.3? Статья

PHP 6 не за горами, но для разработчиков, которые просто не могут ждать, есть хорошие новости — многие функции, первоначально запланированные для PHP 6, были перенесены в PHP 5.3, окончательный стабильный выпуск которого должен быть в Первая половина этого года.

Эта новость также может приветствоваться теми, кто хочет использовать некоторые из новых функций, но чьи хостинг-провайдеры не будут обновляться до версии 6 в течение некоторого времени — хостинг-провайдеры традиционно откладывают обновление основных версий, пока проводится приемочное тестирование (читай: стабильность была доказана в другом месте в первую очередь). Многие хостинговые компании, вероятно, откладывают обновление своих сервисных предложений до выпуска версии 6.1. Незначительное обновление с 5.2.x до 5.3, однако, будет меньшим препятствием для большинства хостинговых компаний.

В этой статье представлены новые функции, приведены примеры того, где они могут быть полезны, а также приведен демонстрационный код, позволяющий приступить к работе с минимальными усилиями. Он не охватывает такие темы, как установка PHP 5.3 — последняя версия для разработчиков, которая в настоящее время доступна . Если вы хотите поиграться с кодом в этой статье, вам следует установить PHP 5.3, а затем загрузить архив кода . Статью по установке PHP 5.3 можно
найден на веб-сайте Мельбурнской группы пользователей PHP.

Пространства имен

До появления объектно-ориентированного PHP многие разработчики приложений использовали подробные имена функций, чтобы избежать конфликтов пространства имен. WordPress, например, реализует такие функции, как wp_update_postwp_create_user wp_ prefix

В объектно-ориентированном мире конфликты пространства имен менее вероятны. Рассмотрим следующий пример фрагмента кода, который основан на вымышленном приложении для ведения блогов:

 <?php 
class User {
 public function set( $attribute, $value ) { ... }
 public function save() { ... }
}
$user = new User();
$user->set('fullname', 'Ben Balbo');
$user->save();

В этом примере метод save не будет конфликтовать с любым другим методом, так как он содержится в классе User. Тем не менее, существует потенциальная проблема: класс User может быть уже определен какой-либо другой частью системы, если, например, приложение для ведения блога работает в системе управления контентом.
Решением этой проблемы является использование нового ключевого слова namespaces. Снова взяв приведенный выше код, рассмотрим следующие примеры файлов:

 <?php 
namespace MyCompany::Blog;
               
class User {
       
       public function set( $attribute, $value ) {
               $this->$attribute = $value;
       }
       
       public function save() {
               echo '<p>Blog user ' . $this->fullname . ' saved</p>';
       }

}

<? PHP
$ user = new MyCompany :: Blog :: User ();
$ user-> set (‘полное имя’, ‘Бен Бальбо’);
$ User-> Save ();

На первый взгляд, преимущества, предлагаемые пространством имен нашей функции, могут быть не сразу очевидны — в конце концов, мы просто изменили MyCompany_Blog_UserMyCompany::Blog::User Однако теперь мы можем создать класс User

 <?php 
namespace MyCompany::CMS;

класс User {

набор публичных функций ($ attribute, $ value) {
$ this -> $ attribute = $ value;
}

публичная функция save () {
echo ‘<p> пользователь CMS’. $ this-> полное имя. ‘сохранен </ p>’;
}

}

Теперь мы можем использовать классы MyCompany::Blog::UserMyCompany::CMS::User

Ключевое слово use

Обращение к классам с использованием полного пространства имен по-прежнему приводит к длительным вызовам, и, если вы используете много классов из пространства имен MyCompany::Blog Здесь ключевое слово use Ваше приложение, скорее всего, будет использовать несколько различных классов в любой момент времени. Скажем, например, пользователь создает новый пост:

 <?php 
use MyCompany::Blog;
$user = new Blog::User();
$post = new Blog::Post();
$post->setUser( $user );
$post->setTitle( $title );
$post->setBody( $body );
$post->save();

Ключевое слово use Вы также можете использовать его для импорта отдельных классов в ваш файл, например так:

 <?php 
use MyCompany::Blog::User;
$user = new User();
Псевдонимы пространства имен

Ранее я указывал, что одним из преимуществ пространства имен является возможность определять более одного класса с одним и тем же именем в разных пространствах имен. Очевидно, будут случаи, когда эти два класса используются одним и тем же сценарием. Мы могли бы просто импортировать пространства имен, однако у нас также есть возможность импортировать только классы. Для этого мы можем использовать псевдонимы пространства имен для идентификации каждого класса, например так:

 <?php 
use MyCompany::Blog::User as BlogUser;
use MyCompany::CMS::User as CMSUser;

$ bloguser = new BlogUser ();
$ bloguser-> set (‘полное имя’, ‘Джон Доу’);
$ Bloguser-> Save ();

$ cmsuser = new CMSUser ();
$ cmsuser-> set (‘полное имя’, ‘Джон Доу’);
$ Cmsuser-> Save ();

Константы класса

Константы теперь могут быть определены на уровне класса! Обратите внимание, что константы класса доступны при импорте пространств имен, но вы не можете импортировать саму константу. Вот пример того, как мы могли бы их использовать:

 <?php 
namespace MyCompany;

Блог класса {
const VERSION = ‘1.0.0’;
}

<? PHP
echo ‘<p> Blog bersion’. MyCompany :: Блог :: ВЕРСИЯ. ‘</ Р>’;

использовать MyCompany :: Blog;
echo ‘<p> Версия блога’. Блог :: ВЕРСИЯ. ‘</ Р>’;

используйте MyCompany :: Blog :: VERSION как Foo;
echo ‘<p> Версия блога’. Фу. ‘</ Р>’;
Это приведет к следующему выводу:
Блог Bersion 1.0.0
Блог версия 1.0.0
Версия блога Foo

Функции пространства имен

Использование статических методов класса устарело использование функций в объектно-ориентированном мире, в котором мы сейчас живем. Однако, если вам нужно добавить функцию в ваш пакет, она тоже будет подвержена пространству имен!

Вот пример:

 <?php 
namespace bundle;
function foo() { echo '<p>This is the bundled foo</p>'; }
foo(); // This prints 'This is the bundled foo'

<? PHP
function foo () {echo ‘<p> Это глобальный foo </ p>’; }
require (‘lib / bundle.class.php’);
расслоение :: Foo (); // Это печатает ‘Это в комплекте Foo’
Foo (); // Это печатает ‘Это глобальный foo’

Глобальное пространство имен

Глобальное пространство имен является важным фактором при работе с функциями. В предыдущем примере вы заметите, что не существует прямого способа вызова глобальной функции foo

Метод разрешения вызовов функций по умолчанию — использовать текущее пространство имен. Если функция не может быть найдена, она будет искать внутреннюю функцию с таким именем. Он не будет смотреть в других пространствах имен автоматически.

Чтобы вызвать глобальную функцию foo Мы делаем это с помощью двойного двоеточия:

 <?php 
namespace bundle;
function foo() { echo '<p>This is the bundled foo</p>'; }
foo(); // This prints 'This is the bundled foo'
::foo(); // This prints 'This is the global foo'

Автозагрузка классов пространств имен

Если вы определяете волшебную функцию __autoload Прежде чем мы сможем использовать пространства имен, этого подхода будет достаточно, поскольку каждый класс должен иметь уникальное имя. Однако теперь возможно иметь несколько классов с одинаковыми именами.

К счастью, функции __autoload Поэтому в приведенных выше примерах вы можете ожидать такой вызов:

 __autoload( 'MyCompany::Blog::User' );

Теперь вы можете выполнить операцию замены строки для этого параметра, чтобы преобразовать двойные двоеточия в другой символ. Наиболее очевидной заменой будет символ разделителя каталогов:

 function __autoload( $classname ) {  
       $classname = strtolower( $classname );  
       $classname = str_replace( '::', DIRECTORY_SEPARATOR, $classname );  
       require_once( dirname( __FILE__ ) . '/' . $classname . '.class.php' );  
}

Это займет ожидаемый вызов выше и включит файл ./classes/mycompany/blog/user.class.php

Позднее статическое связывание

Позднее статическое связывание дает возможность родительскому классу использовать статический метод, который был переопределен в дочернем классе. Вы можете представить, что это будет поведение по умолчанию, но рассмотрите следующий пример:

 <?php  
 
class ParentClass {  
     
       static public function say( $str ) {  
               self::do_print( $str );  
       }  
 
       static public function do_print( $str ) {  
               echo "<p>Parent says $str</p>";  
       }  
 
}  
 
class ChildClass extends ParentClass {  
         
       static public function do_print( $str ) {  
               echo "<p>Child says $str</p>";  
       }  
 
}  
 
ChildClass::say( 'Hello' );

Вы, вероятно, ожидаете, что это вернет «Ребенок говорит Привет». Хотя я понимаю, почему вы можете ожидать этого, вы будете разочарованы, увидев, что он возвращает «Родитель говорит Привет».

Причина этого заключается в том, что ссылки на self::__CLASS__ PHP 5.3 теперь включает static::

         static public function say( $str ) {  
               static::do_print( $str );  
       }

С добавлением static::

__callstatic

До сих пор PHP поддерживал ряд магических методов в классах, с которыми вы уже знакомы, таких как __set__get__call В PHP 5.3 представлен метод __callstatic Другими словами, метод воздействует на нераспознанные статические вызовы непосредственно в классе.

Следующий пример иллюстрирует концепцию:

 <?php  
 
class Factory {  
 
       static function GetDatabaseHandle() {  
               echo '<p>Returns a database handle</p>';  
       }  
 
       static function __callstatic( $methodname, $args ) {  
               echo '<p>Unknown static method <strong>' . $methodname . '</strong>' .  
                       ' called with parameters:</p>';  
               echo '<pre>' . print_r( $args, true ) . '</pre>';  
       }  
}  
 
Factory::GetDatabaseHandle();  
Factory::CreateUser();  
Factory::CreateBlogPost( 'Author', 'Post Title', 'Post Body' );
Переменные статические вызовы

Когда статический член или метод не статичен? Когда это динамически ссылается, конечно!

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

 $classname = 'Factory';  
$methodname = 'CreateUser';  
$classname::$methodname();  
 
$methodname = 'CreateBlogPost';  
$author = 'Author';  
$posttitle = 'Post Title';  
$postbody = 'Post Body';  
 
$classname::$methodname( $author, $posttitle, $postbody );  
You can create dynamic namespaces like so:  
<?php  
require_once( 'lib/autoload.php' );  
 
$class = 'MyCompany::Blog::User';  
$user = new $class();  
$user->set('fullname', 'Ben Balbo');  
$user->save();

Эти маленькие штрихи могут сделать ваш код более читабельным и обеспечить полную гибкость в объектно-ориентированном смысле.

MySQL Native Driver

До версии 5.3 PHP любое взаимодействие с MySQL обычно происходило в сочетании с libmysql

Нативный драйвер MySQL для PHP 5.3 был разработан с нуля для PHP и движка ZEND, что дает ряд преимуществ. Очевидно, что родной драйвер специфичен для PHP и поэтому был оптимизирован для движка ZEND. Это дает клиенту меньшую площадь и меньшее время выполнения.

Во-вторых, нативный драйвер использует управление памятью движка ZEND и, в отличие от libmysql

Нативный драйвер был лицензирован по лицензии PHP, чтобы избежать проблем с лицензированием.

Дополнительные функции OpenSSL

Если вам когда-либо приходилось выполнять какие-либо действия, связанные с OpenSSL, в ваших сценариях (например, генерировать ключ Диффи-Хеллмана или шифровать контент), вы либо выполнили эту операцию в пользовательской среде, либо передали запрос системному вызову. ,

Патч для функциональности OpenSSL в PHP 5.3 предоставляет дополнительные функции, необходимые для выполнения этих действий через библиотеку OpenSSL, которая не только облегчает вашу жизнь и ваши приложения быстрее, но и позволяет вам повторно использовать проверенный код, который поставляется с OpenSSL.

Это будет отличной новостью для тех, кто в настоящее время работает с OpenID.

Улучшенная поддержка параметров командной строки

Надеюсь, вы будете знать, что PHP — это больше, чем просто язык сценариев для Интернета. Версия PHP для командной строки работает вне среды веб-сервера и полезна для автоматизации процессов системы и приложений.

Например, функция getopt в PHP существовала некоторое время, но была ограничена рядом системных типов; чаще всего он не функционировал в среде операционной системы Windows.

Начиная с PHP 5.3, функция getopt больше не зависит от системы. Ура!

XSLT Профилирование

XSLT — сложный зверь, и большинство пользователей этого шаблонного механизма знакомы с опцией профилирования xsltproc. Начиная с PHP 5.3, вы можете профилировать преобразования из ваших скриптов PHP. Этот фрагмент из примера кода , сопровождающего эту статью, дает вам представление о том, как мы могли бы его использовать:

 $doc = new DOMDocument();  
$xsl = new XSLTProcessor();  
 
$doc->load('./lib/collection.xsl');  
$xsl->importStyleSheet($doc);  
 
$doc->load('./lib/collection.xml');  
$xsl->setProfiling("/tmp/xslt-profiling.txt");  
echo $xsl->transformToXML($doc);  
 
echo '<h2>Profile report</h2>';  
echo '<pre>' . file_get_contents( '/tmp/xslt-profiling.txt' ) . '</pre>';

Информация, создаваемая профилем, будет выглядеть примерно так:

 number    match    name   mode     Calls   Tot  100us  Avg  
0         collection                    1       4       4  
1         cd                            2       1       0  
 
          Total                         3       5
Новые уровни ошибок

PHP, безусловно, язык, который имеет несколько причуд. Например, почему E_ALL

Ну, теперь это так! Да, PHP 5.3 теперь включает E_STRICTE_ALL

Кроме того, в то время как E_STRICTE_DEPRECATEDE_STRICT

Другие незначительные улучшения

В PHP 5.3 появилось несколько других улучшений, которые либо не гарантируют целый раздел в этой статье, либо не были протестированы на момент написания этой статьи, такие как:

  • Поддержка Sqlite3 через расширение ext/sqlite
  • DirectoryIteratorArrayAccess
  • Две новостные функции: array_replacearray_replace_recursive Хотя эти функции не были определены при тестировании в PHP 5.3.0, код C, который их реализует, предполагает, что они будут содержать функциональность, аналогичную array_merge Единственное исключение, однако, заключается в том, что функция array_replace Любые ключи, которые присутствуют во втором массиве, но не появляются в первом, будут игнорироваться.
Резюме

PHP 5.3 содержит много функциональных возможностей, которые изначально были предназначены для включения в PHP 6, что превращает его из незначительного обновления в значительный выпуск, о котором каждый разработчик PHP должен задуматься. Мы коснулись большинства функций в этой статье и рассмотрели некоторый код, демонстрирующий, как вы можете использовать эти новые функции.

Не забудьте скачать архив кода, который сопровождает эту статью , и повеселиться, живя на грани!