PHP básico para dummies

Muchos usuarios suponen que hacen las cosas bien, pero hay una realidad que nos invade y es que hay mucha mala influencia dando vuelta entre los programadores. Lo que quiero plantear en este post son un poco de buenas costumbres al momento de programar, y con sus ayudas ir mejorándolo en lo que dice y en nuevas ideas que habré pasado por alto. Cada aporte será agradecido con los debidos créditos en este post. Comencemos desde abajo…

1- Definir los errores al mango.

Es importante que nuestro server esté configurado para que nos muestre el más mínimo de los errores. Haremos dos pasos, en uno editaremos el archivo php.ini, y en el paso dos haremos un trackeo de errores del lado de PHP así podremos tenerlo también cuando subamos nuestros sitios online.
Para el primer paso abran el archivo php.ini (si no saben donde está hacen un archivo que tenga <? phpinfo() ?> y buscan «Loaded Configuration File«, o «Configuration File«).
Editaremos las siguientes directivas:

display_errors = On
error_log = off
error_reporting = 6143
ignore_repeated_errors = off

También pueden leer la sección de errores, hay directivas para jugar y probar cosas, como ser error_append_string y error_prepend_string donde pueden poner html, ej. <h1> y </h1> respectivamente.

Una vez esto ya tendremos los errores un poco más afinados. Si quieren más lean el punto siguiente.

Nota: para probarlo solo hagan un PHP con: <?=$quevariableloca;?>

2- Trackear los errores de PHP.

Los usuarios que usen a futuro nuestro sistema serán los mejores testers del mismo ya que probarán todos los casos de uso, muchos de los cuales posiblemente se nos pasen por alto. Si bien la lógica es un error que dependerá de nosotros y suele ser muy importante, también los son los posibles errores que puedan darse en el script en casos de usos no testeados. Haremos que el poder tenerlos en nuestra cuenta de email para sí solucionarlos.
Para ello lo mejor es crear un archivo, por ejemplo errores.php, y en él poner:
<?
function error_handler($errno, $errstr, $errfile, $errline, $errctx) {
$EN_DESARROLLO = substr_count($_SERVER['HTTP_HOST'],"localhost")==0 ? FALSE : TRUE;
$host = $_SERVER['HTTP_HOST'];
$mail_subject = 'Se ha producido un error en '.$host;
$mail_from = 'errores@midominio.com';
$mail_to = array('nicolas@midominio.com');
$errortype = array(1=>"Error", 2=>"Warning", 4=>"Parsing Error", 8=>"Notice", 16=>"Core Error", 32=>"Core Warning", 64=>"Compile Error", 128=>"Compile Warning", 256=>"User Error", 512=>"User Warning", 1024=>"User Notice", 2048=>"PHP5 Strict Warning");
$error_handler_string = "<font size='2' face='courier' color='#666666'><h3>Error en {$host}<br></h3><b>Date: </b>".date('F j, Y, H:i:s a')."<br><b>Error Type: </b>{$errortype[$errno]} ({$errno})<br><b>Description: <font color=657413>{$errstr}</font></b><br><b>Error File: </b>{$errfile}<br><b>Error Line: </b>{$errline}<br><br>";
while( isset($_SESSION) && list($var, $val) = each($_SESSION) ) $error_handler_string .= "_SESSION[{$var}] = {$val}<BR>";
while( isset($_GET) && list($var, $val) = each($_GET) ) $error_handler_string .= "_GET[{$var}] = {$val}<BR>";
while( isset($_POST) && list($var, $val) = each($_POST) ) $error_handler_string .= "_POST[{$var}] = {$val}<BR>";
while( isset($_COOKIE) && list($var, $val) = each($_COOKIE) ) $error_handler_string .= "_COOKIE[{$var}] = {$val}<BR>";
if( $EN_DESARROLLO ){
exit($error_handler_string);
}else{
@ini_set("sendmail_from",$mail_from);
foreach( $mail_to as $mail_to_str ) mail($mail_to_str, $mail_subject, $error_handler_string, "From: {$mail_from}rnContent-Type: text/html; charset="iso-8859-1"rn");
if( $errno & (E_WARNING | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR) ) exit("<script>location.href = 'mipaginadeerror.php'</script>");
}
}
set_error_handler("error_handler");
error_reporting(E_ALL);
?>

Poniendo este include en todas las páginas tendremos control de los errores (siempre y cuando haya un display_error en on, el cual pueden configurar con una llamada a la función ini_set() o un htaccess).
Si están en localhost tendrán un error en pantalla cortando la ejecución del script, sino, les mandará un email con el error en el cuerpo a todas las cuentas que estén en el array $mail_to, y al usuario lo redireccionará a mipaginadeerror.php la cual tendrá un diseño acorde al sitio donde está puesto.

Nota: para probarlo solo hagan un PHP con: <?=$quevariableloca;?>

3- Setear las variables antes de usarlas.

Es muy común encontrar un script como el siguiente:
<?
if(date('N')==1) $dia = 'Lunes';
echo "que lindo día hace hoy $dia";
?>

Analicemos esto. La variable $día estará seteada solo si hoy es Lunes, pero que pasa en un día Martes? Si hiciste bien el paso 1 tendrás un error del tipo NOTICE diciéndote que $dia no esta definida (Notice: Undefined variable $dia…).
Esto desde ahora en más lo llamaremos lógica, y es muy importante controlar bien el flujo de los datos en nuestro script, es el éxito de que funcione a la perfección.
Para solucionar el caso anterior hay muchas maneras, pondré algunas ya que es solo un ejemplo:
<?
$dia = '';
if(date('N')==1) $dia = 'Lunes';
echo 'que lindo día ', $dia;
?>

Ustedes sabrán que método usar o si usar isset() o empty(), lo importante es que llegados a la función echo() tengamos la variable seteada o sino evaluemos que así lo esté al momento de usarla:
<?
if(date(‘N’)==1) $dia = ‘Lunes’;
else $dia = »;
echo ‘que lindo día ‘, $dia;
?>
<?
if(date(‘N’)==1) $dia = ‘Lunes’;
echo ‘que lindo día ‘, (isset($dia) ? $dia : » );
?>

4- No confundir un string con una constante.

Les suena el siguiente código?:
<?
...
while( $rs = mysql_fetch_assoc( $r ) ) echo $rs[foo];
...
?>

Pues si, está plagado de este código en la web y está mal. Si pensaste que estaba bien te recomiendo leer un poco sobre:
http://php.net/manual/es/language.constants.php
http://php.net/manual/es/language.variables.php
http://php.net/manual/es/language.types.array.php
http://php.net/manual/es/language.types.php

De todas maneras te adelato, que en cada iteración mysql_fetch_assoc() asigna en $rs un array asociativo.
Estos arrays tienen posiciones o claves que son strings y como sabrás un strings va entres comillas, simples o dobles.
Sino, estarás llamando a una constante, te pongo un ejemplo de que sería correcto:
<?
...
$r = mysql_query("Select nombre from tbl");
while( $rs = mysql_fetch_assoc( $r ) ) echo $rs['nombre'];
...
?>

O bien:
<?
...
define('foo','nombre');
$r = mysql_query("Select nombre from tbl");
while( $rs = mysql_fetch_assoc( $r ) ) echo $rs[foo];
...
?>

Si la primer opción, que está mal, te funciona, es porque tenés los errores de PHP mal configurados y PHP entiende que como la constante foo no existe es un string con ese valor, pero no es bueno dejar que PHP decida nuestrá lógica, para eso estamos nosotros los programadores ;).

Nota: Esto aplica a toooodo array asociativo, no necesariamente creado por nosotros, bien puede ser un $_GET[‘valor’].

5- No usar datos de entrada sin antes tratarlos.

Es peligroso, y más cuando se usan sobre la base de datos. Cuando decimos datos de entrada es cualquier dato tomado de fuera de nuestroscript, revisa está lista:
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST

Para ejemplificar usermos $_GET, pero bien podría ser otra de la lista.
Muchos hacen esto:
<?
...
$r = mysql_query("Select nombre from tbl where id = '{$_GET['id']}'");
...
?>

Y es muy peligroso, no explicaré los porque, para eso pueden buscar sql inyección en google y se asustarán si usan lo antes mensionado.
Lo correcto es tener control sobre todo lo que ingresamos a nuestro script, para eso están los tipos de datos y las restricciones que nosotros pongamos.
Hagamos un simple ejemplo:
<?
...
$id = empty($_GET['id']) ? 0 : intval($_GET['id']);
$r = mysql_query("Select nombre from tbl where id = '{$id}'");
...
?>

De esta manera $id siempre será un int. Hay otras maneras de proteger nuestros scripts, dejo unos interesantes links para arrancar:
http://php.net/mysql_real_escape_string
http://ar.php.net/manual/es/function.addslashes.php
http://php.net/manual/es/language.types.php

Quiero aclarar que tampoco es correcto lo siguiente:
<?
...
$id = intval($_GET['id']);
$r = mysql_query("Select nombre from tbl where id = '{$id}'");
...
?>

Y si no sabes porque te cuento que si no se pasa id por GET tirará un error, y si sigues sin sabes de que hablo lee el punto 1, 2 y 3 ;).

6- Ser prolijos al escribir.

Esto no produce errores, pero si produce que cuando necesites ayuda, o alguien vea tu código corra o te critique.
Vayamos al punto, hay reglas básicas que verás a lo largo de sus lecturas, te recuerdo algunas:

  • Escribir variables en minúsculas.
    En vez de $EstaVariable o $ESTA_VARIABLE es mejor usar $estaVariable o $esta_variable (mismo pueden poner $estavariable, es mucho mejor que los casos discriminados). También hay casos donde pueden poner todo en mayúsculas para distinguír por ejemplo grupos de datos, pero no aplica a todo el código que escribamos.
    Es importante (gracias CarlosR) que esto también se aplique al usar bases de datos, tanto en tablas como en campos, y me he dado cuenta que muchos usan la misma lógica para sus archivos, por que poner gr.php si se puede poner grabar.php.
  • No escatimar letras.
    No pongan $uvar, $uv, $unav, no se cobra como un SMS, en su defecto usen $unaVar o $una_var, así es legible y cualquier mortal lo puede leer y saber de que intentamos hablar.
  • No escribir de más
    Tampoco nos vayamos al extremo, no pongamos $esteColorSeraRojoOAzul = TRUE; si podemos poner $azul=TRUE;
  • las constantes a mi parecer muchas veces si es mejor usarlas en mayúsculas para que se encuentren mejor entre nuestro código.
    No es una regla, pero queda mejor apartarlas visualmente de las variables.
  • Esto aplica a funciones, arrays y demás.
    Todo lo dicho anteriormente no solo es aplicable a variables…
  • Es conveniente saber que diferencias hay entre comillas simples y dobles y aplicarlas.
    Lo que esté encerrado entre comillas dobles será evaluado y procesado por PHP, no así lo que esté entre comillas simples.

7- Tratar de usar más valores booleanos.

Aplicado para datos de dos estados, para eso están los binarios.
Muchos usan por ejemplo lo siguiente:
<?
$autentificado = ‘si’;
?>

Cuando es mucho mejor usar:
<?
$autentificado = TRUE;
?>

O bien:
<?
$autentificado = 1;
?>

Cuando pasamos un dato por $_GET, o en nuestra base de datos, es mejor usar 1 o 0, ya que muchas veces TRUE o FALSE serán tratados como strings y los números son más baratos de manipular.

Espero que esto vaya creciendo con sus aportes, es apenas un comienzo. De mi parte me comprometo no solo a agregar cualquier comentario que aporte al post, sino al ir agregando nuevas «malas costumbres» que por mi parte vea en la web.

Y recuerden programar siempre como si la persona que finalmente mantendrá y/o verá tu código fuera un psicópata violento que sabe dónde vives!!!

12 Responses to PHP básico para dummies

  1. Ricardito dice:

    Me gusto mucho!, buena lectura…me enteré de varias cosas que no sabía y que pensé que estaban bien cuando no es así.
    Espero que haya nuevos aportes al post, por mi parte solo puedo por el momento leerlos.

    Gracias!

  2. tOmY dice:

    Genial la funcion de error_reporting!, simplemente lo mejor. El resto sumamente interesante, se ve mucho en foros, script de libre uso y hasta open sourse programados de esta manera…MAL!, estoy cansado, o casi, de probar php pre armados y al correrlos llearme la pantalla de warnings y notices…

    Cuantos alumnos hay en la web….

  3. Elena dice:

    Sin lugar a duda un gran post que ayudara a muchos incluyendome. Me quedo con la frase final que es memorable y por la misma prometo a partir de ahora a ser mas ordenada y a usar por ejemplo mas comillas simples cuando sean necesarias.

    Y agrego algo…recuerden: Programadores hay muchos, programadoras menos, pero gente que programe bien hay muy poca.

    besos a todos, y nico, segui asi!

  4. CarlosR dice:

    Era hora que se escriba algo así.
    Mi aporte es que cuando hablas de nomenclatura cuentes que aplica a base de datos y tablas. Es muy normal ver campos con este formato SMS malisioso que no se sabe que son, o que comienzan en mayusculas, o mismo hacen tablas que comienzan en mayusculas…hay que respetar mucho mas esto.

    Gracias por el aporte.

  5. Pedro Alonso dice:

    Gracias!, espero que muchos lo lean y aprendan. Como dice Ricadito, estoy cansado de ver aplicaciones pre armadas con cientos de warnings y notices. Y muy buena la del error_reporting, ya tenía algo pero me quedo con esta.

  6. Manuel89 dice:

    Cuanta verdad en un solo POST; tan simple y basico pero tan lleno de estas cosas.

    Yo me he curzado con muchos casos tambien, y no solo de genet que recien comienza a programar y se creen dioses, sino de gente que son licenciados y llaman a los campos de una tabla tipo: vRdge, rTrebsn….que corno es eso? eso enseñan en la facultad o lo hacen de puros mal nacidos para que solo ellos comprendan el sistema?

  7. Andres dice:

    Oye muy buen post!. Aprendi cosas nuevas, por ejemplo a que es mejor usar echo con comas que con puntos (acabo de leer sobre eso y es mas optimo), y prometo como varios a usar mas comillas simples cuando sea el caso, a usar variables mas descriptivas y no del tipo $a, $b, $c y a probagar las buenas costumbres un poco mas.

    Gracias!

  8. AlexMontenegro dice:

    gracias!, buen aporte…sigue así

  9. nAcho dice:

    Buen resumen. Yo diría que no es tan recomendable declarar las variables antes de usarlas, en este tipo de lenguajes.

    Diría que lo adecuado es siempre verificar que esté seteada la variable antes de usarla.

  10. pateketrueke dice:

    pues si… si muchos (bastantes) hicieran eso… seriamos una comunidad mas sana, pero bueno….

    algunos aun aprende… mientras otros me sorprenden (siguiendo de arcaicos y erróneos)

  11. Carxl dice:

    Tienes un error:

    «Lo que esté encerrado entre comillas simples será evaluado y procesado por PHP, no así lo que esté entre comillas simples.»

    Creo que en algún lado cambia a «comillas dobles» no?

    Saludos

  12. Gracias Carxl por notar ese error!!, ya está solucionado 😉

Deja un comentario