2018-07-31 21:54:03 +08:00
|
|
|
PHP 7.4 INTERNALS UPGRADE NOTES
|
2010-08-30 18:26:31 +08:00
|
|
|
|
|
|
|
1. Internal API changes
|
2018-08-02 20:08:30 +08:00
|
|
|
a. php_sys_symlink() and php_sys_link()
|
2018-08-22 22:07:31 +08:00
|
|
|
b. zend_lookup_class_ex() and zend_fetch_class_by_name()
|
2018-09-11 22:21:17 +08:00
|
|
|
c. Function/property/class flags
|
2018-09-13 18:47:06 +08:00
|
|
|
d. Removed zend_check_private()
|
2018-10-10 18:00:57 +08:00
|
|
|
e. php_win32_error_to_msg() memory management
|
|
|
|
f. get_properties_for() handler / Z_OBJDEBUG_P
|
2018-10-13 21:30:27 +08:00
|
|
|
g. Required object handlers
|
2018-10-17 20:52:50 +08:00
|
|
|
h. Immutable classes and op_arrays
|
Allow empty $escape to eschew escaping CSV
Albeit CSV is still a widespread data exchange format, it has never been
officially standardized. There exists, however, the “informational” RFC
4180[1] which has no notion of escape characters, but rather defines
`escaped` as strings enclosed in double-quotes where contained
double-quotes have to be doubled. While this concept is supported by
PHP's implementation (`$enclosure`), the `$escape` sometimes interferes,
so that `fgetcsv()` is unable to correctly parse externally generated
CSV, and `fputcsv()` is sometimes generating non-compliant CSV. Since
PHP's `$escape` concept is availble for many years, we cannot drop it
for BC reasons (even though many consider it as bug). Instead we allow
to pass an empty string as `$escape` parameter to the respective
functions, which results in ignoring/omitting any escaping, and as such
is more inline with RFC 4180. It is noteworthy that this is almost no
userland BC break, since formerly most functions did not accept an empty
string, and failed in this case. The only exception was `str_getcsv()`
which did accept an empty string, and used a backslash as escape
character then (which appears to be unintended behavior, anyway).
The changed functions are `fputcsv()`, `fgetcsv()` and `str_getcsv()`,
and also the `::setCsvControl()`, `::getCsvControl()`, `::fputcsv()`,
and `::fgetcsv()` methods of `SplFileObject`.
The implementation also changes the type of the escape parameter of the
PHP_APIs `php_fgetcsv()` and `php_fputcsv()` from `char` to `int`, where
`PHP_CSV_NO_ESCAPE` means to ignore/omit escaping. The parameter
accepts the same values as `isalpha()` and friends, i.e. “the value of
which shall be representable as an `unsigned char` or shall equal the
value of the macro `EOF`. If the argument has any other value, the
behavior is undefined.” This is a subtle BC break, since the character
`chr(128)` has the value `-1` if `char` is signed, and so likely would
be confused with `EOF` when converted to `int`. We consider this BC
break to be acceptable, since it's rather unlikely that anybody uses
`chr(128)` as escape character, and it easily can be fixed by casting
all `escape` arguments to `unsigned char`.
This patch implements the feature requests 38301[2] and 51496[3].
[1] <https://tools.ietf.org/html/rfc4180>
[2] <https://bugs.php.net/bug.php?id=38301>
[3] <https://bugs.php.net/bug.php?id=51496>
2018-12-02 23:28:18 +08:00
|
|
|
i. php_fgetcsv() and php_fputcsv()
|
2010-09-17 16:42:12 +08:00
|
|
|
|
2010-11-18 18:43:01 +08:00
|
|
|
2. Build system changes
|
2018-10-03 14:47:07 +08:00
|
|
|
a. Abstract
|
|
|
|
b. Unix build system changes
|
|
|
|
c. Windows build system changes
|
2010-11-18 18:43:01 +08:00
|
|
|
|
2015-07-03 17:46:30 +08:00
|
|
|
3. Module changes
|
2018-09-16 17:07:40 +08:00
|
|
|
a. ext/xml
|
2018-10-03 14:47:07 +08:00
|
|
|
b. ext/hash
|
2010-11-18 18:43:01 +08:00
|
|
|
|
2010-08-30 18:26:31 +08:00
|
|
|
========================
|
|
|
|
1. Internal API changes
|
|
|
|
========================
|
|
|
|
|
2018-08-02 20:08:30 +08:00
|
|
|
a. php_sys_symlink() and php_sys_link() portability macros have been
|
|
|
|
added, which behave like POSIX's symlink() and link(), respectively, on
|
|
|
|
POSIX compliant systems and on Windows.
|
|
|
|
|
2018-08-22 22:07:31 +08:00
|
|
|
b. zend_lookup_class_ex() and zend_fetch_class_by_name() prototypes were
|
|
|
|
changed to accept optional lower-case class name as zend_string*,
|
|
|
|
instead of zval*.
|
|
|
|
|
2018-09-11 22:21:17 +08:00
|
|
|
c. Function/property/class flags changes
|
2018-09-05 23:14:03 +08:00
|
|
|
- ZEND_ACC_CTOR and ZEND_ACC_DTOR are removed. It's possible to check if
|
|
|
|
method is a constructor/destructor using the following condition
|
2018-10-18 09:14:46 +08:00
|
|
|
(func->common.scope->constructor == func).
|
2018-09-05 18:16:10 +08:00
|
|
|
- ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
|
|
|
|
during inheritance).
|
2018-09-11 17:26:26 +08:00
|
|
|
- ZEND_ACC_IMPLICIT_PUBLIC is removed (it was used only for reflection)
|
2018-09-11 16:56:45 +08:00
|
|
|
- ZEND_ACC_SHADOW property flag is removed. Instead of creating shadow
|
|
|
|
clone, now we use the same private property_info, and should also
|
|
|
|
check property_info->ce (in the same way as with methods).
|
2018-09-18 16:41:40 +08:00
|
|
|
- ZEND_ACC_ANON_BOUND is replaced with ZEND_ACC_LINKED. This flag is set
|
|
|
|
not only during anonymous classes declaration, but also during any
|
|
|
|
run-time or compile-time class declaration.
|
2018-10-02 14:10:04 +08:00
|
|
|
- ZEND_ACC_NO_RT_ARENA renamed into ZEND_ACC_HEAP_RT_CACHE. Now it's used
|
|
|
|
not only for closures, but also for pseudo-main op_arrays.
|
2018-09-11 22:21:17 +08:00
|
|
|
- ZEND_ACC_... flags are re-numbered.
|
2018-09-05 18:16:10 +08:00
|
|
|
|
2018-09-13 18:47:06 +08:00
|
|
|
d. zend_check_private() is removed. Use (func->common.scope == scope) instead.
|
|
|
|
|
2018-09-21 22:27:51 +08:00
|
|
|
e. Pointers returned by php_win32_error_to_msg() have to be freed using
|
|
|
|
php_win32_error_msg_free(). Same regarding php_win_err() vs.
|
|
|
|
php_win_err_free().
|
|
|
|
|
2018-10-10 18:00:57 +08:00
|
|
|
f. A new, optional object handler with the signature
|
|
|
|
|
|
|
|
HashTable *get_properties_for(zval *obj, zend_prop_purpose purpose)
|
|
|
|
|
|
|
|
has been introduced, where zend_prop_purpose (currently) takes one of:
|
|
|
|
|
|
|
|
ZEND_PROP_PURPOSE_DEBUG // var_dump etc.
|
|
|
|
ZEND_PROP_PURPOSE_ARRAY_CAST // (array) $obj
|
|
|
|
ZEND_PROP_PURPOSE_SERIALIZE // "O"-format serialization (__wakeup)
|
|
|
|
ZEND_PROP_PURPOSE_VAR_EXPORT // var_export (__set_state)
|
|
|
|
ZEND_PROP_PURPOSE_JSON // json_encode
|
|
|
|
|
|
|
|
The handler returns a non-null HashTable with increased refcounted, and
|
|
|
|
the return value must be released using zend_release_properties().
|
2018-10-13 20:17:28 +08:00
|
|
|
|
2018-10-10 18:00:57 +08:00
|
|
|
This handler serves the same general function as get_properties(), but
|
|
|
|
provides more control over different property uses, while also making
|
|
|
|
it possible to return a temporary property table.
|
2018-10-13 20:17:28 +08:00
|
|
|
|
2018-10-10 18:00:57 +08:00
|
|
|
get_properties() is still used in cases where none of the above purposes
|
|
|
|
apply, but overloading get_properties() is generally discouraged. If you
|
|
|
|
want to provide purposes for general usage rather than just debugging or
|
|
|
|
serialization, please prefer using properly declared properties.
|
|
|
|
|
|
|
|
get_debug_info() is superseded by get_properties_for() with the
|
|
|
|
ZEND_PROP_PURPOSE_DEBUG purpose, but remains available for backwards-
|
|
|
|
compatibility reasons. However, while it is fine to define this handler,
|
|
|
|
it should never be directly called by consuming code.
|
|
|
|
|
|
|
|
The Z_OBJDEBUG_P macro has been removed. It should be replaced by calls to
|
|
|
|
zend_get_properties_for() with the ZEND_PROP_PURPOSE_DEBUG purpose:
|
|
|
|
|
|
|
|
// OLD
|
|
|
|
int is_temp;
|
|
|
|
HashTable *ht = Z_OBJDEBUG_P(obj, is_temp);
|
|
|
|
// ...
|
|
|
|
if (is_temp) {
|
|
|
|
zend_hash_destroy(ht);
|
|
|
|
FREE_HASHTABLE(ht);
|
|
|
|
}
|
|
|
|
|
|
|
|
// NEW
|
|
|
|
HashTable *ht = zend_get_properties_for(obj, ZEND_PROP_PURPOSE_DEBUG);
|
|
|
|
// ...
|
|
|
|
zend_release_properties(ht);
|
|
|
|
|
2018-10-13 21:30:27 +08:00
|
|
|
g. The following object handlers are now required (must be non-NULL):
|
|
|
|
|
|
|
|
* free_obj
|
|
|
|
* dtor_obj
|
|
|
|
* read_property
|
|
|
|
* write_property
|
|
|
|
* read_dimension
|
|
|
|
* write_dimension
|
|
|
|
* get_property_ptr_ptr
|
|
|
|
* has_property
|
|
|
|
* unset_property
|
|
|
|
* has_dimension
|
|
|
|
* unset_dimension
|
|
|
|
* get_properties
|
|
|
|
* get_method
|
|
|
|
* get_constructor
|
|
|
|
* get_class_name
|
|
|
|
* get_gc
|
|
|
|
|
|
|
|
It is recommended to initialize object handler structures by copying the
|
|
|
|
std object handlers and only overwriting those you want to change.
|
|
|
|
|
2018-10-17 20:52:50 +08:00
|
|
|
h. Opcache may make classes and op_arrays immutable. Such classes are marked
|
|
|
|
by ZEND_ACC_IMMUTABLE flag, they are not going to be copied from opcache
|
|
|
|
shared memory to process memory and must not be modified at all.
|
|
|
|
Few related data structures were changed to allow addressing mutable data
|
|
|
|
structures from immutable ones. This access is implemented through
|
|
|
|
ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of
|
|
|
|
indirection. op_array->run_time_cache, op_array->static_variables_ptr and
|
|
|
|
class_entry->static_members_table now have to be accessed through
|
|
|
|
ZEND_MAP_PTR... macros.
|
|
|
|
It's also not allowed to change op_array->reserved[] handles of immutable
|
|
|
|
op_arrays. Instead, now you have to reserve op_array handle using
|
|
|
|
zend_get_op_array_extension_handle() during MINIT and access its value
|
|
|
|
using ZEND_OP_ARRAY_EXTENSION(op_array, handle).
|
|
|
|
|
Allow empty $escape to eschew escaping CSV
Albeit CSV is still a widespread data exchange format, it has never been
officially standardized. There exists, however, the “informational” RFC
4180[1] which has no notion of escape characters, but rather defines
`escaped` as strings enclosed in double-quotes where contained
double-quotes have to be doubled. While this concept is supported by
PHP's implementation (`$enclosure`), the `$escape` sometimes interferes,
so that `fgetcsv()` is unable to correctly parse externally generated
CSV, and `fputcsv()` is sometimes generating non-compliant CSV. Since
PHP's `$escape` concept is availble for many years, we cannot drop it
for BC reasons (even though many consider it as bug). Instead we allow
to pass an empty string as `$escape` parameter to the respective
functions, which results in ignoring/omitting any escaping, and as such
is more inline with RFC 4180. It is noteworthy that this is almost no
userland BC break, since formerly most functions did not accept an empty
string, and failed in this case. The only exception was `str_getcsv()`
which did accept an empty string, and used a backslash as escape
character then (which appears to be unintended behavior, anyway).
The changed functions are `fputcsv()`, `fgetcsv()` and `str_getcsv()`,
and also the `::setCsvControl()`, `::getCsvControl()`, `::fputcsv()`,
and `::fgetcsv()` methods of `SplFileObject`.
The implementation also changes the type of the escape parameter of the
PHP_APIs `php_fgetcsv()` and `php_fputcsv()` from `char` to `int`, where
`PHP_CSV_NO_ESCAPE` means to ignore/omit escaping. The parameter
accepts the same values as `isalpha()` and friends, i.e. “the value of
which shall be representable as an `unsigned char` or shall equal the
value of the macro `EOF`. If the argument has any other value, the
behavior is undefined.” This is a subtle BC break, since the character
`chr(128)` has the value `-1` if `char` is signed, and so likely would
be confused with `EOF` when converted to `int`. We consider this BC
break to be acceptable, since it's rather unlikely that anybody uses
`chr(128)` as escape character, and it easily can be fixed by casting
all `escape` arguments to `unsigned char`.
This patch implements the feature requests 38301[2] and 51496[3].
[1] <https://tools.ietf.org/html/rfc4180>
[2] <https://bugs.php.net/bug.php?id=38301>
[3] <https://bugs.php.net/bug.php?id=51496>
2018-12-02 23:28:18 +08:00
|
|
|
i. The type of the escape parameter of php_fgetcsv() and php_fputcsv() has
|
|
|
|
been changed from char to int. This allows to pass the new constant macro
|
|
|
|
PHP_CSV_NO_ESCAPE to this parameter, to disable PHP's proprietary escape
|
|
|
|
mechanism.
|
|
|
|
|
2010-11-18 18:43:01 +08:00
|
|
|
========================
|
|
|
|
2. Build system changes
|
|
|
|
========================
|
|
|
|
|
2018-10-03 14:47:07 +08:00
|
|
|
a. Abstract
|
2018-10-13 20:17:28 +08:00
|
|
|
- The hash extension is now always available, meaning the --enable-hash
|
2018-10-03 14:47:07 +08:00
|
|
|
configure argument has been removed.
|
|
|
|
|
|
|
|
b. Unix build system changes
|
2018-08-26 02:52:28 +08:00
|
|
|
- configure --help now also outputs --program-suffix and --program-prefix
|
|
|
|
information by using the Autoconf AC_ARG_PROGRAM macro.
|
2018-09-01 09:56:52 +08:00
|
|
|
- Obsolescent macros AC_FUNC_VPRINTF and AC_FUNC_UTIME_NULL have been
|
|
|
|
removed. Symbols HAVE_VPRINTF and HAVE_UTIME_NULL are no longer defined
|
|
|
|
since they are not needed on the current systems.
|
2014-11-10 21:25:14 +08:00
|
|
|
|
2018-10-03 14:47:07 +08:00
|
|
|
c. Windows build system changes
|
2014-11-10 21:25:14 +08:00
|
|
|
|
2015-01-26 05:14:40 +08:00
|
|
|
========================
|
|
|
|
3. Module changes
|
|
|
|
========================
|
2018-09-16 17:07:40 +08:00
|
|
|
|
|
|
|
a. ext/xml
|
|
|
|
- The public (internal) API of the ext/xml extension has been removed. All
|
|
|
|
functions and structures are private to the extension now.
|
2018-10-03 14:47:07 +08:00
|
|
|
|
|
|
|
b. ext/hash
|
2018-10-13 20:17:28 +08:00
|
|
|
- The hash extension is now always available, allowing extensions to rely
|
2018-10-03 14:47:07 +08:00
|
|
|
on its functionality to be available without compile time checks.
|