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 ()

Ответ на: комментарий от zloelamo

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

Уверен, никто не использовал её ко времени 2.6.

Problems with string exceptions include only sometimes working when a literal is used in both the raise and the except, not providing an OO mechanism for attaching additional information to the exception, and not allowing catching categories of multiple exception types. Exceptions were added to the language before classes, and once exception classes were added string exceptions were only kept for backwards compatibility

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

Да я и не спорю, но такие вещи надо вырезать в мажоре. А встретилась она вообще в сторонней библиотеке, насколько я помню.

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

Это вообще security-fix. Предлагаешь не закрывать проблемы с безопасностью ради обратной совместимости?

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

Начинаются с подчеркивания просто потому, что не стандарт.

Ошибаешься. Как раз стандарт. О выкрутасах ради совместимости в C++ рассказывать не буду. Тяжело объяснить как они делают синтаксис еще более ужасным из-за проблем совместимости.

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

Наводит на мысль, что это библиотека заброшенная со времен 1.x

Согласен в том, надо было вырезать это ещё раньше.

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

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

Именно что не заработает. Не весь код, но шансы нарваться немалые. Ты, очевидно список изменений не смотришь. А читать документацию полезно. Там даже в третьей цифре встречаются «This section lists previously described changes that may require changes to your code».

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

Например, в 3.5 inspect.getargspec была объявлена устаревшей, в ночных билдах её уже удалили. Теперь надо использовать getfullargspec. Пруф.

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

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

Ты странный. Не используй python.

tp_for_my_bunghole ()

Новость хороша, +

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

Ты странный. Не используй python.

Странный ты. python нормальный язык. С кучей недостатков, как другие языки. Вот рассказывать о том, что его недостатки явлются достоинствами или вообще не проблема - не надо. Надо просто все недостатки осознавать.

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

Ладно, убедил.

На счет синтаксиса - основной упор C (наверное и C++) - код, который работал 20 лет назад, должен работать и сейчас. Получается, чтобы добавить новый функционал, да, приходится извращаться.

Но то, что синтаксис именно портится - не согласен. Старый синтаксис не меняется. Уместней сказать, что синтаксис новый фич оставляет желать лучшего.

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

Ну ты просил случай когда код не будет работать: вот пожалуйста. И это не секьюрити фикс. Это бред. Кому нужен был секьюрити, то не использовал инсекьюр, кому не нужен был - использовал.

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

Да просто прогеры не имеют привычки переписывать весь код каждые несколько месяцев. Плохо, но это реальность. Стринг эксепшены работали и работали нормально, поэтому никто об этом не думал.

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

Стринг эксепшены это жуткая древность. Я начинал работать с питоном, когда ещё только old-style классы были и уже тогда стринг эксепшены были устаревшеми и никто ими не пользовался, во всяких книжках их даже не упоминали. Но они работали ещё много лет аж до 2.6.

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

Чувак, у тебя 5 звёзд, но ты такой PHPшник. Лучше не говори больше ничего ни про C ни про Go.

1.

echo "Value is '$str' (string)";
fmt.Printf("Value is '%s' (string)", str)

2.

$r=$$module->$action($para);
В PHP это может в порядке вещей, но в приличных языках за такое руки отрывают. Никогда так нельзя делать, только потому что можешь. В крайнем случае, можно получить значение из map, а не из любой переменной:
var results = map[string]string{}

r, ok := results[module.Action(param)]

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

python нормальный язык. С кучей недостатков, как другие языки. Вот рассказывать о том, что его недостатки явлются достоинствами или вообще не проблема - не надо. Надо просто все недостатки осознавать.

Java без недостатков, используй её. Там рефакторинг.

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

results[module.Action(param)]

WUT? Это так не работает.

$a = 'x';
$b = 'a';
echo $$b;
// x

Идём дальше:

class A {public function method() {return 'result';}}
$a = new A();
$c = 'method';
echo $$b->$c();
// result

Но с тем, что так лучше никогда не делать, соглашусь.

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

Идём дальше:

Ты прежде чем дальше идти, прочти ещё разок:

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

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

но в приличных языках за такое руки отрывают

За использование ссылок/указателей? Okay.

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

Java без недостатков, используй её.

Ж:)

В этом ты очень сильно ошибаешься.

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

А теперь ты прочти ещё раз

Это так не работает.

Твой пример следовало бы написать как-то так:

var modules = map[string]object{}
r, ok := modules[moduleName].Action(param)
Kilte ★★★★★ ()
Ответ на: комментарий от dazdraperma

Лучше не говори больше ничего ни про C ни про Go.

Давай ты не будешь рассказывать что мне говорить, а я не буду рассказывать куда тебе идти.
Я задал конкретный вопрос, есть что ответить по существу - велкам. Нет - проходи мимо.

fmt.Printf(«Value is '%s' (string)», str)

Уже обсуждали. Не ломает глаза только при очень простых кейсах с 2-3 переменными.
А как тебе такое:

void Manager::printYearly(int yearsIn) {
    float yldFund = ((avgFund - startValue)/startValue) * 100;
    float yldBond = ((avgBond - startValue)/startValue) * 100;
    printf("-%*i -%*i -%*8.2f -%*8.2f -%*8.2f -%*3.1f%% -%*8.2f -%*8.2f -%*8.2f -%*3.2f%% -%*8.2f",
           10, yearsIn, 10, (int)(inflationRate*100), '%', 10, (float)avgFund, 10,
           (float)minValFund->getValue(), 10, (float)maxValFund->getValue(), 10,
           yldFund, 10, (float)avgBond, 10, (float)minValBond->getValue(),
           10, (float)maxValBond ->getValue(), 10, yldBond, 10, (float)avgBury);
}


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

Я обычно отрываю руки за неподкрепленные ничем утверждения. Или за объяснения типа такого:

Никогда так нельзя делать,

Либо аргументируй, либо проходи мимо.

А хороший программист умеет использовать имеющиеся инструменты там, где это уместно.

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

Чудачок на букву «М», ссылки в php выглядят так:

$a = & $b;

В примере выше - рефлексия там, где она не нужна, в частности, при приёме параметра от пользователя и определении на его основе, какой action выполнить.

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

ого, здесь еще остались адекваты? Удивительно.

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

Уже обсуждали. Не ломает глаза только при очень простых кейсах с 2-3 переменными.
А как тебе такое:

Стесняюсь спросить, для чего ты включил в свой пример приведение типов, арифметику и отключил подсветку синтаксиса? Можешь привести этот же фрагмент на PHP, мы заценим читаемость?

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

А как тебе такое

А такое писать надо уметь:

void Manager::printYearly(int yearsIn)
{
    // одинаковый кусок startValue * 100 нужно вынести в разовое определение
    float yldFund = ( (avgFund - startValue) / startValue ) * 100;
    float yldBond = ( (avgBond - startValue) / startValue ) * 100;
    // такой принтф нужно разбивать на несколько принтфов,
    // а определение формата вывода можно вынести вообще наружу
    // или определить переменную тут
    printf(
        "-%*i -%*i -%*8.2f -%*8.2f -%*8.2f -%*3.1f%% -%*8.2f -%*8.2f -%*8.2f -%*3.2f%% -%*8.2f",
        // каждый
        10,
        // аргумент
        yearsIn,
        // можно
        10,
        // и
        (int) (inflationRate * 100),
        // даже
        '%',
        // нужно
        10,
        // комментировать
        (float) avgFund,
        // кроме
        10,
        // того
        (float) minValFund->getValue(),
        // построчная
        10,
        // их
        (float) maxValFund->getValue(),
        // передача
        10,
        // повышает
        yldFund,
        // читаемость
        10,
        // кода
        (float) avgBond,
        10,
        (float) minValBond->getValue(),
        10,
        (float) maxValBond ->getValue(),
        10,
        yldBond,
        10,
        (float) avgBury
    );
}

deep-purple ★★★★★ ()
Ответ на: комментарий от dazdraperma

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

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

Я обычно отрываю руки за неподкрепленные ничем утверждения.

Оторви себе. За неподкреплённый обоснованием своей необходимости говнокод.

где это уместно

Или расскажи, где это уместно.

anonymous ()

Хоспыдя, сколько ещё надо поколений, чтобы наконец закопать этот недоперловый высер?!

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

видимо еще долго) слишком активно развивается

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

Это последний релиз перед - rip?

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

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

Ну я так и знала, набегут пэхэпэшники и будут падать в обморок от восторга

Пэхэпешники-то ладно, у них праздник. А ты что здесь делаешь?

))))))

Держи закрывающих: ((((((.

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

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

фейл

Уровня register_globals=off.

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

В этом ты очень сильно ошибаешься.

Ты решил поведать миру что в языках программирования есть недостатки. Они не программируют сами.

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

Не знаю. Я первый раз. Только попробовать.

Я ожидал более глобальных изменений. И пока я не вижу козырей, чтобы разработчики оставались на php, а не переходили на js(node.js).

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

ссылки в php выглядят так

А указатели так:

$somewhat = 10;
$ptr = 'somewhat';
echo $$ptr;

рефлексия там

ЛОЛ ШТО? Где ты тут увидел рефлексию, болван.

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

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

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

Чудесные «указатели»,которые при передаче в другую функцию просто работать перестанут

Они не работают как ты привык - это твоя проблема.

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

чтобы разработчики оставались на php, а не переходили на js(node.js).

Полтора разработчика и два школьника перешли на ноду, теперь php капец!

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

Кто-то и на фортане ещё кодит или ещё на каком старье. Ничего не поделать, это выбор каждого.

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

ещё на каком старье

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

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

node.js - появился в 2009 году. Самому js - 20 лет. php - тоже 20 лет, вот только другие языки его обскакали много раз за эти годы. Какой смысл использовать php в 2016 году?

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