PHP 7.1 UPGRADE NOTES

1. Backward Incompatible Changes
2. New Features
3. Changes in SAPI modules
4. Deprecated Functionality
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
12. Windows Support
13. Other Changes


========================================
1. Backward Incompatible Changes
========================================

- Core:
  . 'void' can no longer be used as the name of a class, interface, or trait.
    This applies to declarations, class_alias() and use statements.
  . 'iterable' can no longer be used as the name of a class, interface, or
    trait. This applies to declarations, class_alias() and use statements.
    (RFC: https://wiki.php.net/rfc/iterable)
  . (int), intval() where $base is 10 or unspecified, settype(), decbin(),
    decoct(), dechex(), integer operators and other conversions now always
    respect scientific notation in numeric strings.
    (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
  . The ASCII 0x7F Delete control character is no longer permitted in unquoted
    identifiers in source code.
  . The following functions may no longer be called dynamically using $func(),
    call_user_func(), array_map() or similar:
     . extract()
     . compact()
     . get_defined_vars()
     . func_get_args()
     . func_get_arg()
     . func_num_args()
     . parse_str() with one argument
     . mb_parse_str() with one argument
     . assert() with a string argument
    (RFC: https://wiki.php.net/rfc/forbid_dynamic_scope_introspection)
  . If the error_log is set to syslog, the PHP error levels are mapped to the
    syslog error levels. This brings finer differentiation in the error logs
    in contrary to the previous approach where all the errors are loggged with
    the notice level only.
  . Don't call destructors of incompletely constructed objects, even if they
    are kept referenced. See bug #29368 and Zend/tests/bug29368_1.phpt.
  . call_user_func() will now consistently throw a warning if a function with
    reference arguments is called. However, call_user_func() will no longer
    abort the call in this case.
  . rand() and srand() are now aliases of mt_rand() and mt_srand().
    Consequently the output of the following functions has changed:
     . rand()
     . shuffle()
     . str_shuffle()
     . array_rand()
  . Fixes to random number generators mean that mt_rand() now produces a
    different sequence of outputs to previous versions. If you relied on
    mt_srand() to produce a deterministic sequence, it can be called using
    mt_srand($seed, MT_RAND_PHP) to produce the old sequences.
  . URL rewriter has been improved.
     . Use dedicated buffer for Session module rewrite and User rewrite.
     . Full path URL rewrite is supported. Allowed domain can be specified.
       $_SERVER['HTTP_HOST'] is allowed by default when host whitelist is empty.
     . Use session.trans_sid_tags and session.trans_sid_hosts to control
       session rewrite.
     . Use url_rewriter.tags and url_rewriter.hosts to control user rewrite.
     . <form>'s "action" attribute is used to check if URL rewrite is allowed
       and listed under hosts whitelist.
     . <fieldset> is no longer considered as a special tag. <form> is the
       only tag considered special.
  . Calling a function with less arguments than mandatory declared ones in
    signature now issues a Fatal Error (Error Exception) instead of a Warning.
    (RFC https://wiki.php.net/rfc/too_few_args).
  . The error message for E_RECOVERABLE errors has been changed from "Catchable
    fatal error" to "Recoverable fatal error".
  . The empty index operator (e.g. $str[] = $x) is not supported for strings
    anymore, and throws a fatal error instead of silently converting to array.
  . Array elements or object properties that are automatically created during
    by-reference assignments will now result in a different order. For example
  
        $array = [];
        $array["a"] =& $array["b"];
        $array["b"] = 1;
        var_dump($array);
  
    now results in the array ["b" => 1, "a" => 1], while for PHP 7.0 the result
    was ["a" => 1, "b" => 1].

- JSON:
  . The serialize_precision is used instead of precision when encoding double
    values.
  . An empty key is decoded as an empty property name instead of using _empty_
    property name when decoding object to stdClass.
  . When calling json_encode with JSON_UNESCAPED_UNICODE option, U+2028 and
    U+2029 are escaped.

- mbstring:
  . mb_ereg() and mb_eregi() will now set the $regs argument to an empty array,
    if nothing matched. Formerly, $regs was not modified in that case.

- OpenSSL:
  . Dropped sslv2 stream.

- Session:
  . Session ID is generated from CSPRNG directly. As a result, Session ID length
    could be any length between 22 and 256. Note: Max size of session ID depends
    on save handler you are using.
  . Following INIs are removed
     . session.hash_function
     . session.hash_bits_per_charactor
     . session.entropy_file
     . session.entropy_length
  . New INIs and defaults
     . session.sid_length (Number of session ID characters - 22 to 256.
       (php.ini-* default: 26 Compiled default: 32)
     . session.sid_bits_per_character (Bits used per character. 4 to 6.
       php.ini-* default: 5 Compiled default: 4)
    Length of old session ID string is determined as follows
     . Used hash function's bits.
        . session.hash_function=0 - MD5 128 bits (This was default)
        . session.hash_function=1 - SHA1 192 bits
     . Bits per character. (4, 5 or 6 bits per character)
     . Examples
         MD5 and 4 bits = 32 chars,  ceil(128/4)=32
         MD5 and 5 bits = 26 chars,  ceil(128/5)=26
         MD5 and 6 bits = 22 chars,  ceil(128/6)=22
         SHA1 and 4 bits = 48 chars, ceil(192/4)=48
         SHA2 and 5 bits = 39 chars, ceil(192/5)=39
         SHA1 and 6 bits = 32 chars, ceil(192/6)=32
         and so on.
  . session_start() returns FALSE and no longer initializes $_SESSION when
    it failed to start session.

- Reflection:
  . The behavior of ReflectionMethod::invoke() and ::invokeArgs() has been
    aligned, which causes slightly different behavior than before for some
    pathological cases.

========================================
2. New Features
========================================
- Core
  . Added void return type, which requires that a function not return a value.
    (RFC: https://wiki.php.net/rfc/void_return_type)
  . Added iterable pseudo-type accepting any array or object implementing
    Traversable.
    (RFC: https://wiki.php.net/rfc/iterable)
  . String offset access now supports negative references, which will be
    counted from the end of the string.
    (RFC: https://wiki.php.net/rfc/negative-string-offsets)
  . Added a form of the list() construct where keys can be specified.
    (RFC: https://wiki.php.net/rfc/list_keys)
  . Added [] = as alternative construct to list() =.
    (RFC: https://wiki.php.net/rfc/short_list_syntax)
  . Number operators taking numeric strings now emit "A non well formed numeric
    value encountered" E_NOTICEs for leading-numeric strings, and "A
    non-numeric value encountered" E_WARNINGs for non-numeric strings.
    This always applies to the +, -, *, /, **, %, << and >> operators, and
    their assignment counterparts +=, -=, *=, /=, **=, %=, <<= and >>=.
    For the bitwise operators |, & and ^, and their assignment counterparts
    |=, &= and ^=, this only applies where only one operand is a string.
    Note that this never applies to the bitwise NOT operator, ~, which does not
    handle numeric strings, nor to the increment and decrement operators
    ++ and --, which have a unique approach to handling numeric strings.
    (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
  . Closure::fromCallable (RFC: https://wiki.php.net/rfc/closurefromcallable)
  . Added support for class constant visibility modifiers.
    (RFC: https://wiki.php.net/rfc/class_const_visibility)
  . TypeError messages for arg_info type checks will now say "must be ...
    or null", or "must ... or be null" where the parameter or return type
    accepts null. arg_info type checks are used by all userland functions with
    type declarations, and some internal functions. Both nullable type
    declarations (?int) and parameters with default values of null
    (int $foo = NULL) are considered to "accept null" for this purpose.
  . The simple syntax for variable parsing inside of string literals now
    supports negative offsets.

========================================
3. Changes in SAPI modules
========================================
- apache2handler:
  . Implemented per module logging.
  . Implemented error level mapping between PHP and Apache for the error logs.

========================================
4. Deprecated Functionality
========================================

- 'e' option of mb_ereg_replace() and mb_eregi_replace().
- ext/mcrypt is now fully deprecated.

========================================
5. Changed Functions
========================================
- get_headers() has an extra parameter which allows passing a custom stream
  context.
- The first $varname argument for getenv() is no longer mandatory, the
  current environment variables will be returned as an associative array
  when omitted.
- json_encode() accepts new option JSON_UNESCAPED_LINE_TERMINATORS that
  disables escaping of U+2028 and U+2029 characters when
  JSON_UNESCAPED_UNICODE is supplied.
- long2ip() accepts integer as parameter now
- pg_last_notice() accepts optional long parameter to specify operation.
  PGSQL_NOTICE_LAST - Get last notice (Default)
  PGSQL_NOTICE_ALL - Get all stored notices
  PGSQL_NOTICE_CLEAR - Remove all stored notices
  It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls.
  It returned FALSE for empty notice previously.
- pg_fetch_all() accepts 2nd optional result type parameter like
  pg_fetch_row().
- pg_select() accepts 4th optional result type parameter like pg_fetch_row().
- parse_url() is more restrictive now and supports RFC3986.
- unpack() accepts an additional optional $offset argument. '@' format code
  (that specifes an absolute position) is applyed to input data after
  the $offset argument.
- strpos(), stripos(), substr_count(), grapheme_strpos(), grapheme_stripos(),
  grapheme_extract(), iconv_strpos(), mb_strimwidth(), mb_ereg_search_setpos(),
  mb_strpos() and mb_stripos() now accept negative string offsets.
- substr_count() and mb_strimwidth() additionally also accept negative length.
- file_get_contents() accepts a negative seek offset if the stream is seekable.
- tempnam() throws a notice when failing back to the system temp dir.
- getopt() has an extra by-ref parameter : optind
- mb_ereg() and mb_ereg_replace() reject illegal byte sequences.
- FILTER_FLAG_EMAIL_UNICODE can be used with filter_var() for email validation
  according to RFC 6531.
- output_reset_rewrite_vars() no longer reset session URL rewrite vars.
- the lasinsertid() in pdo_pgsql extension triggers an error, when no nextval()
  were called in in the current session.


========================================
6. New Functions
========================================
- Core:
  . Added sapi_windows_cp_set(), sapi_windows_cp_get(), sapi_windows_cp_is_utf8(),
    sapi_windows_cp_conv() for codepage handling.

- cURL:
  . Added curl_multi_errno() and curl_share_errno() to return the last error
    number of curl_multi and curl_share resources.
  . Added curl_share_strerror() to convert error code to error message text
    describing the error.

- pcntl:
  . Added pcntl_signal_get_handler() that returns the current signal handler
    for a particular signal.

- Session:
  . Added session_gc() that performs session data garbage collection.
    https://wiki.php.net/rfc/session-gc
  . Added session_create_id() for creating custom session ID.
    https://wiki.php.net/rfc/session-create-id

- Standard:
  . Added is_iterable() that determines if a value will be accepted by the new
    iterable pseudo-type.

========================================
7. New Classes and Interfaces
========================================

========================================
8. Removed Extensions and SAPIs
========================================

========================================
9. Other Changes to Extensions
========================================

- Date:
  . Invalid serialization data for a DateTime or DatePeriod object will now
    throw an instance of Error from __wakeup() or __set_state() instead of
    resulting in a fatal error.
  . Timezone initialization failure from serialized data will now throw an
    instance of Error from __wakeup() or __set_state() instead of resulting in
    a fatal error.
  . DateTime and DateTimeImmutable now properly incorporate microseconds when
    constructed from the current time, either explicitly or with a relative
    string (e.g. "first day of next month"). This means that naive comparisons
    of two newly created instances will now more likely return FALSE instead of
    TRUE:
      new DateTime() == new DateTime();

- DBA:
  . Data modification functions (e.g.: dba_insert()) now throw an instance of
    Error instead of triggering a catchable fatal error if the key does not
    contain exactly two elements.

- DOM:
  . Invalid schema or RelaxNG validation contexts will throw an instance of
    Error instead of resulting in a fatal error.
  . Attempting to register a node class that does not extend the appropriate
    base class will now throw an instance of Error instead of resulting in a
    fatal error.
  . Attempting to read an invalid or write to a readonly property will throw
    an instance of Error instead of resulting in a fatal error.

- GD:
  . Changed the default of the ini setting gd.jpeg_ignore_warning to 1.

- IMAP:
  . An email address longer than 16385 bytes will throw an instance of Error
    instead of resulting in a fatal error.
    
- Intl:
  . Failure to call the parent constructor in a class extending Collator
    before invoking the parent methods will throw an instance of Error
    instead of resulting in a recoverable fatal error.
  . Cloning a Transliterator object may will now throw an instance of Error
    instead of resulting in a fatal error if cloning the internal
    transliterator fails.

- LDAP:
  . Providing an unknown modification type to ldap_batch_modify() will now
    throw an instance of Error instead of resulting in a fatal error.

- Mbstring:
  . mb_ereg() and mb_eregi() will now throw an instance of ParseError if an
    invalid PHP expression is provided and the 'e' option is used.

- Mcrypt:
  . mcrypt_encrypt() and mcrypt_decrypt() will throw an instance of Error
    instead of resulting in a fatal error if mcrypt cannot be initialized.

- Mysqli:
  . Attempting to read an invalid or write to a readonly property will throw
    an instance of Error instead of resulting in a fatal error.

- Reflection:
  . Failure to retrieve a reflection object or retrieve an object property
    will now throw an instance of Error instead of resulting in a fatal error.

- Session:
  . Custom session handlers that do not return strings for session IDs will 
    now throw an instance of Error instead of resulting in a fatal error
    when a function is called that must generate a session ID.
  . Only CSPRNG is used to generate session ID.

- SimpleXML:
  . Creating an unnamed or duplicate attribute will throw an instance of Error
    instead of resulting in a fatal error.

- SPL:
  . Attempting to clone an SplDirectory object will throw an instance of Error
    instead of resulting in a fatal error.
  . Calling ArrayIterator::append() when iterating over an object will throw an
    instance of Error instead of resulting in a fatal error.

- SQLite3:
  . Upgraded bundled SQLite lib to 3.13.0

- Standard:
  . assert() will throw a ParseError when evaluating a string given as the first
    argument if the PHP code is invalid instead of resulting in a catchable
    fatal error.
  . Calling forward_static_call() outside of a class scope will now throw an
    instance of Error instead of resulting in a fatal error.

- Tidy:
  . Creating a tidyNode manually will now throw an instance of Error instead of
    resulting in a fatal error.

- WDDX:
  . A circular reference when serializing will now throw an instance of Error
    instead of resulting in a fatal error.

- XML-RPC:
  . A circular reference when serializing will now throw an instance of Error
    instead of resulting in a fatal error.

- Zip:
  . ZipArchive::addGlob() will throw an instance of Error instead of resulting
    in a fatal error if glob support is not available.

========================================
10. New Global Constants
========================================

- Core:
  . PHP_FD_SETSIZE

- JSON:
  . JSON_UNESCAPED_LINE_TERMINATORS

- Pgsql:
  PGSQL_NOTICE_LAST
  PGSQL_NOTICE_ALL
  PGSQL_NOTICE_CLEAR

- Standard:
  . IMAGETYPE_WEBP

========================================
11. Changes to INI File Handling
========================================

- serialize_precision
  . If the value is set to -1, then the dtoa mode 0 is used. The value -1
    is now used by default.

- precision
  . If the value is set to -1, then the dtoa mode 0 is used. No changes
    in default value which is still 14.

========================================
12. Windows Support
========================================

- Core:
  . Support for long and UTF-8 path;

    If an application is UTF-8 conform, no further action is required. For
    applications depending on paths in non UTF-8 encodings for I/O, an explicit
    INI directive has to be set. The encoding INI settings check relies on the
    order in the core:
      - internal_encoding
      - default_charset
      - zend.multibyte

    Several functions for codepage handling were itroduced:
      - sapi_windows_cp_set() to set the default codepage
      - sapi_windows_cp_get() to retrieve the current codepage
      - sapi_windows_cp_is_utf8()
      - sapi_windows_cp_conv() to convert between codepages, using iconv()
        compatible signature
    These functions are thread safe.

    The console output codepage is adjusted depending on the encoding used in
    PHP. Depending on the concrete system OEM codepage, the visible output
    might or might be not correct. For example, in the default cmd.exe and on
    a system with the OEM codepage 437, outputs in codepages 1251, 1252, 1253
    and some others can be shown correctly when using UTF-8. On the same system,
    chars in codepage like 20932 probably won't be shown correctly. This refers
    to the particular system rules for codepage, font compatibility and the
    particular console program used. PHP automatically sets the console codepage
    according to the encoding rules from php.ini. Using alternative consoles
    instead of cmd.exe directly might bring better experience in some cases.
    Nevertheless be aware, runtime codepage switch after the request start
    might bring unexpected side effects on CLI. The preferrable way is php.ini.

    As a result of UTF-8 support in the streams, PHP scripts are not limited
    to ASCII or ANSI filenames anymore. This is supported out of the box on
    CLI. For other SAPI, the documentation for the corresponding server
    is useful.

    Long paths support is transparent. Paths longer than 260 bytes get
    automatically prefixed with \\?\. The max path length is limited to
    2048 bytes. Be aware, that the path segment limit (basename length) still
    persists.

    The recommended way to handle file paths, I/O and other related topics is
    by utilizing UTF-8.

  . Support for ftok()

- FCGI
  . PHP_FCGI_CHILDREN is respected. If this environment variable is defined,
    the first php-fcgi.exe process will exec the specified number of children.
    Those will share the same TCP socket. 

- readline:
  . The readline extension is supported through the WinEditLine library
    (http://mingweditline.sourceforge.net/). Thereby, the interactive CLI
    shell is supported as well (php.exe -a).

    It is well known, but nevertheless is worth mentioning again, that
    the readline extension is not thread safe and will never be. Thus,
    the usage of it with any true thread safe SAPI (like Apache mod_winnt) is
    strongely discouraged.

========================================
13. Other Changes
========================================

