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 < 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'; -- PHP Webmaster List Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php