Qué esperar de PHP 5.5

El primer PHP 5.5 alfa ha sido lanzado públicamente. Después de tener un tiempo para probar y experimentar con él, ahora podemos ofrecerle una visión general detallada de lo que debemos esperar.!


Instalación

Si desea seguir este artículo, deberá instalar PHP 5.5 usted mismo. Puede encontrar el enlace al paquete fuente aquí. Además, si necesita el archivo binario de Windows, puede obtenerlo de la misma página.

Una vez que haya descargado el código fuente, extraiga todo en una carpeta y navegue hasta él con su programa de Terminal favorito. Puedes instalar PHP donde quieras, pero, por conveniencia, voy a crear un directorio en la raíz de mi disco, llamado PHP5.5. Para crear una nueva carpeta y luego convertir a su usuario en el propietario de dicha carpeta, escriba lo siguiente en su terminal:

 sudo mkdir /PHP5.5 nombre de usuario de sudo chown /PHP5.5

A continuación, debe decidir qué extensiones y características desea instalar con su copia de PHP. Ya que esta es una versión Alpha, destinada solo para pruebas, no me voy a preocupar por hacerla completamente destacada. Para este tutorial, solo voy a instalar cURL, pero es posible que desee agregar otras cosas, como MySQL o zip. Para ver una lista completa de las opciones de configuración, ejecute:

 ./ configure -h

Además de la opción de instalar cURL, hay otras dos propiedades que debemos configurar: prefijo y con-config-file-path opción. Estas dos propiedades configuran la ubicación de la instalación de PHP y la .ini archivo, respectivamente. Así que en la terminal, escriba:

 ./ configure --prefix = / PHP5.5 --with-config-file-path = / PHP5.5 --with-curl = ext / curl make make install

La primera línea configura PHP con cURL y establece la ubicación en la carpeta que creamos anteriormente. Las siguientes dos líneas crean PHP y mueven los archivos al directorio especificado. El siguiente paso es copiar la muestra. php.ini archivo a la carpeta de PHP. Para hacer esto, ejecute:

 cp php.ini-development /PHP5.5/php.ini

Ahora deberías tener todo instalado correctamente. La forma más fácil de probar esta nueva versión es ejecutar su servidor web incorporado. Navegar a la compartimiento carpeta dentro de la PHP5.5 directorio (cd /PHP5.5/bin), y escriba ./ php -t / Path / To / Directory -S 0.0.0.0:4444.

  • los -t la opción establece el directorio raíz del servidor (es decir, la ubicación donde colocará sus archivos PHP)
  • los -S La propiedad establece la dirección IP y el número de puerto al que se debe enlazar el servidor. Utilizando 0.0.0.0 para la dirección IP le dice al servidor que escuche en todas las direcciones IP (por ejemplo, localhost, 127.0.0.1, 192.168.0.100, etc.).

Si todo va bien, debe recibir un mensaje que le indica que el servidor está escuchando en la IP / puerto especificado, y le indicará la raíz del documento desde donde se está sirviendo. Ahora podemos empezar a jugar con las nuevas características.!


Generadores

Los generadores le permiten crear funciones personalizadas, que retienen el estado entre ejecuciones.

La mayor adición a PHP 5.5 tiene que ser generadores. Los generadores le permiten crear funciones personalizadas, que retienen el estado entre las ejecuciones. Funciona de una nueva palabra clave, llamada rendimiento, que se puede utilizar en una función para ingresar y enviar datos.

Esencialmente, cuando la función llega a una línea que contiene el comando de rendimiento, PHP congelará la ejecución de la función y volverá a ejecutar el resto de su programa. Cuando llame para que la función continúe, ya sea diciéndole que continúe o enviándole datos, PHP volverá a la función y continuará donde lo dejó, conservando los valores de cualquier variable local que se haya definido hasta allí..

Esto puede sonar algo genial al principio, pero si lo piensa, esto abre las puertas a muchas opciones de diseño interesantes. En primer lugar, simula los efectos de otros lenguajes de programación que tienen "Evaluación perezosa", como Haskell. Esto solo le permite definir conjuntos de datos infinitos y modelar funciones matemáticas después de su definición real. Además de eso, no tienes que crear tantas variables globales; Si una variable solo está destinada a una función específica, puede incluirla en un generador, y cosas como contadores pasan automáticamente por el propio generador en la forma de la clave del objeto devuelto..

Bueno, eso es suficiente teoría por ahora; Echemos un vistazo a un generador en acción. Para comenzar, navegue hasta la raíz del documento que definió al ejecutar el servidor PHP y cree un archivo, llamado "index.php". Ahora, abra el archivo y escriba lo siguiente:

 función fibonacci () $ a = 0; $ b = 1; while (verdadero) $ a = $ a + $ b; $ b = $ a - $ b; rendimiento $ a; 

Esta es la función "Hola Mundo" de conjuntos de datos infinitos. Es una función que dará salida a todos los números de fibonacci. Para usar el generador, todo lo que tienes que hacer es escribir:

 $ fib = fibonacci (); $ fib-> current (); $ fib-> siguiente (); $ fib-> current (); //… 

Lo que está pasando aquí es que estamos haciendo $ fib un objeto generador, y luego tienes acceso a los comandos subyacentes, como corriente() y siguiente(). los corriente() La función devuelve el valor actual del generador; Este es el valor de lo que rendiste en la función, en nuestro caso., $ a. Puede llamar a esta función varias veces y siempre obtendrá el mismo valor, porque corriente() La función no le dice al generador que continúe evaluando su código. Ahí es donde el siguiente() la función entra siguiente() se utiliza para descongelar el iterador y continuar con la función. Ya que nuestra función está dentro de un infinito. mientras bucle, se congelará de nuevo por la siguiente rendimiento comando, y podemos obtener el siguiente valor con otra llamada a corriente().

El beneficio para los generadores es que las variables locales son persistentes..

Si necesitabas hacer algo como esto en el pasado, deberías poner algún tipo de para bucle que calcula previamente los valores en una matriz y se detiene después de un cierto número de iteraciones (por ejemplo, 100), para no sobrecargar PHP. El beneficio para los generadores es que las variables locales son persistentes, y usted simplemente puede escribir lo que se supone que debe hacer la función, como se indica en la forma en que debe hacerlo. Lo que quiero decir con esto es que simplemente escribe la tarea y no te preocupas por las variables globales, y cuántas iteraciones deben realizarse.

La otra manera rendimiento Se puede utilizar para recibir datos. Funciona de la misma manera que antes: cuando la función llega a una línea con la rendimiento palabra clave, se detendrá, pero, en lugar de leer datos con corriente(), Le daremos datos con el enviar() función. Aquí hay un ejemplo de esto en acción:

 función Logger () $ log_num = 1; while (verdadero) $ f = rendimiento; echo "Log #". $ log_num ++. ":". $ f;  $ logger = Logger (); para ($ i = 0; $ i<10; $i++) $logger->enviar ($ i * 2); 

Este es un generador simple para mostrar un mensaje de registro. Todos los generadores comienzan en un estado de pausa; una llamada a enviar (o incluso corriente) arrancará el generador y continuará hasta que toque un rendimiento mando. los enviar El comando luego ingresará los datos enviados y continuará procesando la función hasta que llegue a la siguiente rendimiento. Cada llamada subsiguiente a enviar procesará un bucle; ingresará los datos enviados en $ f, y luego continuar hasta que vuelva a la siguiente rendimiento.

Entonces, ¿por qué no poner esto en una función regular? Bien, podría, pero, entonces, o bien necesitaría una variable global separada para realizar un seguimiento del número de registro, o tendría que crear una clase personalizada.

No piense en los generadores como una forma de hacer algo que nunca fue posible, sino más bien como una herramienta para hacer las cosas de manera más rápida y eficiente..

Incluso eran posibles conjuntos infinitos, pero tendría que volver a procesar la lista desde el principio cada vez (es decir, repasar los cálculos hasta llegar al índice actual), o almacenar todos sus datos dentro de variables globales. Con los generadores, su código es mucho más limpio y preciso..


Listas en para cada Declaraciones

La siguiente actualización que encontré bastante útil es la capacidad de dividir una matriz anidada en una variable local en una para cada declaración. los lista La construcción ha existido por un tiempo (desde PHP4); asigna una lista de variables a una matriz. Entonces, en lugar de escribir algo como:

 $ data = array ("John", "Smith", "032-234-4923"); $ fName = $ data [0]; $ lName = $ data [1]; $ cell = $ data [2];

Usted podría simplemente escribir:

 $ data = array ("John", "Smith", "032-234-4923"); list ($ fName, $ lName, $ cell) = $ data;

El único problema era que, si tenías una matriz de matrices (una matriz anidada) de información que querías mapear, no podías alternar entre ellas con una para cada lazo. En su lugar, tendría que asignar el para cada resultado a una variable local, y luego mapéelo con una lista construir solo dentro del bucle.

A partir de la versión 5.5, puede eliminar al intermediario y limpiar su código. Aquí hay un ejemplo de la forma antigua, frente a la nueva:

 // - Método antiguo - // foreach ($ parentArr as $ childArr) list ($ one, $ two) = $ childArr; // Continuar con el bucle // - Nuevo método - // foreach ($ parentArr como lista ($ uno, $ dos)) // Continuar con el bucle

La forma antigua puede no parecer demasiado problemática, pero es desordenada y hace que el código sea menos legible.


API de contraseña fácil

En la tarjeta gráfica integrada de mi Mac, pude realizar más de 200 millones de hashes por segundo!

Ahora este requiere un poco de conocimiento de hashes y encriptación para apreciar completamente.

La forma más fácil de codificar una contraseña en PHP ha sido usar algo como MD5 o un algoritmo SHA. El problema con funciones hash como estas es que son increíblemente fáciles de calcular. Ya no son útiles para la seguridad. Hoy en día, solo deben usarse para verificar la integridad de un archivo. Instalé un herher de GPU en mi computadora para probar esta afirmación. En la tarjeta gráfica integrada de mi Mac, ¡pude pasar por más de 200 millones de hashes por segundo! Si estuviera dedicado e invirtiera en una configuración de tarjeta gráfica de primera línea, podría pasar miles de millones de hashes por segundo.

La tecnología para estos métodos no estaba destinada a durar.

Entonces, ¿cómo solucionar este problema? La respuesta es que impones una carga ajustable en el algoritmo. Lo que quiero decir con esto es que haces que sea difícil de procesar. No es que deba tomar un par de segundos por hash, ya que eso arruinaría la experiencia del usuario. Pero, imagina que hiciste que tardara medio segundo en generar. Entonces, es probable que un usuario ni siquiera se dé cuenta de la demora, pero alguien que intente hacer fuerza bruta tendrá que ejecutar millones de intentos, si no más, y todos los segundos y medio sumarán décadas y siglos. ¿Qué pasa con el problema de las computadoras cada vez más rápido con el tiempo? Ahí es donde entra la parte "ajustable": de vez en cuando, aumentaría la complejidad para generar un hash. De esta manera, puede asegurarse de que siempre lleve la misma cantidad de tiempo. Esto es lo que los desarrolladores de PHP están tratando de animar a la gente a hacer..

La nueva biblioteca de PHP es un "flujo de trabajo" de hash, donde las personas pueden encriptar, verificar y actualizar fácilmente los hashes y sus respectivas complejidades con el tiempo. Actualmente solo se entrega con el algoritmo bcrypt, pero el equipo de PHP ha agregado una opción, denominada por defecto, que puede usar. Actualizará automáticamente sus hashes al algoritmo más seguro, cuando agreguen nuevos..

La forma en que funciona bcrypt es que ejecuta su contraseña a través del cifrado de blowfish X cantidad de veces, pero en lugar de utilizar blowfish con una clave para poder revertirla más tarde, pasa la ejecución anterior como la clave para la siguiente iteración. Según Wikipedia, se ejecuta su contraseña a través de 2 al X cantidad. Esa es la parte que podrías ajustar. Por ejemplo, ahora mismo, desea utilizar un nivel de costo de 5: bcrypt ejecutará su hash 2 al 5, o 32 veces. Esto puede parecer un número bajo, pero, dado que el parámetro de costo ajusta la función exponencialmente, si la cambia a 15, la función la ejecutará 32768 veces. El nivel de costo predeterminado es 10, pero esto se puede configurar en el código fuente.

Con la teoría fuera del camino, echemos un vistazo a un ejemplo completo.

 $ pass = "Secret_Password"; $ hash = password_hash ($ pass, PASSWORD_BCRYPT, array ('cost' => 12, 'salt' => "twenty.two.letter.salt")); if (password_verify ($ pass, $ hash)) if (password_needs_rehash ($ hash, PASSWORD_DEFAULT, array ('cost' => 15)) $ hash = password_hash ($ pass, PASSWORD_DEFAULT, array ('cost' => 15));  // Haz algo con hash aquí. 

los contraseña_hash La función acepta tres parámetros: la palabra a hash, una constante para el algoritmo de hash, y una lista opcional de configuraciones, que incluyen la sal y el costo. La proxima funcion, Contraseña verificada, se asegura de que una cadena coincida con el hash después del cifrado y, finalmente, el password_needs_rehash La función se asegura de que un hash sigue los parámetros dados. Por ejemplo, en nuestro caso, establecemos el costo de hash en doce, pero aquí especificamos quince, por lo que la función devolverá cierto, lo que significa que necesita ser repetido.

Usted puede haber notado que, en el Contraseña verificada y password_needs_rehash funciones, no tiene que especificar el método de hashing utilizado, la sal o el costo. Esto se debe a que esos detalles se añaden a la cadena de hash.

Las sales se utilizan para evitar que los hashes se precomputen en la tabla del arco iris.

La razón por la que está bien agrupar el costo y la sal junto con el hash y no mantenerlo en secreto, es por la forma en que el sistema une sus fortalezas. El costo no tiene que ser un secreto, ya que se supone que es un número que proporciona una carga suficientemente grande para el servidor. Lo que quiero decir con esto es que, incluso si alguien obtiene su hash y determina que su nivel de costo requiere 1/2 por segundo para calcularlo, sabrá en qué nivel se encuentra la fuerza bruta, pero le llevará demasiado tiempo descifrarlo (por ejemplo, décadas). ).

Las sales se utilizan para evitar que los hashes se calculen en una tabla de arco iris.

Una tabla de arco iris es básicamente un almacén de valores clave con un "diccionario" de palabras con sus hashes correspondientes como sus claves.

Todo lo que alguien tiene que hacer es calcular de antemano suficientes palabras comunes (o, peor aún, todas las posibilidades de cuerdas) y luego pueden buscar la palabra para un hash dado al instante. Aquí hay un ejemplo de cómo las sales pueden ser de ayuda: digamos que su contraseña es la palabra "contraseña". Normalmente, esta es una palabra bastante común; Probablemente estaría en su mesa de arco iris. Lo que hace un salt es que agrega una cadena aleatoria a tu contraseña; así que, en lugar de "contraseña" de hashing, es realmente "hashing" passwordRandomSalt524% # $ &. " Esto es considerablemente menos probable que sea precalculado.

Entonces, ¿por qué las sales generalmente se consideran información privada? Tradicionalmente, con cosas como MD5 y similares, una vez que alguien conoce tu sal, pueden volver a realizar sus técnicas de fuerza bruta, excepto que agregarán tu sal al final. Esto significa que, en lugar de forzar con fuerza bruta su cadena de contraseña aleatoria, son forzados con una contraseña estándar mucho más corta y solo están agregando el salt. Pero, por suerte, dado que tenemos la configuración del factor de costo, llevaría mucho tiempo calcular cada hash con la nueva sal.

Recordar: las sales aseguran que la precomputación de un hash no se pueda usar de nuevo en otro hash, y el parámetro de costo asegura que no sea posible calcular cada hash desde cero. Ambos son necesarios, pero ninguno de ellos tiene que ser secreto..

Es por eso que la función los une al hash..

Recuerde, no importa cuál sea su sal, siempre que sea única..

Ahora, si comprendió lo que está haciendo la sal, debería saber que es mejor dejar que la función genere uno al azar, que ingresar su propia palabra. Aunque se proporciona esta característica, no desea que todos sus hashes tengan la misma sal. Si lo hacen, entonces, si alguien logró entrar en su base de datos, todo lo que tendrían que hacer es calcular la tabla una vez. Ya que tendrán el nivel de sal y costo, puede tomar un tiempo, pero, con suficientes computadoras, una vez que lo procesen, habrán desbloqueado todos sus hashes. Como tal, es mucho mejor no asignar uno y, en cambio, permitir que PHP genere uno al azar.


adiciones cURL

Hasta ahora, no había una manera fácil de enviar correo a través de SMTP.

cURL es otra área en la que el equipo de PHP ha agregado algunas adiciones y actualizaciones nuevas y emocionantes. A partir de la versión 5.5, ahora tenemos soporte para las directivas FTP, directivas para establecer cookies, directivas para SSL y cuentas, y directivas para los protocolos SMTP y RTSP, entre otros. Tomaría demasiado tiempo discutirlos todos, pero, para ver la lista completa, puede consultar la página de NOTICIAS.

Sin embargo, quiero hablar de un conjunto en particular que me interesó más: el conjunto de directivas SMTP. Hasta ahora, no había una manera fácil de enviar correo a través de SMTP. Tendría que modificar el programa sendmail de su servidor para enviar mensajes a través de un servidor SMTP, o tendría que descargar una biblioteca de terceros, ninguna de las cuales es la mejor opción. Con las nuevas directivas CURL, puede hablar directamente con un servidor SMTP, como Gmail, en unas pocas líneas cortas.

Para comprender mejor cómo funciona el código, vale la pena aprender un poco sobre el protocolo SMTP. Lo que sucede es que su secuencia de comandos se conecta al servidor de correo, el servidor de correo reconoce su conexión y le devuelve su información (por ejemplo, dominio, software). Entonces tienes que responder al servidor con tu dirección. Al ser un protocolo hablador (pero educado), SMTP lo saludará para que sepa que lo recibió..

En este punto, usted está listo para enviar comandos. Los comandos necesarios son los CORREO DE y el RCPT A; estos mapas directamente a las directivas de la CURL, CURLOPT_MAIL_FROM y CURLOPT_MAIL_RCPT, respectivamente. Solo tienes uno desde dirección, pero usted puede especificar múltiples a direcciones Una vez hecho esto, simplemente puede llamar al comando, DATOS, y comience a enviar el mensaje real y los encabezados del mensaje. Para finalizar la transmisión, debe enviar una línea en blanco, seguida de un punto, seguida de otra línea en blanco. Estas dos últimas partes (es decir, el comando DATA y la secuencia final) están a cargo de cURL, por lo que no tenemos que preocuparnos por ello..

Entonces, en PHP, todo lo que tenemos que hacer es especificar el correo desde y a directivas y, a continuación, envíe el mensaje real, todo dentro de cURL. Para hacer las cosas realmente simples, voy a crear una clase, llamada Gmail, que aceptará un nombre de usuario / contraseña y los detalles del mensaje, y enviará correos electrónicos a través de su cuenta de Gmail.

Pegaré toda la clase a continuación, y luego lo revisaremos línea por línea, ya que la mayoría es repetitivo..

 clase Gmail correo privado $; correo electrónico privado $ pase privado; función pública __construct ($ email, $ pass) $ this-> email = $ email; $ this-> pass = $ pass;  función privada mailGen () $ de = rendimiento; $ a = rendimiento; $ sujeto = rendimiento; $ cuerpo = rendimiento; rendimiento "DE: <" . $from . ">\ n "; ceder" a: <" . $to . ">\ n "; rendimiento" Fecha: ". fecha (" r ")." \ n "; rendimiento" Asunto: ". $ sujeto." \ n "; rendimiento" \ n "; rendimiento $ cuerpo; rendimiento" ";  función pública getLine () $ resp = $ this-> mail-> current (); $ this-> mail-> next (); return $ resp; función pública send ($ to, $ subject, $ body) $ this-> mail = $ this-> mailGen (); $ this-> mail-> send ($ this-> email); $ this-> mail-> send ($ to); $ this-> mail- > send ($ subject); $ this-> mail-> send ($ body); $ ch = curl_init ("smtps: //smtp.gmail.com: 465"); curl_setopt ($ ch, CURLOPT_MAIL_FROM, "<" . $this->correo electrónico . ">"); curl_setopt ($ ch, CURLOPT_MAIL_RCPT, array ("<" . $to . ">")); curl_setopt ($ ch, CURLOPT_USERNAME, $ this-> email); curl_setopt ($ ch, CURLOPT_PASSWORD, $ this-> pass); curl_setoptp. , true); opcional si desea ver la transacción curl_setopt ($ ch, CURLOPT_READFUNCTION, array ($ this, "getLine")); return curl_exec ($ ch);

Con suerte, su reacción a este código fue algo así como: "¡Wow, eso es una aplicación SMTP completa!" Por si acaso parece complicado, lo repasaremos. Comenzamos definiendo tres variables privadas: una para el generador de mensajes, una para almacenar el correo electrónico del usuario y otra para almacenar su contraseña. A continuación, tenemos el constructor, que almacena el correo electrónico y la contraseña para más adelante; Esto es para que podamos enviar múltiples correos electrónicos sin volver a ingresar esto cada vez. los mailGen La función es un generador PHP 5.5, que se utiliza para enviar el mensaje de acuerdo con el protocolo de correo electrónico directamente a cURL. La razón por la que se necesita esto es porque el comando utilizado en cURL para ingresar los datos está destinado a la lectura de un archivo, línea por línea. Entonces, en lugar de tener una variable adicional para recordar en qué línea estábamos, utilicé un generador, que guarda su posición.

La siguiente función se utiliza para completar el ciclo a través del generador. No podemos entrar al generador directamente en cURL; Necesitamos un intermediario. cURL continuará llamando a esta función, hasta que llegue a una línea vacía. Es por esto que la última línea en el generador devuelve una cadena en blanco.

La última función en la clase es la que lo une todo. Primero inicializamos el generador a la variable privada definida anteriormente. A continuación, enviamos al generador toda la información requerida y creamos una nueva variable cURL. Ya hemos discutido CURLOPT_MAIL_FROM y CURLOPT_MAIL_RCPT; se asignan a los comandos SMTP equivalentes. CURLOPT_MAIL_RCPT es una matriz para que pueda introducir varias direcciones. A continuación, debemos agregar las credenciales para iniciar sesión en GMail. Dejé la opción verbosa allí; elimínelo, si desea ver la transacción SMTP completa. Las dos últimas líneas simplemente configuran la función desde donde CURL debería obtener los datos para el mensaje, y luego devolvemos los resultados.

Es un buen par de líneas, pero nada demasiado complicado. Para usar esta función, cree una nueva instancia de esta clase y llame a la función de envío. Aquí hay un ejemplo de enviar dos correos electrónicos con esto:

 $ gmail = nuevo Gmail ("[email protected]", "contraseña"); $ gmail-> enviar ("[email protected]", "Asunto del correo electrónico", "Hola chico, \ n ¿Qué está pasando?"); $ gmail-> enviar ("[email protected]", "Asunto diferente", "Mensaje importante");

Bits y Bobs

Para terminar este artículo, repasaré algunas de las actualizaciones más pequeñas a PHP 5.5.

Una cosa bastante interesante es el soporte agregado para la constante eliminación de cadenas / cadenas. Lo que esto significa es que puede acceder a caracteres individuales en una cadena estática, como si la cadena fuera una matriz de caracteres. Un ejemplo rápido de esto es el siguiente:

 echo "Hello World" [1]; // esta línea hará eco en 'e' echo ["one", "two", "three"] [2]; // estos ecos "tres"

A continuación, tenemos la finalmente palabra clave. Esto se añade al final de un bloque try / catch; lo que hace es indicar a PHP que, independientemente de si se llamó o no al try o catch, desea procesar el finalmente sección. Esto es bueno para situaciones, cuando desea manejar el resultado de una declaración try / catch. En lugar de repetir el código en ambos, simplemente puede poner la parte "arriesgada" en el bloque try / catch, y todo el procesamiento en el bloque finally.

Otro uso sugerido por el creador como una buena práctica es poner todo el código de limpieza en el bloque final. Esto asegurará que, por ejemplo, no intentes cerrar la misma secuencia varias veces (por ejemplo, tu código se bloqueó y entró en el bloque catch después de que ya se cerró, e intentas cerrarlo nuevamente).

Lo último que vale la pena mencionar es cómo la extensión de MySQL quedará obsoleta en esta nueva versión. Debes convertir tu código a la mysqli o DOP extensiones en su lugar. A pesar de que hace tiempo que se lo considera un anti-patrón, es bueno que el equipo de PHP lo desapruebe oficialmente..

Si bien ciertamente hay más actualizaciones para investigar, los elementos de este artículo representan lo que creo que son los más importantes y emocionantes..


Conclusión

Gracias por leer; Espero que hayas aprendido un poco! Como siempre, si tiene algún comentario o pregunta, salte a la conversación a continuación y hablemos!