[web-php] master: PHP 8.3 release page (#807)
| From: | Sergey Panteleev via GitHub | Date: | Tue, 21 Nov 2023 10:27:32 +0000 |
| Subject: | [web-php] master: PHP 8.3 release page (#807) | ||
| Groups: | php.webmaster | ||
| Request: | Send a blank email to php-webmaster+get-31058@lists.php.net to get a copy of this message | ||
Author: Sergey Panteleev (saundefined)
Committer: GitHub (web-flow)
Pusher: saundefined
Date: 2023-11-21T13:13:54+03:00
Commit: https://github.com/php/web-php/commit/636b1dbee2ccb6bf40b180e711b6b195c32a88a0
Raw diff: https://github.com/php/web-php/commit/636b1dbee2ccb6bf40b180e711b6b195c32a88a0.diff
PHP 8.3 release page (#807)
Co-authored-by: Tim Düsterhus <timwolla@googlemail.com>
Co-authored-by: Roman Pronskiy <root@pronskiy.com>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
Co-authored-by: Tim Bond <cookieguru@gmail.com>
Changed paths:
A images/php8/logo_php8_3.svg
A images/php8/php_8_3_released.png
A releases/8.3/common.php
A releases/8.3/en.php
A releases/8.3/index.php
A releases/8.3/languages/en.php
A releases/8.3/languages/ru..php
A releases/8.3/release.inc
A releases/8.3/ru.php
Diff:
diff --git a/images/php8/logo_php8_3.svg b/images/php8/logo_php8_3.svg
new file mode 100644
index 0000000000..ae9af2100d
--- /dev/null
+++ b/images/php8/logo_php8_3.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg"
width="451" height="127" fill="none" viewBox="0 0 451
127">
+ <path fill="#fff" fill-rule="evenodd" d="M21.7998
125.799h-21l18.7-96.0998h40.3c12.1 0 21 3.2 26.5 9.5 5.6 6.4 7.2 15.2 5 26.7-.9 4.7-2.5 9-4.6
12.9-2.2 3.9-5 7.5-8.5 10.7-4.2 3.9-8.8 6.7-13.9 8.4-5.1 1.7-11.6 2.4998-19.6 2.4998h-18l-4.9
25.4Zm45.9-76.5998c-2.7-2.9-8-4.4-15.9-4.4h-14.3l-7.8 40.3h12.7c8.4 0 14.7-1.6 18.9-4.8 4.1-3.2
6.9-8.5 8.4-15.9 1.3-7.2.6-12.2-2-15.2Z" clip-rule="evenodd"/>
+ <path fill="#fff" d="M106.6 4.09961h20.8l-5 25.59999h18.5c11.7 0 19.7 2 24.1
6.1 4.4 4.1 5.8 10.7 4 19.8L160.3
100.4h-21.1l8.3-42.6004c.9-4.8.6-8.1-1-9.9-1.6-1.8-5..1-2.6-10.4-2.6h-16.6L108.8 100.4H87.9004L106.6
4.09961Z"/>
+ <path fill="#fff" fill-rule="evenodd" d="M185.2
125.799h-21l18.7-96.0998h40.4c12.1 0 21 3.2 26.5 9.5 5.6 6.4 7.2 15.2 5 26.7-.9 4.7-2.5 9-4.6
12.9-2.2 3.9-5 7.5-8.5 10.7-4.2 3.9-8.8 6.7-13.9 8.4-5.1 1.7-11.6 2.4998-19.6 2.4998h-18l-5
25.4Zm46-76.5998c-2.7-2.9-8-4.4-15.9-4.4h-14.4l-7.8 40.3h12.7c8.4 0 14..7-1.6 18.9-4.8 4.1-3.2
6.9-8.5 8.4-15.9 1.3-7.2.7-12.2-1.9-15.2Z" clip-rule="evenodd"/>
+ <path fill="#fff" d="M317.5 48.5c-5.7-13.6-10.5-25..4-5.8-33.6 1.8-2.5 3.8-3.8
6-3.8 4.5 0 8.6 4.9 8.6 4.9l5.7 6.9-3.6-8.2c-.2-.3-6.3-14.2-17.2-14.2-3.8 0-7.8 1.7-11.7
5.1l-.1.1c-9.5 11-.2 31.8 8.1 50.1l6.1 14.2c2.8 7.3 5.6 16 3.9 22.4-2.6 10-11.5 16.8-11.6 16.9l-5.7
4.4 6.9-2.2c.7-.2 16-5.2 19.7-18.5 2.3-10.9-.6-21.8-3.5-30.2.4-.3-.4.3 0 0L318 49.1"/>
+ <path fill="#0F0F0F" d="m334.4 9.89961-7.1-7.8 5.1 9.29999c.1.1 6.3 11.7-1.6
25.2-2.9 4.2-7.4 8.4-13.1 12.6l-10.3 6.7c-.1-.1-.1-.2 0 0l-.4.3c-11.5 6.6-22.2 10.6-22.4 10.7-15.9
7.1-25.9 18.1-27.3 30.3-1.1 9.2004 3..2 18.2004 11.6 24.5004l.1.1c5.3 3.2 11 4.8 17 4.8 15.7 0
28-10.9 28.5-11.4l7.7-6.9-9.1 4.8c-.1 0-7.7 4-15.6 4-7.1 0-12.1-3.1-15.1-9.4-3.8-13.4004 9.5-22.6004
24.8-33.2004 2-1.4 4.1-2.9 6.2-4.3l.1-.1 9.1-6.8c.1-.2.4-.4.4-.4 7..5-6.2 17.4-15.9 19.7-29.5
1.8-12.3-7.9-23-8.3-23.49999Z"/>
+ <path fill="#fff" d="M345.4 83h19.5l-3.5 17.7h-19.5l3.5-17.7Z"/>
+ <path fill="#fff" d="m379.951 86.1562 12.796-10.4921c4.602 6.0996 9.989 10.0039
18.632 10.0039 9.429 0 14.255-5.7334 14.255-11.1016
0-5.7334-3.704-8.9053-12..684-8.9053h-8.53l3.062-15.4931h9.846c7.97 0 14.817-3.7818 14.817-10.8575
0-5.0019-4.491-8.2954-10.328-8.2954-6.959 0-11.56 3.1719-17.285 8.7832l-9.541-11.833c7.408-8.2959
15.94-13.7856 28.847-13.7856 16.5 0 26.041 10.1255 26..041 22.2031 0 10.4912-5.949 18.1773-17.51
21.8369 5.5 2.44 10.663 8.2949 10.663 16.835 0 15.4932-13.02 27.4483-32.887 27.4483-16.613
0-25.592-8.1739-30.194-16.3468Z"/>
+</svg>
diff --git a/images/php8/php_8_3_released.png b/images/php8/php_8_3_released.png
new file mode 100644
index 0000000000..f8e4fd786c
Binary files /dev/null and b/images/php8/php_8_3_released..png differ
diff --git a/releases/8.3/common.php b/releases/8.3/common.php
new file mode 100644
index 0000000000..249e08239c
--- /dev/null
+++ b/releases/8.3/common.php
@@ -0,0 +1,75 @@
+<?php declare(strict_types=1);
+
+namespace releases\php83;
+
+include_once __DIR__ . '/.../../include/prepend.inc';
+
+function language_redirect(string $currentLang): void {
+ // We don't use the general language selection of php..net,
+ // so soldier on with this one.
+ return;
+}
+
+function common_header(string $description): void {
+ global $MYSITE;
+
+ $meta_image_path = \htmlspecialchars(
+ \filter_var($MYSITE . 'images/php8/php_8_3_released.png', \FILTER_VALIDATE_URL));
+ $meta_description = \htmlspecialchars($description);
+
+ \site_header("PHP 8.3.0 Release Announcement", [
+ 'current' => 'php8',
+ 'css' => ['php8.css'],
+ 'meta_tags' => <<<META
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:site" content="@official_php" />
+<meta name="twitter:title" content="PHP 8.3 Released" />
+<meta name="twitter:description" content="{$meta_description}" />
+<meta name="twitter:creator" content="@official_php" />
+<meta name="twitter:image:src" content="{$meta_image_path}" />
+
+<meta itemprop="name" content="PHP 8.3 Released" />
+<meta itemprop="description" content="{$meta_description}" />
+<meta itemprop="image" content="{$meta_image_path}" />
+
+<meta property="og:image" content="{$meta_image_path}" />
+<meta property="og:description" content="{$meta_description}" />
+META
+ ]);
+}
+
+function language_chooser(string $currentLang): void {
+ $LANGUAGES = [
+ 'en' => 'English',
+ 'ru' => 'Russian',
+ ];
+
+ // Print out the form with all the options
+ echo '
+ <form action="" method="get" id="changelang"
name="changelang">
+ <fieldset>
+ <label for="changelang-langs">Change language:</label>
+ <select onchange="location = this.value + \'.php\'"
name="lang" id="changelang-langs">
+';
+
+ $tab = ' ';
+ foreach ($LANGUAGES as $lang => $text) {
+ $selected = ($lang === $currentLang) ? ' selected="selected"' :
'';
+ echo $tab, "<option
value='$lang'$selected>$text</option>\n";
+ }
+
+ echo ' </select>
+ </fieldset>
+ </form>
+';
+}
+
+function message($code, $language = 'en')
+{
+ $original = require __DIR__ . '/languages/en.php';
+ if (($language !== 'en') && file_exists(__DIR__ . '/languages/' .
$language . '.php')) {
+ $translation = require __DIR__ . '/languages/' . $language . '.php';
+ }
+
+ return $translation[$code] ?? $original[$code] ?? $code;
+}
diff --git a/releases/8..3/en.php b/releases/8.3/en.php
new file mode 100644
index 0000000000..aa9133cd7a
--- /dev/null
+++ b/releases/8.3/en.php
@@ -0,0 +1,5 @@
+<?php
+
+$lang = 'en';
+
+include_once __DIR__ . '/release.inc';
\ No newline at end of file
diff --git a/releases/8.3/index.php b/releases/8.3/index.php
new file mode 100644
index 0000000000..88b80dbf69
--- /dev/null
+++ b/releases/8.3/index.php
@@ -0,0 +1,5 @@
+<?php
+ $_SERVER['BASE_PAGE'] = 'releases/8.3/index.php';
+include (__DIR__ . '/../../include/site.inc');
+
+mirror_redirect('/releases/8.3/en.php');
diff --git a/releases/8.3/languages/en.php b/releases/8.3/languages/en.php
new file mode 100644
index 0000000000..0ad1638dd4
--- /dev/null
+++ b/releases/8.3/languages/en.php
@@ -0,0 +1,49 @@
+<?php
+
+return [
+ 'common_header' => 'PHP 8.3 is a major update of the PHP language. It
contains many new features, such as explicit typing of class constants, deep-cloning of readonly
properties and additions to the randomness functionality. As always it also includes performance
improvements, bug fixes and general cleanup.',
+ 'documentation' => 'Doc',
+ 'main_title' => 'Released!',
+ 'main_subtitle' => 'PHP 8.3 is a major update of the PHP language.<br
class="display-none-md">It contains many new features, such as explicit typing of class
constants, deep-cloning of readonly properties and additions to the randomness functionality. As
always it also includes performance improvements, bug fixes and general cleanup.',
+ 'upgrade_now' => 'Upgrade to PHP 8.3 now!',
+
+ 'readonly_title' => 'Deep-cloning of readonly properties',
+ 'readonly_description' => '<code>readonly</code> properties may
now be modified once within the magic <code>__clone</code> method to enable deep-cloning
of readonly properties.',
+ 'json_validate_title' => 'New <code>json_validate()</code>
function',
+ 'json_validate_description' => '<code>json_validate()</code>
allows to check if a string is syntactically valid JSON, while being more efficient than
<code>json_decode()</code>.',
+ 'typed_class_constants_title' => 'Typed class constants',
+ 'override_title' => 'New <code>#[\Override]</code>
attribute',
+ 'override_description' => 'By adding the
<code>#[\Override]</code> attribute to a method, PHP will ensure that a method with the
same name exists in a parent class or in an implemented interface. Adding the attribute makes it
clear that overriding a parent method is intentional and simplifies refactoring, because the removal
of an overridden parent method will be detected.',
+ 'randomizer_getbytesfromstring_title' => 'New <code>Randomizer<span
style="word-break: break-all;">::</span>getBytesFromString()</code>
method',
+ 'randomizer_getbytesfromstring_description' => 'The <a
href="/releases/8.2/en.php#random_extension">Random Extension</a> that was added
in PHP 8.2 was extended by a new method to generate random strings consisting of specific bytes
only. This method allows to easily generate random identifiers, such as domain names, and numeric
strings of arbitrary length.',
+ 'randomizer_getfloat_nextfloat_title' => 'New
<code>Randomizer::getFloat()</code> and <code>Randomizer::nextFloat()</code>
methods',
+ 'randomizer_getfloat_nextfloat_description' => '<p>Due to the limited
precision and implicit rounding of floating point numbers, generating an unbiased float lying within
a specific interval is non-trivial and the commonly used userland solutions may generate biased
results or numbers outside the requested range.</p><p>The Randomizer was also extended
with two methods to generate random floats in an unbiased fashion. The
<code>Randomizer::getFloat()</code> method uses the γ-section algorithm that was
published in <a href="https://doi.org/10.1145/3503512"
target="_blank" rel="noopener noreferrer">Drawing Random Floating-Point
Numbers from an Interval. Frédéric Goualard, ACM Trans. Model. Comput. Simul., 32:3,
2022.</a></p>',
+ 'dynamic_class_constant_fetch_title' => 'Dynamic class constant fetch',
+
+ 'new_classes_title' => 'New Classes, Interfaces, and Functions',
+ 'new_dom' => 'New <a
href="/manual/en/domelement.getattributenames.php"><code>DOMElement::getAttributeNames()</code></a>,
<a
href="/manual/en/domelement.insertadjacentelement.php"><code>DOMElement::insertAdjacentElement()</code></a>,
<a
href="/manual/en/domelement.insertadjacenttext.php"><code>DOMElement::insertAdjacentText()</code></a>,
<a
href="/manual/en/domelement.toggleattribute.php"><code>DOMElement::toggleAttribute()</code></a>,
<a
href="/manual/en/domnode.contains.php"><code>DOMNode::contains()</code></a>,
<a
href="/manual/en/domnode.getrootnode.php"><code>DOMNode::getRootNode()</code></a>,
<a
href="/manual/en/domnode.isequalnode.php"><code>DOMNode::isEqualNode()</code></a>,
<code>DOMNameSpaceNode::contains()</code>, and <a
href="/manual/en/domparentnode.replacechildren.php"><code>DOMParentNode::replaceChildren()</code></a>
methods.',
+ 'new_intl' => 'New <a
href="/manual/en/intlcalendar.setdate.php"><code>IntlCalendar::setDate()</code></a>,
<a
href="/manual/en/intlcalendar.setdatetime.php"><code>IntlCalendar::setDateTime()</code></a>,
<a
href="/manual/en/intlgregoriancalendar.createfromdate.php"><code>IntlGregorianCalendar::createFromDate()</code></a>,
and <a
href="/manual/en/intlgregoriancalendar.createfromdatetime.php"><code>IntlGregorianCalendar::createFromDateTime()</code></a>
methods.',
+ 'new_ldap' => 'New <code>ldap_connect_wallet()</code>, and
<code>ldap_exop_sync()</code> functions.',
+ 'new_mb_str_pad' => 'New <a
href="/manual/en/function.mb-str-pad.php"><code>mb_str_pad()</code></a>
function.',
+ 'new_posix' => 'New <a
href="/manual/en/function.posix-sysconf.php"><code>posix_sysconf()</code></a>,
<a
href="/manual/en/function.posix-pathconf.php"><code>posix_pathconf()</code></a>,
<a
href="/manual/en/function.posix-fpathconf.php"><code>posix_fpathconf()</code></a>,
and <a
href="/manual/en/function.posix-eaccess.php"><code>posix_eaccess()</code></a>
functions.',
+ 'new_reflection' => 'New <a
href="/manual/en/reflectionmethod.createfrommethodname.php"><code>ReflectionMethod::createFromMethodName()</code></a>
method.',
+ 'new_socket' => 'New <a
href="/manual/en/function.socket-atmark.php"><code>socket_atmark()</code></a>
function.',
+ 'new_str' => 'New <a
href="/manual/en/function.str-increment.php"><code>str_increment()</code></a>,
<a
href="/manual/en/function.str-decrement.php"><code>str_decrement()</code></a>,
and <a
href="/manual/en/function.stream-context-set-option.php"><code>stream_context_set_options()</code></a>
functions.',
+ 'new_ziparchive' => 'New <a
href="/manual/en/ziparchive.getarchiveflag.php"><code>ZipArchive::getArchiveFlag()</code></a>
method.',
+ 'new_openssl_ec' => 'Support for generation EC keys with custom EC parameters
in OpenSSL extension.',
+ 'new_ini' => 'New INI setting <a
href="/manual/en/migration83.other-changes.php#migration83.other-changes.ini"><code>zend.max_allowed_stack_size</code></a>
to set the maximum allowed stack size.',
+
+ 'bc_title' => 'Deprecations and backward compatibility breaks',
+ 'bc_datetime' => 'More Appropriate Date/Time Exceptions.',
+ 'bc_arrays' => 'Assigning a negative index <code>n</code> to an
empty array will now make sure that the next index is <code>n + 1</code> instead of
<code>0</code>.',
+ 'bc_range' => 'Changes to the <code>range()</code>
function.',
+ 'bc_traits' => 'Changes in re-declaration of static properties in
traits.',
+ 'bc_umultipledecimalseparators' => 'The
<code>U_MULTIPLE_DECIMAL_SEPERATORS</code> constant is deprecated in favor of
<code>U_MULTIPLE_DECIMAL_SEPARATORS</code>.',
+ 'bc_mtrand' => 'The <a
href="/manual/en/random.constants.php#constant.mt-rand-php"><code>MT_RAND_PHP</code></a>
Mt19937 variant is deprecated.',
+ 'bc_reflection' => '<a
href="/manual/en/reflectionclass.getstaticproperties.php"><code>ReflectionClass::getStaticProperties()</code></a>
is no longer nullable.',
+ 'bc_ini' => 'INI settings <a
href="/manual/en/info.configuration.php#ini.assert.active"><code>assert.active</code></a>,
<a
href="/manual/en/info.configuration.php#ini.assert.bail"><code>assert.bail</code></a>,
<a
href="/manual/en/info.configuration.php#ini.assert.callback"><code>assert.callback</code></a>,
<a
href="/manual/en/info.configuration.php#ini.assert.exception"><code>assert.exception</code></a>,
and <a
href="/manual/en/info.configuration.php#ini.assert.warning"><code>assert.warning</code></a>
have been deprecated.',
+
+ 'footer_title' => 'Better performance, better syntax, improved type
safety.',
+ 'footer_description' => '<p>For source downloads of PHP 8.3 please
visit the <a href="/downloads">downloads</a> page. Windows binaries can be
found on the <a href="https://windows.php.net/download">PHP for
Windows</a> site. The list of changes is recorded in the <a
href="/ChangeLog-8.php#PHP_8_3">ChangeLog</a>.</p>
+ <p>The <a href="/manual/en/migration83.php">migration guide</a>
is available in the PHP Manual. Please consult it for a detailed list of new features and
backward-incompatible changes.</p>',
+];
diff --git a/releases/8.3/languages/ru.php b/releases/8.3/languages/ru.php
new file mode 100644
index 0000000000..cef2e7e8fd
--- /dev/null
+++ b/releases/8.3/languages/ru..php
@@ -0,0 +1,49 @@
+<?php
+
+return [
+ 'common_header' => 'PHP 8.3 — большое обновление
языка PHP. Оно содержит множество новых возможностей,
таких как явная типизация констант классов, глубокое
клонирование readonly-свойств, а также улучшения класса
Randomizer. Как всегда, в нём также улучшена
производительность, исправлены ошибки и многое
другое.',
+ 'documentation' => 'Документация',
+ 'main_title' => 'выпущен!',
+ 'main_subtitle' => 'PHP 8.3 — большое обновление
языка PHP.<br class="display-none-md">Оно содержит
множество новых возможностей, таких как явная
типизация констант классов, глубокое клонирование
readonly-свойств, а также улучшения класса Randomizer. Как
всегда, в нём также улучшена производительность,
исправлены ошибки и многое другое.',
+ 'upgrade_now' => 'Переходите на PHP 8.3!',
+
+ 'readonly_title' => 'Глубокое клонирование
readonly-свойств',
+ 'readonly_description' => 'Свойства, доступные только
для чтения (<code>readonly</code>) теперь могут быть
изменены один раз с помощью магического метода
<code>__clone</code> для обеспечения возможности
глубокого клонирования readonly-свойств.',
+ 'json_validate_title' => 'Новая функция
<code>json_validate()</code>',
+ 'json_validate_description' => 'Функция
<code>json_validate()</code> позволяет проверить, является
ли строка синтаксически корректным JSON, при этом она
более эффективна, чем функция
<code>json_decode()</code>.',
+ 'typed_class_constants_title' => 'Типизированные
константы классов',
+ 'override_title' => 'Новый атрибут
<code>#[\Override]</code>',
+ 'override_description' => 'Добавив методу атрибут
<code>#[\Override]</code>, PHP убедится, что метод с таким же
именем существует в родительском классе или в
реализованном интерфейсе. Добавление атрибута даёт
понять, что переопределение родительского метода
является намеренным, а также упрощает рефакторинг,
поскольку удаление переопределённого родительского
метода будет обнаружено.',
+ 'randomizer_getbytesfromstring_title' => 'Новый метод
<code>Randomizer<span style="word-break:
break-all;">::</span>getBytesFromString()</code>',
+ 'randomizer_getbytesfromstring_description' => '<a
href="/releases/8.2/ru.php#random_extension">Модуль Random</a>,
добавленный в PHP 8.2, был дополнен новым методом
генерации случайных строк, состоящих только из
определённых байтов. Этот метод позволяет легко
генерировать случайные идентификаторы, например,
имена доменов и числовые строки произвольной
длины.',
+ 'randomizer_getfloat_nextfloat_title' => 'Новые методы
<code>Randomizer::getFloat()</code> и
<code>Randomizer::nextFloat()</code>',
+ 'randomizer_getfloat_nextfloat_description' => '<p>Из-за
ограниченной точности и неявного округления чисел с
плавающей точкой генерация несмещённого числа,
лежащего в определённом интервале, является
нетривиальной задачей, а пользовательские решения
могут давать смещённые результаты или числа,
выходящие за пределы требуемого
диапазона.</p><p>Класс Randomizer был расширен двумя
методами, позволяющими генерировать случайные числа с
плавающей точкой несмещённым образом. Метод
<code>Randomizer::getFloat()</code> использует алгоритм
γ-секции, который был опубликован в <a href="https://doi.org/10.1145/3503512"
target="_blank" rel="noopener noreferrer">Drawing Random Floating-Point
Numbers from an Interval. Frédéric Goualard, ACM Trans. Model. Comput. Simul., 32:3,
2022.</a></p>',
+ 'dynamic_class_constant_fetch_title' => 'Динамическое
получение констант класса',
+
+ 'new_classes_title' => 'Новые классы, интерфейсы и
функции',
+ 'new_dom' => 'Новые методы <a
href="/manual/ru/domelement.getattributenames.php"><code>DOMElement::getAttributeNames()</code></a>,
<a
href="/manual/ru/domelement.insertadjacentelement.php"><code>DOMElement::insertAdjacentElement()</code></a>,
<a
href="/manual/ru/domelement.insertadjacenttext.php"><code>DOMElement::insertAdjacentText()</code></a>,
<a
href="/manual/ru/domelement.toggleattribute.php"><code>DOMElement::toggleAttribute()</code></a>,
<a
href="/manual/ru/domnode.contains.php"><code>DOMNode::contains()</code></a>,
<a
href="/manual/ru/domnode..getrootnode.php"><code>DOMNode::getRootNode()</code></a>,
<a
href="/manual/ru/domnode.isequalnode.php"><code>DOMNode::isEqualNode()</code></a>,
<code>DOMNameSpaceNode::contains()</code> и <a
href="/manual/ru/domparentnode.replacechildren.php"><code>DOMParentNode::replaceChildren()</code></a>.',
+ 'new_intl' => 'Новые методы <a
href="/manual/ru/intlcalendar.setdate.php"><code>IntlCalendar::setDate()</code></a>,
<a
href="/manual/ru/intlcalendar.setdatetime.php"><code>IntlCalendar::setDateTime()</code></a>,
<a
href="/manual/ru/intlgregoriancalendar.createfromdate.php"><code>IntlGregorianCalendar::createFromDate()</code></a>
и <a
href="/manual/ru/intlgregoriancalendar.createfromdatetime.php"><code>IntlGregorianCalendar::createFromDateTime()</code></a>.',
+ 'new_ldap' => 'Новые функции
<code>ldap_connect_wallet()</code> и <code>ldap_exop_sync()</code>.',
+ 'new_mb_str_pad' => 'Новая функция <a
href="/manual/ru/function.mb-str-pad.php"><code>mb_str_pad()</code></a>.',
+ 'new_posix' => 'Новые функции <a
href="/manual/ru/function.posix-sysconf.php"><code>posix_sysconf()</code></a>,
<a
href="/manual/ru/function.posix-pathconf.php"><code>posix_pathconf()</code></a>,
<a
href="/manual/ru/function.posix-fpathconf.php"><code>posix_fpathconf()</code></a>
и <a
href="/manual/ru/function.posix-eaccess.php"><code>posix_eaccess()</code></a>.',
+ 'new_reflection' => 'Новый метод <a
href="/manual/ru/reflectionmethod.createfrommethodname.php"><code>ReflectionMethod::createFromMethodName()</code></a>.',
+ 'new_socket' => 'Новая функция <a
href="/manual/ru/function.socket-atmark.php"><code>socket_atmark()</code></a>.',
+ 'new_str' => 'Новые функции <a
href="/manual/ru/function.str-increment.php"><code>str_increment()</code></a>,
<a
href="/manual/ru/function.str-decrement.php"><code>str_decrement()</code></a>
и <a
href="/manual/ru/function.stream-context-set-option.php"><code>stream_context_set_options()</code></a>.',
+ 'new_ziparchive' => 'Новый метод <a
href="/manual/ru/ziparchive.getarchiveflag.php"><code>ZipArchive::getArchiveFlag()</code></a>.',
+ 'new_openssl_ec' => 'Поддержка генерации EC-ключей с
пользовательскими EC-параметрами в модуле OpenSSL.',
+ 'new_ini' => 'Новый параметр INI <a
href="/manual/ru/migration83.other-changes.php#migration83.other-changes.ini"><code>zend.max_allowed_stack_size</code></a>
для установки максимально допустимого размера
стека.',
+
+ 'bc_title' => 'Устаревшая функциональность и
изменения в обратной совместимости',
+ 'bc_datetime' => 'Более подходящие исключения в
модуле Date/Time.',
+ 'bc_arrays' => 'Присвоение отрицательного
индекса <code>n</code> пустому массиву теперь
гарантирует, что следующим индексом будет <code>n +
1</code>, а не <code>0</code>.',
+ 'bc_range' => 'Изменения в функции
<code>range()</code>.',
+ 'bc_traits' => 'Изменения в повторном объявлении
статических свойств в трейтах.',
+ 'bc_umultipledecimalseparators' => 'Константа
<code>U_MULTIPLE_DECIMAL_SEPERATORS</code> объявлена устаревшей,
вместо неё рекомендуется использовать константу
<code>U_MULTIPLE_DECIMAL_SEPARATORS</code>.',
+ 'bc_mtrand' => 'Вариант Mt19937 <a
href="/manual/ru/random.constants.php#constant.mt-rand-php"><code>MT_RAND_PHP</code></a>
объявлен устаревшим.',
+ 'bc_reflection' => '<a
href="/manual/ru/reflectionclass.getstaticproperties.php"><code>ReflectionClass::getStaticProperties()</code></a>
теперь не возвращает значение <code>null</code>.',
+ 'bc_ini' => 'Параметры INI <a
href="/manual/ru/info.configuration.php#ini.assert.active"><code>assert.active</code></a>,
<a
href="/manual/ru/info.configuration.php#ini.assert.bail"><code>assert.bail</code></a>,
<a
href="/manual/ru/info.configuration.php#ini.assert.callback"><code>assert.callback</code></a>,
<a
href="/manual/ru/info.configuration.php#ini.assert.exception"><code>assert.exception</code></a>
и <a
href="/manual/ru/info.configuration.php#ini.assert.warning"><code>assert.warning</code></a>
объявлены устаревшими.',
+
+ 'footer_title' => 'Выше производительность, лучше
синтаксис, надёжнее система типов.',
+ 'footer_description' => '<p>Для загрузки исходного
кода PHP 8.3 посетите страницу <a
href="/downloads">Downloads</a>. Бинарные файлы Windows
находятся на сайте <a href="https://windows.php.net/download">PHP for
Windows</a>. Список изменений перечислен на странице <a
href="/ChangeLog-8.php#PHP_8_3">ChangeLog</a>.</p>
+ <p><a href="/manual/ru/migration83.php">Руководство по
миграции</a> доступно в разделе документации.
Ознакомьтесь с ним, чтобы узнать обо всех новых
возможностях и изменениях, затрагивающих обратную
совместимость.</p>',
+];
diff --git a/releases/8.3/release.inc b/releases/8.3/release.inc
new file mode 100644
index 0000000000..501f873067
--- /dev/null
+++ b/releases/8.3/release.inc
@@ -0,0 +1,494 @@
+<?php
+
+use function releases\php83\common_header;
+use function releases\php83\language_chooser;
+use function releases\php83\language_redirect;
+use function releases\php83\message;
+
+if (!isset($lang)) {
+ $lang = 'en';
+}
+
+$_SERVER['BASE_PAGE'] = 'releases/8.3/' . $lang . '.php';
+
+include_once __DIR__ . '/common.php';
+
+language_redirect($lang);
+
+common_header(message('common_header', $lang));
+
+?>
+ <section class="php8-section php8-section_dark php8-section_header center">
+ <div class="page-tools">
+ <div class="change-language">
+ <?php language_chooser($lang); ?>
+ </div>
+ </div>
+ <div class="php8-section__content">
+ <div class="php8-logo">
+ <img src="/images/php8/logo_php8_3.svg" alt="PHP 8.3"
height="126" width="343">
+ </div>
+ <div class="php8-title"><?= message('main_title', $lang)
?></div>
+ <div class="php8-subtitle"><?= message('main_subtitle',
$lang) ?></div>
+ <div class="php8-button-wrapper center">
+ <a class="php8-button php8-button_light"
href="/downloads"><?= message('upgrade_now', $lang) ?></a>
+ </div>
+ </div>
+ </section>
+
+ <section class="php8-section center">
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="typed_class_constants">
+ <?= message('typed_class_constants_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/typed_class_constants">RFC</a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+interface I {
+ // We may naively assume that the PHP constant is always a string.
+ const PHP = 'PHP 8.2';
+}
+
+class Foo implements I {
+ // But implementing classes may define it as an array.
+ const PHP = [];
+}
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+interface I {
+ const string PHP = 'PHP 8.3';
+}
+
+class Foo implements I {
+ const string PHP = [];
+}
+
+// Fatal error: Cannot use array as value for class constant
+// Foo::PHP of type string
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="dynamic_class_constant_fetch">
+ <?= message('dynamic_class_constant_fetch_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/dynamic_class_constant_fetch">RFC</a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+class Foo {
+ const PHP = 'PHP 8.2';
+}
+
+$searchableConstant = 'PHP';
+
+var_dump(constant(Foo::class . "::{$searchableConstant}"));
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+class Foo {
+ const PHP = 'PHP 8.3';
+}
+
+$searchableConstant = 'PHP';
+
+var_dump(Foo::{$searchableConstant});
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="override_attribute">
+ <?= message('override_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/marking_overriden_methods">RFC</a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+use PHPUnit\Framework\TestCase;
+
+final class MyTest extends TestCase
+{
+ protected $logFile;
+
+ protected function setUp(): void
+ {
+ $this->logFile = fopen('/tmp/logfile', 'w');
+ }
+
+ protected function taerDown(): void
+ {
+ fclose($this->logFile);
+ unlink('/tmp/logfile');
+ }
+}
+
+// The log file will never be removed, because the
+// method name was mistyped (taerDown vs tearDown).
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+use PHPUnit\Framework\TestCase;
+
+final class MyTest extends TestCase
+{
+ protected $logFile;
+
+ protected function setUp(): void
+ {
+ $this->logFile = fopen('/tmp/logfile', 'w');
+ }
+
+ #[\Override]
+ protected function taerDown(): void
+ {
+ fclose($this->logFile);
+ unlink('/tmp/logfile');
+ }
+}
+
+// Fatal error: MyTest::taerDown() has #[\Override] attribute,
+// but no matching parent method exists
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+
+ <div class="php8-compare__content">
+ <?= message('override_description', $lang) ?>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="readonly_classes">
+ <?= message('readonly_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/readonly_amendments">RFC</a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+readonly class Foo {
+ public \DateTime $dateTime;
+
+ function __construct(\DateTime $dateTime) {
+ $this->dateTime = $dateTime;
+ }
+
+ public function __clone()
+ {
+ $this->dateTime = clone $this->dateTime;
+ }
+}
+
+$today = new Foo(new \DateTime());
+$tomorrow = clone $today;
+
+// Fatal error: Cannot modify readonly property Foo::$dateTime
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+readonly class Foo {
+ public \DateTime $dateTime;
+
+ function __construct(\DateTime $dateTime) {
+ $this->dateTime = $dateTime;
+ }
+
+ public function __clone()
+ {
+ $this->dateTime = clone $this->dateTime;
+ }
+}
+
+$today = new Foo(new \DateTime());
+$tomorrow = clone $today;
+
+$tomorrow->dateTime->modify('+1 day');
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+ <div class="php8-compare__content">
+ <?= message('readonly_description', $lang) ?>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="json_validate">
+ <?= message('json_validate_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/json_validate">RFC</a>
+ <a class="php8-rfc" href="/manual/<?= $lang
?>/function.json-validate.php"><?= message('documentation', $lang)
?></a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+function json_validate(string $string): bool {
+ json_decode($string);
+ return json_last_error() === JSON_ERROR_NONE;
+}
+
+var_dump(json_validate('{ "test": { "foo": "bar" } }')); //
true
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+var_dump(json_validate('{ "test": { "foo": "bar" } }')); //
true
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+ <div class="php8-compare__content">
+ <?= message('json_validate_description', $lang) ?>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="randomizer_get_bytes_from_string">
+ <?= message('randomizer_getbytesfromstring_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/randomizer_additions#getbytesfromstring">RFC</a>
+ <a class="php8-rfc" href="/manual/<?= $lang
?>/random-randomizer.getbytesfromstring.php"><?= message('documentation',
$lang) ?></a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+// This function needs to be manually implemented.
+function getBytesFromString(string $string, int $length) {
+ $stringLength = strlen($string);
+
+ $result = '';
+ for ($i = 0; $i < $length; $i++) {
+ // random_int is not seedable for testing, but secure.
+ $result .= $string[random_int(0, $stringLength - 1)]);
+ }
+
+ return $result;
+}
+
+$randomDomain = sprintf(
+ "%s.example.com",
+ getBytesFromString(
+ 'abcdefghijklmnopqrstuvwxyz0123456789',
+ 16,
+ ),
+);
+
+echo $randomDomain;
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+// A \Random\Engine may be passed for seeding,
+// the default is the secure engine.
+$randomizer = new \Random\Randomizer();
+
+$randomDomain = sprintf(
+ "%s.example.com",
+ $randomizer->getBytesFromString(
+ 'abcdefghijklmnopqrstuvwxyz0123456789',
+ 16,
+ ),
+);
+
+echo $randomDomain;
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+
+ <div class="php8-compare__content">
+ <?= message('randomizer_getbytesfromstring_description', $lang) ?>
+ </div>
+ </div>
+
+ <div class="php8-compare">
+ <h2 class="php8-h2" id="randomizer_get_float">
+ <?= message('randomizer_getfloat_nextfloat_title', $lang) ?>
+ <a class="php8-rfc" href="https://wiki.php.net/rfc/randomizer_additions#getfloat">RFC</a>
+ <a class="php8-rfc" href="/manual/<?= $lang
?>/random-randomizer.getfloat.php"><?= message('documentation', $lang)
?></a>
+ </h2>
+ <div class="php8-compare__main">
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label">PHP < 8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+// Returns a random float between $min and $max, both including.
+function getFloat(float $min, float $max) {
+ // This algorithm is biased for specific inputs and may
+ // return values outside the given range. This is impossible
+ // to work around in userland.
+ $offset = random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
+ return $offset * ($max - $min) + $min;
+}
+
+$temperature = getFloat(-89.2, 56.7);
+
+$chanceForTrue = 0.1;
+// getFloat(0, 1) might return the upper bound, i.e. 1,
+// introducing a small bias.
+$myBoolean = getFloat(0, 1) < $chanceForTrue;
+PHP
+
+ ); ?>
+ </div>
+ </div>
+ <div class="php8-compare__arrow"></div>
+ <div class="php8-compare__block example-contents">
+ <div class="php8-compare__label php8-compare__label_new">PHP
8.3</div>
+ <div class="php8-code phpcode">
+ <?php highlight_php_trimmed(
+ <<<'PHP'
+$randomizer = new \Random\Randomizer();
+
+$temperature = $randomizer->getFloat(
+ -89.2,
+ 56.7,
+ \Random\IntervalBoundary::ClosedClosed,
+);
+
+$chanceForTrue = 0.1;
+// Randomizer::nextFloat() is equivalent to
+// Randomizer::getFloat(0, 1, \Random\IntervalBoundary::ClosedOpen).
+// The upper bound, i.e. 1, will not be returned.
+$myBoolean = $randomizer->nextFloat() < $chanceForTrue;
+PHP
+ ); ?>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="php8-compare__content">
+ <?= message('randomizer_getfloat_nextfloat_description', $lang) ?>
+ </div>
+
+
+ </section>
+
+ <section class="php8-section center php8-section_light php8-columns">
+ <div class="php8-column">
+ <h2 class="php8-h2" id="other_new_things"><?=
message('new_classes_title', $lang) ?></h2>
+ <div class="php8-compare__content php8-compare__content--block">
+ <ul>
+ <li><?= message('new_dom', $lang) ?></li>
+ <li><?= message('new_intl', $lang) ?></li>
+ <li><?= message('new_ldap', $lang) ?></li>
+ <li><?= message('new_mb_str_pad', $lang) ?></li>
+ <li><?= message('new_posix', $lang) ?></li>
+ <li><?= message('new_reflection', $lang) ?></li>
+ <li><?= message('new_socket', $lang) ?></li>
+ <li><?= message('new_str', $lang) ?></li>
+ <li><?= message('new_ziparchive', $lang) ?></li>
+ <li><?= message('new_openssl_ec', $lang) ?></li>
+ <li><?= message('new_ini', $lang) ?></li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="php8-column">
+ <h2 class="php8-h2" id="deprecations_and_bc_breaks"><?=
message('bc_title', $lang) ?></h2>
+ <div class="php8-compare__content">
+ <ul>
+ <li><?= message('bc_datetime', $lang) ?></li>
+ <li><?= message('bc_arrays', $lang) ?></li>
+ <li><?= message('bc_range', $lang) ?></li>
+ <li><?= message('bc_traits', $lang) ?></li>
+ <li><?= message('bc_umultipledecimalseparators', $lang)
?></li>
+ <li><?= message('bc_mtrand', $lang) ?></li>
+ <li><?= message('bc_reflection', $lang) ?></li>
+ <li><?= message('bc_ini', $lang) ?></li>
+ </ul>
+ </div>
+ </div>
+ </section>
+
+ <section class="php8-section php8-section_dark php8-section_footer
php8-footer">
+ <div class="php8-section__content">
+ <h2 class="php8-h2 center"><?= message('footer_title',
$lang) ?></h2>
+ <div class="php8-button-wrapper center">
+ <a class="php8-button php8-button_light"
href="/downloads"><?= message('upgrade_now', $lang) ?></a>
+ </div>
+ <div class="php8-footer__content"><?=
message('footer_description', $lang) ?></div>
+ </div>
+ </section>
+
+<?php
+
+site_footer();
diff --git a/releases/8.3/ru.php b/releases/8.3/ru..php
new file mode 100644
index 0000000000..4aefaf9a8c
--- /dev/null
+++ b/releases/8.3/ru.php
@@ -0,0 +1,5 @@
+<?php
+
+$lang = 'ru';
+
+include_once __DIR__ . '/release.inc';