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 <timwo...@googlemail.com>
Co-authored-by: Roman Pronskiy <r...@pronskiy.com>
Co-authored-by: Jakub Zelenka <bu...@php.net>
Co-authored-by: Tim Düsterhus <t...@bastelstu.be>
Co-authored-by: Tim Bond <cookieg...@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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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';


--
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to