PHP 7.3. Que hay de nuevo


Sintaxis


  1. Soften Heredoc y Nowdoc Requisitos de sintaxis
  2. Soporte para comas finales en llamadas a funciones y métodos
  3. Enlaces en la list()

Características en desuso (en desuso)


  1. image2wbmp() desuso
  2. Las banderas FILTER_FLAG_SCHEME_REQUIRED y FILTER_FLAG_HOST_REQUIRED cuando se utiliza FILTER_VALIDATE_URL
  3. Registrar constantes independientes en desuso

Nuevas características


  1. json_decode excepciones opcional para errores en json_decode json_encode y json_decode
  2. Agregar la función is_countable()
  3. Agregar las funciones array_key_first() y array_key_last()

Cambios


  1. Migración de PCRE a PCRE2

Soften Heredoc y Nowdoc Requisitos de sintaxis


Heredoc y Nowdoc exigieron poner el identificador de cierre primero en una nueva línea.


Un ejemplo:


 $foo = <<<IDENTIFIER the crazy dog jumps over the lazy fox "foo" bar; IDENTIFIER 

Aquí, el IDENTIFIER cierre debe ser el primer carácter en la nueva línea para que esto funcione. Además, no debería haber ningún otro carácter después del identificador de cierre (excepto ; que es opcional).


El RFC para PHP 7.3 sugiere eliminar estos requisitos para mejorar la legibilidad del código. En primer lugar, agregar sangría al usar identificadores heredoc/nowdoc .


Lista completa de cambios a la sintaxis heredoc/nowdoc :


  1. El identificador de cierre no tiene que ser el primer carácter de la cadena.
  2. El identificador de cierre está sangrado con espacios o pestañas.
  3. La sangría (espacios o pestañas) no debe mezclarse. Si hace esto, obtendrá el Parse error: Invalid indentation - tabs and spaces cannot be mixed in .. on line ..
  4. El número exacto de espacios / pestañas utilizados antes del identificador de cierre se eliminará de cada línea de la expresión heredoc/nowdoc .
  5. Si el número de caracteres de sangría utilizados antes del identificador de cierre es mayor que en cualquiera de las líneas de la expresión, obtendrá el Parse error: Invalid body indentation level (expecting an indentation level of at least ..) in .. on line ..
  6. varias expresiones después del identificador de cierre funcionarán sin errores

Aquí hay un fragmento que aprovecha las nuevas funciones sin romper las nuevas reglas:


 $foo = ['foo', 'bar', <<<EOT baz - hello world! -- ahoy EOT, 'qux', 'quux' ]; var_dump($foo); 

La salida será:


 array(5) {        [0]=>           string(3) "foo" [1]=>           string(3) "bar" [2]=>           string(29) "baz - hello world! -- ahoy" [3]=> string(3) "qux" [4]=> string(4) "quux" }     ` 

Tenga en cuenta que la sangría utilizada en la declaración que usa heredoc no se muestra en la salida de var_dump() , y continuamos enumerando los elementos de la matriz después del identificador EOT .


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Hasta que use un conjunto de identificadores de caracteres heredox/nowdoc idénticos como el comienzo de una línea, heredox/nowdoc en un caballo.


 $foo = <<<HELLO HELLO_WORLD <--         HELLOWORLD <--     HELLO WORLD <--    HELLO; 

Si tiene heredoc/nowdoc sintaxis heredoc/nowdoc similar a la descrita anteriormente, noto que con PHP 7.3, PHP aceptará el primer literal HELLO y arrojará un error en la siguiente línea. En versiones anteriores, HELLO WORLD no se percibía como un identificador de cierre para heredoc. Gracias / u / ImSuperObjective2 con reddit por señalar esto


Soporte para comas finales en llamadas a funciones y métodos


Este es un cambio simple que permite el uso de comas finales en llamadas a funciones y métodos. Esto no afecta la declaración.


Por ejemplo, será posible la siguiente sintaxis:


 //  foo('bar', 'baz',); //        'baz' 

En versiones anteriores a PHP-7.3, el fragmento anterior arroja un PHP Parse error: syntax error, unexpected ')' in .. on line ..


No puede usar más de una coma al final o usar comas para omitir argumentos. Esto es principalmente un cambio para una función con parámetros variables. También con nuevas ediciones, la sintaxis de la matriz se verá más consistente.


Tenga en cuenta que no puede usar esta función en las declaraciones de función / método; esto está mal:


 function foo($bar, $baz, ) { // nah, you can't do this. } 

RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Nada El código existente continuará funcionando. Si tiene llamadas a funciones que aceptan parámetros variables, agregue comas finales a estos lugares para mayor comodidad. Pero usarlos en todas partes es obviamente demasiado.


Enlaces en la list()


La función list() es útil para asignar rápidamente valores a variables desde una matriz. Antes de PHP 7.3, no era posible especificar una variable por referencia. Antes de PHP 7.3, el siguiente fragmento condujo a un error fatal:


 $arr = ['apple', 'orange']; list($a, &$b) = $arr; $b = 'banana'; echo $arr[1]; // Fatal error: [] and list() assignments cannot be by reference in .. on line .. 

Es imposible hacer referencia a variables non-referencable : list($a, &$b) = [12, 14]; dará un Fatal error: Cannot assign reference to non referencable value in .. on line ..


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


No En lugar de usar list() para llenar varias variables, sugeriría que use objetos de valor para simplificar las cosas. Todavía se pasarán por referencia, pero harán que su código sea mucho más limpio.


image2wbmp() desuso


image2wbmp() función image2wbmp() de la extensión GD se usa para generar imágenes en el formato WBMP (Wireless Bitmap). En PHP 7.3, está en desuso a favor de la función imagewbmp() .


Si usa image2wbmp() , simplemente reemplace el nombre de la función con imagewbmp y todo estará bien. Más de 5,500 image2wbmp() en github versus más de 39,300 imagewbmp() . Parece que el equipo de desarrollo de PHP está quitando características menos utilizadas para minimizar el impacto.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Si usa la función image2wbmp() , reemplace la llamada con imagewbmp . Aproveche la automatización que puede cambiar esto por usted.


Las banderas FILTER_FLAG_SCHEME_REQUIRED y FILTER_FLAG_HOST_REQUIRED cuando se utiliza FILTER_VALIDATE_URL


Este es un movimiento hacia adelante. Cuando usa filter_var($var, FILTER_VALIDATE_URL) , se pueden establecer dos filter_var($var, FILTER_VALIDATE_URL) adicionales para garantizar una comprobación estricta de URL: FILTER_FLAG_SCHEME_REQUIRED y FILTER_FLAG_HOST_REQUIRED .
A partir de PHP 5.2.1, ambos indicadores se aplican implícitamente independientemente de si están configurados o no.


Si su código usa estas banderas, simplemente elimínelas y estará bien. Actualmente hay más de 5,000 resultados de búsqueda de github que los usan.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Dado que estos dos indicadores están en desuso, verá una notificación como:


 Deprecated: filter_var(): explicit use of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is deprecated in ... 

Todo lo que tienes que hacer es eliminar las dos banderas, como ya están implícitos cuando se usa FILTER_VALIDATE_URL .


Registrar constantes independientes en desuso


La función define() permite declarar una constante en modo sin distinción entre mayúsculas y minúsculas. Debe declarar explícitamente una constante entre mayúsculas y minúsculas pasando el tercer parámetro de la función true . Este no es el comportamiento predeterminado y probablemente no sea coherente con la capacidad de declarar constantes a través de la palabra clave const .


 define('Foo', 'Bar', true); 

El código anterior arrojará una notificación de obsolescencia: En desuso Deprecated: define(): Declaration of case-insensitive constants is deprecated in ...


Además, cuando intente acceder a las constantes que se declararon en Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo" ( FOO ), verá una advertencia bastante útil: Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo" Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Tendrá que ir al código base, donde las constantes independientes del registro se declaran y posteriormente son correctas. Es extremadamente improbable que haya algún problema con esto, porque es bastante laborioso detectar todos los casos de uso, pero como resultado el código se aclarará.


No he encontrado ningún ejemplo de este uso en github, pero al menos Drupal y WordPress (dos proyectos PHP bastante antiguos y maduros) tienen constantes que no distinguen entre mayúsculas y minúsculas.


json_decode excepciones opcional para errores en json_decode json_encode y json_decode


Uno de mis favoritos Durante todos estos años, json_encode() y json_decode() silencio sobre los errores en las variables PHP o las cadenas json, lo que condujo a un código etiquetado. Este caso fue incluso en la famosa crítica de PHP: un fractal de diseño pobre .


json_decode devuelve nulo para entrada no válida, mientras que nulo es un objeto absolutamente verdadero para JSON decodificado. Esta función es completamente poco confiable, a menos que, por supuesto, llame a json_last_error cada vez que la use.

Pasaron 6 años después de esa publicación de blog y tuvimos la oportunidad de obtener un error sobre fallas de json:


 try { json_decode("{", false, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $exception) { echo $exception->getMessage(); //  "Syntax error" } 

La nueva \JsonException es un descendiente de \Exception , así como la constante JsonException y la propia JsonException están en el espacio de nombres global.


Le recomiendo que comience a usar esta función. Hay bibliotecas de terceros, como daverandom / excepcional-json , que implementan una funcionalidad similar para las versiones de PHP 7.2 y posteriores. Con la aparición de esta función en el núcleo de PHP, puede eliminar este paquete y toneladas de código de plantilla feo con la llamada json_last_error() en cada lugar donde trabaje con json.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Nada si no está utilizando su propia excepción y / o constante con los mismos nombres.


Agregar la función is_countable()


PHP 7.2 tiene muchas funciones obsoletas y con errores. Si estás en PHP 7.2. call count() usando una variable no countable , entonces PHP mostrará una advertencia al respecto. En ediciones generales, había una propuesta para verificar la variable resultante para countable antes de usarla en count() .


countable variable countable es una matriz u objeto que implementa la interfaz \Countable . Dado que se usará una gran cantidad de código repetitivo durante la verificación, PHP 7.3 introdujo una nueva función is_countable() , que verifica la variable para ... bueno ... la posibilidad de usar count() .


Escribí un polyfile para is__countable () si quieres comenzar a usar esta característica ahora.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Hasta que se is_countable() su propia función is_countable() , no habrá problemas.


Agregar las funciones array_key_first() y array_key_last()


En PHP, hay 75 funciones diferentes para trabajar con matrices, pero hasta ahora no ha sido una forma fácil de obtener las primeras y últimas claves de una matriz sin cambiar el puntero de la matriz o iterar sobre todas las claves (a través de array_keys() ) y luego obtener el primer / último valor.


Han array_key_first() dos nuevas funciones, array_key_first() y array_key_last() que le permiten hacer esto.


El RFC también sugirió agregar array_value_first() y array_value_last() , pero esta parte no pasó la votación.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Si no declaró sus propias array_key_first() y array_key_last() , entonces no hay problema.


Migración de PCRE a PCRE2


PHP usa expresiones regulares compatibles con Perl o PCRE en la biblioteca para trabajar con expresiones regulares. Desde PHP 7.2, se ha utilizado la versión 8.x de PCRE Legacy Library, y en PHP 7.3 ya se utilizará PCRE2. Tenga en cuenta que PCRE2 se considera una nueva biblioteca, aunque es en gran medida compatible con PCRE (8.x).


La nueva biblioteca es más agresiva en la validación de patrones y puede provocar errores en el código existente. El siguiente fragmento no será válido con PHP 7.3:


 preg_match('/[\w-.]+/', ''); 

PHP lanzará una advertencia Warning: preg_match(): Compilation failed: invalid range in character class at offset 3 .
El problema con el patrón: para que esto funcione, el guión debe moverse al final o escapar.


 preg_match('/[\w\-.]+/', ''); 

El código anterior funcionará bien no solo con PHP 7.3, sino también con versiones anteriores. En el nuevo patrón, el guión se escapa - a \- . Este es el problema más común que puede encontrar al resolver problemas de compatibilidad.


Este es un cambio bastante menor, pero existe la posibilidad de que todo salga mal. El mensaje de error indica la posición exacta del personaje en la expresión regular. Asegúrese de revisar cuidadosamente su código. Verifique la compatibilidad de sus expresiones regulares con la sintaxis Regex Buddy través de Regex Buddy u otro software similar. Consulte la descripción de la sintaxis PCRE2 y la sintaxis PCRE heredada para obtener más información.


RFC , discusión sobre Externals.io , implementación


Impacto de compatibilidad hacia atrás


Dado que PCRE2 es más exigente y estricto con las plantillas, algunas de sus llamadas preg_match() y similares pueden no funcionar. La solución varía desde simplemente actualizar la plantilla (por ejemplo, guiones de escape) hasta reescribir plantillas. Asegúrese de que todas sus pruebas pasen.

Source: https://habr.com/ru/post/es422507/


All Articles