From: Pierrick Charron Date: Thu, 28 Jul 2016 03:36:22 +0000 (-0400) Subject: Merge branch 'PHP-5.6' into PHP-7.0 X-Git-Tag: php-7.0.10RC1~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf37b97d9cedccf01f6b1cfe9ee61102ac14e2a0;p=php Merge branch 'PHP-5.6' into PHP-7.0 Conflicts: ext/curl/interface.c --- bf37b97d9cedccf01f6b1cfe9ee61102ac14e2a0 diff --cc NEWS index f1327a54f2,6c22dd9d74..9e99676b43 --- a/NEWS +++ b/NEWS @@@ -20,16 -10,12 +20,17 @@@ PH phpize). (Yuji Uchiyama) . Fixed bug #72641 (phpize (on Windows) ignores PHP_PREFIX). (Yuji Uchiyama) + . Fixed potential segfault in object storage freeing in shutdown sequence. + (Bob) + . Fixed bug #72683 (getmxrr broken). (Anatol) -- Curl: - . Fixed bug #71144 (Segmentation fault when using cURL with ZTS). - (maroszek at gmx dot net) - . Fixed bug #71929 (Certification information (CERTINFO) data parsing error). +- COM: + . Fixed bug #72569 (DOTNET/COM array parameters broke in PHP7). (Anatol) + +- CURL: + . Fixed bug #71709 (curl_setopt segfault with empty CURLOPT_HTTPHEADER). (Pierrick) ++ . Fixed bug #71929 (CURLINFO_CERTINFO data parsing error). (Pierrick) - Date: . Fixed bug #66836 (DateTime::createFromFormat 'U' with pre 1970 dates fails diff --cc UPGRADING index 1e73336098,353ffa73ad..6201719704 --- a/UPGRADING +++ b/UPGRADING @@@ -19,805 -20,505 +19,811 @@@ 1. Backward Incompatible Changes ======================================== -- Core: - By fixing bug #66015 it is no longer possible to overwrite keys in static scalar - arrays. Quick example to illustrate: - class Test { - const FIRST = 1; - public $array = array( - self::FIRST => 'first', - 'second', - 'third' - ); - } - Test::$array will have as expected three array keys (1, 2, 3) and no longer - two (0, 1). self::FIRST will no longer overwrite 'third' having key 1 then, - but will mark the beginning of indexing. +Language changes +================ -- JSON: - json_decode() no longer accepts non-lowercase variants of lone JSON true, - false or null values. For example, True or FALSE will now cause json_decode to - return NULL and set an error value you can fetch with json_last_error(). - This affects JSON texts consisting solely of true, false or null. Text - containing non-lowercase values inside JSON arrays or objects has never been - accepted. +Changes to variable handling +---------------------------- -- OpenSSL: - To prevent man-in-the-middle attacks against encrypted transfers client - streams now verify peer certificates by default. Previous versions - required users to manually enable peer verification. As a result of this - change, existing code using ssl:// or tls:// stream wrappers (e.g. - file_get_contents(), fsockopen(), stream_socket_client()) may no longer - connect successfully without manually disabling peer verification via the - stream context's "verify_peer" setting. Encrypted transfers delegate to - operating system certificate stores by default if not overridden via the - new openssl.cafile and openssl.cafile ini directives or via call-time SSL - context options, so most users should be unaffected by this transparent - security enhancement. (https://wiki.php.net/rfc/tls-peer-verification) - -- Mcrypt: - The mcrypt_encrypt(), mcrypt_decrypt() and mcrypt_{MODE}() functions no - longer accept keys or IVs with incorrect sizes. Furthermore an IV is now - required if the used block cipher mode requires it. - -- cURL: - Uploads using the @file syntax are now unsupported by default. +* Indirect variable, property and method references are now interpreted with + left-to-right semantics. Some examples: -======================================== -2. New Features -======================================== + $$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz'] + $foo->$bar['baz'] // interpreted as ($foo->$bar)['baz'] + $foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']() + Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']() -- Added constant scalar expressions syntax. - (https://wiki.php.net/rfc/const_scalar_exprs) + To restore the previous behavior add explicit curly braces: -- Added dedicated syntax for variadic functions. - (https://wiki.php.net/rfc/variadics) + ${$foo['bar']['baz']} + $foo->{$bar['baz']} + $foo->{$bar['baz']}() + Foo::{$bar['baz']}() + +* The global keyword now only accepts simple variables. Instead of -- Added support for argument unpacking to complement the variadic syntax. - (https://wiki.php.net/rfc/argument_unpacking) + global $$foo->bar; -- Added an exponentiation operator (**). - (https://wiki.php.net/rfc/pow-operator) + it is now required to write the following: -- Added unified default encoding. default_charset=UTF-8 and functions/extensions - use encoding settings honor default_charset. + global ${$foo->bar}; -- The php://input stream is now re-usable and can be used concurrently with - enable_post_data_reading=0. +* Parentheses around variables or function calls no longer have any influence + on behavior. For example the following code, where the result of a function + call is passed to a by-reference function -- Added use function and use const. - (https://wiki.php.net/rfc/use_function) + function getArray() { return [1, 2, 3]; } -- Added a function for timing attack safe string comparison - (https://wiki.php.net/rfc/timing_attack) + $last = array_pop(getArray()); + // Strict Standards: Only variables should be passed by reference + $last = array_pop((getArray())); + // Strict Standards: Only variables should be passed by reference -- Added the __debugInfo() magic method to allow userland classes to implement - the get_debug_info API previously available only to extensions. - (https://wiki.php.net/rfc/debug-info) + will now throw a strict standards error regardless of whether parentheses + are used. Previously no notice was generated in the second case. -- Added gost-crypto (CryptoPro S-box) hash algorithm. +* Array elements or object properties that are automatically created during + by-reference assignments will now result in a different order. For example -- Stream wrappers verify peer certificates and host names by default in - encrypted client streams. + $array = []; + $array["a"] =& $array["b"]; + $array["b"] = 1; + var_dump($array); -- Added openssl certificate fingerprint support (inclusive stream context - option). + now results in the array ["a" => 1, "b" => 1], while previously the result + was ["b" => 1, "a" => 1]; -- Added support for SAN x509 extension matching when verifing host names in - encrypted streams. +Relevant RFCs: +* https://wiki.php.net/rfc/uniform_variable_syntax +* https://wiki.php.net/rfc/abstract_syntax_tree -- Added a range of new SSL context options for improved encrypted stream - server security (https://wiki.php.net/rfc/improved-tls-defaults): +Changes to list() +----------------- - . "honor_cipher_order" allows servers to prioritize cipher suites of their - choosing when negotiating SSL/TLS handshakes. - . "single_ecdh_use" and "single_dh_use" allow for improved forward - secrecy in encrypted stream servers. - . "dh_param" allows specification of pre-generated key generation - parameters when negotiating ephemeral DHE ciphers in stream servers. - . "ecdh_curve" allows stream servers to specify which curve to use when - negotiating ephemeral ECDHE ciphers (defaults to NIST P-256). - . "rsa_key_size" SSL context option gives stream servers control - over the key size (in bits) used when negotiating RSA ciphers. - . "capture_session_meta" if specified stores an array of data describing - the TLS session's protocol/cipher in the "session_meta" SSL context key. +* list() will no longer assign variables in reverse order. For example -- Added automatic mitigation against client-initated TLS renegotiation DoS - attacks in encrypted server streams. Renegotiation limiting may be - customized via three new SSL context options: + list($array[], $array[], $array[]) = [1, 2, 3]; + var_dump($array); - . "reneg_limit" (number of allowed renegotiations per time window) - . "reneg_window" (renegotiation time window in seconds) - . "reneg_limit_callback" (optional notification callback on limiting) + will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only + the **order** of the assignments changed, but the assigned values stay the + same. E.g. a normal usage like -- Encrypted TLS servers now support the server name indication (SNI) TLS - extension via the new "SNI_server_certs" SSL context option. + list($a, $b, $c) = [1, 2, 3]; + // $a = 1; $b = 2; $c = 3; + + will retain its current behavior. -- Added "crypto_method" SSL context option for use in encrypted streams. +* Empty list() assignments are no longer allowed. As such all of the following + are invalid: -- Added "peer_name" SSL context option to better reflect peer certificate - name matching using SAN extension (replaces deprecated "CN_match"). + list() = $a; + list(,,) = $a; + list($x, list(), $y) = $a; -- Added stream wrapper support when specifying "cafile" SSL context paths. +* list() no longer supports unpacking strings (while previously this was only + supported in some cases). The code -- Independent peer cert and peer name validation is now available via a new - boolean "verify_peer_name" SSL context option. This option is enabled by - default in encrypted client streams. + $string = "xy"; + list($x, $y) = $string; -- Added protocol-specific tlsv1.0://, tlsv1.1:// and tlsv1.2:// encryption - stream wrappers. tls:// wrapper now supports TLSv1.1 and TLSv1.2 (previously - only supported TLSv1). + will now result in $x == null and $y == null (without notices) instead of + $x == "x" and $y == "y". Furthermore list() is now always guaranteed to + work with objects implementing ArrayAccess, e.g. -- Stream crypto method specification now accepts flags instead of values - allowing support for multiple discrete protocols in a given stream. + list($a, $b) = (object) new ArrayObject([0, 1]); -- PostgreSQL database connections may now be established asynchronously using - new constants and polling functions in ext/pgsql. + will now result in $a == 0 and $b == 1. Previously both $a and $b were null. -- Non-blocking read/write query behavior now optionally available in database - operations using the ext/pgsql extension. +Relevant RFCs: +* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list +* https://wiki.php.net/rfc/fix_list_behavior_inconsistency -======================================== -3. Changes in SAPI modules -======================================== +Changes to foreach +------------------ -- Added phpdbg SAPI. - (https://wiki.php.net/rfc/phpdbg) +* Iteration with foreach() no longer has any effect on the internal array + pointer, which can be accessed through the current()/next()/etc family of + functions. For example -- Support for FPM workers changing the apparmor profile through the pool configuration. - (https://wiki.php.net/rfc/fpm_change_hat) + $array = [0, 1, 2]; + foreach ($array as &$val) { + var_dump(current($array)); + } -- Support for several XML MIME types in the built-in CLI server. For static - files with extensions .xml, .xsl, .xsd the Content-Type header - application/xml is now sent automatically. + will now print the value int(0) three times. Previously the output was int(1), + int(2) and bool(false). -======================================== -4. Deprecated Functionality -======================================== +* When iterating arrays by-value, foreach will now always operate on a copy of + the array, as such changes to the array during iteration will not influence + iteration behavior. For example -- Incompatible context calls: - Instance calls from an incompatible context are now deprecated and issue - E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx + $array = [0, 1, 2]; + $ref =& $array; // Necessary to trigger the old behavior + foreach ($array as $val) { + var_dump($val); + unset($array[1]); + } -- The "CN_match" and "SNI_server_name" SSL context options are deprecated in - favor of the new "peer_name" option. Name verification now checks certificate - SAN names as well as the CN field and the specific name fields are deprecated - to avoid confusion. Their use triggers E_DEPRECATED but continues to work as - before. If specified, the specific values take precedence over the general - "peer_name" value. + will now print all three elements (0 1 2), while previously the second element + 1 was skipped (0 2). -- Deprecated PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, an - undocument constant effectively equivalent to PDO::ATTR_EMULATE_PREPARES. +* When iterating arrays by-reference, modifications to the array will continue + to influence the iteration. However PHP will now do a better job of + maintaining a correct position in a number of cases. E.g. appending to an + array during by-reference iteration -- Deprecated INIs: Following INIs are deprecated in favour of new - internal_encoding/input_encoding/output_encoding. Refer to "Changes to - encodings in PHP 5.6" in "11. Other Changes" section for more details. + $array = [0]; + foreach ($array as &$val) { + var_dump($val); + $array[1] = 1; + } - iconv.input_encoding - iconv.output_encoding - iconv.internal_encoding - mbstring.http_input - mbstring.http_output - mbstring.internal_encoding + will now iterate over the appended element as well. As such the output of this + example will now be "int(0) int(1)", while previously it was only "int(0)". -======================================== -5. Changed Functions -======================================== +* Iteration of plain (non-Traversable) objects by-value or by-reference will + behave like by-reference iteration of arrays. This matches the previous + behavior apart from the more accurate position management mentioned in the + previous point. -- cURL: - CURLOPT_SAFE_UPLOAD is now turned on by default and uploads with @file - do not work unless it is explicitly set to false. +* Iteration of Traversable objects remains unchanged. - curl_setopt() now supports the following nullable settings (>= 5.5.11): - . CURLOPT_CUSTOMREQUEST - . CURLOPT_FTPPORT - . CURLOPT_RANGE - . CURLOPT_FTP_ACCOUNT - . CURLOPT_RTSP_SESSION_ID - . CURLOPT_KRBLEVEL - . CURLOPT_KRB4LEVEL +Relevant RFC: https://wiki.php.net/rfc/php7_foreach - curl_getinfo($ch, CURLINFO_CERTINFO) returns certificate Subject and Issuer - as a string (PHP >= 5.6.25) +Changes to parameter handling +----------------------------- -- Strings: - substr_compare() now allows $length to be zero. - pack() and unpack() now support 64-bit format specifiers: q, Q, J and P. +* It is no longer possible to define two function parameters with the same name. + For example, the following method will trigger a compile-time error: -- Crypt: - crypt() will now raise an E_NOTICE error if the salt parameter is omitted. - See: https://wiki.php.net/rfc/crypt_function_salt + public function foo($a, $b, $unused, $unused) { + // ... + } -- Mcrypt: - The $source parameter of mcrypt_create_iv() now defaults to - MCRYPT_DEV_URANDOM instead of MCRYPT_DEV_RANDOM. + Code like this should be changed to use distinct parameter names, for example: -- OpenSSL: - The $crypto_type parameter is now optional in stream_socket_enable_crypto() - if the stream's SSL context specifies the new "crypto_type" option. The - crypto method from the context is used as a fallback if no crypto method is - specified at call-time. - -- Reflection: - ReflectionClass::newInstanceWithoutConstructor previously didn't allow the - instantiation of any internal class which used custom object storage - (overriding the default create_object handler), this was changed to only - reject the instantiation of such classes if the class is also marked as - final. - -- XMLReader: - XMLReader::getAttributeNs and XMLReader::getAttributeNo now return NULL if - the attribute could not be found, just like XMLReader::getAttribute. - -- Pgsql: - pg_insert()/pg_select()/pg_update()/pg_delete() are no longer EXPERIMENTAL. - The following functions no longer block until query write completion if the - socket stream underlying a database connection is set to non-blocking mode: - . pg_send_execute() - . pg_send_prepare() - . pg_send_query() - . pg_send_query_params() - -- unserialize: - Manipulated serialization strings for objects implementing Serializable by - replacing "C:" with "O:" at the start will now produce an error. - -- parse_ini_file(): -- parse_ini_string(): - Added scanner mode INI_SCANNER_TYPED to yield typed .ini values. - For PHP >= 5.6.1 + public function foo($a, $b, $unused1, $unused2) { + // ... + } -- JSON: - Added JSON_PRESERVE_ZERO_FRACTION option (PHP >= 5.6.5) +* The func_get_arg() and func_get_args() functions will no longer return the + original value that was passed to a parameter and will instead provide the + current value (which might have been modified). For example -======================================== -6. New Functions -======================================== + function foo($x) { + $x++; + var_dump(func_get_arg(0)); + } + foo(1); -- Datetime: - Added DatePeriod::getStartDate(), DatePeriod::getEndDate(), DatePeriod::getDateInterval() in 5.6.5. + will now print "2" instead of "1". This code should be changed to either + perform modifications only after calling func_get_arg(s) -- GMP: - Added gmp_root($a, $nth) and gmp_rootrem($a, $nth) for calculating nth roots. - Added gmp_import($data, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) in PHP 5.6.1. - Added gmp_export($gmpnumber, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) in PHP 5.6.1. - Added gmp_random_range() and gmp_random_bits() in PHP 5.6.3. + function foo($x) { + var_dump(func_get_arg(0)); + $x++; + } -- Hash - Added hash_equals($known_string, $user_string) + or avoid modifying the parameters altogether: -- OpenSSL: - Added string openssl_x509_fingerprint($x509, $type, $binary). - Added string openssl_spki_new($private_key, $challenge, $algorithm) - Added bool openssl_spki_verify($spkac) - Added string openssl_spki_export($spkac) - Added string openssl_spki_export_challenge($spkac) - Added array openssl_get_cert_locations() - -- LDAP: - Added ldap_escape($value, $ignore = "", $flags = 0). - Added ldap_modify_batch($link_identifier, $dn, $modifications) described in - https://wiki.php.net/rfc/ldap_modify_batch. - -- Pgsql: - Added pg_socket($connection) to allow async connections and non-blocking IO - Added pg_connect_poll($connection) for establishing async connections - Added pg_consume_input($connection) for non-blocking query result consumption - Added pg_flush($connection) for non-blocking query write completion - -- PDO_pgsql - Added PDO::pgsqlGetNotify($result_type = PDO::FETCH_USE_DEFAULT, $ms_timeout = 0) - Added PDO::pgsqlGetPid() + function foo($x) { + $newX = $x + 1; + var_dump(func_get_arg(0)); + } -- Reflection - Added ReflectionFunction::isVariadic() and ReflectionParameter::isVariadic(). +* Similarly exception backtraces will no longer display the original value that + was passed to a function and show the modified value instead. For example -- SPL - Added SplFileObject::fread($length) to complement fwrite() method (>= 5.5.11) + function foo($x) { + $x = 42; + throw new Exception; + } + foo("string"); -- Zip: - Added ZipArchive::setPassword($password) + will now result in the stack trace -======================================== -7. New Classes and Interfaces -======================================== + Stack trace: + #0 file.php(4): foo(42) + #1 {main} + while previously it was: -======================================== -8. Removed Extensions -======================================== + Stack trace: + #0 file.php(4): foo('string') + #1 {main} + While this should not impact runtime behavior of your code, it is worthwhile + to be aware of this difference for debugging purposes. -======================================== -9. Other Changes to Extensions -======================================== + The same limitation also applies to debug_backtrace() and other functions + inspecting function arguments. + +Relevant RFC: https://wiki.php.net/phpng + +Changes to integer handling +--------------------------- + +* Invalid octal literals (containing digits larger than 7) now produce compile + errors. For example, the following is no longer valid: + + $i = 0781; // 8 is not a valid octal digit! + + Previously the invalid digits (and any following valid digits) were simply + ignored. As such $i previously held the value 7, because the last two digits + were silently discarded. + +* Bitwise shifts by negative numbers will now throw an ArithmeticError: + + var_dump(1 >> -1); + // ArithmeticError: Bit shift by negative number + +* Left bitwise shifts by a number of bits beyond the bit width of an integer + will always result in 0: + + var_dump(1 << 64); // int(0) + + Previously the behavior of this code was dependent on the used CPU + architecture. For example on x86 (including x86-64) the result was int(1), + because the shift operand was wrapped. + +* Similarly right bitwise shifts by a number of bits beyond the bit width of an + integer will always result in 0 or -1 (depending on sign): + + var_dump(1 >> 64); // int(0) + var_dump(-1 >> 64); // int(-1) + +Relevant RFC: https://wiki.php.net/rfc/integer_semantics + +Changes to string handling +-------------------------- + +* Strings that contain hexadecimal numbers are no longer considered to be + numeric and don't receive special treatment anymore. Some examples of the + new behavior: + + var_dump("0x123" == "291"); // bool(false) (previously true) + var_dump(is_numeric("0x123")); // bool(false) (previously true) + var_dump("0xe" + "0x1"); // int(0) (previously 16) + + var_dump(substr("foo", "0x1")); // string(3) "foo" (previously "oo") + // Notice: A non well formed numeric value encountered + + filter_var() can be used to check if a string contains a hexadecimal number + or convert such a string into an integer: + + $str = "0xffff"; + $int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX); + if (false === $int) { + throw new Exception("Invalid integer!"); + } + var_dump($int); // int(65535) + +* Due to the addition of the Unicode Codepoint Escape Syntax for double-quoted + strings and heredocs, "\u{" followed by an invalid sequence will now result in + an error: + + $str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence + + To avoid this the leading backslash should be escaped: + + $str = "\\u{xyz}"; // Works fine + + However, "\u" without a following { is unaffected. As such the following code + won't error and will work the same as before: + + $str = "\u202e"; // Works fine + +Relevant RFCs: +* https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings +* https://wiki.php.net/rfc/unicode_escape + +Changes to error handling +------------------------- -- cURL: - - The following constants have been removed as they are now marked "obsolete" - in the underlying library and never had any effect to begin with: - . CURLOPT_CLOSEPOLICY - . CURLCLOSEPOLICY_CALLBACK - . CURLCLOSEPOLICY_LEAST_RECENTLY_USED - . CURLCLOSEPOLICY_LEAST_TRAFFIC - . CURLCLOSEPOLICY_OLDEST - . CURLCLOSEPOLICY_SLOWEST - -- GMP: - The GMP extension now uses objects as the underlying data structure, rather - than resources. GMP instances now support dumping, serialization, cloning, - casts to primitive types and have overloaded operators. - (RFC: https://wiki.php.net/rfc/operator_overloading_gmp) - -- OCI8: - - Added Implicit Result Set support for Oracle Database 12c with a - new oci_get_implicit_resultset() function. - - Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no longer - unnecessarily initiates an internal ROLLBACK during connection - close. - - Multi-row OCI_RETURN_LOB queries require fewer "round trips" to the database. - - Added DTrace probes enabled with PHP's generic --enable-dtrace - - The oci_internal_debug() function is now a no-op. - - The phpinfo() output format for OCI8 has changed. +* There are now two exception classes: Exception and Error. Both classes + implement a new interface Throwable. Type hints in exception handling code + may need to be changed to account for this. + +* Some fatal errors and recoverable fatal errors now throw an Error instead. + As Error is a separate class from Exception, these exceptions will not be + caught by existing try/catch blocks. + + For the recoverable fatal errors which have been converted into an exception, + it is no longer possible to silently ignore the error from an error handler. + In particular, it is no longer possible to ignore type hint failures. + +* Parser errors now generate a ParseError that extends Error. Error + handling for eval()s on potentially invalid code should be changed to catch + ParseError in addition to the previous return value / error_get_last() + based handling. + +* Constructors of internal classes will now always throw an exception on + failure. Previously some constructors returned NULL or an unusable object. + +* The error level of some E_STRICT notices has been changed. + +Relevant RFCs: +* https://wiki.php.net/rfc/engine_exceptions_for_php7 +* https://wiki.php.net/rfc/throwable-interface +* https://wiki.php.net/rfc/internal_constructor_behaviour +* https://wiki.php.net/rfc/reclassify_e_strict + +Other language changes +---------------------- + +* Removed support for static calls to non-static methods from an incompatible + $this context. In this case $this will not be defined, but the call will be + allowed with a deprecation notice. An example: + + class A { + public function test() { var_dump($this); } + } + + // Note: Does NOT extend A + class B { + public function callNonStaticMethodOfA() { A::test(); } + } + + (new B)->callNonStaticMethodOfA(); + + // Deprecated: Non-static method A::test() should not be called statically + // Notice: Undefined variable $this + NULL + + Note that this only applies to calls from an incompatible context. If class B + extended from A the call would be allowed without any notices. + +* It is no longer possible to use the following class, interface and trait names + (case-insensitive): + + bool + int + float + string + null + false + true + + This applies to class/interface/trait declarations, class_alias() and use + statements. + + Furthermore the following class, interface and trait names are now reserved + for future use, but do not yet throw an error when used: + + resource + object + mixed + numeric + +* The yield language construct no longer requires parentheses when used in an + expression context. It is now a right-associative operator with precedence + between the "print" and "=>" operators. This can result in different behavior + in some cases, for example: + + echo yield -1; + // Was previously interpreted as + echo (yield) - 1; + // And is now interpreted as + echo yield (-1); + + yield $foo or die; + // Was previously interpreted as + yield ($foo or die); + // And is now interpreted as + (yield $foo) or die; + + Such cases can always be resolved by adding additional parentheses. + + . Removed ASP (<%) and script (