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)

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

Все твои несогласия - это попросту результат неосиляторства.

«Плохой ЯП» - это либо когда он тормознутый (или оверхеднутый), либо когда он не выполняет не то и не так, как от него это ожидают.

Если ЯП тебе $var=3+2; возвращает 10 - согласен, язык говно.

ООП - это не достижение цивилизации, а всего лишь способ пофиксить одни косяки, создав при этом другие косяки. Более тебе скажу, как программер, ты ОБЯЗАН УМЕТЬ решить одну и ту же задачу и при ООП и процидурками, а если ты этого не умеешь, то ... нутыпонел.

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

Поэтому со скриптовым говном никогда не стоит связываться.

Особо не разбираюсь, подскажи, я запустил хеллоуворлд скриптового языка, или не ?

root@gideon:~/test# ls -l
total 20
-rwxrwxr-x 1 root root 15096 Nov 27 02:19 lor
-rwxr-xr-x 1 root root   102 Nov 27 02:20 lor.c
root@gideon:~/test# file lor
lor: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fd3b07ffefb6cd609d2c55a7accb1e3f872e4e7b, for GNU/Linux 3.2.0, stripped
root@gideon:~/test# ./lor
Hello World
root@gideon:~/test#
windows10 ★★★★★
()
Ответ на: комментарий от windows10

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

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

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

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

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

После этих и других слов можно смело отправлять все твои сообщения в /dev/null без захода из в мозг)

Что есть нормальный проект?

Является ли им личный проект гражданина И., который создал личный сайт с использованием связки php/apache с кучей всего от блога до системы управления домом для своей семьи?

В небольшом городе Н. общество «Помощь раковым больным города Н.» разработала проект сайта со всем необходимым функционалом. Связка php/apache. Является ли этот проект нормальным?

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

laravel

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

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

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

Ну да, именно поэтому у нас в компании ищут рубиста с ЗП до 250к.

нищебродненько

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

в свете наличия Clojure/Clojurescript ничего из вышеозвученного не нужно

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

Если вы не понимаете, что язык !== фреймворки, то о чём вообще речь?

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

но, конечно, кому и кобыла - невеста

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

Да, нет, я помню! Мы обсуждаем, зачем нужен пхп в 2К21.

большая часть языков из TIOBE в 2021 не нужна, но легаси, карл…

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

ты щас прям как плюсовики говоришь, «а вот в c++48 комитет наконец-то сделает збс, и тогда-то заживём!»

хотя просто берёшь, и не пишешь на этом говне, чего ждать и страдать?

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

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

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

кормить нищебродов без чувства прекрасного? конечно! (см. Stack overflow survey за последний год)

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

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

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

ты щас прям как плюсовики говоришь, «а вот в c++48 комитет наконец-то сделает збс, и тогда-то заживём!»

Подброшу дровишек …
За много десятилетий НИКОМУ не удалось создать «серебрянную пулю».

Почему?

Потому что все языки программирования разрабатываются с использованием грамматик.
А у них архитектурных недостатков ВАГОН! …

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

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

Получится Java с фрактальным дизайном.

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

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

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

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

Апач устарел, он делался под другие реалии, использовать его для чего-то кроме легаси-проектов - полная глупость. Да и легаси-проекты (кроме совсем уж легаси), в большинстве, легко переводятся на nginx просто конвертацией пачки htaccess-ов в nginx-конфиг.

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

Потому что все языки программирования разрабатываются с использованием грамматик. А у них архитектурных недостатков ВАГОН! …

Какие альтернативы? И вообще такое ЯП без грамматики?

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

чтобы из питона сделать что-то пригодное для веба, его надо обмазать таким количеством абстракций….

flask? А что есть в мире пыха, кстати? Yii - архитектурное убожество, обожаемый народными массами wp вообще представляет собой нагромождение костылей и по сю пору еле-еле работает без апача. Разве что Laravel.

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

flask

Кому он нужен?

Yii - архитектурное убожество

3(третий) полностью переделанный вот скоро выйдет. А так да, yii поэтому только в СНГ и популярен.

обожаемый народными массами wp

Никем он не обожаемый, это тот ещё позор.

Разве что Laravel

Так ларавел и есть. Ещё симфони.

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

Потому что там плохо практически всё.

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

Хотя название языка как бы намекает что это не язык общего назначения.

Которое из них, кстати?

Поначалу ведь PHP расшифровывалось как Personal Home Page. И для создания оных, я считаю, было практически идеальным средством. Для проектов, состоящиих на 80-90% из HTML, а на оставшуюся часть из вкраплений кода, самое то. И тут сразу понятно и почему нет строгой типизации, и многое другое.

Потом оно обернулось в PHP: Hypertext Preprocessor и стало распространяться везде, где только можно. Хотя вот уже даже для какой-нибудь CMS преимущества PHP далеко не так очевидны, и там уже, возможно, была бы лучше та же Java, Go или ещё что-то, где код отдельно, разметка отдельно.

Я не прав?

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

где код отдельно, разметка отдельно

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

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

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

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

Фрейд с Роршахом довольны этим тредом…

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

Вот и мне это же напомнило.) А по сабжу: хорошо, что обновляется.

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

В DRF достаточно в наследнике класса ModelViewset переопределить метод get_queryset типа такого:

page = self.request.query_params['page']
if page is not None:
  queryset = self.queryset.filter(page = page)
return queryset

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

А ты загляни к нему во внутренности.

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

и почему он при этом имеет довольный вид...

Harald ★★★★★
()
Ответ на: комментарий от 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)
Ответ на: комментарий от fernandos

Ещё симфони.

мне когда-то очень понравилось симфони, потому что это был полный копипаст спринг-веба из джавки ))

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

а вот с yii (тогда была версия 1, вроде бы, это был лет 6 назад) я не смог разобраться вообще (( По крайней мере, за выделенные на это три дня. Мне нужно было прикрутить oauth2, и там всё-просто-неработало. Очень странная штука.

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

Понятно, очередной пустозвон

Ну вот, теперь вы ВСЕ ЗНАЕТЕ!

А большего вам и не нужно знать.
anonymous
()
Ответ на: комментарий от anonymous

Это символизирует твою судьбу, если будешь пользоваться этим чудом.

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

потому что это был полный копипаст спринг-веба из джавки

Именно! Ещё так ант украли.

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

Это не из коробки, это из целого фреймворка.

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

В DRF достаточно в наследнике класса ModelViewset переопределить метод get_queryset типа такого:

Еще раз, чем отличается page = self.request.query_params[‘page’] от $page=$_GET[‘page’] ?

Оно тебе что-то другое вернет из строки урла ?

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