Как может выглядеть PHP 5.5

в 16:27, , рубрики: php

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

Однако необходимо понять: PHP 5.5 еще на ранней стадии развития, поэтому никто не знает, как он будет выглядеть в итоге. Все, о чем здесь написано это только предложения. Я уверен, что не все это будет в PHP 5.5, или будет, но не в таком виде.

Так что не стоит слишком возбуждаться :)

Теперь, без лишних церемоний, список фич, над которыми ведется работа в PHP 5.5:

Обратная совместимость

Начнем с двух изменений, которые уже попали в master и влияют на обратную совместимость (по крайней мере в некоторой степени):

Отказ от поддержки Windows XP и 2003

Статус: landed; Ответственный: Pierre Joye

PHP 5.5 больше не поддерживает Windows XP и 2003. Этим системам около десяти лет, поэтому PHP отказалось от них.

Модификатор /e признан устаревшим

Статус: landed; Ответственный: Nikita Popov

Модификатор e указывает функции preg_replace выполнить заменяемую строку как код PHP, а не просто сделать замену. Неудивительно, что такое поведение является постоянным источником проблем, в том числе проблем безопасности. Именно поэтому использование этого модификатора выдаст предупреждение deprecated в PHP 5.5. В качестве замены необходимо использовать функцию preg_replace_callback. Вы можете найти более подробную информацию об этом изменении в соответствующем RFC.

Новые функции и классы

Далее мы рассмотрим некоторые запланированные новые функции и классы:

boolval()

Статус: landed; Ответственный: Jille Timmermans

В PHP уже реализованы функции strval, intval и floatval. Для согласованности добавлена функция boolval. Она делает то же самое, что и приведение (bool), но может быть использована в качестве аргумента для другой функции.

hash_pbkdf2()

Статус: landed; Ответственный: Anthony Ferrara

PBKDF2 означает «Password-Based Key Derivation Function 2» и, как можно понять из названия, это алгоритм для получения ключа шифрования из пароля. Она необходима для алгоритмов шифрования, но может быть использована и для хэширования паролей. Более подробное описание и примеры использования в RFC.

Добавления в расширении intl

Статус: landed; Ответственный: Gustavo André dos Santos Lopes

Будет много улучшений в расширение intl. Например, появятся новые классы IntlCalendar, IntlGregorianCalendar, IntlTimeZone, IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator. Я к сожалению не много знаю о расширении intl, так что, если вы хотите узнать больше, я рекоммендую ознакомиться с анонсами в список рассылки для Calendar и BreakIterator.

array_column()

Статус: proposed; Ответственный: Ben Ramsey

Существует предложение новой функции array_column (или array_pluck), которая будет вести себя следующим образом:

<?php

$userNames = array_column($users, 'name');
// тоже самое что
$userNames = [];
foreach ($users as $user) {
    $userNames[] = $user['name'];
}

Это как выборка столбца из базы данных, только для массивов.

Простой API для хеширования пароля

Статус: proposed; Ответственный: Anthony Ferrara

Недавняя утечка паролей (из LinkedIn и др.) показали, что даже крупные сайты не используют правильное хэширование паролей. Люди много лет выступают за использование BCrypt, но все же большинство людей, похоже, используют совершенно небезопасный sha1 хэш.

Мы полагали, что причиной этого может быть очень трудное использование функции crypt. Таким образом, мы хотели бы представить новый, простой API для безопасного хэширования пароля:

<?php

$password = "foo";

// создание хеша
$hash = password_hash($password, PASSWORD_BCRYPT);

// проверка пароля
if (password_verify($password, $hash)) {
    // пароль верный!
} else {
    // пароль неверный!
}

Новый API для хэширования имеет больше возможностей, все они изложены в RFC.

Изменения в языке

Теперь перейдем к действительно интересным вещам: новые возможности и усовершенствования языка.

Разыменование массивов

Статус: landed; Ответственный: Xinchen Hui

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

<?php

function randomHexString($length) {
    $str = '';
    for ($i = 0; $i < $length; ++$i) {
        $str .= "0123456789abcdef"[mt_rand(0, 15)]; // dereference для строки
    }
}

function randomBool() {
    return [false, true][mt_rand(0, 1)]; // dereference для массива
}

Я не думаю, что эта функция очень полезна на практике, но это делает язык согласованнее. См. также RFC.

empty() работает с вызовами функций и другими выражениями

Статус: landed; Ответственный: Nikita Popov

В настоящее время конструкция языка empty() может быть использована только с переменными, но не с выражениями. Например, код empty($this->getFriends()) выдаст ошибку. В PHP 5.5 это будет валидный код. Для получения дополнительной информации см. RFC.

Получение полного имени класса

Статус: proposed; Ответственный: Ralph Schindler

В PHP 5.3 представили пространства имен с возможностью назначать классам и пространствам имен более короткие псевдонимы. Это не распространяется на строку с именем класса:

<?php

use SomeDeeplyNestedNamespaceFooBar;

// не работает, потому что будет использован глобальный класс `FooBar`
$reflection = new ReflectionClass('FooBar');

В качестве решения предложен новый синтаксис FooBar::class, который возвращает полное имя класса:

<?php

use SomeDeeplyNestedNamespaceFooBar;

// работает, потому что FooBar::class интерпретируется в "Some\Deeply\Nested\Namespace\FooBar"
$reflection = new ReflectionClass(FooBar::class);

Больше примеров в RFC.

Пропуск параметров

Статус: proposed; Ответственный: Stas Malyshev

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

Возьмем пример функции из RFC:

function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }

Нет никакого способа установить $report_errors = false без повторения двух других значений по умолчанию. Для решения этой проблемы предлагается использовать пропуск параметров:

create_query("deleted=0", "name", default, default, false);

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

Контроль типа для скалярных значений

Статус: proposed; Ответственный: Anthony Ferrara

Контроль типа для скалярных значений изначально планировался в 5.4, но его не сделали из-за отсутствия консенсуса. Для получения дополнительной информации о том, почему его еще не сделали в PHP, см.: Scalar typehints are harder than you think.

В PHP 5.5 обсуждения возобновились, и я думаю, появилось довольно приличное предложение для контроля типа скалярных значений используя преобразования типов.

Оно будет работать, приводя входящее значение в указанный тип, но только если приведение может происходить без потери данных. Например 123, 123.0, "123" будут действительны для int параметров, но "привет мир" не будет. Это соответствует поведению внутренних функций.

function foo(int $i) { ... }

foo(1);      // $i = 1
foo(1.0);    // $i = 1
foo("1");    // $i = 1
foo("1abc"); // пока не ясно, может быть $i = 1 с выводом notice
foo(1.5);    // пока не ясно, может быть $i = 1 с выводом notice
foo([]);     // ошибка
foo("abc");  // ошибка

Getters и setters

Статус: proposed; Ответственный: Clint Priest

Если вы не поклонник писать все эти методы getXYZ() и setXYZ($value), то это должно быть позитивным изменением для вас. Предложение добавляет новый синтаксис для определения того, что должно произойти, когда свойство пишут или читают:

<?php

class TimePeriod {
    public $seconds;

    public $hours {
        get { return $this->seconds / 3600; }
        set { $this->seconds = $value * 3600; }
    }
}

$timePeriod = new TimePeriod;
$timePeriod->hours = 10;

var_dump($timePeriod->seconds); // int(36000)
var_dump($timePeriod->hours);   // int(10)

Есть еще ​​несколько нововведений, например read-only свойства. Если вы хотите узнать больше, посмотрите RFC.

Генераторы

Статус: proposed; Ответственный: Nikita Popov

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

Например, вот как можно определить функцию range как итератор:

<?php

function *xrange($start, $end, $step = 1) {
    for ($i = $start; $i < $end; $i += $step) {
        yield $i;
    }
}

foreach (xrange(10, 20) as $i) {
    // ...
}

Приведенная выше функция xrange имеет такое же поведение, как встроенная функция range с одним отличием: вместо возвращения массива со всеми значениями, она возвращает итератор, который генерирует значения на лету.

Для более глубокого введения в тему можно посмотреть RFC.

Выделение списков и выражения-генераторы

Статус: proposed; Ответственный: Nikita Popov

Выделение списков обеспечивают простой способ произвести операции над массивами:

$firstNames = [foreach ($users as $user) yield $user->firstName];

Выше приведенный код эквивалентен следующему:

$firstNames = [];
foreach ($users as $user) {
    $firstNames[] = $user->firstName;
}

Также можно фильтровать массивы следующим образом:

$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user];

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

Дополнительные примеры в анонсе в списке рассылки.

Заключение

Как вы видите, есть много удивительных вещей, над которыми ведется работа в PHP 5.5. Но, как я уже сказал, PHP 5.5 еще молод, поэтому мы не знаем наверняка, что будет в нем, а что нет.

Если вы хотите оставаться в курсе новых возможностей или хотите помочь в обсуждении и/или развитии, не забудьте подписаться на внутренний список рассылки.

Комментарии приветствуются!

Автор: KeepYourMind

* - обязательные к заполнению поля