Esta sección reúne varios errores comunes a los que se puede enfrentar mientras se escriben scripts de PHP.
PHP es un pegamento que une cientos de bibliotecas externas y esto, a veces, lo complica. Por eso, una simple regla de oro es la siguiente:
Los parámetros de las funciones de Array están ordenados como "aguja, pajar", mientras que sucede lo contrario con las funciones de String, esto es, "pajar, aguja".
PHP ofrece muchas variables predefinidas, como la variable superglobal $_POST. Se puede recorrer la variable $_POST, ya que es un array asociativo con todos los valores provenientes de POST. Por ejemplo, vamos a recorrerla simplemente con foreach, comprobar los valores vacíos, empty(), y mostrarlos todos.
<?php
$vacío = $post = array();
foreach ($_POST as $nombre_variable => $nombre_valor) {
if (empty($nombre_valor)) {
$vacío[$nombre_variable] = $nombre_valor;
} else {
$post[$nombre_variable] = $nombre_valor;
}
}
print "<pre>";
if (empty($vacío)) {
print "Ninguno de los valores de POST esta vacío, se envió:\n";
var_dump($post);
} else {
print "Tenemos " . count($vacío) . " valores vacíos\n";
print "Registrados:\n"; var_dump($post);
print "Vacíos:\n"; var_dump($vacío);
exit;
}
?>
Asumiendo que esto es para una base de datos, utilice el mecanismo de escape que viene con esta. Por ejemplo, emplee la función mysql_real_escape_string() con MYSQL y pg_escape_string() con PostgreSQL. Existen también las funciones genéricas addslashes() y stripslashes(), las cuales son más comunes en código PHP antiguo.
Nota: Sobre de la directiva: magic_quotes_gpc
La directiva de PHP magic_quotes_gpc tiene por defecto el valor on. Básicamente ejecuta addslashes() en los datos obtenidos por GET, POST, y COOKIE. Se puede usar stripslashes() para quitarlos.
Lo más probable es que esas barras invertidas existan porque la directiva de PHP magic_quotes_gpc está activada. Esta es una característica antigua de PHP que debería deshabilitarse y no usarse más. También se puede utilizar la función stripslashes() para eliminar las barras invertidas de un string.
Nota: Sobre de la directiva: magic_quotes_gpc
La directiva de PHP magic_quotes_gpc tiene por defecto el valor on. Básicamente ejecuta addslashes() en los datos obtenidos por GET, POST, y COOKIE. Se puede usar stripslashes() para quitarlos.
Esta característica ha sido declarada OBSOLETA desde PHP 5.3.0 y ELIMINADA a partir de PHP 5.4.0.
En primer lugar, una explicación de lo que hace este ajuste ini. Digamos que se está utilizando el siguiente URL: http://example.com/foo.php?animal=cat y en el fichero foo.php tuviéramos el siguiente código PHP:
<?php
// Aquí es preferible usar $_GET
echo $_GET['animal'];
// Para que $animal exista, register_globlas debe estar activado
// NO HAGA ESTO
echo $animal;
// Esto se aplica a todas las variables, inclusve a $_SERVER
echo $_SERVER['PHP_SELF'];
// De nuevo, para que $PHP_SELF exista, register_globals debe estar activado
// NO HAGA ESTO
echo $PHP_SELF;
?>
El código anterior demuestra cómo register_globals crea muchas variables. Durante años, este tipo de código ha sido mal visto, y durante años ha estado deshabilitado por defecto. Así que, aunque la mayoría de alojamientos web deshabilitan register_globals, aun existen artículos, tutoriales y libros desactualizados que requieren que esté habilitado. Actúe en consecuencia.
Véase también los siguientes recursos para más información:
Nota:
En el ejemplo anterior, usamos un URL que contenía un QUERY_STRING. El paso de información como esta se hace a través de una solicitud GET de HTTP, y es esta la razón por la que se usa la superglobal $_GET.
<?php
function mi_función($argumento)
{
echo $argumento + 10;
}
$variable = 10;
echo "mi_función($variable) = " . mi_función($variable);
?>
Para poder usar los resultados de funciones en una expresión (como la concatenación con otras cadenas del ejemplo anterior), es necesario devolver el valor con return; no utilzar echo.
<pre>
<?php echo "Esto debería ser la primer línea."; ?>
<?php echo "Esto debería mostrarse después de la línea anterior."; ?>
</pre>
En PHP, la terminación de un bloque de código se realiza bien con "?>" o con "?>\n" (donde \n significa una nueva línea). Con el ejemplo anterior, las sentencias de 'echo' estarán en una línea debido a que PHP omite las nuevas líneas después del final de un bloque. Esto significa que es necesario agregar una nueva línea extra después de cada bloque de código PHP para poder imprimir una nueva línea.
¿Por qué PHP hace esto? Porque cuando se formatea HTML normal, esto hace la vida más fácil ya que normalmente no se desea esa nueva línea, pero se tendrían que crear líneas extremadamente largas o, de lo contrario, hacer el código fuente de la pagina ilegible para obtener tal efecto.
Las funciones header(), setcookie(), y las funciones de sesión necesitan agregar cabeceras al flujo de salida, pero las cabeceras solo pueden enviarse antes de cualquier otro contenido. No puede haber ninguna salida antes de usar esas funciones, salidas como HTML. La función headers_sent() comprobará si un script ya ha enviado las cabeceras. Véase también las funciones de control de salida.
La función getallheaders() lo hará si se está ejecutando PHP como un módulo de Apache. El siguiente trozo de código mostrará todas las cabeceras de la petición:
<?php
$cabeceras = getallheaders();
foreach ($cabeceras as $nombre => $contenido) {
echo "headers[$nombre] = $contenido<br />\n";
}
?>
Véae también apache_lookup_uri(), apache_response_headers(), y fsockopen()
El modelo de seguridad de IIS es el culpable en este caso. Es un problema común a todos los programas CGI que se ejecutan bajo IIS. Una solución es crear un fichero de HTML plano (no analizado por PHP) como la página de entrada en un directorio autenticado. Se debe utilizar entonces una etiqueta META para redirigir a la página de PHP, o tener un enlace a dicha página. PHP reconocerá así la autenticación correctamente. Con el módulo ISAPI, esto no es un problema. Esto no debería afectar a otros servidores web NT. Para más información, véase: » http://support.microsoft.com/kb/q160422/ y la sección del manual sobre Autenticación HTTP .
Ha de cambiar Ir a los Servicios de Información de Internet. Localice su fichero PHP y vaya a sus propiedades. Luego vaya a la pestaña Seguridad de Archivos, Editar -< Acceso anónimo y control de autenticación.
Se puede corregir el problema ya sea desmarcando Acceso anónimo y dejando Autenticación integrada de Windows marcado, o marcando Acceso anónimo y editando el usuario, que ya no tendría que tener derecho de acceso.
Con el fin de integrar directamente <?xml en código de PHP, se han de desactivar las etiquetas abreviadas estableciendo la directiva de PHP short_open_tags a 0. Esta directiva no se puede establecer con ini_set(). Independientemente de que short_open_tags esté activada o no, se puede hacer algo como: <?php echo '<?xml'; ?>. El valor predeterminado de esta directiva es On.
Lea la página del manual sobre variables predefinidas, que incluye un listado parcial de variables predefinidas disponibles para su script. Se pude ver un listado completo de las variables disponibles (y mucha mas información) llamando a la función phpinfo(). Asegúrese de leer la sección del manual sobre variables desde fuentes externas a PHP, la cual describe escenarios comunes para variables externas, como desde un formulario HTML, una cookie, y un URL.
Nota: register_globals: Observación importante
Desde PHP 4.2.0, el valor por defecto de la directiva register_globals es off. La comunidad de PHP desaconseja el uso de esta directiva y sugiere el uso de otras formas como superglobals.
Hay algunas alternativas escritas en PHP como » FPDF y » TCPDF.
También esta la extensión Haru que utiliza la biblioteca externa libHaru gratuita.
Es importante saber que la directiva de PHP register_globals también afecta a variables de servidor y de entorno. Cuando register_globals = off (el valor por defecto desde PHP 4.2.0), $DOCUMENT_ROOT no existirá. En su lugar, se debe usar $_SERVER['DOCUMENT_ROOT'] . Si register_globals = on, las variables $DOCUMENT_ROOT y $GLOBALS['DOCUMENT_ROOT'] también existirán.
Si se está seguro de que register_globals = on y se pregunta por qué $DOCUMENT_ROOT no está disponible dentro de las funciones, es porque son como las demás variables, requiriendo dentro de la función global $DOCUMENT_ROOT. Véase también la página del manual sobre ámbito de las variables. Es preferible codificar con register_globals = off.
Las opciones disponibles son K (para Kilobytes), M (para Megabytes) y G (para Gigabytes; disponible desde PHP 5.1.0). Ninguna considera las mayúsculas/minúsculas. Cualquier otra cosa asume bytes. 1M es igual a un Megabyte o 1048576 bytes. 1K es igual a un Kilobyte o 1024 bytes. Estas notaciones abreviadas pueden utlizarse en php.ini y en la función ini_set(). Observe que el valor numérico se moldea a integer; por ejemplo, 0.5M es interpretado como 0.
Nota: kilobyte contra kibibyte
La notación de PHP describe que un kilobyte equivale a 1024 bytes, mientras que el estándar IEC considera que debe ser un kibibyte. Resumiendo: k y K = 1024 bytes.
Antes de PHP 5.3.4, existía un error en el código de resolución de red dentro de PHP que ocasionaba que localhost fallase en todas las situaciones relacionadas con flujos si IPv6 estaba habilitado. Para solucionar este problema se puede usar tanto "127.0.0.1" como deshabilitar la resolución de IPv6 en el fichero hosts.