summaryrefslogtreecommitdiff
path: root/UPGRADING
blob: 9faf7c7ce6ca5ec1f2ae57088b70800a86f55d76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
PHP 7.0 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
========================================

Language changes
================

Changes to variable handling
----------------------------

* Indirect variable, property and method references are now interpreted with
  left-to-right semantics. Some examples:

      $$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']()

  To restore the previous behavior add explicit curly braces:

      ${$foo['bar']['baz']}
      $foo->{$bar['baz']}
      $foo->{$bar['baz']}()
      Foo::{$bar['baz']}()
      
* The global keyword now only accepts simple variables. Instead of

      global $$foo->bar;

  it is now required to write the following:

      global ${$foo->bar};

* 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

      function getArray() { return [1, 2, 3]; }

      $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

  will now throw a strict standards error regardless of whether parentheses
  are used. Previously no notice was generated in the second case.

* 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 ["a" => 1, "b" => 1], while previously the result
  was ["b" => 1, "a" => 1];

Relevant RFCs:
* https://wiki.php.net/rfc/uniform_variable_syntax
* https://wiki.php.net/rfc/abstract_syntax_tree

Changes to list()
-----------------

* list() will no longer assign variables in reverse order. For example

      list($array[], $array[], $array[]) = [1, 2, 3];
      var_dump($array);

  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

      list($a, $b, $c) = [1, 2, 3];
      // $a = 1; $b = 2; $c = 3;
  
  will retain its current behavior.

* Empty list() assignments are no longer allowed. As such all of the following
  are invalid:

      list() = $a;
      list(,,) = $a;
      list($x, list(), $y) = $a;

* list() no longer supports unpacking strings (while previously this was only
  supported in some cases). The code

      $string = "xy";
      list($x, $y) = $string;

  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.

      list($a, $b) = (object) new ArrayObject([0, 1]);

  will now result in $a == 0 and $b == 1. Previously both $a and $b were null.

Relevant RFCs:
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency

Changes to foreach
------------------

* 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

      $array = [0, 1, 2];
      foreach ($array as &$val) {
          var_dump(current($array));
      }

  will now print the value int(0) three times. Previously the output was int(1),
  int(2) and bool(false).

* 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

      $array = [0, 1, 2];
      $ref =& $array; // Necessary to trigger the old behavior
      foreach ($array as $val) {
          var_dump($val);
          unset($array[1]);
      }

  will now print all three elements (0 1 2), while previously the second element
  1 was skipped (0 2).

* 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

      $array = [0];
      foreach ($array as &$val) {
          var_dump($val);
          $array[1] = 1;
      }

  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)".

* 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.

* Iteration of Traversable objects remains unchanged.

Relevant RFC: https://wiki.php.net/rfc/php7_foreach

Changes to parameter handling
-----------------------------

* 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:

      public function foo($a, $b, $unused, $unused) {
          // ...
      }

  Code like this should be changed to use distinct parameter names, for example:

      public function foo($a, $b, $unused1, $unused2) {
          // ...
      }

* 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

      function foo($x) {
          $x++;
          var_dump(func_get_arg(0));
      }
      foo(1);

  will now print "2" instead of "1". This code should be changed to either
  perform modifications only after calling func_get_arg(s)

      function foo($x) {
          var_dump(func_get_arg(0));
          $x++;
      }

  or avoid modifying the parameters altogether:

      function foo($x) {
          $newX = $x + 1;
          var_dump(func_get_arg(0));
      }

* Similarly exception backtraces will no longer display the original value that
  was passed to a function and show the modified value instead. For example

      function foo($x) {
          $x = 42;
          throw new Exception;
      }
      foo("string");

  will now result in the stack trace

      Stack trace:
      #0 file.php(4): foo(42)
      #1 {main}

  while previously it was:

      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.

  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
-------------------------

* 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 (<script language=php>) tags.
    (RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
  . Removed support for assigning the result of new by reference.
  . Removed support for scoped calls to non-static methods from an incompatible
    $this context. See details in https://wiki.php.net/rfc/incompat_ctx.
  . Removed support for #-style comments in ini files. Use ;-style comments
    instead.
  . $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.

Standard library changes
========================

  . substr() now returns an empty string instead of FALSE when the truncation happens on boundaries.
  . call_user_method() and call_user_method_array() no longer exists.
  . ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an 
    output buffer is created in an output buffer handler.
  . The internal sorting algorithm has been improved, what may result in
    different sort order of elements that compare as equal.
  . Removed dl() function on fpm-fcgi.
  . setcookie() with an empty cookie name now issues a WARNING and doesn't send an empty set-cookie header line anymore.

Other
=====

- Curl:
  . Removed support for disabling the CURLOPT_SAFE_UPLOAD option. All curl file
    uploads must use the curl_file / CURLFile APIs.

- Date:
  . Removed $is_dst parameter from mktime() and gmmktime().

- DBA
  . dba_delete() now returns false if the key was not found for the inifile
    handler, too.

- GMP
  . Requires libgmp version 4.2 or newer now.
  . gmp_setbit() and gmp_clrbit() now return FALSE for negative indices, making
    them consistent with other GMP functions.

- Intl:
  . Removed deprecated aliases datefmt_set_timezone_id() and
    IntlDateFormatter::setTimeZoneID(). Use datefmt_set_timezone() and
    IntlDateFormatter::setTimeZone() instead.

- libxml:
  . Added LIBXML_BIGLINES parser option. It's available starting with libxml 2.9.0
    and adds suppport for line numbers >16-bit in the error reporting.

- Mcrypt
  . Removed deprecated mcrypt_generic_end() alias in favor of
    mcrypt_generic_deinit().
  . Removed deprecated mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb()
    functions in favor of mcrypt_encrypt() and mcrypt_decrypt() with an
    MCRYPT_MODE_* flag.

- Session
  . session_start() accepts all INI settings as array. e.g. ['cache_limiter'=>'private']
    sets session.cache_limiter=private. It also supports 'read_and_close' which closes
    session data immediately after read data.
  . Save handler accepts validate_sid(), update_timestamp() which validates session
    ID existence, updates timestamp of session data. Compatibility of old user defined
    save handler is retained.
  . SessionUpdateTimestampHandlerInterface is added. validateSid(), updateTimestamp()
    is defined in the interface.
  . session.lazy_write(default=On) INI setting enables only write session data when
    session data is updated.

- Opcache
  . Removed opcache.load_comments configuration directive. Now doc comments
    loading costs nothing and always enabled.

- OpenSSL:
  . Removed the "rsa_key_size" SSL context option in favor of automatically
    setting the appropriate size given the negotiated crypto algorithm.
  . Removed "CN_match" and "SNI_server_name" SSL context options. Use automatic
    detection or the "peer_name" option instead.

- PCRE:
  . Removed support for /e (PREG_REPLACE_EVAL) modifier. Use
    preg_replace_callback() instead.

- PDO_pgsql:
  . Removed PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT attribute in favor of
    ATTR_EMULATE_PREPARES.

- Standard:
  . Removed string category support in setlocale(). Use the LC_* constants
    instead.
  . Removed set_magic_quotes_runtime() and its alias magic_quotes_runtime().

- JSON:
  . Rejected RFC 7159 incompatible number formats in json_decode string -
        top level (07, 0xff, .1, -.1) and all levels ([1.], [1.e1])
  . Calling json_decode with 1st argument equal to empty PHP string or value that 
    after casting to string is empty string (NULL, FALSE) results in JSON syntax error.

- Stream:
  . Removed set_socket_blocking() in favor of its alias stream_set_blocking().

- XSL:
  . Removed xsl.security_prefs ini option. Use XsltProcessor::setSecurityPrefs()
    instead.

========================================
2. New Features
========================================

- Core
  . Added group use declarations.
    (RFC: https://wiki.php.net/rfc/group_use_declarations)
  . Added null coalesce operator (??).
    (RFC: https://wiki.php.net/rfc/isset_ternary)
  . Support for strings with length >= 2^31 bytes in 64 bit builds.
  . Closure::call() method added (works only with userland classes).
  . Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings
    and heredocs.
  . define() now supports arrays as constant values, fixing an oversight where
    define() did not support arrays yet const syntax did.
  . Added the comparison operator (<=>), aka the spaceship operator.
    (RFC: https://wiki.php.net/rfc/combined-comparison-operator)
  . Added the yield from operator for delegating Generators like coroutines.
    (RFC: https://wiki.php.net/rfc/generator-delegation)
  . Reserved keywords can now be used in various new contexts.
    (RFC: https://wiki.php.net/rfc/context_sensitive_lexer)
  . Added support for scalar type declarations and strict mode using
    declare(strict_types=1) (RFC: https://wiki.php.net/rfc/scalar_type_hints_v5)
  . Added support for cryptographically secure user land RNG
    (RFC: https://wiki.php.net/rfc/easy_userland_csprng)

- Opcache
  . Added second level file based opcode cache. It may be enabled by setting
    opcache.file_cache=<DIR> configuration directive in php.ini. The second
    level cache may improve performance when SHM is full, at server restart or
    SHM reset. In addition, it's possibe to use file cache without SHM at all,
    using opcache.file_cache_only=1 (this may be useful for sharing hosting),
    and disable file cache consistency check, to speedup loading at the cost of
    safety, using opcache.file_cache_consistency_checks=0.
  . Added ability to move PHP code pages (PHP TEXT segment) into HUGE pages.
    It's possible to enable/disable this feature in php.ini through
    opcache.huge_code_pages=0/1. OS should be configured to provide huge pages.
  . Added Windows only opcache.file_cache_fallback=1 ini option, which implies
    the implemented fallback mechanism. When OPcache was not able to reattach
    the shared memory segment to the desired address and opcache.file_cache
    is on, opcache.file_cache_only=1 will be automatically enforced.

- OpenSSL
  . Added "alpn_protocols" SSL context option allowing encrypted client/server
    streams to negotiate alternative protocols using the ALPN TLS extension when
    built against OpenSSL 1.0.2 or newer. Negotiated protocol information is
    accessible through stream_get_meta_data() output.

- Reflection
  . Added a ReflectionGenerator class (yield from Traces, current file/line,
    etc.)
  . Added a ReflectionType class to better support the new return type and
    scalar type declarations features. The new ReflectionParameter::getType()
    and ReflectionFunctionAbstract::getReturnType() methods both return an
    instance of ReflectionType.

- Stream:
  . New Windows only stream context options was added to allow blocking reads
    on pipes. To enable it, pass array("pipe" => array("blocking" => true))
    when creating the stream context. Be aware, that this option can under
    circumstances cause dead locks on the pipe buffer. However it can be useful
    in several CLI use case scenarios.

========================================
3. Changes in SAPI modules
========================================

- FPM
  . Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes).
  . Listen = port now listen on all addresses (IPv6 and IPv4-mapped).

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

- Core
  . PHP 4 style constructors, where the constructor name is the same as the
    class name, are now deprecated.
  . Static calls to non-static methods are now deprecated.

- OpenSSL
  . The "capture_session_meta" SSL context option is now deprecated. Meta
    data concerning active crypto on a stream resource is now accessible
    through the return result from stream_get_meta_data().

========================================
5. Changed Functions
========================================

- parse_ini_file():
- parse_ini_string():
  . Added scanner mode INI_SCANNER_TYPED to yield typed .ini values.
- unserialize():
  . Added second parameter for unserialize function 
    (RFC: https://wiki.php.net/rfc/secure_unserialize) allowing to specify
    acceptable classes: 
    unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);

- proc_open():
  . The maximum number of pipes used by proc_open() was previously limited by
  hardcoded value of 16. This limit is now removed and the number of pipes is
  effectively limited by the amount of memory available to PHP.
  . New Windows only configuration option "blocking_pipes" can be used to
  force blocking reads on child process pipes. This covers several
  edge cases in CLI usage however can lead to dead locks. Also, this
  correlates with the new stream context options for pipes.

- array_column():
  The function now supports an array of objects as well as two-dimensional
  arrays. Only public properties are considered, and objects that make use of
  __get() for dynamic properties must also implement __isset().

- stream_context_create()
  It accepts now a Windows only configuration 
  array("pipe" => array("blocking" => <boolean>))  which forces blocking reads
  on pipes. This option should be used carefully because due to the
  platform restrictions dead locks on pipe buffers are possible.

- dirname()
  A new optional argument ($levels) allow to go up various times
  dirname(dirname($foo)) => dirname($foo, 2);

- debug_zval_dump
  It prints now "int" instead of "long", and "float" instead of "double".

========================================
6. New Functions
========================================

- GMP
  . Added gmp_random_seed().

- PCRE:
  . Added preg_replace_callback_array function
    (RFC: https://wiki.php.net/rfc/preg_replace_callback_array)

- Standard
  . Added intdiv() function for integer division.
  . Added error_clear_last() function to reset error state.

- Zip:
  . Added ZipArchive::setCompressionIndex() and ZipArchive::setCompressionName()
    for setting the compression method.

- Zlib:
  . Added deflate_init(), deflate_add(), inflate_init(), inflate_add()
    functions allowing incremental/streaming compression/decompression.

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

- ReflectionGenerator
- ReflectionType

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

- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/nsapi
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/mysql
- ext/sybase_ct
- ext/ereg

For more details see 

https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts
https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7

NOTE: NSAPI was not voted in the RFC, however it was removed afterwards. It turned
out, that the corresponding SDK isn't available anymore.

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

- Mhash
  Mhash is not an extension anymore, use function_exists("mhash") to check whether
  it is avaliable.

- GD
  The bundled libgd requires libwebp instead of libvpx for the WebP functionality.

- Openssl
  minimum supported OpenSSL version series was raised to 0.9.8

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

- Core
  . PHP_INT_MIN added.

- PCRE
  . This error constant is added to signal errors due to stack size limitations
    when PCRE JIT support is enabled:
  . PREG_JIT_STACKLIMIT_ERROR

- Zlib
  . These constants are added to control flush behavior with the new
    incremental deflate_add() and inflate_add() functions:
  . ZLIB_NO_FLUSH
  . ZLIB_PARTIAL_FLUSH
  . ZLIB_SYNC_FLUSH
  . ZLIB_FULL_FLUSH
  . ZLIB_BLOCK
  . ZLIB_FINISH

- GD
  . T1Lib support removed, thus lifting the optional dependency on T1Lib, the
    following is therefore not available anymore:

    Functions:
      - imagepsbbox()
      - imagepsencodefont()
      - imagepsextendedfont()
      - imagepsfreefont()
      - imagepsloadfont()
      - imagepsslantfont()
      - imagepstext()

    Resources:
      - 'gd PS font'
      - 'gd PS encoding'

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

- Core
  . Removed asp_tags ini directive. Trying to enable it will result in a fatal
    error.
  . Removed always_populate_raw_post_data ini directive.

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

- Core
  . Support for native 64 bit integers in 64 bit builds.
  . Support for large files in 64 bit builds.
  . Support for getrusage()

- ftp
  . The ftp extension is always shipped shared
  . For SSL support, the dependency on the openssl extension was abolished. Instead
    it depends alone on the openssl library. If it's present at the compile time,
    ftp_ssl_connect() is enabled automatically.

- imap
  . Static building of ext/imap is disabled

- odbc
  . The odbc extension is always shipped shared

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

- Core
  . Instead of being undefined and platform-dependent, NaN and Infinity will
    always be zero when cast to integer.
  . Calling a method on a non-object now raises a catchable error instead of a
    fatal error; see: https://wiki.php.net/rfc/catchable-call-to-member-of-non-object
  . Error messages for zend_parse_parameters, type hints and conversions now
    always say "integer" and "float" instead of "long" and "double".
  . Output buffering now continues to work for an aborted connection if
    ignore_user_abort is set to true.
  . Zend Extensions API was extended with zend_extension.op_array_persist_calc()
    and zend_extensions.op_array_persist() handlers. They allow to store (or
    reset) associated with op_array addition information in Opcache Shared
    Memory.
  . zend_internal_function.reserved[] array was introduced to allow association
    of aditional information with internal functions. In PHP-5 it was possible
    to use zend_function.op_array.reserved[] even for internal functions, but
    now we don't allocate extra space.