martes, 27 de diciembre de 2011

Tochopost: Todas las novedades finales en PHP 5.4 recapituladas y al descubierto #php

Tal y como ya comenté hace más de un año aquí mismo en mi blog, PHP 5.4 viene repleto de novedades interesantes. Y aunque se ha prolongado su liberación demasiado tiempo, ahora PHP 5.4 está en un periodo de Release Candidates, y todos esperamos que nos llegue la versión final para el primer trimestre de 2012.

Y precisamente ahora que PHP 5.4 está en su periodo de Releases Candidates con las características congeladas y únicamente corrigiendo bugs, es el momento ideal para analizar las novedades finales que nos vendrán con esta nueva versión. La mejor hasta la fecha, pero que sigue por detrás en muchas características con respecto a la gran mayoría de lenguajes de programación modernos.


Cosas que se han quedado en el tintero:

  • Scalar type hints en parámetros y tipos primitivos como keywords (inteer, string...). Al final no se podrá forzar a que un parámetro sea entero, float, booleano... Debido a problemas de retrocompatibilidad, como en frameworks que definen clases con los nombres de los tipos primitivos. Ejemplo: class integer { }
  • Cadenas Unicode/UTF-8 directamente en el lenguaje. Posiblemente haya que esperar a PHP 6 para cadenas unicode. Por lo menos se ha incluído la extensión antigua mbstring como parte del core de PHP 5.4. Así que a partir de ahora las funciones mb_* deberían estar disponibles siempre.
  • Soporte para anotaciones nativas. Actualmente las anotaciones se pueden simular usando documentación embebida, que se puede obtener mediante reflexión. Aunque esta opción es poco limpia e introduce una serie de problemas sustanciales. Además de que muchos editores contraen por defecto los comentarios de documentación y podemos obviar información relevante incluída en los comentarios y usada como anotaciones.
  • Soporte de list() directamente en foreach: foreach ($array as list($a, $b))
  • Acceso a constantes de tipo array: [0, 1, 2][1]
  • Soporte para cualquier combinación mínimamente compleja de acceso $a()() o $a()[0]()
  • Sobreescritura de operadores en clases de usuario. Sin duda sería un gran añadido a PHP, pero que parece estar aún muy lejos.

Resumen de novedades que sí nos llegan:

Sintaxis reducida para arrays

Simplifica la sintaxis de los literales de array pareciéndose un poco más a JSON pero sin llegar a serlo:

array('a', 'b', 'c', 'd' => array(1, 2, 3)) == ['a', 'b', 'c', 'd' => [1, 2, 3]]

Las listas de índice autonumérico se definen igual que en JSON [1, 'str', 3, 4].
La parte de claves no correlativas, lo medianamente equivalente a objetos JSON {a: 1, b: 2}, en PHP 5.4 se define igual que array() ['a' => 1, 'b' => 2]
En general la sintaxis es la misma que con array(...) pero cambiándolo por [...]

Mayor flexibilidad (aunque aún bastante limitada) de sintaxis en llamadas a método y acceso a arrays

Llamadas de primer nivel con array dereferencing y acceso directo a arrays en llamadas a función

function helloWorld() { echo "Hello World from PHP 5.4!\n"; }
$a = [[['helloWorld']]];
$a[0][0][0]();



function test() { return [['a'], ['b', 'result']]; }
echo test()[1][1];

Llamadas dinámicas a métodos estáticos

class A { function test() { } }
$var = 'test';
A::$var();

Traits

Permitirá separación de clases grandes en clases más pequeñas, y reutilización horizontal en clases no relacionadas de código común.

trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}

class CanIGetHello {
use HelloWorld;
}

$hello = new CanIGetHello();
$hello->sayHello();

Callable typehint


  function foo(callable $do) {
  }
  foo("strcmp");
  foo(function() {});
  $o = new ArrayObject();
  foo(array($o, "count"));
  foo(1); // error
  foo(array()); // error
  foo(NULL); // error

Notación binaria

https://wiki.php.net/rfc/binnotation4ints

$flags  = 0b00000000;
$flags |= 0b01010101;

Montones de nuevas APIs y mejoras de las actuales

Mejoras de rendimiento y de recursos utilizados

Referencias:

Listado detallado de todos los cambios en PHP 5.4:
Información relevante para todos los desarrolladores de PHP (nuevas sintaxis, APIs y características deprecadas) y administradores de sistemas (PHP.INI y liberaciones de versiones):
Información relevante para creadores de extensiones en C para PHP:
Información relevante sobre Request For Comments de PHP implementados, desestimados y futuros:
RFCs relevantes:
Más información:

Changelog reducido:

- General improvements:
  . Changed silent conversion of array to string to produce a notice. (Patrick)
  . Added class member access on instantiation (e.g. (new foo)->bar()) support.
    (Felipe)
  . Improve the warning message of incompatible arguments. (Laruence)
  . Improve ternary operator performance when returning arrays. (Arnaud, Dmitry)
  . Added callable typehint. (Hannes)
  . Implemented closure rebinding as parameter to bindTo. (Gustavo Lopes)
  . Turn on html_errors by default again in php.ini-production like it was in
    PHP 5.3, but only generate docref links when the docref_root INI setting is
    not empty. (Derick)
  . Fixed bug #55378: Binary number literal returns float number though its
    value is small enough. (Derick)
  . Added support for SORT_NATURAL and SORT_FLAG_CASE in array
    sort functions (sort, rsort, ksort, krsort, asort, arsort and
    array_multisort). FR#55158 (Arpad)
  . Disable windows CRT warning by default, can be enabled again using the ini
    directive windows_show_crt_warnings. (Pierre)
  . Removed support for putenv("TZ=..") for setting the timezone. (Derick)
  . Removed the timezone guessing algorithm in case the timezone isn't set with
    date.timezone or date_default_timezone_set(). Instead of a guessed
    timezone, "UTC" is now used instead. (Derick)
 . Short array syntax, see UPGRADING guide for full details
   (rsky0711 at gmail . com, sebastian.deutsch at 9elements . com, Pierre)
 . Binary numbers format (0b001010). (Jonah dot Harris at gmail dot com)
 . Support for Class::{expr}() syntax (Pierrick)
 . Zend Signal Handling. (Lucas Nealan,Arnaud Le Blanc,Brian Shire, Ilia)  https://wiki.php.net/rfc/zendsignals
- Removed legacy features:
 . Removed magic_quotes_gpc, magic_quotes_runtime and magic_quotes_sybase
    ini options. get_magic_quotes_gpc, get_magic_quotes_runtime are kept
    but always return false, set_magic_quotes_runtime raises an
    E_CORE_ERROR. (Pierrick, Pierre)
. break/continue $var syntax. (Dmitry) . Safe mode and all related ini options. (Kalle) . register_globals and register_long_arrays ini options. (Kalle) . import_request_variables(). (Kalle) . allow_call_time_pass_reference. (Pierrick) . define_syslog_variables ini option and its associated function. (Kalle) . highlight.bg ini option. (Kalle) . Session bug compatibility mode (session.bug_compat_42 and session.bug_compat_warn ini options). (Kalle) . session_is_registered(), session_register() and session_unregister() functions. (Kalle) . y2k_compliance ini option. (Kalle)

- Changed E_ALL to include E_STRICT. (Stas)

- Improved Zend Engine
  . Improved parse error messages. (Felipe) 
https://wiki.php.net/rfc/improved-parser-error-message
- Improved CLI SAPI:
  . Added built-in web server that is intended for testing purpose.
    (Moriyoshi)

- Improved core functions:
  . Changed http_response_code() to be able to set a response code. (Kalle) 
http://es2.php.net/http_response_code

- General improvements:
  . Added multibyte support by default. Previously php had to be compiled
    with --enable-zend-multibyte. Now it can be enabled or disabled through
    zend.multibyte directive in php.ini. (Dmitry)
  . Removed compile time dependency from ext/mbstring (Dmitry)
  . Added support for Traits. (Stefan)
  . Added closure $this support back. (Stas)
  . Added array dereferencing support. (Felipe)
  . Added indirect method call through array. FR #47160. (Felipe)
  . Added support for object references in recursive serialize() calls.
    FR #36424. (Mike)
  . Added http_response_code() function. FR #52555. (Paul Dragoonis, Kalle)
  . Added header_register_callback() which is invoked immediately
    prior to the sending of headers and after default headers have
    been added. (Scott)
  . Added DTrace support. (David Soria Parra)
  . Improved output layer, see README.NEW-OUTPUT-API for internals. (Mike)
  . Improved unserialize() performance.
    (galaxy dot mipt at gmail dot com, Kalle)
  . Improved unix build system to allow building multiple PHP binary SAPIs and
    one SAPI module the same time. FR #53271, FR #52419. (Jani)
  . Added optional argument to debug_backtrace() and debug_print_backtrace()
    to limit the amount of stack frames returned. (Sebastian, Patrick)
  . Added stream metadata API support and stream_metadata() stream class
    handler. (Stas)
  . User wrappers can now define a stream_truncate() method that responds
    to truncation, e.g. through ftruncate(). FR #53888. (Gustavo)

- Improved Zend Engine memory usage: (Dmitry)
  . Replaced zend_function.pass_rest_by_reference by
    ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags.
  . Replaced zend_function.return_reference by ZEND_ACC_RETURN_REFERENCE
    in zend_function.fn_flags.
  . Removed zend_arg_info.required_num_args as it was only needed for internal
    functions. Now the first arg_info for internal functions (which has special
    meaning) is represented by zend_internal_function_info structure.
  . Moved zend_op_array.size, size_var, size_literal, current_brk_cont,
    backpatch_count into CG(context) as they are used only during compilation.
  . Moved zend_op_array.start_op into EG(start_op) as it's used only for
    'interactive' execution of single top-level op-array.
  . Replaced zend_op_array.done_pass_two by ZEND_ACC_DONE_PASS_TWO in
    zend_op_array.fn_flags.
  . op_array.vars array is trimmed (reallocated) during pass_two.
  . Replaced zend_class_entry.constants_updated by ZEND_ACC_CONSTANTS_UPDATED
    in zend_class_entry.ce_flags.
  . Reduced the size of zend_class_entry by sharing the same memory space
    by different information for internal and user classes.
    See zend_class_entry.info union.
  . Reduced size of temp_variable.

- Changed the structure of op_array.opcodes. The constant values are moved from
  opcode operands into a separate literal table. (Dmitry)

- Improved Zend Engine, performance tweaks and optimizations: (Dmitry)
  . Inlined most probable code-paths for arithmetic operations directly into
    executor.
  . Eliminated unnecessary iterations during request startup/shutdown.
  . Changed $GLOBALS into a JIT autoglobal, so it's initialized only if used.
    (this may affect opcode caches!)
  . Improved performance of @ (silence) operator.
  . Simplified string offset reading. $str[1][0] is now a legal construct.
  . Added caches to eliminate repeatable run-time bindings of functions,
    classes, constants, methods and properties.
  . Added concept of interned strings. All strings constants known at compile
    time are allocated in a single copy and never changed.
  . Added an optimization which saves memory and emalloc/efree calls for empty
    HashTables. (Stas, Dmitry)
  . ZEND_RECV now always has IS_CV as its result.
  . ZEND_CATCH now has to be used only with constant class names.
  . ZEND_FETCH_DIM_? may fetch array and dimension operands in different order.
  . Simplified ZEND_FETCH_*_R operations. They can't be used with the
    EXT_TYPE_UNUSED flag any more. This is a very rare and useless case.
    ZEND_FREE might be required after them instead.
  . Split ZEND_RETURN into two new instructions ZEND_RETURN and
    ZEND_RETURN_BY_REF.
  . Optimized access to global constants using values with pre-calculated
    hash_values from the literals table.
  . Optimized access to static properties using executor specialization.
    A constant class name may be used as a direct operand of ZEND_FETCH_*
    instruction without previous ZEND_FETCH_CLASS.
  . zend_stack and zend_ptr_stack allocation is delayed until actual usage.

- Improved CLI SAPI: (Johannes, Moriyoshi)
  . Added command line option --rz <name> which shows information of the
    named Zend extension. (Johannes)
  . Interactive readline shell improvements: (Johannes)
    . Added "cli.pager" php.ini setting to set a pager for output.
    . Added "cli.prompt" php.ini setting to configure the shell prompt.
    . Added shortcut #inisetting=value to change ini settings at run-time.
    . Changed shell not to terminate on fatal errors.
    . Interactive shell works with shared readline extension. FR #53878.

- Improved FastCGI SAPI: (Dmitry)
  . Added apache compatible functions: apache_child_terminate(),
    getallheaders(), apache_request_headers() and apache_response_headers()
  . Improved performance of FastCGI request parsing.

- Improved core functions:
  . number_format() no longer truncates multibyte decimal points and thousand
    separators to the first byte. FR #53457. (Adam)
  . Added hex2bin() function. (Scott)

- Improved Date extension:
  . Added the + modifier to parseFromFormat to allow trailing text in the
    string to parse without throwing an error. (Stas, Derick)

- Improved JSON extension:
  . Added JsonSerializable interface. (Sara)
  . Added JSON_BIGINT_AS_STRING, extended json_decode() sig with $options.
    (Sara)
  . Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
    numeric strings to integers. (Ilia)
  . Added new json_encode() option JSON_PRETTY_PRINT. FR #44331. (Adam)
  . Added new json_encode() option JSON_UNESCAPED_SLASHES. FR #49366. (Adam)

UPGRADING reducido

=============================
2. Reserved words and classes
=============================

- "callable", "insteadof" and "trait" are reserved words now.

===================================
3. Changes made to engine behaviour
===================================

- It's now possible to enforce the class' __construct arguments in an abstract
  constructor in the base class.

  abstract class Base
  {
    abstract public function __construct();
  }
  class Foo extends Base
  {
    public function __construct($bar) {}
  }

  Now emits a Fatal error due the incompatible declaration.

- In previous versions, names of superglobals could be used for parameter
  names, thereby shadowing the corresponding superglobal. This now causes a
  fatal error such as "Cannot re-assign auto-global variable GLOBALS".

- Turning null, false or empty string into an object by adding a property
  will now emit a warning instead of an E_STRICT error.

  $test = null;
  $test->baz = 1;

  To create a generic object you can use StdClass:
  $test = new StdClass;
  $test->baz = 1;

- Converting array to string now will cause E_NOTICE warning.

- Chained string offsets - e.g. $a[0][0] where $a is a string - now work.

- Non-numeric string offsets - e.g. $a['foo'] where $a is a string - now return
  false on isset() and true on empty(), and produce warning if trying to use them.
  Offsets of types double, bool and null produce notice. Numeric strings ($a['2'])
  still work as before.
  Note that offsets like '12.3' and '5 and a half' are considered non-numeric
  and produce warning, but are converted to 12 and 5 respectively for BC reasons.

- Changed E_ALL to include E_STRICT.

- Closures now support scopes and $this and can be rebound to
  objects using Closure::bind() and Closure::bindTo().

- Added multibyte support by default. Now it can be enabled or disabled through
  zend.multibyte directive in php.ini.

- <?= is now always available regardless of the short_open_tag setting.

- Parse error messages are changed to contain more information about the error.
====================
12. Syntax additions
====================
- Traits:
    trait HelloWorld {
        public function sayHello() {
            echo 'Hello World!';
        }
    }

    class CanIGetHello {
        use HelloWorld;
    }

    $hello = new CanIGetHello();
    $hello->sayHello();

- Function call result array access:
  e.g.
    foo()[0]
    $foo->bar()[0]

- Callable typehint, argument must be callable (i.e. pass is_callable($arg, false))
  example:
  function foo(callable $do) {
  }
  foo("strcmp");
  foo(function() {});
  $o = new ArrayObject();
  foo(array($o, "count"));

- Short array syntax:
    $a = [1, 2, 3, 4];
    $a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4];
    $a = ['one' => 1, 2, 'three' => 3, 4];

- Binary number format:
    0b00100 0b010101

- $str[1][0] where $str is a string is now a legal construct.

- Anonymous functions now support using $this and class scope.
  Anonymous function can be declared as "static" to ignore the scope.

- Class::{expr}() syntax is now supported:
    class A {
        static function foo() {
            echo "Hello world!\n";
        }
    }
    $x = "f";
    $y = "o";
    A::{$x.$y.$y}();

- Class member access on instantiation:
  (new foo)->method()
  (new foo)->property
  (new foo)[0]

No hay comentarios:

Publicar un comentario en la entrada