1. Backward Incompatible Changes
========================================
-Core:
- . The ext_skel utility has been completely redesigned with new options and
- some old options removed. This is now written in PHP and has no external
- dependencies.
- . Support for BeOS has been dropped.
- . Exceptions thrown due to automatic conversion of warnings into exceptions
- in EH_THROW mode (e.g. some DateTime exceptions) no longer populate
- error_get_last() state. As such, they now work the same way as manually
- thrown exceptions.
- . TypeError now reports wrong types as `int` and `bool` instead of `integer`
- and `boolean`.
- . Due to the introduction of flexible heredoc/nowdoc syntax (see New Features
- section), doc strings that contain the ending label inside their body may
- cause syntax errors or change in interpretation. For example in
-
- $str = <<<FOO
- abcdefg
- FOO
- FOO;
-
- the indented occurrence of "FOO" did not previously have any special
- meaning. Now it will be interpreted as the end of the heredoc string and
- the following "FOO;" will cause a syntax error. This issue can always be
- resolved by choosing an ending label that does not occur within the contents
- of the string.
- . "continue" statements targeting "switch" control flow structures will now
- generate a warning. In PHP such "continue" statements are equivalent to
- "break", while they behave as "continue 2" in other languages.
-
- while ($foo) {
- switch ($bar) {
- case "baz":
- continue;
- // Warning: "continue" targeting switch is equivalent to
- // "break". Did you mean to use "continue 2"?
- }
- }
+- Core:
+ . Trying to use values of type null, bool, int, float or resource as an
+ array (such as $null["key"]) will now generate a notice. This does not
+ affect array accesses performed by list().
+ RFC: https://wiki.php.net/rfc/notice-for-non-valid-array-container
+ . get_declared_classes() no longer returns anonymous classes that haven't
+ been instantiated yet.
+ . "fn" is now a reserved keyword. In particular, it can no longer be used as a
+ function or class name. It can still be used as a method or class constant
+ name.
+ . Passing the result of a (non-reference) list() assignment by reference is
+ consistently disallowed now. Previously this worked if the right-hand side
+ was a simple (CV) variable and did not occur as part of the list().
+ . `<?php` at the end of the file (without trailing newline) will now be
+ interpreted as an opening PHP tag. Previously it was interpreted either as
+ `<? php` and resulted in a syntax error (with short_open_tag=1) or was
+ interpreted as a literal `<?php` string (with short_open_tag=0).
+ . When using include/require on a stream, stream_set_option() will be invoked
+ with the STREAM_OPTION_READ_BUFFER option. Custom stream wrapper
+ implementations may need to implement the stream_set_option() method to
+ avoid a warning (always returning false is a sufficient implementation).
+ . The "creating default object from empty value" warning is now consistently
+ thrown if a falsy value is promoted into an stdClass object. Previously some
+ cases like `$null->prop[0] = $val` missed this warning.
+ . Previously get_declared_classes() always returned parent classes before
+ child classes. This is no longer the case. No particular order is guaranteed
+ for the get_declared_classes() return value.
+
+- BCMath:
+ . BCMath functions will now warn if a non well-formed number is passed, such
+ as "32foo". The argument will be interpreted as zero (as before).
+
+- Curl:
+ . Attempting to serialize a CURLFile class will now generate an exception.
+ Previously the exception was only thrown on unserialization.
+ . Using CURLPIPE_HTTP1 is deprecated, and is no longer supported as of cURL
+ 7.62.0.
+ . The $version parameter of curl_version() is deprecated. If any value not
+ equal to the default CURLVERSION_NOW is passed, a warning is raised and the
+ parameter is ignored.
+
+- Date:
+ . Calling var_dump() or similar on a DateTime(Immutable) instance will no
+ longer leave behind accessible properties on the object.
+ . Comparison of DateInterval objects (using ==, < and so on) will now generate
+ a warning and always return false. Previously all DateInterval objects were
+ considered equal, unless they had properties.
+
++DOM:
++ . As of PHP 7.4.4, the value of the $childNodes property of DOMDocument,
++ DOMNode, DOMProcessingInstruction, DOMComment, DOMText, DOMCdataSection and
++ DOMNotation is now an empty DOMNodeList instead of NULL, according to the
++ W3C and WHATWG standards and the PHP manual.
++
+- Intl:
+ . The default parameter value of idn_to_ascii() and idn_to_utf8() is now
+ INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.
+
+- MySQLi:
+ . The embedded server functionality has been removed. It was broken since
+ at least PHP 7.0.
+ . The undocumented mysqli::$stat property has been removed in favor of
+ mysqli::stat().
+
+- Openssl:
+ . The openssl_random_pseudo_bytes() function will now throw an exception in
+ error situations, similar to random_bytes(). In particular, an Error is
+ thrown if the number of requested bytes is less than *or equal to* zero,
+ and an Exception is thrown if sufficient randomness cannot be gathered.
+ The $crypto_strong output argument is guaranteed to always be true if the
+ function does not throw, so explicitly checking it is not necessary.
+ RFC: http://php.net/manual/de/function.openssl-random-pseudo-bytes.php
+
+- Pcntl:
+ . The $restart_syscalls flag for pcntl_signal() will now be respected for
+ SIGALARM. Previously it was hardcoded to false. To reduce the backwards
+ compatibility impact, the default for SIGALARM will remain false however.
+
+- PCRE:
+ . When PREG_UNMATCHED_AS_NULL mode is used, trailing unmatched capturing
+ groups will now also be set to null (or [null, -1] if offset capture is
+ enabled). This means that the size of the $matches will always be the same.
+
+- PEAR:
+ . Installation of PEAR (including PECL) is no longer enabled by default. It
+ can be explicitly enabled using --with-pear. This option is deprecated and
+ may be removed in the future.
+
+- PDO:
+ . Attempting to serialize a PDO or PDOStatement instance will now generate
+ an Exception rather than a PDOException, consistent with other internal
+ classes which do not support serialization.
+
+- Reflection:
+ . Reflection objects will now generate an exception if an attempt is made
+ to serialize them. Serialization for reflection objects was never
+ supported and resulted in corrupted reflection objects. It has been
+ explicitly prohibited now.
+ . The signature of the ReflectionMethod::getClosure() method changed to
+ account for existing behavior with static methods:
+ Before: ReflectionMethod::getClosure($object)
+ After: ReflectionMethod::getClosure($object = null)
+ The new signature is also (LSP) compatible with older PHP versions.
+
+- SPL:
+ . Calling get_object_vars() on an ArrayObject instance will now always return
+ the properties of the ArrayObject itself (or a subclass). Previously it
+ returned the values of the wrapped array/object unless the STD_PROP_LIST
+ flag was specified. Other affected operations are:
+
+ * ReflectionObject::getProperties()
+ * reset(), current(), etc. Use Iterator methods instead.
+ * Potentially others working on object properties as a list.
+ * Other internal functions that iterate over an array, but which
+ previously silently accepted an ArrayObject as well; eg curl_setopt()
+ when used with an option that expects an array.
+
+ (array) casts are *not* affected. They will continue to return either the
+ wrapped array, or the ArrayObject properties, depending on whether the
+ STD_PROP_LIST flag is used.
+ . SplPriorityQueue::setExtractFlags() will throw an exception if zero is
+ passed. Previously this would generate a recoverable fatal error on the
+ next extraction operation.
+ . ArrayObject, ArrayIterator, SplDoublyLinkedList and SplObjectStorage now
+ support the __serialize() + __unserialize() mechanism in addition to the
+ Serializable interface. This means that serialization payloads created on
+ older PHP versions can still be unserialized, but new payloads created by
+ PHP 7.4 will not be understood by older versions.
+
+- Standard:
+ . The "o" serialization format has been removed. As it is never produced by
+ PHP, this may only break unserialization of manually crafted strings.
+ . Password hashing algorithm identifiers are now nullable strings rather
+ than integers.
+
+ * PASSWORD_DEFAULT was int 1; now is null in PHP <7.4.3 and string '2y' afterwards
+ * PASSWORD_BCRYPT was int 1; now is string '2y'
+ * PASSWORD_ARGON2I was int 2; now is string 'argon2i'
+ * PASSWORD_ARGON2ID was int 3; now is string 'argon2id'
+
+ Applications correctly using the constants PASSWORD_DEFAULT,
+ PASSWORD_BCRYPT, PASSWORD_ARGON2I, and PASSWORD_ARGON2ID will continue to
+ function correctly.
+ . htmlentities() will now throw a notice (instead of a strict standards
+ warning) if it is used with an encoding for which only basic entity
+ substitution is supported, in which case it is equivalent to
+ htmlspecialchars().
+ . fread() and fwrite() will now return false if the operation failed.
+ Previously an empty string or 0 was returned. EAGAIN/EWOULDBLOCK are not
+ considered failures.
+ . fread() and fwrite() on plain files will now throw a notice on failure,
+ such as when trying to write to a read-only file resource.
+ . The stream_read() and stream_write() methods on stream wrappers now
+ interpret "false" as a failure return values. If no data is available, but
+ no error occurred, an empty string should be returned instead.
+ . round(-0.0) will now return -0.0 rather than +0.0.
+
+- Tokenizer:
+ . token_get_all() will now emit a T_BAD_CHARACTER token for unexpected
+ characters instead of leaving behind holes in the token stream.
+
+========================================
+2. New Features
+========================================
+
+- Core:
+ . Added support for typed properties. For example:
- . Array accesses of type $obj["123"], where $obj implements ArrayAccess and
- "123" is an integer string literal will no longer result in an implicit
- conversion to integer, i.e., $obj->offsetGet("123") will be called instead
- of $obj->offsetGet(123). This matches existing behavior for non-literals.
- The behavior of arrays is not affected in any way, they continue to
- implicitly convert integeral string keys to integers.
- . In PHP, static properties are shared between inheriting classes, unless the
- static property is explicitly overridden in a child class. However, due to
- an implementation artifact it was possible to separate the static properties
- by assigning a reference. This loophole has been fixed.
-
- class Test {
- public static $x = 0;
+ class User {
+ public int $id;
+ public string $name;
}
- class Test2 extends Test { }
- Test2::$x = &$x;
- $x = 1;
+ This will enforce that $user->id can only be assigned integers and
+ $user->name can only be assigned strings. For more information see the
+ RFC: https://wiki.php.net/rfc/typed_properties_v2
- var_dump(Test::$x, Test2::$x);
- // Previously: int(0), int(1)
- // Now: int(1), int(1)
+ . Added support for arrow functions with implicit by-value scope binding.
+ For example:
- . References returned by array and property accesses are now unwrapped as
- part of the access. This means that it is no longer possible to modify the
- reference between the access and the use of the accessed value:
+ $factor = 10;
+ $nums = array_map(fn($num) => $num * $factor, $nums);
- $arr = [1];
- $ref =& $arr[0];
- var_dump($arr[0] + ($arr[0] = 2));
- // Previously: int(4), Now: int(3)
+ RFC: https://wiki.php.net/rfc/arrow_functions_v2
- This makes the behavior of references and non-references consistent. Please
- note that reading and writing a value inside a single expression remains
- undefined behavior and may change again in the future.
+ . Added support for limited return type covariance and argument type
+ contravariance. The following code will now work:
- . Argument unpacking stopped working with Traversables with non-integer keys.
- The following code worked in PHP 7.0-7.2 by accident.
+ class A {}
+ class B extends A {}
- function foo(...$args) {
- var_dump($args);
+ class Producer {
+ public function method(): A {}
}
- function gen() {
- yield 1.23 => 123;
+ class ChildProducer extends Producer {
+ public function method(): B {}
}
- foo(...gen());
- Now it generates an exception.
+ Full variance support is only available if autoloading is used. Inside a
+ single file only non-cyclic type references are possible, because all
+ classes need to be available before they are referenced.
+ RFC: https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
-BCMath:
- . All warnings thrown by BCMath functions are now using PHP's error handling.
- Formerly some warnings have directly been written to stderr.
- . bcmul() and bcpow() now return numbers with the requested scale. Formerly,
- the returned numbers may have omitted trailing decimal zeroes.
+ . Added support for coalesce assign (??=) operator. For example:
-DOM:
- . As of PHP 7.3.16, the value of the $childNodes property of DOMDocument,
- DOMNode, DOMProcessingInstruction, DOMComment, DOMText, DOMCdataSection and
- DOMNotation is now an empty DOMNodeList instead of NULL, according to the
- W3C and WHATWG standards and the PHP manual.
+ $array['key'] ??= computeDefault();
+ // is roughly equivalent to
+ if (!isset($array['key'])) {
+ $array['key'] = computeDefault();
+ }
-IMAP:
- rsh/ssh logins are disabled by default. Use imap.enable_insecure_rsh if you want
- to enable them. Note that the IMAP library does not filter mailbox names before
- passing them to rsh/ssh command, thus passing untrusted data to this function
- with rsh/ssh enabled is insecure.
-
-MBString:
- . Due to added support for named captures, mb_ereg_*() patterns using named
- captures will behave differently. In particular named captures will be part
- of matches and mb_ereg_replace() will interpret additional syntax. See
- "New Features" section for more information.
-
-mysqli:
- . Prepared statements now properly report the fractional seconds for DATETIME/
- TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
- microseconds). Formerly, the fractional seconds part was simply omitted from
- the returned values.
-
-PDO/MySQL:
- . Prepared statements now properly report the fractional seconds for DATETIME/
- TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
- microseconds). Formerly, the fractional seconds part was simply omitted from
- the returned values.
- Please note that this only affects the usage of PDO_MYSQL with emulated
- prepares turned off (e.g. using the native preparation functionality).
- Statements using connections having PDO::ATTR_EMULATE_PREPARES=true (which
- is the default) were not affected by the bug fixed and have already been
- getting the proper fractional seconds values from the engine.
-
-Reflection:
- . Reflection export to string now uses `int` and `bool` instead of `integer`
- and `boolean`.
-
-SPL:
- . If an SPL autoloader throws an exception, following autoloaders will not be
- executed. Previously all autoloaders were executed and exceptions were
- chained.
-
-SimpleXML:
- . Mathematic operations involving SimpleXML objects will now treat the text as
- an integer or float, whichever is more appropriate. Previously values were
- treated as integers unconditionally.
-
-Standard:
- . Undefined variables passed to compact() will now be reported as a notice.
- . getimagesize() and related functions now report the mime type of BMP images
- as image/bmp instead of image/x-ms-bmp, since the former has been registered
- with the IANA (see RFC 7903).
- . stream_socket_get_name() will now return IPv6 addresses wrapped in brackets.
- For example "[::1]:1337" will be returned instead of "::1:1337".
+ RFC: https://wiki.php.net/rfc/null_coalesce_equal_operator
-========================================
-2. New Features
-========================================
+ . Added support for unpacking inside arrays. For example:
+
+ $arr1 = [3, 4];
+ $arr2 = [1, 2, ...$arr1, 5];
+ // $arr2 == [1, 2, 3, 4, 5]
+
+ RFC: https://wiki.php.net/rfc/spread_operator_for_array
+
+ . Added support for underscore separators in numeric literals. Some examples:
+
+ 6.674_083e-11; // float
+ 299_792_458; // decimal
+ 0xCAFE_F00D; // hexadecimal
+ 0b0101_1111; // binary
+
+ RFC: https://wiki.php.net/rfc/numeric_literal_separator
+
+ . Support for WeakReferences has been added.
+ RFC: https://wiki.php.net/rfc/weakrefs
+
+ . Throwing exceptions from __toString() is now permitted. Previously this
+ resulted in a fatal error. Existing recoverable fatals in string conversions
+ have been converted to Error exceptions.
+ RFC: https://wiki.php.net/rfc/tostring_exceptions
+
+- CURL:
+ . CURLFile now supports stream wrappers in addition to plain file names, if
+ the extension has been built against libcurl >= 7.56.0. The streams may
+ need to be seekable.
+
+- Filter:
+ . The FILTER_VALIDATE_FLOAT filter now supports the min_range and max_range
+ options, with the same semantics as FILTER_VALIDATE_INT.
+
+- FFI:
+ . A new extension which provides a simple way to call native functions, access
+ native variables and create/access data structures defined in C libraries.
+ RFC: https://wiki.php.net/rfc/ffi
+
+- GD:
+ . Added the "scatter" image filter (IMG_FILTER_SCATTER) to apply a scatter
+ filter to images. This filter has the following prototype:
+
+ imagefilter($im, IMG_FILTER_SCATTER, int $sub, int $plus, array $colors = []);
+
+ The $colors array can be populated with a set of indexed colors to
+ apply the scatter pixel shifting on.
+
+ Note, the result of this filter is always random.
+
+- Hash:
+ . Added "crc32c" hash using Castagnoli's polynomial. This crc32 variant is
+ used by storage systems, such as iSCSI, SCTP, Btrfs and ext4.
+
+- Mbstring:
+ . Added mb_str_split() function, which provides the same functionality as
+ str_split(), but operating on code points rather than bytes.
+ RFC: https://wiki.php.net/rfc/mb_str_split
+ . Added mbstring.regex_retry_limit ini setting defaulting to 1000000. It
+ limits the amount of backtracking that may be performed during one mbregex
+ match and thus protects against exponential backtracking attacks (ReDOS).
+ This setting only takes effect when linking against oniguruma >= 6.8.0.
+
+- OPcache:
+ . Support for preloading code has been added.
+ RFC: https://wiki.php.net/rfc/preload
+
+- PCRE:
+ . The preg_replace_callback() and preg_replace_callback_array() functions now
+ accept an additional $flags argument, with support for the
+ PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags. This influences the
+ format of the matches array passed to the callback function.
+
+- PDO:
+ . The username and password can now be specified as part of the PDO DSN for
+ the mysql, mssql, sybase, dblib, firebird and oci drivers. Previously this
+ was only supported by the pgsql driver. If a username/password is specified
+ both in the constructor and the DSN, the constructor takes precedence.
+
+ new PDO("mysql:host=xxx;port=xxx;dbname=xxx;user=xxx;password=xxx");
+
+- PDO_OCI:
+ . PDOStatement::getColumnMeta() is now available
+
+- PDO_SQLite:
+ . PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) allows
+ checking whether the statement is read-only, i.e. if it doesn't modify
+ the database.
+ . PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) enables the
+ use of SQLite3 extended result codes in errorInfo().
+
+- SQLite3:
+ . Added SQLite3::lastExtendedErrorCode() to fetch the last extended result
+ code.
+ . Added SQLite3::enableExtendedResultCodes($enable = true), which will make
+ SQLite3::lastErrorCode() return extended result codes.
+
+- Standard:
+ . strip_tags() now also accepts an array of allowed tags: Instead of
+ strip_tags($str, '<a><p>') you can now write strip_tags($str, ['a', 'p']).
+
+ . A new mechanism for custom object serialization has been added, which
+ uses two new magic methods:
+
+ // Returns array containing all the necessary state of the object.
+ public function __serialize(): array;
+
+ // Restores the object state from the given data array.
+ public function __unserialize(array $data): void;
-Core:
- . Implemented flexible heredoc and nowdoc syntax: The closing marker for doc
- strings is no longer required to be followed by a semicolon or newline.
- Additionally the closing marker may be indented, in which case the
- indentation will be stripped from all lines in the doc string.
- (RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes)
- . Array destructuring now supports reference assignments using the syntax
- [&$a, [$b, &$c]] = $d. The same is also supported for list().
- (RFC: https://wiki.php.net/rfc/list_reference_assignment)
- . instanceof now allows literals as the first operand,
- in which case the result is always FALSE.
- . A new CompileError exception has been added, from which ParseError inherits.
- A small number of compilation errors will now throw a CompileError instead
- of generating a fatal error. Currently this only affects compilation errors
- that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors
- may be converted in the future.
- . Trailing commas in function and method calls are now allowed.
- (RFC: https://wiki.php.net/rfc/trailing-comma-function-calls)
-
-BCMath:
- . bcscale() can now also be used as getter to retrieve the current scale in use.
-
-MBString:
- . Support for full case-mapping and case-folding has been added. Unlike simple
- case-mapping, full case-mapping may change the length of the string. For
- example:
-
- mb_strtoupper("Straße")
- // Produces STRAßE on PHP 7.2
- // Produces STRASSE on PHP 7.3
-
- The different casing mapping and folding modes are available through
- mb_convert_case():
-
- . MB_CASE_LOWER (used by mb_strtolower)
- . MB_CASE_UPPER (used by mb_strtoupper)
- . MB_CASE_TITLE
- . MB_CASE_FOLD
- . MB_CASE_LOWER_SIMPLE
- . MB_CASE_UPPER_SIMPLE
- . MB_CASE_TITLE_SIMPLE
- . MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
-
- Only unconditional, language agnostic full case-mapping is performed.
- . Case-insensitive string operations now use case-folding instead of case-
- mapping during comparisons. This means that more characters will be
- considered (case insensitively) equal now.
- . mb_convert_case() with MB_CASE_TITLE now performs title-case conversion
- based on the Cased and CaseIgnorable derived Unicode properties. In
- particular this also improves handling of quotes and apostophes.
- . Data tables have been updated for Unicode 11.
- . Mbstring now correctly supports strings larger than 2GB.
- . Performance of the mbstring extension has been significantly improved
- across the board. The largest improvements are in case conversion functions.
- . mb_ereg_*() functions now support named captures. Matching functions like
- mb_ereg() will now return named captures both using their group number and
- their name, similar to PCRE:
-
- mb_ereg('(?<word>\w+)', '国', $matches);
- // => [0 => "国", 1 => "国", "word" => "国"];
-
- Additionally, mb_ereg_replace() now supports the \k<> and \k'' notations
- to reference named captures in the replacement string:
-
- mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
- // => "_foo_foo_"
-
- \k<> and \k'' can also be used for numbered references, which also works
- with group numbers greater than 9.
-
-readline:
- . Support for the completion_append_character and completion_suppress_append
- options has been added to readline_info(). These options are only available
- if PHP is linked against libreadline (rather than libedit).
-
-Standard:
- . The --with-password-argon2[=dir] configure argument now provides support for
- both Argon2i and Argon2id hashes in the password_hash(), password_verify(),
- password_get_info(), and password_needs_rehash() functions. Passwords may be
- hashed and verified using the PASSWORD_ARGON2ID constant.
- Support for both Argon2i and Argon2id in the password_* functions now requires
- PHP be linked against libargon2 reference library >= 20161029.
- (RFC: https://wiki.php.net/rfc/argon2_password_hash_enhancements).
-
-LDAP:
- . Full support for LDAP Controls has been added to LDAP querying functions
- and ldap_parse_result
+ The new serialization mechanism supersedes the Serializable interface,
+ which will be deprecated in the future.
+
+ RFC: https://wiki.php.net/rfc/custom_object_serialization
+
+ . A new 'max_depth' option for unserialize(), as well as an
+ unserialize_max_depth ini setting have been added. These control the
+ maximum depth of structures permitted during unserialization, and are
+ intended to prevent stack overflows. The default depth limit is 4096 and
+ can be disabled by setting unserialize_max_depth=0.
+
+ . array_merge() and array_merge_recursive() may now be called without any
+ arguments, in which case they will return an empty array. This is useful
+ in conjunction with the spread operator, e.g. array_merge(...$arrays).
+
+ . proc_open() now accepts an array instead of a string for the command. In
+ this case the process will be opened directly (without going through a
+ shell) and PHP will take care of any necessary argument escaping.
+
+ proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
+
+ . proc_open() now supports "redirect" and "null" descriptors. For example:
+
+ // Like 2>&1 on the shell
+ proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
+ // Like 2>/dev/null or 2>nul on the shell
+ proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
+
+ . password_hash() has argon2i(d) implementations from ext/sodium when PHP is
+ built without libargon.
+
+ RFC: https://wiki.php.net/rfc/sodium.argon.hash
========================================
3. Changes in SAPI modules