Hola
<?php
echo "mundo<br>";
echo strftime("Son las %H horas");
?>
PHP es muy similar a C y otros lenguajes. Las instrucciones se separan con ; y los cambios de línea son equivalentes a los espacios en blanco (fuera de las cadenas, claro). Debemos respetar las reglas de identación buscando la claridad. Los comenrarios se delimitan con // o # para una línea, y con /* y */ para bloques de líneas.
<? phpinfo(); ?> y cárgalo con el navegador
vía servidor web (algo como http://localhost/directorio/info.php). Observa la información suminstrada.
Las variables en PHP explotan al máximo
las características que ofrece un lenguaje interpretado, pudiendo hacer operaciones totalmente impensables para un lenguaje compilado.
Las variables siempre comienzan con el signo $ y su nombre sigue las reglas habituales de otros lenguajes.
La asignación de un valor se realiza con el signo =.
Las variables no se declaran y pueden tomar diversos tipos de datos en tiempo de ejecución, cambiando de uno a otro según el
valor que se les asigne. Los nombres de las variables son sensibles ante mayúsculas y minúsculas. Veamos este ejemplo:
Hemos definido la variable $v1 y le hemos asignado el entero 50. Después mostramos uan variable del sistema y
definimos una constante, cuyo uso es de escaso interés a mi juicio. La asignación se realiza siempre por valor, es decir copiando.
En PHP existen las referencias, pero deben usarse con mucho cuidado,
teniendo en cuenta que no son direcciones como en C.
// variable declarada explícitamente
$v1 = 50;
// imprimimos una de las variables del sistema
echo $_SERVER ["DOCUMENT_ROOT"] ;
//definimos una constante
define ("VARIABLE_CONSTANTE" , 80) ;
echo VARIABLE_CONSTANTE;
// copia el valor
$v2=$v1;
$v1=3+5;
// se convierten ambas variables a string y se concatenan
$v1=$v1.$v2;
// error de sintaxis
$2v = 5;
Una variable puede tener que separarse de su entorno, por ejemplo dentro de una cadena, entonces puede usarse el formato ${variable}.
El formato $$ es una forma simplificada de evaluación, en el sentido que $$x significa la variable cuyo nombre esta en $x:
$nom="variable";
$variable=6;
echo "La variable '$nom' lleva un '".$$nom."'";
for ($i=1; $i <100; $i++) {
$nom="nom$i";
$$nom=$i;
echo "La variable '$nom' lleva un '".$$nom."'\n";
} La construcción $$ es realmente forma simplificada de ${$variable}.
Realmente el formato ${} significa evalúa lo que hay dentro y el resultado interprétalo
como un nombre de variable. Según esto, podemos escribir:
${x}=3;
${"x"}=3;
${"x".rand(3,10)}=5;
${$x}=8;
echo "He llegado hasta quí sin errores";
En consecuencia, el anterior bucle se escribe mejor como:
for ($i=1; $i <100; $i++)
${"nom".$i}=$i;
Una característica de los lenguajes interpretados es la presencia de la potentísima instrucción eval(), cuya misión es
interpretar el código fuente que se le pasa como parámetro, lo que significa analizarlo léxica y sintácticamente y ejecutarlo.
Esta sentencia permite ejecutar nuevo código creado en tiempo de ejecución, lo que extiende las posibilidades del lenguaje al infinito,
ya que es recusiva (un eval puede contener otro eval).
Así, el anterior ejemplo sería una forma abreviada y cómoda de:
for ($i=1; $i <100; $i++)
eval("\$nom$i=$i;");
Observa la necesidad del ;. Estrictamente, el eval que corresponde es:
for ($i=1; $i <100; $i++)
eval("\$nom$i=\$i;");
Como es complicado saber lo que se va a evaluar, yo recomiendo aislar el trozo del eval y susttituirlo por un print,
según lo cual:
for ($i=1; $i <100; $i++)
print("\$nom$i=\$i;<br>");
La sentencia eval() eleva notablemente la potencia de un lenguaje, pero oscurece el código en la misma
medida en que lo acorta. Un uso sencillo de eval es saber si un código PHP es sintácticamente correcto:
$x="echo Hola;";
if (@eval("return true; $x"))
echo "Es correcto";
La sentencia return funciona dentro de eval y establece el valor de la ejecución de la misma. El significado de @ lo explico a continuación.
La sentencia eval() puede aparecer embebida en preg_replace.
PHP tiene distintos niveles de error. A veces se producen eventos simplemente informativos, otros de atención y otros de error. Normalmente los eventos informativos no se muestran, pero puede configurarse para que así sea con ánimo de depurar código. Los avisos de atención pueden esconderse en llamadas a funciones precediendo la llamada con una @, lo debe hacerse sólo cuando estamos seguros de que no es importante el aviso que ignoramos. Cuando se produce un error, la ejecución del código se para, el mensaje de error también puede esconderse con @, aunque probablemente es una mala idea hacerlo.
Por ejemplo, si quiero obtener el contenido de un archivo, y detectar si no existe o está vacío, puedo hacer:
if ($x=@file_get_contents("unarchivo"))
echo "Existe y no está vacío";
else
echo "La cosa ha ido mal";
Al no existir unarchivo, se produce un warning (mensaje de atención), pero no lo vemos porque @ ha anulado la visibilidad del mensaje. Si file_get_contents produjera error en lugar de warning, no hubiésemos leído ningún mensaje, pues la ejecución del código se hubiera parado.
// $a es un entero
$a=3;
// el valor de $a (no la propia varaible) se convierte
// a cadena y se concatena con otra cadena.
$b="hola ".$a; Los tipos boolean, integer y float no requieren demasiada atención, simplemente debemos ir en cuidado al manejarlos, por ejemplo:
if (!$x) echo "Sí" escribirá Sí tanto si $a no está definida, como si contiene la cadena nula "",
como si contiene la cadena "0", como si contiene un integer o float de valor 0 o un boolean de valor false.
Si queremos saber realmente si $a no está definida, podemos usar la función isset. Los tipos pueden compararse usando, por ejemplo,
el operador === que dice si dos expresiones evalúan igual y son del mismo tipo. El habitual operador de comparación == no compara
el tipo, sólo el valor, y la condición 0 == "0" es cierta.
$x=0x7fffffff ; echo "$x ",is_int($x),"\n";
$x=2*$x; echo "$x ",is_int($x),"\n";
$x=0xffffffff ; echo "$x ",is_int($x),"\n";
$x=0x100000000; echo "$x ",is_int($x),"\n";
$x=0x10000000000000000 ; echo $x; El tipo resource es empleado para operaciones de entrada salida, no tiene un interés especial, simplemente se usa cuando se debe. De los tipos array y object nos ocuparemos expresamente, por sus peculiaridades. Ahora nos detendremos en el tipo string.
Las cadenas merecen cierta atención. Una cadena en PHP viene delimitada por comillas imples (') o dobles ("). Las comillas
simples producen literalidad: cualquier caracter dentro de ellas es interpretado como tal, excepto la propia comilla que debe ser escapada:
echo 'Martin\'s House';
La doble comilla produce la evaluación de las variables y la interpretación de
secuencias especiales como \n o \014:
$x=2300;
echo "Somos $x";
Para delimitar una variable cuando va pegada a una cadena, podemos emplear la forma ${variable}, pero es mejor usar {$variable}:
$x=23;
echo "Somos $x00\n"; // falla
echo "Somos ${x}00\n";
echo "Somos {$x}00\n";
$a['ejemplo']='algo';
$b['otro']['ejemplo']='nada';
echo "Ejemplo: $a['ejemplo'] con array"; // error de sintaxis
echo "Ejemplo: $a[ejemplo] con array"; // funciona, pero por compatibilidad obsoleta
echo "Ejemplo: {$a['ejemplo']} con array"; // correcto
echo "Ejemplo: ${a['ejemplo']} con array"; // correcto
echo "Ejemplo: ".$a['ejemplo']." con array"; // obviamente correcto, pero más farragoso
echo "Ejemplo: {$b['otro']['ejemplo']} con array"; // correcto
echo "Ejemplo: ${b['otro']['ejemplo']} con array"; // error de sintaxis
La forma $a[ejemplo] implica la definición de una constante de nombre ejemplo, que no estando previamente definida, toma el valor 'ejemplo'. Esta forma no debería usarse, exite por compatibilidad con las primeras versiones de PHP.
if (condición)
acción ;
if (condición)
acción ;
else
otra_acción ;
if (condición) acción ;
elseif (otra_condición) otra_acción
else más_acción;
switch ((expresión) {
case valor: acciones;
case valor: acciones;
default: acciones;
}
while (condición) acción;
do acción while (condición);
for (expresión inicial, exp. inicial2 ;
condición ;
expresión de paso, expresión de paso2)
acción;
foreach (expresión_array as $valor)
acción;
foreach (expresión_array as $indice => $valor)
acción;
Creo que estas estructuras se comprenden sin más, pero haré algunas aclaraciones.
El término acción; hace referencia a una sentencia cualquiera (o colección de sentencias agrupadas con { y }).
El término condición se refiere a cualquier expresión que se evaluará como un boolean. Es decir que será false tanto la cadena vacía, como un 0 numérico como una cadena que contiene un "0", como un array vacío. Una array que contenga al menos un elemento, aunque sea array(false), evalúa como true.
Respecto a switch, hay que tener en cuenta que para cada case pueden ponerse varias acciones sin {}. La última de las
mencionadas acciones suele ser break. Si break no está presente, la ejecución sigue con el siguiente grupo de acciones:
switch(5) {
case 5: echo "Hola ";
case 6: echo "soy yo";
}
Respecto a while, la acción se ejecuta 0 o más veces, pues la condición se evalúa antes. En cambio do ... while ejecuta la acción al menos una vez, pues la condición se evaúa después.
La sentencia foreach permite ejecutar la acción para cada uno de los elementos del array, que es copiado en la variable
que he etiquetado como $valor. Si $indice está presente, se accede, además, a cada uno de los índices. Observa la ejecución de
este código:
foreach($a=array("lun","mar") as $dia) {
$dia="dom";
echo $dia."\n";
}
print_r($a);
foreach($a as $i => $dia)
$a[$i]="dom";
print_r($a);
La sentencia break se usa no sólo en el ámbito de switch, sino principalmente
para romper bucles. Aunque los puristas opinan que es una forma poco estructurada de programación,
sí que lo es si se usa correctamente, es decir para tratar, por ejemplo, excepciones o errores.
También es necesaria si se usa para cualquier ruptura con foreach. El siguiente código
Busca un elemento en un array usando foreach:
unset($donde);
foreach($a as $i => $v)
if ($v == buscado) {
$donde=$i;
break;
}
if (isset($donde)) // no puedo usar if ($donde) pues podría ser 0
echo "Está en $donde";
Igualmente la sentencia continue, mucho menos util que break, causa que, dentro de un bucle, no se procesen el resto de instrucciones y se pase a la siguiente iteración.
Por último, la sentencia return, que se usa para establecer el valor devuelto por una función, causa también el fin de la ejecución del código de la función, dando una funcionalidad similar a break, pero sólo dentro de funciones, o en el caso especial de la sentencia eval.
$a[3]=8; que crea un array de nombre $a y le asigna un entero 8 a la posición
3. He remarcado el término posición porque realmente se trata de un índice:
$a[3]=8;
$a[1]="Hola";
print_r($a); También es típica la autoasignación de índice mediante el uso de []:
$a["clave1"]="hola" ;
$a["clave2"]="adios" ;
$a[]=1;
$a[]=2;
$a[20]= 3;
$a[]= 4;
print_r($a) ;
$a[20]= 3;
foreach ($a as $elemento => $valor)
unset($a[$elemento]) ;
$a[]= 4;
print_r($a) ; El constructor array() permite formar un array de un tirón. Observemos este ejemplo:
$v=array("coche" => "bmw", "moto" => "honda");
print_r($v);
$v[coche]="audi";
print_r($v);
define("coche","moto");
$v[coche]="ferrari";
print_r($v);
El ejemplo ilustra como construir un array usando array(). Al mismo tiempo ilustra el peligro de usar constantes como índices de arrays si se usan también sentencias define.
Los arrays multidimensionales no existen como tales, son simplemente arrays de arrays y se manejan así:
$a[8][3][5][3]=22;
print_r($a);
Parece obvio que los índices de un array son únicos, lo que me puede ser útil. Por ejemplo, para saber qué (y cuántas veces)
elementos HTML aparecen en un archivo, puedo usar:
preg_match_all('%<([^/]\w+)%',
file_get_contents($_SERVER['SCRIPT_FILENAME']),$mat);
$eles=array();
foreach ($mat[1] as $ele)
$eles[$ele]++;
ksort($eles); // si no ordeno, el orden es el de la primera aparición
print_r($eles);
Un uso del constructor array() es la generación de listas sobre la marcha para ahorrar y dar claridad al código.
En el siguiente ejemplo, para añadir más días sólo tengo que modificar el array:
setlocale(LC_TIME,"es_ES");
$f=time();
foreach(array("mon" => "cansado",
"tue" => "aburrido",
"fri" => "contento"
) as $d => $que)
echo strftime("El %A %e de %b estaré $que\n",$f=strtotime($d,$f));
function ejemplo($valor) { // absurda función
echo "Hola";
return $valor+1;
}
Los parámetros se pasan por valor si no se dice lo contrario. Las funciones pueden retornar cualquier tipo de datos
e igualmete los parámetros pueden ser de cualquier tipo.
Una función puede definirse antes o después del momento de usarse. Puede definirse también de forma condicional, por ejemplo
dentro de un if. En este caso, no quedan definidas si no se entra en el if.
Si se invoca a una función que no existe se produce un error fatal. Una función no puede redefinirse.
Los parámetros admiten dos variantes además del formato clásico. Por una parte los parámetros por defecto permiten
que ciertos parámetros tengan un valor preestablecido si no se pasa a la función:
function defecto($color,$fondo="negro") {
echo "$color sobre fondo $fondo\n";
}
defecto("amarillo");
defecto("azul","naranja");
Por supuesto las funciones admiten parámetros por referencia, usando el operador &:
function referencia(&$variable) {
$variable="sí";
}
$modi="no";
referencia($modi);
echo "La variable $modi ha sido modificada";
Si en una variable de tipo string almacenamos el nombre de una función, podemos llamar a ésta usando la variable:
function uno() { echo "Una\n"; }
function dos() { echo "Dos\n"; }
$func="uno"; $func();
$func="dos"; $func();
function factorial($x) {
if ($x == 0)
return 1;
else
return $x*factorial($x-1);
}
echo "Factorial de 3 = ".factorial(3); Una expresión regular es un patrón que describe un conjunto de cadenas sin enumerarlas, es decir que las representa sin especificar cuales son. Por ejemplo: ab?c representa a las cadenas abc y ac. La expresión se contruye con los elementos que integran las cadenas más unos signos (operadores) que las definen. De unos lenguajes de programación a otros la sintaxis cambia bastante, puede haber más o menos signos o ser distinta su interpretación exacta. Básicamente las expresiones se componen de operadores:
Otros caracteres tienen significados especiales. Por ejemplo . significa cualquier caracter, normalmete se excluye el cambio de línea (\n), pero en PCRE puede especificarse que también lo incluya. Los signos ^ y $ no se corresponden con ningún caracter, sino que representan posiciones dentro de la cadena, concretamente al inicio y al final. Los signos [ y ] marcan la definición de una clase de caracteres, cambiando el significado de ^ y -.
Todos estos signos y operadores pueden combinarse con cuidado. Por ejemplo si queremos representar sólo las cadenas pan y agua, podemos usar la expresión ^pan|agua$, pero ésta puede representar:
Cuando en una expresión se quieren introducir literalmente los citados signos (es decir que no se interpreten como operadores, sino como integrantes de la cadena), es necesario escaparlos, lo que se logra precediéndolos del signo \. Por ejemplo para representra a todas las posibles direcciones de correo dentro de nisu.org y todos sus subdominios (por ejemplo buyer@hony.nisu.org, puedo usar la expresión @.*nisu\.org$. Obsérvese queno es necesario poner .* delante.
La barra \ sirve además para dar significados especiales a otros caracteres, por ejemplo \s significa cualquier cantidad de espacio en blanco (incluído \r y \n), y por ejemplo \b no coincide con ningún caracter pero marca el inicio de una palabra. El tercer uso de la barra \ ya se habrá adivinado, es para indicar caracteres especiales como \r y \n.
Los signos [ y ] marcan conjuntos de caracteres, por ejemplo [A-Z] significa una mayúscula y [A-Z][A-Z_a-z0-9]* significa una mayúscula pero seguida de cero o más mayúsculas, minúsculas, cifras o el caracter _; la expresión [^0-9] significa cualquier caracter excepto cifras.
Las expresiones regulares tienden a coincidir con cadenas lo más largas posibles, es decir que ^.*a en la cadena patata, la letra a coincidirá con la última a. Si queremos que coincida con la primera, debemos usar el signo ? con un nuevo significado, acortar expresiones. Así ^.*?a significa cero o más caracteres pero los menos posibles seguidos de una a. Por ello la cadena representada por ^.*?a sobre patata es realmente pa. Obviamente si la expresión es ^.*?a$, tabién representa a patata, pero esta vez coincide con toda la palabra.
Las expresiones regulares pueden modificar su significado en función de unos modificadores que se indican junto con ella. Normalmente la expresión regular se expresa delimitada por un caracter (por costumbre es la barra /) y a continuación dichos modificadores. El carácter delimitador pierde el significado que pueda tener dentro de la expresión. A partir de ahora las escribiremos así. Modificadores importantes son: s, que significa que el . también coincide con cambios de línea, y m que indica que ^ y $ también coinciden a principio y final de línea (cuando la cadena tiene varias líneas), sin este modificador sólo indican principio y final de cadena.
Con lo que sabemos ahora, vemos algunos ejemplos:
//!
$variable="una cadena".
"otra cadena"
; Mucho más avanzado es el uso de subpatrones de la forma (?loquesea). Su utilidad es muy diversa:
preg_match('%(<(\w+).*?>)([^<]*)(</\2.*?>)%',
file_get_contents($_SERVER['SCRIPT_FILENAME']),$mat);
print_r($mat);
Si queremos todas las coincidencias, no la primera, debemos usar preg_match_all:
preg_match_all('%(<(\w+).*?>)([^<]*)(</\2.*?>)%',
file_get_contents($_SERVER['SCRIPT_FILENAME']),$mat);
print_r($mat);
Quizá el orden devuelto, no es el que interesa, puedo establecerlo de otro modo:
preg_match_all('%(<(\w+).*?>)([^<]*)(</\2.*?>)%',
file_get_contents($_SERVER['SCRIPT_FILENAME']),$mat,PREG_SET_ORDER);
print_r($mat);
La función preg_replace reeemplaza un patrón por una cadena en otra cadena. La expresión regular y la cadena de reemplazo pueden ser de tipo array y equivale a aplicar preg_replace iterativamente. En la cadena de reemplazo podemos emplear \1, \2, etc. para hacer referencia a las zonas marcadas con ().
Veamos algunos ejemplos. Dado $y con el texto:
Podemos eliminar todos los comentarios excepto uno con la sentencia:
// %es%: Esto es un comentario
// %en%: This is a comment
// %fr%: Ici un commentaire
$lg="es";
echo preg_replace(array("#^[ \t]*//[ \t]+%..(?<!$lg)%:[ \t].*\n#m",
"#^([ \t]*//[ \t]+)%$lg%:[ \t]+#m"),
array("","\\1"),$y);
// Esto es un comentario
Un modificador espectacular aplicable a preg_replacees /e,
que significa: una vez sustituído, evalúalo, es decir que la cadena de reemplazo
debe generar código php válido que después se interpreta y ejecuta (evalúa).
Por ejemplo, dado que php no dispone de función
para codificar en quoted-printable, podemos hacerlo así:
echo preg_replace('/[^\x21-\x3C\x3E-\x7E\x09\x20]/e',
'sprintf( "=%02x", ord ( "$0" ) ) ;',
"Hola campeón,\n¿qué tal te va?");
Observa la necesidad del ; al final del sprintf.
PCRE no siempre funciona como parece. Observemos esta instrucción:
preg_match('+(a)(.*?)(b)(.*?)(c)+s','hola12a33a.b.c',$m); print_r($m);
preg_match('+.*(a)(.*?)(b)(.*?)(c)+s','hola12a33a.b.c',$m); print_r($m); A veces la expresión regular no es constante sino variable, es decir, algo como:
preg_match('/(<img[^>]*src=)"?'.$f.'"?/',$html);
En este caso, si $f contiene una barra /, la expresión regular deja de ser válida. Podría usar otro caracter
para delimitar la expresión regular, pero no adelanto nada, en tanto que puede contener puntos, por ejemplo. El problema se resuelve
usando preg_quote, que "escapa" los caracteres especiales:
preg_match('/(<img[^>]*src=)"?'.preg_quote($f,'/').'"?/',$html);
echo "Mi URL: http://{$_SERVER['HTTP_HOST']}{$_SERVER['SCRIPT_NAME']}<br>";
echo "Tu IP: {$_SERVER['REMOTE_ADDR']} o {$_SERVER['HTTP_X_FORWARDED_FOR']}"; Es interesante hacer notar que PHP puede usarse desde línea de comando. Los arrays $argc y $argv están disponibles para acceder a los parámetros.
<form method="post" action="procform.php">
Escribe: <input name="prueba" value="pre escrito">
<input type=submit name="env" value="Enviar">
</form>
El formulario no es más que HTML que el navegador muestra de una forma que permite interacción con el usuario:
<?
echo '<xmp>';
print_r($_POST);
echo '</xmp>';
?> El resultado (pulsa el botón en el formulario anterior para verlo) es:
Prestemos atención a ciertas cuestiones:
<form method="post" action="procform.php">
Escribe: <input name="prueba" value="pre"escrito">
<input name="prueba" value="otro igual">
<select name=multi multiple size=4>
<option>1<option>2<option>3<option>4<option>5<option>6
</select>
<input type=submit name="env" value="Enviar">
<input type=submit name="env2" value="Enviar también">
<input type=hidden name=malsecreto value="oculto">
</form>
Para resolver el problema de los nombres iguales (que, insisto, es un problema de PHP, no del navegador)
debemos adaptar el HTML y llamar a los campos repetidos como si fueran arrays. Obviamente para el
HTML no son arrays, pero PHP sí que los interpretará como tales:
<form method="post" action="procform.php">
Escribe: <input name="prueba[]" value="pre"escrito">
<input name="prueba[]" value="otro igual"><br>
<input name="con_indice[33]"><input name="con_indice[66]">
<select name="multi[]" multiple size=4>
<option>1<option>2<option>3<option>4<option>5<option>6
</select>
<input type=submit name="env" value="Enviar">
</form>
Obsérvese lo antiestético del formulario.
El aprendizaje del procesado de formularios se completa necesariamente leyendo aquí .
<form enctype="multipart/form-data" method="post" action="cojearchivo.php">
<input type="hidden" name="MAX_FILE_SIZE" value="10000">
Elige el archivo que quieres enviar: <input type=file name=fich>
y <input type=submit value="envíalo">
</form>
Notemos que el formulario debe llevar codificación multipart/form-data (la codificación por defecto de los formularios es application/x-www-form-urlencoded, que envía los datos en codificación urlencoded, muy ineficiente para grandes volúmenes). El método debe ser necesariamente POST.
PHP es capaz de interpretar la codificación multipart/form-data, de modo que el programador no nota diferencia
en lo que encuentra en $_POST respecto a un formulario "normal".
Pero el campo input de tipo file no es almacenado en la
variable $_POST, pues un archivo grande desbordaría la memoria (realmente, versiones antiguas de PHP
cargaban el archivo enviado en memoria antes de procesarlo, esto ha sido corregido en las versiones actuales).
En su lugar, la variabe $_FILES contiene lo que necesitamos. Desafortunadamente los navegadores no suelen
incluir barras de progreso del envío del archivo, por lo que envíos grandes suelen desesperar al usuario.
El campo oculto de nombre MAX_FILE_SIZE debería ser interpretado por el navegador para no dejar enviar
archivos de un tamaño mayor. Obviamente esto no debe usarse con propósitos de seguridad, pues el navegador puede
no hacer caso o el usuario modificar el HTML.
PHP tiene su propio límite de tamaño de archivo admitido, que es un límite insalvable y puede obtenerse mediante
ini_get. Éste límite debe ser menor que el límite establecido para un POST:
echo "El tamaño máximo de archivo en este servidor es ".ini_get("upload_max_filesize")."\n";
echo "El POST más grande posible es ".ini_get("post_max_size");
Probemos el ejemplo:
El archivo es recibido por cojearchivo.php que contiene:
<?
echo '<pre>';
print_r($_FILES);
echo '</pre>';
?>
Y produce:
Observamos que la variable $_FILES contiene información del archivo recibido, indexada por el nombre del campo (en este caso fich). Nos suministra el nombre original (name), el tipo MIME del archivo (type), el nombre con que se ha grabado en el servidor (tmp_name), el posible error, y el tamaño del archivo. Con esta información, lo habitual será comprobar si el tamaño esta en los límites esperados, si es de un tipo esperado, y en ese caso cambiarlo de ubicación y probablemente de nombre, con la función move_uploaded_file. Es importante hacer notar que el nombre original del archivo debería usarse sólo como dato informativo, no debería renombrarse el archivo recibido a su nombre original, pues puede ser incompatible con el sistema de archivos o producir problemas de seguridad graves.
Este podría ser un uso normal:
foreach ($_FILES as $cmp => $fic) {
if ($fic["size"] > 100000) {
echo "Tamaño de archivo (campo $cmp) excesivo";
continue;
}
if (substr($fic["type"],0,6) != "image/") {
echo "Esperaba una imagen en el campo $cmp";
continue;
}
$minombre=strftime("Archivo_subido_el_%Y_%m_%d_%H_%M");
if (!move_uploaded_file($fic["tmp_name"],"midirectorio/$minombre"))
echo "Algo ha pasado con el archivo del campo $cmp";
}
<?
$v=$_GET['test'] or $v="'";
echo '<form>'.
"<input name=test value=\"$v\">".
'<input type=submit value=Continuar>'.
'</form>';
?> Pulsa Continuar repetidas veces:
session_start();
Su misión es establecer el nmbre de sesión y leer los datos si la sesión ya existe y si no, lanzar la cookie. Por esta razón debe llamarse
siempre antes de que el programa escriba nada por el output.
$_SESSION['nombre']='Lucas';
almacena un dato que podemos consultar en otra ejecución del programa. Un ejemplo muy sencillo:
<?
session_start();
$_SESSION['cont']++;
echo "Contador: ".$_SESSION['cont'].
' - <a href="?dum='.rand().'">incrementar</a>';
?>
if (!$_SESSION['autenticado']) {
... autenticar ...
}
else {
// autenticado
session_write_close();
readfile("Fichero descarga");
}
echo '<br>Más información <a href="http://otra.com/?sid='.
session_id().'">aquí</a>';
Y en la segunda página forzar el uso de esa sessión:
if ($sid=$_GET['sid']) {
session_id($sid);
session_start();
// limpia la URL
header("Location: ?");
die();
}
$hServ=mysql_connect("localhost","miuser","mipassword")
or salir("No se pudo conectar con el servidor MySQL");
$dbSel=mysql_select_db("mibase")
or salir("Error al abrir la Base de Datos.");
A partir de este punto ya podemos lanzar consultas. Obsérvese que, al
seleccionar la base de datos, no le he indicado
el servidor en el que se encuentra (es un parámetro opcional). Muchas funciones de MySQL siguen este patrón, tomando
la última llamada a una función MySQL como referencia. En el ejemplo, al usar un solo servidor y una sola base de datos,
$hServ y $dbSel no son necesarias.
$col=$_GET['col'];
$qu=mysql_query("select * from tabla where col = '$col'");
while ($fil=mysql_fetch_assoc($qu))
echo $fil['otracol'];
Es importante señalar varias cosas. En primer lugar, al usar $col en la consulta, debemos estar seguros de que
magic-quotes-gpc está activo.
De lo contrario podría producirse un problema de seguridad. En segundo lugar, de las diversas funciones mysql_fetch_
debemos usar, en general, mysql_fetch_assoc y no mysql_fetch_row. De este modo, si se altera la tabla,
el código php seguirá siendo válido. Puede usarse mysql_fetch_row en una situación como ésta:
list($nume