PHP 8.6 INTERNALS UPGRADE NOTES

1. Internal API changes

2. Build system changes

3. Module changes

4. OpCode changes

5. SAPI changes

========================
1. Internal API changes
========================

- Removed:
  . The misnamed ZVAL_IS_NULL() has been removed. Use Z_ISNULL() instead.
  . The zval_is_true() alias of zend_is_true() has been removed. Call
    zend_is_true() directly instead.
  . The _zval_get_*() compatibility macros for PHP 7.2 have been removed
    call the variant without the leading underscore instead.
    Affected: _zval_get_long, _zval_get_double, _zval_get_string,
    _zval_get_long_func, _zval_get_double_func, _zval_get_string_func
  . CHECK_ZVAL_NULL_PATH() and CHECK_NULL_PATH() have been removed, use
    zend_str_has_nul_byte(Z_STR_P(...)) and zend_char_has_nul_byte()
    respectively.
  . ZEND_LTOA() (and ZEND_LTOA_BUF_LEN) has been removed, as it was
    unsafe. Directly use ZEND_LONG_FMT with a function from the
    printf family.
  . The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed.
    Call zval_ptr_dtor_nogc() directly instead.
  . The internal zend_copy_parameters_array() function is no longer exposed.
  . The internal zend_hash_minmax() function is no longer exposed. Scan the
    HashTable directly and use zend_compare() for value comparisons instead.
  . The zend_make_callable() function has been removed, if a callable zval
    needs to be obtained use the zend_get_callable_zval_from_fcc() function
    instead. If this was used to store a callable, then an FCC should be
    stored instead.
  . The zend_exception_save() and zend_exception_restore() functions were
    removed.
  . The zend_set_hash_symbol() API has been removed.
  . The WRONG_PARAM_COUNT and ZEND_WRONG_PARAM_COUNT() macros have been
    removed. Call zend_wrong_param_count(); followed by RETURN_THROWS();
    instead.
  . PHP_HAVE_STREAMS macro removed from <php.h>.
  . The INI_STR(), INI_INT(), INI_FLT(), and INI_BOOL() macros have been
    removed. Instead new zend_ini_{bool|long|double|str|string}_literal()
    macros have been added. This fixes an internal naming inconsistency as
    "str" usually means zend_string*, and "string" means char*.
    However INI_STR() returned a char*
  . The INI_ORIG_{INT|STR|FLT|BOOL}() macros have been removed as they are
    unused. If this behaviour is required fall back to the zend_ini_*
    functions.
  . The unused ZEND_AST_PARENT_PROPERTY_HOOK_CALL has been removed.
  . The EMPTY_SWITCH_DEFAULT_CASE() macro has been removed. Use
    default: ZEND_UNREACHABLE(); instead.
  . The ZEND_RESULT_CODE type has been removed. Use zend_result directly.
  . The zend_parse_parameters_none_throw(), zend_parse_parameters_throw(),
    and ZEND_PARSE_PARAMS_THROW have been removed due to being misleading,
    since ZPP always throws, unless ZEND_PARSE_PARAMS_QUIET is given. Use
    the non-throw versions.
  . The XtOffsetOf() alias of C’s offsetof() macro has been removed. Use
    offsetof() directly.
  . The deprecated Z_COPYABLE(), Z_COPYABLE_P(), Z_OPT_COPYABLE(), and
    Z_OPT_COPYABLE_P() macros have been removed. Check for IS_ARRAY directly.
  . The deprecated Z_IMMUTABLE(), Z_IMMUTABLE_P(), Z_OPT_IMMUTABLE(), and
    Z_OPT_IMMUTABLE_P() macros have been removed. Check for
    IS_ARRAY && !REFCOUNTED directly.
  . The unused Z_GC_*() macros have been removed. Use the corresponding
    GC_*() macro on the result of Z_COUNTED().
  . The zend_binary_zval_strcmp() and zend_binary_zval_strncmp() functions
    have been removed, because they are unsafe by relying on the zvals
    having a specific type. Use zend_binary_strcmp() / zend_binary_strncmp(),
    string_compare_function() or similar instead.
  . The OPENBASEDIR_CHECKPATH() compatibility macro has been removed, instead
    use php_check_open_basedir() directly.
  . The Z_CONSTANT(), Z_CONSTANT_P(), Z_OPT_CONSTANT(), and
    Z_OPT_CONSTANT_P() macros have been removed. Check for IS_CONSTANT_AST
    directly.
  . The {_}php_stream_fopen_with_path() functions have been removed as they are
    unused.
  . The php_error_docref1() and php_error_docref2() functions have been
    removed, instead rely on the error_include_args INI option to show the
    arguments to functions in a consistent manner.
  . The following PHP stream functions prefixed with _ have been removed,
    and the macro without it has become the canonical function name:
    * _php_stream_cast()
    * _php_stream_free_enclosed()
    * _php_stream_free()
    * _php_stream_seek()
    * _php_stream_tell()
    * _php_stream_read()
    * _php_stream_write()
    * _php_stream_fill_read_buffer()
    * _php_stream_printf()
    * _php_stream_eof()
    * _php_stream_getc()
    * _php_stream_putc()
    * _php_stream_flush()
    * _php_stream_sync()
    * _php_stream_get_line()
    * _php_stream_puts()
    * _php_stream_stat()
    * _php_stream_mkdir()
    * _php_stream_rmdir()
    * _php_stream_readdir()
    * _php_stream_set_option()
    * _php_stream_get_url_stream_wrappers_hash()
    * _php_get_stream_filters_hash()
    * _php_stream_mmap_unmap()
    * _php_stream_mmap_unmap_ex()
    * _php_stream_filter_prepend()
    * _php_stream_filter_append()
    * _php_stream_filter_flush()
  . The PHP stream function _php_stream_stat_path() has been renamed to
    php_stream_stat_path_ex()
  . The PHP stream function _php_stream_scandir() was removed,
    insted the PHP macro php_stream_scandir() is now a function as the
    flags parameter was never used.
  . The PHP stream function _php_stream_flush() was removed,
    instead the PHP macro php_stream_flush() is now a proper function.

- Changed:
  . Internal functions that return by reference are now expected to
    automatically unwrap references when the result of the call is stored in an
    IS_TMP_VAR variable. This may be achieved by calling the
    zend_return_unwrap_ref() function.
  . ZEND_AST_METHOD_REFERENCE has been renamed to
    ZEND_AST_TRAIT_METHOD_REFERENCE.
  . Functions using zend_forbid_dynamic_call() *must* be flagged with
    ZEND_ACC2_FORBID_DYN_CALLS (@forbid-dynamic-calls in stubs). In debug
    builds, failing to include that flag will lead to assertion failures.
  . The zend_get_call_trampoline_func() API now takes the __call or
    __callStatic zend_function* instead of a CE and a boolean argument.
  . ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and
    zend_string_starts_with_literal_ci() now support strings containing NUL
    bytes. Passing non-literal char* is no longer supported.
  . The zend_active_function{_ex}() functions now return a const zend_function
    pointer.
  . zend_function.arg_info is now always a zend_arg_info*. Before, it was a
    zend_internal_arg_info on internal functions, unless the
    ZEND_ACC_USER_ARG_INFO flag was set.
  . ZEND_INI_GET_ADDR() is now a void* pointer instead of a char* pointer. This
    more correctly represents the generic nature of the returned pointer and
    allows to remove explicit casts, but possibly breaks pointer arithmetic
    performed on the result.
  . The zend_dval_to_lval_cap() function no longer takes a second
    zend_string* parameter.
  . EG(in_autoload) was renamed to EG(autoload_current_classnames) and no
    longer is a pointer, but a directly embedded HashTable struct.
  . Extended php_stream_filter_ops with seek method.
  . zend_argument_error_variadic() now takes a new 'function' parameter.
  . The param argument in the php_verror() function has been removed.

- Added:
  . New zend_class_entry.ce_flags2 and zend_function.fn_flags2 fields were
    added, given the primary flags were running out of bits.
  . Added zend_hash_str_lookup().
  . Added zend_ast_call_get_args() to fetch the argument node from any call
    node.
  . Added Z_PARAM_ENUM().
  . Added zend_enum_fetch_case_id().
  . Added zend_enum_get_case_by_id().
  . Added zend_bin2hex() and zend_bin2hex_str() as helper functions to remove
    dependencies on /ext/hash in various extensions.
  . Added a C23_ENUM() helper macro to define forward-compatible fixed-size
    enums.
  . Added zend_fcall_info.consumed_args together with
    zend_fci_consumed_arg(), which allows moving a selected callback argument
    instead of copying it in zend_call_function(). Currently only a single
    consumed argument is supported.
  . Added ZEND_CONTAINER_OF().
  . Added zend_reflection_property_set_raw_value_without_lazy_initialization(),
    zend_reflection_property_set_raw_value() to expose the functionality of
    ReflectionProperty::setRawValueWithoutLazyInitialization() and
    ReflectionProperty::setRawValue() to C extensions.
  . Added zend_argument_error_ex(), zend_argument_type_error_ex(),
    zend_argument_value_error_ex().
  . Added zend_ast_dup().
  . Added zend_compile_ast().
  . Added zend_check_type_ex().
  . Added zend_create_partial_closure().
  . Added a new IO copy API in <php_io.h>. php_io_copy() copies bytes between
    file descriptors using the most efficient platform primitive available
    (sendfile, splice, copy_file_range, TransmitFile), and is now used by
    php_stream_copy_to_stream_ex(). The mmap-based copy fallback was removed.
  . Added zend_string_equals_cstr_ci().
  . Added zend_cstr_append_char(), zend_cstr_concat(), and
    zend_cstr_concat3() as helper functions to allocate NUL-terminated raw C
    strings from one or more buffers.
  . Added zend_string_ends_with() and related variants.
  . Added trait support for internal classes.
  . Added do_php_cli().

========================
2. Build system changes
========================

- Abstract:
  . Minimum required PHP version found on the host system for running scripts
    like build/gen_stub.php during development has been updated from 7.4 to 8.1.
  . build/gen_stub.php may now generate a _decl.h file in addition to
    the _arginfo.h file, if the stub declares enums and is annotated with
    @generate-c-enums. For each enum the file will contain a C enum. Enum
    values can be compared to the result of
    zend_enum_fetch_case_id(zend_object*).

- Unix build system changes:
  . scripts/dev/update-autoconf.sh has been added to update config.*/libtool.
  . libtool has been upgraded to 2.5.4 (serial 63), which fixes many bugs.
  . As part of the upgrade to the new libtool:
    . libtool is now spread across multiple files. phpize has been updated to
      handle this.
    . On macOS, libtool now uses -undefined dynamic_lookup for shared objects,
      instead of -undefined suppress -flat_namespace.
    . --with-pic is now --enable-pic. The old flag will result in an error.
  . Symbol HAVE_ST_BLOCKS has been removed from php_config.h (use
    HAVE_STRUCT_STAT_ST_BLOCKS).
  . Added a new configure option --disable-apache2-conf to prevent apxs from
    editing httpd.conf during installation.

- Windows build system changes:
  . Function SETUP_OPENSSL() doesn't accept 6th argument anymore and doesn't
    define the HAVE_OPENSSL_SSL_H preprocessor macro anymore.
  . Function SETUP_SQLITE3() doesn't define HAVE_SQLITE3_H and HAVE_SQLITE3EXT_H
    preprocessor macros anymore.
  . Added a new function CHECK_HEADER() which is intended to be used instead of
    the CHECK_HEADER_ADD_INCLUDE().

- Embed:
  . The CLI SAPI can not be disabled when building the embed SAPI
    (--enable-embed is incompatible with --disable-cli).

========================
3. Module changes
========================

- ext/date:
  . php_idate() now returns the result state, and moves the return value into an
    out parameter.

- ext/intl:
  . Added intl_icu_compat.h with helpers and feature macros for ICU
    version-specific API differences. Code in ext/intl should use the
    intl_icu_compat_* helpers and INTL_ICU_HAS_* macros instead of adding
    direct U_ICU_VERSION_* guards for supported ICU API variants.
  . The internal grapheme_get_break_iterator() helper no longer accepts a
    stack buffer argument; pass only the UErrorCode* status argument.

- ext/mbstring:
  . Added GB18030-2022 to default encoding list for zh-CN.

- ext/mysqlnd:
  . Dropped session_options parameter from all methods in mysqlnd_auth.
    The same information is present in conn->options and should be used
    instead.
  . Removed charsets plugin.

- ext/session:
  . php_session_flush() now returns a bool rather than a zend_result.
  . The mod_user_names global has been removed.
  . The mod_user_uses_object_methods_as_handlers global has been added,
    it indicates whether the session handlers are methods of an object or not.
  . Removed session_adapt_url().
  . PS_OPEN_ARGS is now defined as
    `void **mod_data, zend_string *save_path, zend_string *session_name`
    rather than
    `void **mod_data, const char *save_path, const char *session_name`
  . PS_FUNCS() now includes the PS_VALIDATE_SID_FUNC()
  . PS_MOD() now requires that the PS_CREATE_SID_FUNC() and
    PS_VALIDATE_SID_FUNC() functions are defined.
  . PS_FUNCS_SID() and PS_MOD_SID() have been removed.
    Either use PS_FUNCS()/PS_MOD() or PS_FUNCS_UPDATE_TIMESTAMP()/
    PS_MOD_UPDATE_TIMESTAMP() if timestamp support exists.

- ext/standard:
  . _php_error_log() now has a formal return type of zend_result.
  . _php_error_log() now accepts zend_string* values instead of char*.
  . _php_error_log_ex() has been removed.
  . php_mail()'s extra_cmd parameter is now a zend_string*.
  . The php_math_round_mode_from_enum() function now takes a
    zend_enum_RoundingMode parameter.

- ext/uri:
  . The value parameter of the php_uri_property_handler_write callback is now
    const zval * instead of zval *, reflecting that write handlers must
    not modify the input zval.

- ext/xml:
  . Removed the XML_ExpatVersion() libxml compatibility wrapper,
    as it was unused.
  . Removed the XML_GetCurrentByteCount() libxml compatibility wrapper,
    as it was unused and could return the wrong result.

========================
4. OpCode changes
========================

- Added ZEND_TYPE_ASSERT to check a value's type against the parameter
  type of a function, throwing a TypeError on failure as if the function
  was called. Used in optimizations that elide function calls.

========================
5. SAPI changes
========================

- SAPIs should explicitly release a thread's resources by calling
  ts_free_thread() before terminating it. tsrm_shutdown() can only release the
  resources of the calling thread, for resources allocated with
  ts_allocate_tls_id().

- AG and SCNG are now allocated with ts_allocate_tls_id() and live in native
  __thread storage on ZTS builds.

- php-cli functionality is now available in embed builds via the do_php_cli()
  function.
