Luego de comentar diferencias y tips a tener en cuenta a la hora de usar PHP4 y PHP5, ha llega el momento de ocuparnos de PHP6.

Aparentemente, y esto es solo una estimación, tendremos la versión estable de PHP6 a finales de este año, aunque hay quienes apuestan por su salida a principios de 2007. En ese momento estarán conviviendo 3 versiones de PHP en el mercado. Es por eso que recomendamos empezar a plantearse que acción se tomará para no quedar relegado y usando software obsoleto.

Por lo pronto, para que vayas saboreando la nueva llegada y para que lo veas con tus propios ojos, te dejo el php.ini que se maneja para PHP6-dev, o sea PHP6 versión desarrollo, construido el 14 de agosto. En varias oportunidades haremos mención en este artículo a alguna opción del php.ini que se agregó, o a alguna que se quitó, por lo que puede ser interesante ver directamente en el archivo las nuevas configuraciones disponibles.

Soporte pleno a UNICODE

UNICODE es la solución provista por el UNICODE Consortium para brindar pleno soporte a todos los caracteres y símbolos de cualquier lenguaje en el mundo. Identifica cada carácter a través de un número, independientemente de la plataforma o el lenguaje de programación. Actualmente soporta más de 99.000 caracteres, con capacidad para soportar más de 1 millón de ellos.

También soporta el concepto de “locale”, los cuales actúan como agrupadores locales referidos a la lingüística y preferencias culturales de una comunidad de usuarios.
Actualmente existen 360 locales, distribuidos en 121 lenguajes y 142 territorios. Con esto, estaríamos hablando de grandes modificaciones en la manipulación de Strings para nuestros scripts. Explicaremos a que nos referimos:

La estrategia PHP4/PHP5 para la manipulación de strings es “byte-oriented”, y usada tanto para texto como para imágenes. Es decir, un único tipo de string es soportado por el Core de PHP. A pesar de las extensiones iconv y mbstring, persiste el inconveniente de interoperabilidad entre distintas plataformas.

Por otro lado, mientras que en PHP4 y PHP5 tenemos un solo tipo de string, en PHP6 tendremos dos tipos: el string tipo UNICODE (texto con UTF-16 encoding) y el string tipo Binario (texto con otros encodings y reales datos binarios). El php.ini nos proporcionará la siguiente línea:

unicode.semantics=off|on

Con unicode.semantics=off estaremos usando los conocidos strings con caracteres de 1 byte (PHP4 y PHP5). De la otra forma, strings literales UNICODE, que pueden ocupar mas de 1 byte.

Tendremos:
    

Cantidad de caracteres -> strlen() Cantidad de bytes -> otra función distinta de strlen()
Para los strings binarios, PHP6 introduce una nueva sintaxis. El contenido depende directamente del encoding.

<?
  // Asumimos  que el script está escrito en UTF-8
  $str  = b'woof'; // 77 6F  6F 66
  $str  = b"\xa0\x01"; // A0 01
  ?>);

Otro recurso que se agrega en PHP6 es el de secuencias de escapeo, lo que significa que podemos embeber caracteres UNICODE dentro del string, a través de su código.

Utilizando la barra invertida:

 $str =  "letra hebrea alef: א";
  es lo  mismo que …
  $str =  "letra hebrea alef: \u05D0"; 

Utilizando el nombre del caracter:

$str  = "Alef: \C{HEBREW LETTER ALEF}";
  es lo  mismo que …
  $str =  "Alef: \u05D0";

En cuanto al encoding, también tendremos muchas opciones:

//  unicode.runtime_encoding = iso-8859-1
  Determina  que encoding utilizar a la hora de las conversiones (castings)
  Ejemplo:
  $str  = “Pichongol”;
  $str  = (binary) $str; 
  //  String binario con encoding iso-8859-1
  
  $str  = (unicode) $str; 
  //  String UNICODE
  
  $str =  (string) $str 
  // Si  unicode.semantics=on convierte a string UNICODE, 
  // caso contrario convierte a tipo binario
  unicode.script_encoding  = iso-8859-1
  
  //  Determina encoding utilizado para leer el script
  //  Podemos modificar el script encoding en tiempo de ejecución
  declare  (encoding="iso-8859-1"); 
  
  unicode.output_encoding  = utf-8 
  // Determina encoding para el flujo de la salida estándar:  echo(), var_dump(), print()
  
  unicode.filename_encoding  = utf-8
//  Especifica encoding para nombres de archivos y directorios

<?
  $str  = "øl"; // string UNICODE (ISO-8859-1)
  echo $str;  // convierte $str a UTF-8
?>

Acceso a caracteres:

La novedad en PHP6 en cuanto a acceso a caracteres UNICODE utilizando la sintaxis de los corchetes, es la resolución en función de los puntos de código UNICODE, en lugar de resolución por numero de byte.
Ejemplo:

$str = “אƻ”;
  echo $str[1]; // veremos “ƻ”

Lo interesante es que esta modificación solo afecta al Core de PHP, y no a nuestro script, por lo que no necesitaremos hacer modificaciones en nuestro código cuando accedemos a caracteres con la sintaxis de corchetes.

Una buena noticia para los desarrolladores de PHP en todos los puntos del planeta, es la posibilidad de utilizar identificadores de variables, clases y demás, con caracteres UNICODE.
Podríamos hacer: 

<?
  class µαβ {   function  Ω£α(){…}
  }  
  
  //  o ….
  $фшь  = “algo”;
  ?>

Esto es simplemente un resumen de lo que la incorporación de UNICODE a PHP6 nos permite. Podríamos escribir un artículo entero sobre ello, lo cual no es el objetivo real de este artículo. Seguiremos en nuestro camino, enfocándonos en los restantes aspectos en los cuales PHP6 nos traerá novedades.

Modo compatibilidad con PHP 4.x

PHP.ini:
; Enable compatibility mode with Zend Engine 1 (PHP 4.x)
zend.ze1_compatibility_mode = Off/On

Esta línea permite mantener el comportamiento del Zend Engine 1 (PHP 4.x). Por ejemplo, el paso de objetos como argumentos de funciones se realiza por valor (copia), y no por referencia (identificador).
Claramente, en la práctica el modo compatibilidad no obtuvo los resultados esperados, por lo que es un hecho que se descartará, no solo en PHP6, sino en el mucho más próximo release PHP5.2.

Register globals queda en el pasado

Muchos desarrolladores consideran esta opción un verdadero dolor de cabeza, y con justa razón. A su vez, también fue un cambio polémico el introducido en PHP4.2 al dejar en nuestro php.ini register_globals=off. Esta opción le indica a PHP si debe crear una variable
Explicaremos cual es el comportamiento detrás de esto: hacemos la petición dominio.com/validar.php.
Se ejecuta el siguiente código:

<?
  if(pago_al_dia()){
		$vigente=true;
  }
  if($vigente){
		echo “Excelente, estamos dentro del  sistema”;
  }
  ?>

Supongamos que la función pago_al_dia()  toma datos de un formulario y los procesa.
Hasta acá esta todo perfecto, chequeamos si el cliente tiene su pago al día, para tildarlo como vigente. Ahora bien, ¿que sucede si algún “amigo” cambia la petición http anterior por dominio.com/validar.php?vigente=1 ?
Si tenemos register_globals=off, la variable $vigente se crea como una entrada para el array superglobal $_GET…algo así como $_GET[‘vigente’]

En nuestra porción de código:

<?
  if($vigente){
		echo “Excelente, estamos dentro del  sistema”;
  }
  ?>

La evaluación if($vigente) saldrá con false, por lo que no se producirá login.
La situación cambia si tenemos register_globals=on. Ante una petición dominio.com/validar.php?vigente=1 PHP generara la entrada para $_GET y además seteará $vigente=1. En este caso la evaluación del if anterior saldrá con true, y se producirá el login, con el consecuente grave fallo de seguridad para nuestro sistema.

Como decíamos anteriormente, siempre estuvo la discusión sobre si activar o desactivar las register_globals. Y tenemos para todos los gustos…pareciera que lo único aceptable es dejar las register_globals desactivadas, pero no faltaría quien diría que en el ejemplo anterior podríamos hacer:

<?
    $vigente=false;
	
	if(pago_al_dia()){
		$vigente=true;
  }
  
  if($vigente){
		echo “Excelente, estamos dentro del  sistema”;
  }
  ?>

De esta forma acondicionamos nuestro script para trabajar con las register_globals=on. Evolución de las register_globals ¿Qué acción toma PHP6 al respecto? Se acabo la discusión. Se elimina la opción del php.ini, y queda el comportamiento register_globals=off inalterable.

Evolución:

  • PHP3: Todas las variables de request(GET, POST, etc.) se registran como globales.
  • PHP4: La opción en nuestro php.ini nos permite register_globals=on|off
    • PHP4 <= 4.2: Default register_globals=on
    • PHP4 >= 4.2: Default register_globals=off
  • PHP5: La opción en nuestro php.ini nos permite register_globals=on|off
    • Default register_globals=off
  • PHP6: Se elimina la opción register_globals
    • No se registran variables como globales.

Safe Mode (Modo Seguro) eliminado

Otra opción del php.ini relacionada con la seguridad de nuestros script es safe_mode=on|off.
Entra en juego cuando tenemos configurados servidores virtuales en el mismo servidor físico.
Cuando tenemos safe mode activado y en el caso de que necesitemos operar sobre un archivo, PHP se encarga de chequear que el dueño del script que se esta ejecutando sea el mismo dueño del archivo(UID del .php = UID del archivo). De la misma forma, deshabilita funciones “críticas” de seguridad.

La experiencia ha indicado que el safe_mode trae más amarguras que alegrías.
Por ejemplo, en sistemas Unix con safe_mode=on, cuando creamos un directorio le asigna el UID del Apache. Por ende, un usuario común no tiene acceso a modificar ni eliminar dicho directorio, como así tampoco de los archivos dentro de el.

Cuestiones como esta creemos que hicieron replantear el tema entre los diseñadores de PHP. El resultado: PHP6 elimina el soporte para safe_mode.
Afortunadamente seguiremos contando con open_base_dir, opción que cuando se activa, limita todas las operaciones de archivos a dicho directorio, y a sus subdirectorios.

Adiós a los $HTTP_*_VARS

Es el fin de los Arrays largos. Esto supone que los superglobales $_* han cumplido correctamente su objetivo, y no tiene sentido registrar información duplicada.
Por supuesto, se elimina del php.ini la opción register_long_arrays = Off|On.

Magic quotes también están fuera

Las magic quotes, o comillas mágicas, son una solución para la inserción de datos en bases de datos, como así también, atacan problemas de seguridad de los scripts, como el conocido SQL injection. Se encargan de escapear comillas simples y comillas dobles, agregándoles una barra invertida delante de cada una.
De todas formas, son más sus contras que sus pro.

Por un lado, no siempre necesitamos escapear los datos. Muchas veces es innecesario e ineficiente para el entorno de ejecución tener que hacerlo sistemáticamente. Además los datos se vuelven no portables y hasta a veces dificultan su uso.

Como era de esperar, no se incluyen en PHP6 como opción de nuestro php.ini, a su vez, en PHP4 y PHP5 se recomienda largamente desactivar dichas opciones y utilizar desde el código la función que agrega las magic quotes, solo cuando realmente es necesario: addslashes()

En PHP4 y PHP5 se recomienda:

magic_quotes_gpc  = Off
  magic_quotes_runtime  = Off
  magic_quotes_sybase = Off

Pero cuidado: requiere de una mayor responsabilidad a la hora de programar y validar los datos que el usuario ingresa.

Hasta aquí, los principales cambios que nos traerá PHP6

A modo de conclusión, y refiriéndonos explícitamente al objetivo del artículo, podemos finalizar con que claramente la migración a PHP5 no debe subestimarse, y mucho menos desestimarse. La compatibilidad PHP4 -> PHP6 no es algo que se ganará en uno o dos, pero se puede lograr incrementalmente saltando a PHP5 a mitad de camino.

PHP6 será el trazo que cierre el circulo sobre el cual se están moviendo todos los cambios del Core de PHP, con el que Zend intenta competir a nivel empresarial con potencias como Java o .NET, claro está, en ambientes Web.