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)

А я даже о PHP 6.0 не слышал. Я в самом деле его пропустил или они перескочили через одну версию?

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

Тонны старого быдлокода просто сломаются. И хрена толку от всех оптимизаций? Вон с 5.3 люди не могут слезть до сих пор, лол.

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

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

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

Анонимные функции и замыкания ещё в 5.3 появились, 6+ лет назад.

Кто-то ими пользуется? Или так, карго-культик?

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

Что сложного в том, чтобы прошерстить проект на наличие таких мест и проставить скобочки? Это всё мелочи. В конце-концов все, кто хотели, уже обзавелись поддержкой PHP 7 или в процессе. А всякое легаси как работало на древних неподдерживаемых версиях, так и будет дальше там работать. Тут вот недавно в каком-то треде писали, что до сих пор поддерживают проекты на PHP 4, что же теперь надо было продолжать тащить за собой всё то древнее говно в новые версии?

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

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

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

В микро-фреймворках очень удобно в них контроллёры определять.

А ещё вот такая штука достаточно популярна: http://pimple.sensiolabs.org/

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

Кстати, есть ли кто-нибудь кому интересно узнать как устроен процесс компиляции в PHP?

Есть такие интересные ресурсы как:
http://www.phpinternalsbook.com/
http://lxr.php.net/xref/PHP_TRUNK/
http://nikic.github.io/
http://jpauli.github.io/index.html
https://wiki.php.net/internals

и конечно спецификация PHP: https://github.com/php/php-langspec/blob/master/spec/00-specification-for-php.md

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

интересно, а когда сделают такое же, но в node

Только с перламутровыми пуговицами

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

Последний раз когда я пробовал Node.js, не получилось заставить нормально работать MySQL. Есть ли в Node.js нормальная поддержка MySQL, вернее есть ли пакет, который делает это нормально для приложений масштаба предприятий (enterprise)?

Есть ли в ноде обработка сессий, аналог функций session_*() из PHP?

Каков механизм работы с датами?

Насколько я понимаю благодаря генераторам и await в ноде код стало писать не так больно.

ProtoH
()

На пхп не пишу, но новость на 5+!

cdshines ★★★★★
()

Не пыхпышник, но приятно за кодеров и за сайт с прилично оформленной новостью.

Stalin ★★★★★
()

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

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

В отличии от питона, где было сломано всё, что только можно.

Ha-ha-ha-ha, oh wow.

А новость хорошо оформлена.

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

Ты ошибся, .net убил ноду. Когда появился async.

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

Выравнивание данных. Для этого в язык добавили спецификатор _Alignas

Какое отношение имеет расположение переменной в памяти к «признаку переменной»?

Поддержка многопоточности, для этого в стандарт добавили спецификатор типа _Thread_local

А каким образом «признак переменной» позволяет иначе решить проблему?

А если уж говорить об области видимости, но наиболее продуманный подход внезапно обнаружился у vimscript:

g:varname	 The variable is global 
s:varname	 The variable is local to the current script file 
w:varname	 The variable is local to the current editor window 
t:varname	 The variable is local to the current editor tab 
b:varname	 The variable is local to the current editor buffer 
l:varname	 The variable is local to the current function 
a:varname	 The variable is a parameter of the current function 
v:varname	 The variable is one that Vim predefines

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

я конечно дико извеняюсь, но в жо ес можно и без долларов

А можно примерчик?

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

Кстати, Go разве не компилируемый? Если компилируемый, то там вообще такого не должно быть возможным сделать.

Kroz ★★★★★
()

В основном возникают только мысли вроде «как, там и этого не было?».

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

echo «Value is {str}»; же

Кстати, я этот подход использовал много раз, но почему-то не пришло в голову использовать его для такого кейса.
Спасибо за идею, Надо будет попробовать...

«test%.2f» % 0.12345

Это не из той оперы. Это аналог printf в Си, да, оно работает, но наглядность кода страдает.

Кстати, а примеры на каком языке программирования приведены? Я что-то не помню конструкцию с '%'.

А вообще большая часть такой работы с текстом должна быть в движке шаблонов.

PHP и есть один большой движок шаблонов.

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

Если я правильно понял слово «интерполяция», то см. мой коммент выше.

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

println «The sum of 2 and 3 equals ${2 + 3}»

Это пример демонстрирующий что?

А вот это вообще лапша.

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

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

Это пример демонстрирующий что?

как в строчку код вставляется.
ещё пример:

println "The sum of 2 and 3 equals ${def s = 2 + 3; s}"

но вот с удобством и читабельность тут все впорядке.

Угу, так впорядке что «Но не обошлось и без потери обратной совместимости:»
Что PHP в конечном итоге избавляется от кучи косяков, это конечно хорошо.
Но вот то, что многие косяки являются следствием хренового дизайна, это факт.

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

println «The sum of 2 and 3 equals ${def s = 2 + 3; s}»

Это уже черезчур.
ИМХО, в bash как раз на нужно уровне реализовано. Больше не нужно.

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

ЛОЛ, кстати, да.

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

Кстати, а примеры на каком языке программирования приведены? Я что-то не помню конструкцию с '%'

pyhton

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

Теперь представь, что не начинается. Напиши аналог вот такого:

echo "Value is '$str' (string)";

Строковая интерполяция --- это функция, которая никак не зависит от того, используются ли сигилы при записи имён переменных. Она присутствует во многих других ЯП, только сделана не так криво (например, позволяет использовать произвольные выражения):

> x, y = 2, 3
=> [2, 3]
> puts "#{x}­ plus #{y} equal­s #{x + y}"
=> "2 plus 3 equals 5"

и такого:

result = module.send action, *params
theNamelessOne ★★★★★
()
Ответ на: комментарий от Kroz

первое делается легко, в джаве например плейсхолдеры обычно выглядят как ${str}.

второе, т.е. переменные переменные, нафиг ненужно и ВРЕДНО. Похапэшники даже хотели это выпилить во имя n-цатикратного ускорения кода, но не смогли (+лигаси код).

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

Лол. еще одна телка, которая не отличает java от javascript.

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

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

если бы мой ЯП менял мажорную версию каждую неделю, я бы сильно засомневался в адекватности его авторов и сменил ЯП

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

ну теперь-то хостинги точно перелезут с 5.2 и 5.3 на 5.4!

buratino ★★★★★
()

как бы не случилось разделения как с питоном :)

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

осталось внести жит и нормальную неумираемость

Да нормально у него с неумираемостью. Нормально написанные на нём демоны работают очень долго и падать не думают.

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

Теперь представь, что не начинается. Напиши аналог вот такого:

«Value is '{}' (string)».format(s)

и такого:

eval(module).action(para)

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

добавят пробелы

Какие пробелы?

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

это аналог printf в Си

Нет. Тут можно делать так:


'%s = %s' % ('x', 10)
[\code]

>наглядность кода страдает

Ничего не страдает, "{}" заменяется на "%s", всё.
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.