LINUX.ORG.RU

PHP 8.1

 

PHP 8.1

2

2

Состоялся релиз PHP 8.1 — языка программирования общего назначения, под управлением которого, согласно данным w3techs, работают порядка 78 % сайтов. Среди основных изменений в новой версии стоит отметить добавление перечислений, «зелёных» потоков и интерсекционных типов.

Новая функциональность

Enums

Добавлены перечисления, которые базируются на классах и объектах (поэтому оператор проверки типа instanceof работает и с ними). Перечисления вмещают ряд констант. Но что самое важное, перечисления создают отдельный тип, с которым уже можно работать.

Пример работы с перечислениями, взятый из RFC:

enum Suit { 
  case Hearts; 
  case Diamonds; 
  case Clubs; 
  case Spades; 
} 

function pick_a_card(Suit $suit) { ... } 

$val = Suit::Diamonds; 

pick_a_card($val);        // OK 
pick_a_card(Suit::Clubs); // OK 
pick_a_card('Spades');    // TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given 

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

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

Подкреплённые перечисления

По умолчанию элементы перечислений не имеют скалярного типа, но всё же его можно объявить при создании перечисления (доступно только для int или string):

enum Suit: string { 
  case Hearts = 'H'; 
  case Diamonds = 'D'; 
  case Clubs = 'C'; 
  case Spades = 'S'; 
} 

Такие значения называются подкреплёнными (backed), ведь значение «подкрепляются» более простым скалярным типом.

Также доступно свойство только для чтения «value», хранящее значение.

Подкреплённые перечисления реализуют интерфейс BackedEnum, который определяет два метода:

  • from(int|string): self принимает скалярный тип и возвращает соответствующее значение перечисления (Enum Case), а если такого нет, то будет выброшена ошибка типа ValueError;

  • tryFrom(int|string): ?self аналогичен первому методу, только теперь ошибка не будет выброшена, а просто возвратится null.

Интерфейсы, трейты и методы в перечислениях

Перечисление может вмещать методы (причём даже статические), а также использовать трейты.

Если перечисление реализует какой-то интерфейс, то все элементы перечисления пройдут проверку на тип, реализующий этот интерфейс:


interface Colorful { 
  public function color(): string; 
} 

enum Suit implements Colorful { 
  case Hearts; 
  case Diamonds; 
  case Clubs; 
  case Spades; 

  // Fulfills the interface contract. 

  public function color(): string { 
    return match($this) { 
      Suit::Hearts, Suit::Diamonds => 'Red', 
      Suit::Clubs, Suit::Spades => 'Black', 
    }; 
  } 

  // Not part of an interface; that's fine. 
  public function shape(): string { 
    return "Rectangle"; 
  } 
} 

function paint(Colorful $c) { ... } 

paint(Suit::Clubs);  // Works 

print Suit::Diamonds->shape(); // "rectangle" 

Перечисление значений

Также перечисления реализуют метод cases(), возвращающий список объектов перечисления:

Suit::cases(); 

// [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit:Spades] 

Интерсекционные типы

В противовес союзным типам в РНР 8.0, добавлена возможность указания более точных типов, путём их объединения при помощи логического «и». Это достигается благодаря комбинации имён классов или интерфейсов при помощи амперсанда & (пример из php.watch):

function count_and_iterate(Iterator&\Countable $value) { 
    foreach($value as $val) {} 
    count($value); 
} 

Поддерживаются только чистые интерсекционные типы, без композиции с nullable или союзными типами. Кроме того, поддерживаются только имена классов и интерфейсов.

Нити

Добавлены файберы, предоставляющие низкоуровневый интерфейс для создания «зелёных потоков». Нити позволяют управлять параллельными процессами в пределах одного физического процесса. То есть, де-факто не будет двух участков кода, выполняющихся в один момент времени, но файберы позволяют выполнять действия в момент, пока один участок кода простаивает.

Возвращаемый тип never

Добавлена возможность объявить возвращаемый функцией тип как never, если она всегда вызывает остановку программы. Этого можно достичь, вызывая в этой функции конструкцию exit или die. Пример из PHP.Watch


function redirect(string $url): never { 
    header('Location: ' . $url); 
    exit(); 
} 

Цель этого изменения — указать, что вызов определённой функции гарантированно остановит выполнение программы.

final для констант класса

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

class Foo { 
    final public const X = "foo"; 
} 

class Bar extends Foo { 
    public const X = "bar"; 
} 

// Fatal error: Bar::X cannot override final constant Foo::X 

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

Свойства только для чтения

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

class Test {
    public readonly string $prop;
 
    public function __construct(string $prop) {
        // Заполнение readonly-свойства
        $this->prop = $prop;
    }
}
 
$test = new Test("foobar");
// Так можно
var_dump($test->prop); // string(6) "foobar"
 
// А так нельзя, пускай значение и совпадает
$test->prop = "foobar";
// Error: Cannot modify readonly property Test::$prop

Ключевое слово readonly можно использовать только с типизированным свойством. Инициализация свойства только для чтения может происходить только в классе, содержащем это свойство.

При попытке повторного установления значения или удаления переменной будет выброшено исключение типа Error.

Кроме этого:

  • Добавлены функции:
    • fsync: синхронизация изменений в файле (включая метадату);
    • fdatasync: синхронизация изменений в файле без метадаты;
    • array_is_list: проверяет, является ли массив списком;
    • Функции для поддержки потокового шифрования XChaCha20 в Sodium;
  • Добавлено новое поле full_path в суперглобальном массиве $_FILES, хранящее полный путь к файлам, который был передан браузером;
  • Синтаксис first-class callable;
  • Новый атрибут #[ReturnTypeWillChange];
  • Оператор распаковки массивов теперь поддерживает массивы со строковыми ключами;
  • Добавлена поддержка алгоритмов хеширования xxHash и MurmurHash3;
  • Добавлен новый параметр $options для функций хеширования для определения алгоритмоспецифичных дополнительных опций;
  • Добавлена поддержка префикса 0o/0O для восьмеричных чисел;
  • Новый класс IntlDatePatternGenerator, позволяющий лучше поддерживать локализованные даты;
  • В phar добавлена поддержка алгоритмов подписи OpenSSL-256 и OpenSSL-512;
  • В расширение mysqli добавлена константа MYSQLI_REFRESH_REPLICA аналогичная уже существующей константе MYSQLI_REFRESH_SLAVE, это сделано из-за того, что в MySQL версии 8.0.23 некоторые опции, содержащие слова «slave», были признаны устаревшимы и заменены на аналогичные с «replica». Тем не менее MYSQLI_REFRESH_SLAVE в РНР устаревшей не признана и планов по удалению этой константы нет;
  • GD:
  • Curl:
    • Добавлена поддержка DNS-over-HTTPS;
    • Добавлен класс CURLStringFile, позволяющий осуществлять загрузку файла путём отправки его содержимого.

Изменения

Ограничение использования суперглобального массива $GLOBALS

Суперглобальный массив $GLOBALS, хранящий пары имя_переменной => ссылка_на_переменную больше нельзя передавать по ссылке, приравнивать его к пустому массиву или ссылке на переменную.

// Будет работать:
foreach ($GLOBALS as $var => $value) {
    echo "$var => $value\n";
}
$GLOBALS['x'] = 1;
$GLOBALS['x']++;
isset($GLOBALS['x']);
unset($GLOBALS['x']);
// ...что угодно, используя $GLOBALS['x'].

// Выдаёт ошибку времени компиляции:
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);
// ...и другие подобные операции чтения-записи над $GLOBALS

// Выдаёт исключения типа Error во время исполнения:
by_ref($GLOBALS);

А также:

  • Функции для работы HTML теперь будут обрабатывать одинарные кавычки ', а невалидные символы теперь будут просто заменены на � (U+FFFD);
  • Теперь класс SplFixedArray реализует интерфейс JsonSerializable, что позволит функции json_encode воспринимать его как массив;
  • Режим интерактивной оболочки (php -a) теперь требует наличия расширения readline;
  • Функции fputcsv и SplFileObject::fputcsv теперь могут принимать новый параметр, оборачивающий конец строки;
  • Функция version_compare() теперь не может принимать частичные значения для операторов;
  • Функция compact() теперь выбрасывает предупреждение, если типы её параметров отличались от массива и строки;
  • Разрешено использование ключевого слова new в параметрах функции по умолчанию, аргументах атрибутов, инициализаторах статических переменных и глобальных констант;
  • Благодаря изменениям в работе OPcache, производительность была повышена на 0.5-8%;
  • В phar алгоритм подписи по умолчанию изменён с SHA1 на SHA256;
  • Расширение MySQLi теперь использует режим выброса исключений при возникновении ошибки;
  • Следующие ресурсы стали объектами:
    • file_info => finfo
    • imap => IMAP\Connection
    • ftp => FTP\Connection
    • Функция imageloadfont теперь возвращает экземпляр класса GdFont
    • Ресурсы LDAP мигрировали в экземпляры классов LDAP\Connection, LDAP\Result и LDAP\ResultEntry
    • Ресурсы PostgreSQL мигрировали в экземпляры классов PgSql\Connection, PgSql\Result и PgSql\Lob
    • pspell => PSpell\Dictionary, pspell config => PSpell\Config

Объявлено устаревшим

>>> Подробности

★★★

Проверено: sudopacman ()
Последнее исправление: sudopacman (всего исправлений: 22)
Ответ на: комментарий от fernandos

В пыхе это проверяется сторонними средствами.

и в джаве много что проверяется сторонними средствами. Какой-нибудь FindBugs ого-го чего может найти

но рантайм и компилятор проверяют код всегда перед запуском. Если код неправильный на уровне интерпретатора (джава тоже интерпретирует - байткод) то он просто не запустится. Если неправильный на уровне синтаксиса - ругнется компилятор при компиляции

в пыхе можно было бы точно так же: встроить в php.exe на уровне первоначального парсинга синтаксиса. (вроде бы -l так и работает?). Контролировать ничего не нужно, нужно только написать ворнинг в консоль. И дать возможность этот ворнинг сделать критикалом, какой-нибудь E_GENERICS_MISMATCH, включенный по умолчанию

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

но рантайм и компилятор проверяют код всегда перед запуском

В джаве статическая сильная типизация, в РНР часто тип переменной узнаётся во время выполнения.

в пыхе можно было бы точно так же: встроить в php.exe на уровне первоначального парсинга синтаксиса

Для этого надо туда вставить линтер. -л — убожество, я повторяю. А после встраивания линтера окажется, что надо предоставить форму, которая будет освобождена от необходимости прохода линтера, оную назовут байткод, а потом резко обнаружится, что на логотипе не слон, а чашка кофе.

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

У меня после LOR-а все время остается чувство, что с последователями Платона и Гегеля поговорил об платоновских идеях или даже древними алхимиками о чистых элементах, а не с современными инженерами.

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

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

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

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

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

нэт, линукс это единственная ОС, которая может проработать больше 10и лет обновляясь до самых актуальных версий без переустановок. Аналогично код на джаве может за 10 лет смигрировать до самых новых версий платформы и библиотек без полного переписывания и оставаться пригодным для развития

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

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

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

вот если вы писали на пыхе вы прошли этапы:

пхп4 процедурный код и вставки в хтмл

жумла/друпал vs mvc zf/symfony

laravel, phalanger или как их там

?? вас заставили опять переписывать все авно на го без ООП, женериков и исключений, чтобы потом опять перерисывать

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

если вы пейсали на спринге 10 лет назад, то и дальше можете это делать со спокойной совестью ну или с javaee/jackartaee та же тема примерно

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

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

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

обычно все оканчивается на первом этапе

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

Нет, линукс это не ОС а ядро, а из линукс-дистров конечно какие-то так могут, но далеко не все. И могут так не только линукс-дистры.

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

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

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

laravel

Решил почитать Википедию по сабжу и взоржал

В 2015 году в результате опроса sitepoint.com по использованию PHP-фреймворков среди программистов занял первое место в номинациях:

  • Фреймворк корпоративного уровня
  • Фреймворк для личных проектов
  • Кладезь антипаттернов
Crocodoom ★★★★★
()
Ответ на: комментарий от Crocodoom
Ответ на: комментарий от Crocodoom

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

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

в ларавеле по-моему все через нетипизированный сервис локатор было реализовано, ну и сектантское сообщество с проактивным шизом во главе

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

Когда в Жабу добавят норм. дженерики без type erasure?

эммм… никогда? это сломает совместимость (в обе стороны?), а совместимость - священная корова

что там может произойти - это например, возможность писать примитивные типы внутри дженериков: http://openjdk.java.net/jeps/8261529

Панаму ковырял

я уже несколько лет не в теме джавного R&D, хз что там в панаме сейчас

когда я в последний раз пробовал, там была векторизация (https://github.com/openjdk/panama-vector, https://openjdk.java.net/jeps/338, http://cr.openjdk.java.net/~vlivanov/panama/vectors/vectors.html), и она даже работала. Там даже работали какие-то примеры с автоматической векторизацией циклов, которые показывали на конференциях.

есть какая-то вероятность, что я вернусь назад в джаву (в компиляторщину в смысле), но придется потратить на это пару лет. Неясно, стоит ли игра свеч

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 4)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.