LINUX.ORG.RU

PHP 7.0.0

 , ,


4

5

Команда разработчиков PHP рада сообщить о релизе PHP 7.0.

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

Abstract Syntax Tree

Наиболее крупным изменением является введение абстрактного синтаксического дерева (AST). Разделение парсера и компилятора позволило избавиться от ряда хаков и сделало реализацию более сопровождаемой и понятной. Кроме того, это позволило реализовать синтаксис, который ранее не был возможным при однопроходном процессе компиляции.

PHPNG

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

Scalar Type Hints

Добавлены четыре новые декларации для скалярных типов: int, float, string и bool. По умолчанию используется нестрогий режим проверки и данные будут приводиться к тому типу, что указан в декларации:

function add(int $a, int $b) {
    // is_int($a) - true
    // is_int($b) - true
    return $a + $b;
}

add("1", "2");

С помощью новой директивы declare(strict_types=1); можно включить режим строгой проверки. Режим распространяется на тот файл, где вызван declare, а не тот, где была определена вызываемая функция. Если типы не совпадут, это приведет к ошибке:

declare(strict_types=1);

function add(int $a, int $b) {
    return $a + $b;
}

add(1.5, 2.5);
// Catchable fatal error: Argument 1 passed to add() must be of the type integer, float given

В дополнение к пользовательским функциями, cтрогий режим проверки типа также влияет на функции стандартной библиотеки и расширений:

declare(strict_types=1);

$foo = substr(52, 1);
// Catchable fatal error: substr() expects parameter 1 to be string, integer given

Return Type Declarations

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

Краткий пример синтаксиса в действии:

function foo(): array {
    return [];
}

Здесь так же, как и для type-hint, можно объявить строгий режим. Дополнительные примеры можно найти в RFC.

Uniform Variable Syntax

Введён единый синтаксис переменных. Благодаря этому изменению следующие выражения стали корректными:

// support missing combinations of operations
$foo()['bar']()
[$obj1, $obj2][0]->prop
getStr(){0}

// support nested ::
$foo['bar']::$baz
$foo::$bar::$baz
$foo->bar()::baz()

// support nested ()
foo()()
$foo->bar()()
Foo::bar()()
$foo()()

// support operations on arbitrary (...) expressions
(...)['foo']
(...)->foo
(...)->foo()
(...)::$foo
(...)::foo()
(...)()

// two more practical examples for the last point
(function() { ... })()
($obj->closure)()

// support all operations on dereferencable scalars (not very useful)
"string"->toLower()
[$obj, 'method']()
'Foo'::$bar

Но не обошлось и без потери обратной совместимости:

                        // old meaning            // new meaning
$$foo['bar']['baz']     ${$foo['bar']['baz']}     ($$foo)['bar']['baz']
$foo->$bar['baz']       $foo->{$bar['baz']}       ($foo->$bar)['baz']
$foo->$bar['baz']()     $foo->{$bar['baz']}()     ($foo->$bar)['baz']()
Foo::$bar['baz']()      Foo::{$bar['baz']}()      (Foo::$bar)['baz']()

Generator Return Expressions

Добавлена возможность возвращать значения из генераторов.

function gen() {
    yield "Hello";
    yield " ";
    yield "Sun!";

    return "Goodbye Moon!";
}

$gen = gen();

foreach ($gen as $value) {
    echo $value;
}
// Hello Sun!

echo $gen->getReturn(); // Goodbye Moon!

Generator Delegation

Введён новый синтаксис yield from <expr>, позволяющий генераторам делегировать операции Traversable объектам и массивам.

function hello() {
     yield "Hello";
     yield " ";
     yield "Sun!";
     yield " ";

     yield from goodbye();
}

function goodbye() {
     yield "Goodbye";
     yield " ";
     yield "Moon!";
}

$gen = hello();
foreach ($gen as $value) {
     echo $value;
}

// Hello Sun! Goodbye Moon!

Anonymous classes

Добавлена поддержка анонимных классов.

Они могут быть использованы вместо полного определения класса для одноразовых объектов:

(new class extends ConsoleProgram {
    public function main() {
       /* ... */
    }
})->bootstrap();

Closure::call

PHP7 добавляет легкий способ переопределить $this для анонимной функции прямо во время вызова с помощью Closure::call().

class A {
    private $x = 1;
}

// Pre PHP 7 code
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX();

// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A);

Throwable Interface

Изменена иерархия исключений. А именно, введён интерфейс Throwable, который реализуют два базовых исключения: Exception и Error. Пользовательские классы не могут реализовывать этот интерфейс.

Таким образом, новая иерархия выглядит вот так:

  • interface Throwable
    • Exception implements Throwable
      • ...
    • Error implements Throwable
      • TypeError extends Error
      • ParseError extends Error
      • AssertionError extends Error

Unicode Codepoint Escape Syntax

Добавлен новый экранирующий символ \u, который позволяет указывать специфические unicode-символы внутри PHP-строк:

echo "\u{aa}"; // ª
echo "\u{0000aa}"; // ª (same as before but with optional leading 0's)
echo "\u{9999}"; // 香

Combined Comparison (Spaceship) Operator

Добавлен новый оператор комбинированного сравнения: (expr) <=> (expr). Он возвращает 0, если оба операнда равны, 1 в случае, когда левый операнд больше правого и -1, если правый больше левого.

echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

Group Use Declarations

Добавлена возможность группировки use деклараций.

// Before:
use Doctrine\Common\Collections\Expr\Comparison;
use Doctrine\Common\Collections\Expr\Value;
use Doctrine\Common\Collections\Expr\CompositeExpression;

// After:
use Doctrine\Common\Collections\Expr\{ Comparison, Value, CompositeExpression };

Null coalesce operator

Ещё один новый оператор — ??, который возвращает левый операнд, если тот не имеет значение NULL, в противном случае возвращается правый операнд. В отличии от короткого тернарного оператора ?:, он работает как isset().

// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalesces can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';

Прочие изменения

Особо стоит отметить, что из PHP была удалена вся функциональность помеченная устаревшей в версиях 5.x.x, включая расширения ereg и mysql.

Следующие возможности объявлены устаревшими и будут удалены в будущих версиях:

  • Конструкторы классов в стиле PHP 4.
  • Статические вызовы нестатических методов.
  • Опция salt для password_hash().
  • Опция capture_session_meta для SSL context.

>>> Руководство по миграции с PHP 5.6.x

>>> Исходники для загрузки

>>> Список изменений

★★★★★

Проверено: maxcom ()
Последнее исправление: cetjs2 (всего исправлений: 3)

Размаскировал версию 7.0, поставил на локальной машинке. Свои сайты вроде бы нормально работают. Остаётся дождаться когда на FreeBSD появится.

Feonis ★★★
()
Ответ на: комментарий от Kroz

получится такое

Получится такое

echo "Value is '{str}' (string)";
А кроме того, есть sprintf.

$r=$$module->$action($para);

Фантазируем без $:

r = $module->$action(para)
Т.е. используем $ для взятия «ссылки». Даже логичнее выглядит.

no-such-file ★★★★★
()

Это знают даже негры

php - говно. Все.

anonymous
()
Ответ на: комментарий от anonymous

Вот он и фейл. История третьего питона ничему не научила?

Та «потеря обратной совместимости», что в PHP7 — это уровень, который в Питоне в минорщине случается :) Весь софт, который в последние лет 10 не пользовался depricated техниками и который не использовал неоднозначное поведение продолжит работать как работал. Все эти $$foo['bar']['baz'] (не путать с $foo['bar']['baz']) итак требовали отрывания рук программисту и в прошлые времена.

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

Кто-то ими пользуется?

Очень многие. Я — так с момента появления. Даже анонимные функции намного удобнее пустышек или кривых create_function. А замыкания вообще в ряде случаев код в разы упрощают. Какой-нибудь preg_replace_callback, например, взять внутри метода класса. Только через замыкание можно передать текущий объект.

KRoN73 ★★★★★
()
Ответ на: комментарий от xonix

Как там в 2015 без нативного юникода?

Х.з. Я юникод активно и без ухищрений использую с начала 2004-го: http://www.balancer.ru/g/p351760

При чём переход на него лимитировал не PHP, а MySQL. Как только 4.0-alpha стал поддерживать полноценно юникод, так и начал переводить на него свои проекты.

Так что я не понимаю всеъ этих плясок вокруг «нативного юникода» уже 10 лет как. Просто всё что надо работает :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Kroz

Если написать аналог без доллара, то получится такое:

В js почему-то получилось всё нормально:

console.log(`Value is '${str}' (string)`);
holuiitipun
()
Ответ на: комментарий от anonymous

Наступил 2015г, на часах железо и софт уже мощнее чем на суперкомпьютерах 10 летней давности. И все стали компилировать скрипты! Видимо что-то случилось...

Элементарно.

1. 10 лет назад в той же России было около 10 млн. интернет-пользователей и ходили они со стационарных компов изредка. В 2015-м их уже более 80 млн. и сидят они в Интернете часто безвылазно, даже с телефонов в дороге. Нагрузка на сайты выросла на порядок-два.

2. Сегодня мало кому интересны статические HTML-странички Васи Пупкина, как это было 10 лет назад. Сегодня подавай персонизацию, рекомендации, лайки, комментарии в виде сотен страниц срачей. Это дополнительно увеличивает нагрузку на сайты на пару порядков.

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

'%s = %s' % ('x', 10)

За такой синтаксис, кстати, руки отрывать надо дизайнерам языка. Задалбывает в любом более-менее длинном тексте подсчитывать номер переменной в двух местах. А если в строке ещё и экранированные символы процента — вообще каша. Хуже только скобочки у Лиспа :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Kroz
 $r=$$module->$action($para); 

Кстати а что в php сейчас можно положить в $module и $action? Я 4-шник по Котерову и помню только про строковое разыменование ;]

Просто интересно как. Если делать obj->abc, то как понять, abc это имя метода или переменная, из которой это имя нужно взять.

В js так:

obj.abc - abc имя метода
obj[abc] - в abc хранится имя метода

Так что $$module->$action($para) это что-то навроде:
modules[module][action](para)

Ещё есть методы функций call и apply, они часто используются в callback'ах:

var obj = {
   button_callback: function (id, event) {
   },
   ajax_callback: function(error, content) {
   }
};

// умный метод, сам умеет вызывать obj.ajax_callback.call(obj, error, content);
ajax('GET', 'url', obj.ajax_callback, obj);

// тупой метод, просто кладёт функцию куда-то к себе в массив и потом вызывает в глобальном scope.
// button.onclick(obj.button_callback); скорее всего будет неправильно работать, т.к. в button_callback придёт this, который window, а не obj, как хотелось бы
// поэтому нужна анонимная функция, которая делает правильный вызов функции как метода объекта
button.onclick(function() {
  obj.button_callback.apply(obj, arguments);
});

diafour
()

Интересно, как теперь «семёрочка» будет по производительности по сравнению с HHVM и что там было у ВКшников (забыл, как оно называлось)?!

Twissel ★★★★★
()
Последнее исправление: Twissel (всего исправлений: 1)

PHP 7.0 в половине бенчмарков на alioth быстрее в 1.5-2-3 раза чем Python (3.5).

Кажется обогнали даже Lua, или сравнялись. Судя по результатам, компилятор Hack для PHP от Facebook тоже оказался не нужен.

tp_for_my_bunghole
()
Последнее исправление: tp_for_my_bunghole (всего исправлений: 1)
Ответ на: комментарий от Kilte

какой-то джаваскрипт получился
Он уже давно такой, ИМХО. Даже Spring свой есть

Х-спади, вот он, настоящий PHP-тред /)_o

bytecode ★★
()
Ответ на: комментарий от Twissel

и что там было у ВКшников

KPHP вроде бы, php4 на «стероидах»

umren ★★★★★
()
Ответ на: комментарий от tp_for_my_bunghole

Судя по результатам, компилятор Hack для PHP от Facebook тоже оказался не нужен.

Он же не инициализируется. Так что еще как нужен. Посмотри тесты под нагрузкой, а не прогона одного скрипта.

umren ★★★★★
()
Ответ на: комментарий от MATPOCKUH

Сравнивать корректно можно только после того, как в PHP все его расширения будут написаны на PHP, а не на Си.

У питона уже все расширения написали на Python?

umren ★★★★★
()
Ответ на: комментарий от MATPOCKUH

Сравнивать корректно можно только после того, как в PHP все его расширения будут написаны на PHP, а не на Си.

Верно, вся стандартная библиотека PHP на C, в Python std намного больше и часть на python.

Cython нравится. Осваиваю Kivy. К тому же Emacs сейчас в принципе полноценная IDE для Python, с использованием Jedi.

tp_for_my_bunghole
()
Ответ на: комментарий от tp_for_my_bunghole

полноценная IDE для Python

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

umren ★★★★★
()
Ответ на: комментарий от MATPOCKUH

Сравнивать корректно можно только после того, как в PHP все его расширения будут написаны на PHP, а не на Си.

«Я буду играть защиту Каро-Канн, только вы мне не мешайте, пожалуйста» (c)

no-such-file ★★★★★
()
Ответ на: комментарий от umren

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

По моему есть всё что имеет смысл в динамическом языке

https://jedi.readthedocs.org/en/latest/

tp_for_my_bunghole
()
Последнее исправление: tp_for_my_bunghole (всего исправлений: 1)
Ответ на: комментарий от Kroz

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

Как отличить переменную от зарезервированного слова?

x86_64 ★★★
()
Ответ на: комментарий от no-such-file

Это проблемы питона, им никто руки не выкручивал.

Это не проблемы.

Проблемы скорее в php, где 98% пользователей не знают C. Python source читал ради интереса. Источники php не видел никогда, не знаю даже где они.

tp_for_my_bunghole
()

интересно, сколько процентов собирает пхп в своем секторе ?

kto_tama ★★★★★
()
Ответ на: комментарий от KRoN73

И в этом, конечно, PHP виноват? :)

Узкая сфера применения языка, часть web-а, хоть и большая.

В python нативный модуль это shared object, динамическая библиотека. Как пишут для php, не представить.

tp_for_my_bunghole
()
Ответ на: комментарий от umren

Я знаю про Jedi, это автокомплит. Лишь один из аспектов IDE.

Рефакторинг не свойство IDE как таковой. Это свойство Java IDE.

В python чаще test-driven development, TDD. Сначала представляешь как твой код будет использоваться. Пишешь короткий тест, функции и классы заглушки. Потом реализуешь дополняя тест.

tp_for_my_bunghole
()
Последнее исправление: tp_for_my_bunghole (всего исправлений: 1)

Что там с async io и green threads? Сотку тыщ какие-нибудь websocket'ов оно уже осилит?

anonymous
()
Ответ на: комментарий от tp_for_my_bunghole

Источники php не видел никогда, не знаю даже где они

А это уже твои проблемы.

Проблемы скорее в php, где 98% пользователей не знают C

И зачем им это знать? От этого скорость работы библиотек никак не зависит.

Python source читал ради интереса

Т.е. ради того, чтобы такие как ты из интереса могли потыкать исходники библиотек их стоит писать не на Си, а на питоне? И это оправдание тормозов питона? Л.О.Л.!

no-such-file ★★★★★
()
Ответ на: комментарий от x86_64

И сколько надо операций на необходимый рефакторинг.

Столько, сколько нужно для успешного прохода теста в поставленной задаче. Не просто корректность аннотаций.

tp_for_my_bunghole
()
Ответ на: комментарий от no-such-file

А это уже твои проблемы.

Не мои, и не проблемы )

Т.е. ради того, чтобы такие как ты из интереса могли потыкать исходники библиотек их стоит писать не на Си, а на питоне? И это оправдание тормозов питона? Л.О.Л.!

Я призываю тебя не использовать «питон». Это наверно должно тебя успокоить.

tp_for_my_bunghole
()
Ответ на: комментарий от tp_for_my_bunghole

Столько, сколько нужно для успешного прохода теста в поставленной задаче. Не просто корректность аннотаций.

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

x86_64 ★★★
()
Ответ на: комментарий от x86_64

Это означает, в случае сложных рефакторингов, написание тестов для промежуточных состояний.

^^Это java thinking.

Test-driven. Не рефакторинг ведёт к изменению теста, а изменённый тест требует рефакторинг. Потому что тест является формализацией задачи/подзадачи на уровне языка. Никакая Java IDE не может знать что и каким способом ты хочешь реализовать.

tp_for_my_bunghole
()
Последнее исправление: tp_for_my_bunghole (всего исправлений: 1)

Мне больше всего из новинок понравилась массивы-константы. Наконец-то.

Infra_HDC ★★★★★
()
Ответ на: комментарий от x86_64

Посмотри на Си, как там изгаляются вводя новые ключевые слова

Lolwut?

Aswed ★★★★★
()
Ответ на: комментарий от tp_for_my_bunghole

Никакая Java IDE не может знать что и каким способом ты хочешь реализовать.

Только есть методики безопасных изменений. Ты пропагандируешь писать неизменяемый код?

x86_64 ★★★
()
Последнее исправление: x86_64 (всего исправлений: 1)
Ответ на: комментарий от KRoN73

уровень, который в Питоне в минорщине случается :)

Можно примеры? Если использовать новые фичи то да, код написаный на python 2.5 может не завестись на python 2.4, но не наоборот же.

pawnhearts ★★★★★
()
Ответ на: комментарий от KRoN73

http://habrahabr.ru/post/129640/comments/

оспидя, сколько ниасиляторства в одном треде! И какой пример в пользу того, что нода - говно! А чо фибоначи то? А не sleep(5) например, ну чтоб совсем круто? В общем типичный скулеж не осилившего почитать хотяб стартовую доку. JS, конечно, говно, но PHP в разы хуже.

anonymous
()
Ответ на: комментарий от KRoN73

В питоне даже в старом форматинге можно было делать как-то так

In [1]: '%(foo)s blabla %(foo)s' % {'foo': 'x'}
Out[1]: 'x blabla x'

И был string.Template для длинных текстов.

pawnhearts ★★★★★
()

пыщщщщ

пыходрочеры

anonymous
()
Ответ на: комментарий от Kroz

Если делать obj->abc, то как понять, abc это имя метода или переменная, из которой это имя нужно взять.

яннп. в динамических языках обычно методы и функции это first-class objects. То есть если abc это метод, то можно сделать obj->abc(), а можно и оперировать с obj->abc как с переменной и, например, передать его в другую функцию типа map(obj->abc, [1,2,3])

pawnhearts ★★★★★
()
Ответ на: комментарий от x86_64

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

Начинаются с подчеркивания просто потому, что не стандарт. Не посмотрел что Си, смотрел аналог на C++, там ни подчеркиваний, ни больших букв.
http://en.cppreference.com/w/cpp/language/alignas
http://en.cppreference.com/w/cpp/language/storage_duration

Kroz ★★★★★
()
Ответ на: комментарий от pawnhearts

Ну чтоб не завестись пожалуй нет, но противные мелочи выползают. Например в 2.6 запретили использовать string exceptions.

Не то, чтобы это было большой проблемой, но сам подход: рубануть деприкейтед в миноре....

http://stackoverflow.com/questions/11497234/typeerrorexceptions-must-be-old-s...

zloelamo ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.