Академический Документы
Профессиональный Документы
Культура Документы
Curso:
PHP, MySQL y E-Commerce
Módulo:
“Estructuras del lenguaje PHP”
Tutor: Ing. Oscar R. Espeche
2.3 Funciones
2.6 Cookies
2.7 Sesiones
Las sentencias normalmente acaban con punto y coma. Además, las sentencias se pueden
agrupar en grupos de sentencias encapsulando un grupo de sentencias con llaves. Un grupo
de sentencias es también una sentencia. A continuación se describen los diferentes tipos de
sentencias.
La sentencia if
if (expr)
sentencia
A menudo, se desea tener más de una sentencia ejecutada de forma condicional. Por
supuesto, no hay necesidad de encerrar cada sentencia con una cláusula if. En vez de eso,
se pueden agrupar varias sentencias en un grupo de sentencias. Por ejemplo, este código
mostraría a es mayor que b si $a fuera mayor que $b, y entonces asignaría el valor de $a a
$b:
Las sentencias if se pueden anidar indefinidamente dentro de otras sentencias if, lo cual
proporciona una flexibilidad completa para ejecuciones condicionales en las diferentes partes
de tu programa.
La sentencia else
Autor: Ing. Oscar R. Espeche 3
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
A menudo queremos ejecutar una sentencia si se cumple una cierta condición, y una
sentencia distinta si la condición no se cumple. Esto es para lo que sirve else. else extiende
una sentencia if para ejecutar una sentencia en caso de que la expresión en la sentencia if
se evalúe como FALSE. Por ejemplo, el siguiente código mostraría a es mayor que b si $a
fuera mayor que $b, y a NO es mayor que b en cualquier otro caso:
La sentencia elseif
elseif, como su nombre sugiere, es una combinación de if y else. Como else, extiende una
sentencia if para ejecutar una sentencia diferente en caso de que la expresión if original se
evalúa como FALSE.
Puede haber varios elseifs dentro de la misma sentencia if. La primera expresión elseif (si
hay alguna) que se evalúe como TRUE se ejecutaría.
En PHP, también se puede escribir 'else if' (con dos palabras) y el comportamiento sería
idéntico al de un 'elseif' (una sola palabra).
PHP ofrece una sintaxis alternativa para alguna de sus estructuras de control; a saber, if,
while, for, y switch. En cada caso, la forma básica de la sintaxis alternativa es cambiar abrir-
llave por dos puntos (:) y cerrar-llave por endif;, endwhile;, endfor;, or endswitch;,
respectivamente.
En el ejemplo de arriba, el bloque HTML "A = 5" se anida dentro de una sentencia if escrita
en la sintaxis alternativa. El bloque HTML se mostraría solamente si $a fuera igual a 5.
La sintaxis alternativa se aplica a else y también a elseif. La siguiente es una estructura if
con elseif y else en el formato alternativo:
if ($a == 5):
print "a es igual a 5";
print "...";
elseif ($a == 6):
print "a es igual a 6";
print "!!!";
else:
print "a no es ni 5 ni 6";
endif;
La sentencia while
Los bucles while son los tipos de bucle más simples en PHP. Se comportan como su
contrapartida en C. La forma básica de una sentencia while es:
El significado de una sentencia while es simple. Le dice a PHP que ejecute la(s) sentencia(s)
anidada(s) repetidamente, mientras la expresión while se evalúe como TRUE. El valor de la
expresión es comprobado cada vez al principio del bucle, así que incluso si este valor cambia
durante la ejecución de la(s) sentencia(s) anidada(s), la ejecución no parará hasta el fin de
la iteración (cada vez que PHP ejecuta las sentencias en el bucle es una iteración).
A veces, si la expresión while se evalúa como FALSE desde el principio de todo, la(s)
sentencia(s) anidada(s) no se ejecutarán ni siquiera una vez.
Como con la sentencia if, se pueden agrupar múltiples sentencias dentro del mismo bucle
while encerrando un grupo de sentencias con llaves, o usando la sintaxis alternativa:
Los siguientes ejemplos son idénticos, y ambos imprimen números del 1 al 10:
/* ejemplo 1 */
$i = 1;
while ($i <= 10) {
print $i++; /* el valor impreso sería
$i antes del incremento
(post-incremento) */
}
/* ejemplo 2 */
$i = 1;
while ($i <= 10):
print $i;
$i++;
endwhile;
La sentencia do..while
Los bucles do..while son muy similares a los bucles while, excepto que las condiciones se
comprueban al final de cada iteración en vez de al principio.
La principal diferencia frente a los bucles regulares while es que se garantiza la ejecución de
la primera iteración de un bucle do..while (la condición se comprueba sólo al final de la
iteración), mientras que puede no ser necesariamente ejecutada con un bucle while regular
(la condición se comprueba al principio de cada iteración, si esta se evalúa como FALSE
desde el principio la ejecución del bucle finalizará inmediatamente).
$i = 0;
do {
print $i;
} while ($i>0);
El bucle de arriba se ejecutaría exactamente una sola vez, después de la primera iteración,
cuando la condición se comprueba, se evalúa como FALSE ($i no es más grande que 0) y la
ejecución del bucle finaliza.
La sentencia for
Autor: Ing. Oscar R. Espeche 6
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
Los bucles for son los bucles más complejos en PHP. Se comportan como su contrapartida en
C. La sintaxis de un bucle for es:
La primera expresión (expr1) se evalúa (ejecuta) incondicionalmente una vez al principio del
bucle.
Al comienzo de cada iteración, se evalúa expr2 . Si se evalúa como TRUE, el bucle continúa
y las sentencias anidadas se ejecutan. Si se evalúa como FALSE, la ejecución del bucle
finaliza.
Cada una de las expresiones puede estar vacía. Que expr2 esté vacía significa que el bucle
debería correr indefinidamente (PHP implicitamente lo considera como TRUE, al igual que
C).
Esto puede que no sea tan inútil como se podría pensar, puesto que a menudo se quiere
salir de un bucle usando una sentencia break condicional en vez de usar la condición de for.
Considera los siguientes ejemplos. Todos ellos muestran números del 1 al 10:
/* ejemplo 1 */
/* ejemplo 2 */
/* ejemplo 3 */
$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
/* ejemplo 4 */
Por supuesto, el primer ejemplo parece ser el mas elegante (o quizás el cuarto), pero uno
puede descubrir que ser capaz de usar expresiones vacías en bucles for resulta útil en
muchas ocasiones.
PHP también soporta la "sintaxis de dos puntos" alternativa para bucles for.
Otros lenguajes poseen una sentencia foreach para traducir un array o una tabla hash. PHP3
no posee tal construcción; PHP4 sí (ver foreach). En PHP3, se puede combinar while con las
funciones list() y each() para conseguir el mismo efecto. Mirar la documentación de estas
funciones para ver un ejemplo.
La sentencia foreach
PHP4 (PHP3 no) incluye una construcción foreach, tal como perl y algunos otros lenguajes.
Esto simplemente da un modo fácil de iterar sobre arrays. Hay dos sintaxis; la segunda es
una extensión menor, pero útil de la primera:
La primera forma recorre el array dado por expresión_array. En cada iteración, el valor del
elemento actual se asigna a $value y el puntero interno del array se avanza en una unidad
(así en el siguiente paso, se estará mirando el elemento siguiente).
La segunda manera hace lo mismo, salvo que la clave del elemento actual será asignada a la
variable $key en cada iteración.
Nota: Hay que tener en cuanta que foreach trabaja con una copia de la lista
(array) especificada y no la lista en si, por ello el puntero de la lista no es
modificado como en la construcción each.
reset( $arr );
while( list( , $value ) = each( $arr ) ) {
echo "Valor: $value<br>\n";
}
reset( $arr );
while( list( $key, $value ) = each( $arr ) ) {
echo "Key: $key; Valor: $value<br>\n";
}
foreach($a as $v) {
print "Valor actual de \$a: $v.\n";
}
foreach($a as $v) {
print "\$a[$i++] => $v.\n";
}
La sentencia break
break escapa de la estructuras de control iterante (bucle) actuales for, while, o switch.
break acepta un parámetro opcional, el cual determina cuantas estructuras de control hay
que escapar.
$i = 0;
while (++$i) {// este es un loop
switch ($i) {// este es otro loop
case 5:
echo "En 5<br>\n";
break 1;
case 10:
echo "En 10; salir<br>\n";
break 2;
default:
break;
}
}
La sentencia continue
continue se usa dentro de la estructura del bucle para saltar el resto de la iteración actual
del bucle y continuar la ejecución al comienzo de la siguiente iteración.
continue accepta un parámetro opcional, el cual determina cuantos niveles (bluces) hay que
saltar antes de continuar con la ejecución.
continue;
}
hacer_algo ($value);
}
$i = 0;
while ($i++ < 5) {
echo "bucle externo<br>\n";
while (1) {
echo " bucle medio<br>\n";
while (1) {
echo " bucle interno<br>\n";
continue 3;
}
echo "Esto nunca se envía<br>\n";
}
echo "Esto tampoco<br>\n";
}
La sentencia switch
La sentencia switch es similar a una serie de sentencias IF.. ELSEIF. En muchas ocaciones,
se quiere comparar la misma variable (o expresión) con nuchos valores diferentes, y ejecutar
una parte de código distinta dependiendo de a qué valor es igual. Para ello sirve la sentencia
switch.
Los siguientes dos ejemplos son dos modos distintos de escribir la misma cosa, uno usa una
serie de sentencias if, y el otro usa la sentencia switch:
if ($i == 0) {
print "i es igual a 0";
}
if ($i == 1) {
print "i es igual a 1";
}
if ($i == 2) {
print "i es igual a 2";
}
switch ($i) {
case 0:
print "i es igual a 0";
break;
case 1:
print "i es igual a 1";
break;
case 2:
print "i es igual a 2";
break;
}
Es importante entender cómo se ejecuta la sentencia switch para evitar errores. La sentencia
switch ejecuta línea por línea (realmente, sentencia a sentencia). Al comienzo, no se ejecuta
código. Sólo cuando se encuentra una sentencia case con un valor que coincide con el valor
de la expresión switch PHP comienza a ejecutar las sentencias.
PHP continúa ejecutando las sentencias hasta el final del bloque switch, o la primera vez que
vea una sentencia break. Si no se escribe una sentencia break al final de una lista de
sentencias case, PHP seguirá ejecutando las sentencias del siguiente case. Por ejemplo:
switch ($i) {
case 0:
print "i es igual a 0";
case 1:
print "i es igual a 1";
Autor: Ing. Oscar R. Espeche 12
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
case 2:
print "i es igual a 2";
}
Aquí, si $i es igual a 0, ¡PHP ejecutaría todas las sentecias print! Si $i es igual a 1, PHP
ejecutaría las últimas dos sentencias print y sólo si $i es igual a 2, se obtendría la conducta
'esperada' y solamente se mostraría 'i es igual a 2'.
Así, es importante no olvidar las sentencias break (incluso aunque pueda querer evitar
escribirlas intencionadamente en ciertas circunstancias).
En una sentencia switch, la expresión se evalúa sólo una vez y el resultado se compara a
cada sentencia case. En una sentencia elseif, la condición se evalúa otra vez. Si tu condición
es más complicada que una comparación simple y/o está en un bucle estrecho, un switch
puede ser más rápido.
La lista de sentencias de un case puede también estar vacía, lo cual simplemente pasa el
control a la lista de sentencias del siguiente case.
switch ($i) {
case 0:
case 1:
case 2:
print "i es menor que 3, pero no negativo";
break;
case 3:
print "i es 3";
}
Un case especial es el default case. Este case coincide con todo lo que no coincidan los otros
case. Por ejemplo:
switch ($i) {
case 0:
print "i es igual a 0";
break;
case 1:
print "i es igual a 1";
break;
case 2:
print "i es igual a 2";
break;
default:
print "i no es igual a 0, 1 o 2";
}
La expresión case puede ser cualquier expresión que se evalúe a un tipo simple, es decir,
números enteros o de punto flotante y cadenas de texto. No se pueden usar aquí ni arrays ni
objetos a menos que se conviertan a un tipo simple.
La sintaxis alternativa para las estructuras de control está también soportada con switch.
Para más información, ver Sintaxis alternativa para estructuras de control.
switch ($i):
case 0:
print "i es igual 0";
break;
case 1:
print "i es igual a 1";
break;
case 2:
print "i es igual a 2";
break;
default:
print "i no es igual a 0, 1 o 2";
endswitch;
require()
require() no es en realidad una función de PHP; es más una construcción del lenguaje. Está
sujeta a algunas reglas distintas de las de funciones. Por ejemplo, require() no esta sujeto
a ninguna estructura de control contenedora. Por otro lado, no devuelve ningún valor;
intentar leer un valor de retorno de una llamada a un require() resulta en un error del
intérprete.
Esto significa que no se puede poner una sentencia require() dentro de una estructura de
bucle y esperar que incluya el contenido de un archivo distinto en cada iteración. Para hacer
esto, usa una sentencia include().
require( 'cabecera.inc' );
Cuando un archivo es icorporado con require(), el código de éste hereda el ámbito de las
variables disponibles en la línea donde se ejecuta require().
Si se ejecuta require() dentro de una función, todo el código del archivo incorporado se
comporta como si fuese definido dentro de la función.
Se puede ejecutar require() para incorporar un archivo mediante una URL donde se podrán
opcionalmente enviar prámetros GET. En realidad lo que se incorpora es el resultado de la
ejecución de la página PHP en el servidor.
Autor: Ing. Oscar R. Espeche 15
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
require ("http://algunserver/archivo1.txt?varuno=1&vardos=2");
En PHP3, es posible ejecutar una sentencia return dentro de un archivo referenciado con
require(), en tanto en cuanto esa sentencia aparezca en el ámbito global del archivo
requerido (require()). No puede aparecer dentro de ningún bloque (lo que siginifica dentro
de llaves({})).
include()
Si "URL fopen wrappers" esta activada en PHP (como está en la configuración inicial), se
puede especificar el archivo que se va a incluir usando una URL en vez de un archivo local
(con su Path) Ver Archivos remotos y fopen() para más información.
Esto sucede cada vez que se encuentra la sentencia include(), así que se puede usar una
sentencia include() dentro de una estructura de bucle para incluir un número de archivos
diferentes.
include() difiere de require() en que la sentencia include se re-evalúa cada vez que se
encuentra (y sólo cuando está siendo ejecutada), mientras que la sentencia require() se
reemplaza por el archivo referenciado cuando se encuentra por primera vez, se vaya a
evaluar el contenido del archivo o no (por ejemplo, si está dentro de una sentencia if cuya
condición evaluada es falsa).
Debido a que include() es una construcción especial del lenguaje, se debe encerrar dentro
de un bloque de sentencias si está dentro de un bloque condicional.
if ($condicion)
include($archivo);
else
include($otro);
/* Esto es CORRECTO. */
if ($condicion) {
include($archivo);
} else {
include($otro);
}
En ambos, PHP3 y PHP4, es posible ejecutar una sentencia return dentro de un archivo
incluido con include(), para terminar el procesado de ese archivo y volver al archivo de
comandos que lo llamó.
Existen algunas diferencias en el modo en que esto funciona, no obstante. La primera es que
en PHP3, return no puede aparecer dentro de un bloque a menos que sea un bloque de
función, en el cual return se aplica a esa función y no al archivo completo. En PHP4, no
obstante, esta restricción no existe.
También, PHP4 permite devolver valores desde archivos incluidos con include(). Se puede
capturar el valor de la llamada a include() como se haría con una función normal. Esto
generaría un error de intérprete en PHP3.
Asumamos la existencia del siguiente archivo (llamado test.inc) en el mismo directorio que el
archivo principal:
<?php
echo "Antes del return <br>\n";
if ( 1 ) {
return 27;
}
echo "Después del return <br>\n";
?>
<?php
$retval = include( 'test.inc' );
echo "El archivo devolvió: '$retval'<br>\n";
?>
<?php
include( 'test.inc' );
echo "De vuelta en main.html<br>\n";
?>
El error del intérprete es resultado del hecho de que la sentencia return está encerrada en
un bloque de no-función dentro de test.inc. Cuando el return se mueve fuera del bloque, la
salida es:
El '27' espúreo se debe al hecho de que PHP3 no soporta devolver valores con return desde
archivos como ese.
Cuando un archivo es icorporado con include(), el código de éste hereda el ámbito de las
variables disponibles en la línea donde se ejecuta include().
Si se ejecuta include() dentro de una función, todo el código del archivo incorporado se
comporta como si fuese definido dentro de la función.
Se puede ejecutar include() para incorporar un archivo mediante una URL donde se podrán
opcionalmente enviar prámetros GET. En realidad lo que se incorpora es el resultado de la
ejecución de la página PHP en el servidor.
include ("http://algunserver/archivo1.txt?varuno=1&vardos=2");
require_once()
Es similar a require() salvo que asegura que la inclusión se realiza una sola vez en el script.
De esta forma se evitan las posibles redefiniciones de variables y funciones por ejemplo.
include_once()
Es similar a include() salvo que asegura que la inclusión se realiza una sola vez en el script.
De esta forma se evitan las posibles redefiniciones de variables y funciones por ejemplo.
2.3 Funciones
Veremos con más detalle aspectos de las funciones en PHP.
Cualquier instrucción válida de PHP puede aparecer en el cuerpo de la función, incluso otras
funiones y definiciones de clases.
En PHP3, las funciones deben definirse antes de que se referencien. En PHP4 no existe tal
requerimiento.
PHP4 soporta ambos: ver Listas de longitud variable de parámetros y las referencias de las
funciones.
La información puede suministrarse a las funciones mediante la lista de parámetros, una lista
de variables y/o constantes separadas por comas.
PHP soporta pasar parámetros por valor (el comportamiento por defecto), por referencia, y
parámetros por defecto.
Por defecto, los parámetros de una función se pasan por valor (de manera que si cambias el
valor del argumento dentro de la función, no se ve modificado fuera de ella). Si deseas
permitir a una función modificar sus parámetros, debes pasarlos por referencia.
Si quieres que un parámetro de una función siempre se pase por referencia, puedes
anteponer un ampersand (&) al nombre del parámetro en la definición de la función:
function algo(&$string) {
$string .= ' y algo más.';
}
Si deseas pasar una variable por referencia a una función que no toma el parámetro por
referencia por defecto, puedes anteponer un ampersand al nombre del parámetro en la
llamada a la función:
function algo($bar) {
$bar .= ' y algo más.';
}
algo (&$str);
echo $str; // Saca 'Esto es una cadena, y algo más.'
Una función puede definir valores por defecto para los parámetros escalares estilo C++:
El valor por defecto tiene que ser una expresión constante, y no una variable o miembro de
una clase.
En PHP 4.0 también es posible especificar unset como parámetro por defecto. Esto significa
que el argumento no tomará ningún valor en absoluto si el valor no es suministrado.
Destacar que cuando se usan parámetros por defecto, estos tienen que estar a la derecha de
cualquier parámetro que no tenga valor por defecto; de otra manera las cosas no
funcionarán de la forma esperada. Considera el siguiente fragmento de código:
PHP4 soporta las listas de longitud variable de parámetros en las funciones definidas por el
usuario.
No necesita de ninguna sintaxis especial, y las listas de parámetros pueden ser escritas en la
llamada a la función y se comportarán de la manera esperada.
Devolución de valores
Los valores se retornan usando la instrucción opcional return. Puede devolverse cualquier
tipo de valor, incluyendo listas y objetos.
No puedes devolver múltiples valores desde una función, pero un efecto similar se puede
conseguir devolviendo una lista.
function numeros_pequeños() {
return array (0, 1, 2);
}
Funciones variable
PHP soporta el concepto de funciones variable, esto significa que si una variable tiene unos
paréntesis añadidos al final, PHP buscará una función con el mismo nombre que la
evaluación de la variable, e intentará ejecutarla. Entre otras cosas, esto te permite
implementar retrollamadas (callbacks), tablas de funciones y demás.
<?php
function algo() {
echo "Dentro de algo()<br>\n";
}
$func = 'algo';
$func();
$func = 'bar';
$func( 'prueba' );
?>
system(EscapeShellCmd($cmd))
Si el parámetro array existe, entonces el array especificado se rellenará con cada una
de las líneas de la salida producida por la orden. Notar que si el array ya contiene
algunos elementos, exec() los añadirá al final del array. Si no quiere que la función
incorpore dichos elementos, haga un unset() sobre el array antes de pasárselo a
exec().
Un uso típico de ello es ejecutar algo como las utilidades pbmplus las cuales pueden
dar como resultado directamente el flujo de datos de una imagen. Poniendo el
content-type a image/gif y llamando al programa pbmplus para mostrar un gif, usted
puede crear archivos de órdenes PHP que generen directamente imágenes.
system(PHP 3, PHP 4 )
Trataremos el tema de los archivos y como se trabaja en ellos desde PHP. No va a ser
exhaustivo ni mucho menos, pretende proporcionar las bases para que experimenten por su
cuenta y riesgo. Vamos a aprender unas cuantas cosas útiles al respecto de los archivos, así
que, si están listos, empezamos.
<?php
#Abrimos el archivo en modo de escritura
$DescriptorArchivo = fopen("archivo_prueba.txt","w");
#Escribimos la primera línea dentro de él
$string1 = "Esta es la primera línea de texto\r\n";
fputs($DescriptorArchivo,$string1);
#Escribimos la segunda línea de texto
$string2 = "Y esta es la segunda línea de texto\r\n";
fputs($DescriptorArchivo,$string2);
#Cerramos el archivo
fclose($DescriptorArchivo);
?>
Así pues, el script anterior lo único que hace es abrir un archivo llamado
archivo_prueba.txt, y escribe dentro de él dos líneas de texto. Se habrán fijado en el \r\n
de detrás de las líneas de texto, en las variables $string1 y $string2. Esto se debe a que, si
no estuviese puesto, el programa escribiría todo seguido. Con solo \n no sirve, al menos en
Windows 2000. En Linux, basta con un \n.
Otra de las cosas importantes del anterior script es algo que quizás no hayamos visto de
cerca. Fijémonos en la siguiente línea:
$DescriptorArchivo = fopen("archivo_prueba.txt","w");
La función fopen sirve para abrir un archivo en un modo. Los modos pueden ser seis y son
los siguientes. Además de listarlos, explicaré las diferencias (no siempre tan obvias), al
respecto de ellos.
apertura
Modo de solo lectura. Se abre el archivo y el cursor se coloca al principio del
r
mismo, permitiendo leerlo hasta el final.
Modo de lectura/escritura. Se abre el archivo y el cursor se coloca al principio
r+
del mismo, permitiendo leer o escribir en el archivo.
Modo de solo escritura. Se crea el archivo si no existiese, y, si existe, se borra
w todo su contenido, se sitúa el cursor al principio del archivo permitiéndonos
escribir.
Modo de escritura/lectura. Si el archivo no existe, se crea, y, si existiese, se
w+ borra todo su contenido, se sitúa el cursor al principio del archivo
permitiéndonos escribir y leer.
Modo de añadido. Abre el archivo, sitúa el cursor al final del mismo y permite
a escribir. Si el archivo no existe, lo crea, pero, en caso de existir, no borra su
contenido.
Modo de añadido/lectura. Sitúa el cursor al final del archivo y permite escribir y
a+
leer. Si el archivo no existe, lo crea, pero, si existe, no borra su contenido.
Así pues, estos son los seis modos de abrir un archivo. Vamos ahora a ver un ejemplo de
código del uso de los mismos. El siguiente script va a hacer las siguientes tareas:
escribir2.php
<?php
#Abrimos el archivo en modo de escritura
$DescriptorArchivo = fopen("archivo_prueba.txt","w");
#Escribimos la primera línea dentro de él
$string1 = "Esta es la primera línea de texto\r\n";
fputs($DescriptorArchivo,$string1);
#Escribimos la segunda línea de texto
$string2 = "Y esta es la segunda línea de texto\r\n";
fputs($DescriptorArchivo,$string2);
#Cerramos el archivo
fclose($DescriptorArchivo);
#Volvemos a abrir el archivo, esta vez en modo de añadir
$Descriptor2 = fopen("archivo_prueba.txt","a");
#Añadimos la tercera línea de texto
fputs($Descriptor2,"Esta es la tercera línea, añadida con modo \"a\"\r\n");
#Añadimos la cuarta línea de texto
fputs($Descriptor2,"Esta es la cuarta línea, añadida con modo \"a\"\r\n");
#Cerramos el archivo
fclose($Descriptor2);
?>
Autor: Ing. Oscar R. Espeche 28
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
Como poden comprobar si se abre el archivo recién creado, éste contiene cuatro líneas, dos
de ellas escritas con modo "w" y otras dos con modo "a".
A continuación vamos a pasar a ver dos funciones muy útiles para leer archivos de texto:
fgets() y feof(). A través de fgets() podemos leer una línea del archivo de texto cada vez.
feof() sirva para saber si hemos llegado al final del archivo. Para ver como funcionan,
crearemos un script que leerá el archivo que hemos creado con los dos scripts anteriores.
leer.php
<?php
#Abrimos el archivo en modo lectura
$DescriptorArchivo = fopen("archivo_prueba.txt","r");
#Hasta que no lleguemos al final del archivo
while(!feof($DescriptorArchivo)){
#Capturamos 4096 caracteres dentro de la línea (tamaño del buffer reservado),
#o menos si hay un retorno de carro antes
#(\r\n en Win32, \n en UNIX)
$buffer = fgets($DescriptorArchivo,4096);
#Eviamos el texto, añadiendo <BR> detrás
echo $buffer."<BR>";
}
?>
Como ven, este script lee el archivo de texto línea a línea y lo va mostrando en el navegador.
La función feof() devuelve TRUE cuando ha llegado al final del archivo. fgets(), va, pues,
leyendo línea a línea y almacenándolo en una variable llamada $buffer.
Ahora vamos a ver como funcionan los modos w+, r+ y a+. Verán que son diferentes de los
anteriores en el sentido de que permiten dos operaciones, y también en el sentido de como
tratan los archivos. Empezaremos con w+. El siguiente script explica qué es lo que hace este
modo con los archivos.
leer_wmas.php
<?php
#Abrimos el archivo en modo w+
$Descriptor1 = fopen("nuevo_archivo.txt","w+");
#Vamos a escribir un par de líneas en el archivo
fputs($Descriptor1,"Esta es la primera línea de texto\r\n");
fputs($Descriptor1,"Esta es la segunda línea de texto\r\n");
#Ahora cerraremos el archivo
fclose($Descriptor1);
#Volvemos a abrirlo en modo w+
$Descriptor2 = fopen("nuevo_archivo.txt","w+");
Autor: Ing. Oscar R. Espeche 29
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
¿Por qué no aparecen la primera y la segunda línea escritas? Observemos lo que hemos
hecho. Primero abrimos el archivo y escribimos dentro de él dos líneas de texto. Tras esto, lo
cerramos y lo volvemos a abrir, en modo w+. Este modo BORRA EL CONTENIDO
ANTERIOR del archivo, por lo que en este solo aparecen las dos últimas líneas. Como ven,
se puede utilizar este modo para leer desde el archivo con fgets().
Ahora vamos a ver un ejemplo con r+. Vamos a crear un script que haga lo mismo que el
anterior, pero en vez de abrir los archivos con w+, los abrirá con r+.
leer_rmas.php
<?
#Abrimos el archivo en modo w
$Descriptor1 = fopen("nuevo_archivo.txt","w");
#Vamos a escribir un par de líneas en el archivo
fputs($Descriptor1,"Esta es la primera línea de texto\r\n");
fputs($Descriptor1,"Esta es la segunda línea de texto\r\n");
#Ahora cerraremos el archivo
fclose($Descriptor1);
#Volvemos a abrirlo en modo r+
$Descriptor2 = fopen("nuevo_archivo.txt","r+");
#Escribimos un par de líneas
fputs($Descriptor2,"Esta es la tercera línea de texto\r\n");
fputs($Descriptor2,"Esta es la cuarta línea de texto\r\n");
#Volvemos al principio del archivo
rewind($Descriptor2);
#Vamos leyendo líneas y mostrándolas
while(!feof($Descriptor2)){
Autor: Ing. Oscar R. Espeche 30
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
$buffer = fgets($Descriptor2,4096);
echo $buffer."<BR>";
}
#Cerramos el archivo
fclose($Descriptor2);
?>
leer_amas.php
<?
#Abrimos el archivo en modo w+
$Descriptor1 = fopen("nuevo_archivo.txt","w+");
#Vamos a escribir un par de líneas en el archivo
fputs($Descriptor1,"Esta es la primera línea de texto\r\n");
fputs($Descriptor1,"Esta es la segunda línea de texto\r\n");
#Ahora cerraremos el archivo
fclose($Descriptor1);
#Volvemos a abrirlo en modo a+
$Descriptor2 = fopen("nuevo_archivo.txt","a+");
#Escribimos un par de líneas
fputs($Descriptor2,"Esta es la tercera línea de texto\r\n");
fputs($Descriptor2,"Esta es la cuarta línea de texto\r\n");
#Volvemos al principio del archivo
rewind($Descriptor2);
#Vamos leyendo líneas y mostrándolas
while(!feof($Descriptor2)){
$buffer = fgets($Descriptor2,4096);
echo $buffer."<BR>";
}
#Cerramos el archivo
fclose($Descriptor2);
?>
Esto es todo en cuanto a modos de apertura. En la siguiente sección vamos a ver como subir
archivos al servidor, algo muy útil cuando se trata de páginas web.
PHP es capaz de recibir envíos de archivo de cualquier navegador que cumpla la norma RFC-
1867 (entre los que se incluyen Netscape Navigator 3 o posterior, Microsoft Internet Explorer
3 con un parche o posterior sin éste).
Ésta característica permite que los usuarios envien archivos de texto y binarios. Mediante la
autentificación y funciones de manejo de archivos de PHP, es posible un control total de
quién puede enviar archivos y que se hace con éstos una vez recibidos.
Es importante destacar que PHP también soporta el método PUT para envío de archivos tal y
como lo utiliza Netscape Composer y el cliente Amaya de W3C.
Una página de envío de archivos se puede crear mediante un formulario parecido a éste:
La _URL_ debe tener como destino un script PHP. El input oculto MAX_FILE_SIZE debe
encontrarse antes del input de tipo "file" para indicar el tamaño máximo de archivo que se
puede enviar en bytes
Aviso
MAX_FILE_SIZE debe ser consultado por el navegador; aun así es sencillo saltarse este
máximo por lo tanto no se debe presuponer que el navegador siempre lo respetará. En
contrapartida, la configuracion de PHP relativa al tamaño maximo no puede ser obviada.
Las variables de las que hablaremos a continuación serán definidas en la página destino
despues de una recepción de archivo correcta.
Nota: track_vars esta activado siempre desde PHP 4.0.3. A partir de PHP
4.1.0 , $_FILES puede ser utilizado alternativamente a
$HTTP_POST_FILES. $_FILES es siempre global así que global no debe ser
usado con $_FILES en el ámbito de función.
$HTTP_POST_FILES['archivo']['name']
El nombre original del archivo en la máquina cliente.
$HTTP_POST_FILES['archivo']['type']
El tipo mime del archivo (si el navegador lo proporciona). Un ejemplo podría ser
"image/gif".
$HTTP_POST_FILES['archivo']['size']
El tamaño en bytes del archivo recibido.
$HTTP_POST_FILES['archivo']['tmp_name']
El nombre del archivo temporal que se utiliza para almacenar en el servidor el archivo
recibido.
Nota: A partir de PHP 4.1.0 se puede utilizar el variable corta $_FILES. PHP 3
no soporta $HTTP_POST_FILES.
Por defecto, los archivos serán almacenados en el directorio temporal por defecto del
servidor a no ser que se especifique otra localizacion con la directiva upload_tmp_dir en
php.ini. El directorio temporal por defecto del servidor puede ser modificado cambiando el
valor de la variable de entorno TMPDIR en el contexto en que se ejecuta PHP. La
configuración de las variables de entorno no se puede realizar en PHP a través de la función
putenv(). Esta variable de entorno puede ser utilizada también para asegurarnos que otras
operaciones con archivos recibidos están funcionando correctamente.
Los siguientes ejemplos son válidos para versiones de PHP 4 superiores a la 4.0.2. Veanse
las funciones is_uploaded_file() y move_uploaded_file().
<?php
// En PHP 4.1.0 o superior, $_FILES debería usarse en vez de $HTTP_POST_FILES.
if (is_uploaded_file($HTTP_POST_FILES['archivo']['tmp_name'])) {
copy($HTTP_POST_FILES['archivo']['tmp_name'], "path_donde_copiar");
} else {
echo "posible intento de cargar un archivo en forma ilegal. nombre: " .
$HTTP_POST_FILES['archivo']['name'];
}
/* ...o... */
move_uploaded_file($HTTP_POST_FILES['archivo']['tmp_name'], "path_donde_mover");
?>
El script PHP que recibe el archivo, debe implementar la lógica necesaria para determinar
que debe ser realizado con el archivo.
Errores comunes
Si post_max_size tiene un valor muy pequeño, los archivos mas grandes a este valor, no
podrán ser enviados. Por ello, se debe asegurar un valor suficientemente grande para
post_max_size.
No verificar que archivos se estan manipulando puede tener como consecuencia que los
usuarios puedan acceder a información sensible en otros directorios.
Cada uno de estos arrays tendrá en los índices numericos correspondientes los valores para
cada archivo recibido.
En estos ejemplos usaremos las variables globales que se habilitan con la directiva
register_globals=On en php.ini.
Para ejemplificar la subida de archivos al servidor en archivos PHP, vamos a ver un script de
ejemplo que contiene variantes de los que vimos anteriormente. El script tiene dos partes; la
primera, el formulario, en el que se introduce el archivo a cargar, y la segunda parte, en la
que se procesa la subida y se informa al usuario del éxito o fracaso de la carga. En los
siguientes ejemplos es necesario que esté en On la variable register_globals de php.ini.
upload.php
<?php
Autor: Ing. Oscar R. Espeche 35
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
if(!isset($cargar)){
?>
<!DOCTIPO HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>:: Formulario de carga de archivos ::</TITLE>
</HEAD>
<BODY>
<FORM NAME="elForm" METHOD="POST"
ACTION="<?php echo $PHP_SELF; ?>?cargar=1"
ENCTYPE="multipart/form-data">
<TABLE WIDTH="80%" STYLE="font-family:Arial;font-size:9pt;">
<TR>
<TD ALIGN="LEFT"><INPUT TYPE="FILE" NAME="elArchivo"></INPUT></TD>
</TR>
<TR>
<TD ALIGN="LEFT"><INPUT TYPE="SUBMIT" VALUE="Subir el archivo">
</TR>
</TABLE>
</FORM></BODY></HTML>
<?
}
#Aquí realizamos la carga del archivo
if(isset($cargar)){
#Le damos al archivo un nuevo nombre
$nuevositio = "nuevo_archivo_caragado.000"; //se podría indicar otro path
#Lo copiamos
if(!copy($elArchivo,$nuevositio)){
echo "NO SE HA PODIDO SUBIR EL ARCHIVO";
}
else{
echo "ARCHIVO SUBIDO CON ÉXITO";
}
}
?>
Como vemos, el script realiza la carga del archivo. Veremos ahora la carga de múltiples
archivos. Se compondrá de tres partes. La primera, en la que se pregunta al usuario el
número de archivos que desea introducir. La segunda, en la que aparecen todos los campos
de tipo archivo, y la tercera, en la que se procesa la carga. El código es como sigue:
upload_multiple.php
<?php
/* Este script se encarga de subir múltiples archivos al servidor. */
#Formulario en el que se pregunta el número de archivos
if(!isset($arch) && !isset($cargar)){
Autor: Ing. Oscar R. Espeche 36
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
$txt ="<HTML><HEAD>\n";
$txt.="<TITLE>:: ¿Cuántos archivos quiere subir hoy? ::</TITLE>\n";
$txt.="</HEAD><BODY>\n";
$txt.="<FORM NAME=\"frmNumArchivos\"
METHOD=\"POST\"
ACTION=\"".$PHP_SELF."?arch=1\">\n";
$txt.="<BR><BR><BR><BR>\n";
$txt.="<DIV ALIGN=\"CENTER\">\n";
$txt.="<INPUT TYPE=\"TEXT\" NAME=\"numArchivos\">\n";
$txt.=" ";
$txt.="<B>Introduce el número de archivos</B>\n";
$txt.="<BR><BR>\n";
$txt.="<INPUT TYPE=\"SUBMIT\"
VALUE=\"Mostrar campos para subir archivos\">\n";
$txt.="<BR></DIV>\n";
$txt.="</FORM></BODY></HTML>\n";
echo $txt; //envía el texto HTML al navegador
}
#Formulario en el que se muestran los campos tipo archivo
if(isset($arch)){
$txt ="<HTML><HEAD>\n";
$txt.="<TITLE>:: ¿Cuántos archivos quiere subir hoy? ::</TITLE>\n";
$txt.="</HEAD><BODY>\n";
$txt.="<FORM ENCTYPE=\"multipart-form/data\"
NAME=\"frmCargaArchivos\"
METHOD=\"POST\"
ACTION=\"".$PHP_SELF."?cargar=1&cantidad=".$HTTP_POST_VARS["numArchivos"]."\">\n";
for($i=0;$i<$HTTP_POST_VARS["numArchivos"];$i++){
for($n=0;$n<$cantidad;$n++){
#Creamos la "variable variable"
$nomvar = "archivo_$n";
$valvar = ${$nomvar};
#Extraemos el nombre del archivo sin la ruta
$nomarchivo = basename($valvar); //rescatamos el nombre original del archivo
#Le damos al archivo su nombre, copiándolo dentro del directorio /subidas
$nuevositio = "subidas/".$nomarchivo."";
Autor: Ing. Oscar R. Espeche 37
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
#Lo copiamos
if(!copy($valvar,$nuevositio)){
echo "NO SE HA PODIDO SUBIR EL ARCHIVO: ".$nomarchivo;
}
else{
echo "ARCHIVO: “.$nomarchivo. “SUBIDO CON ÉXITO";
}
}
}
?>
De este modo podemos cargar varios archivos al mismo tiempo. Tendrás que crear el
directorio /subidas manualmente. Vamos a terminar con esta sección y pasar a la siguiente,
en la que se explica como forzar al cliente a descargarse el archivo en vez de verlo on-line.
A veces puede ser interesante que el usuario se descargue el archivo en vez de verlo on-line.
Para realizar esta operación, solo necesitamos utilizar el siguiente código que voy a explicar
a continuación. El script consta de una sola parte. Vamos a descargarnos un archivo .html,
en vez de verlo en el navegador. El nombre del archivo será prueba_descarga.html. El
código es como sigue:
descargar.php
<?php
function descargar($ElArchivo){
$TheFile = basename($ElArchivo);
Como ves, el script se ejecuta y el archivo, pese a ser HTML, e interpretable por el
navegador, es forzado a ser descargado, igual que si hubiéramos pulsado el botón derecho.
PHP es uno de los lenguajes del lado del servidor más completos y con mayor número de
funciones útiles. Veremos otras funciones (aunque ya vimos alguna de ellas) que permiten
trabajar con archivos, y en algunos casos con directorios.
Autor: Ing. Oscar R. Espeche 38
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
basename()
Esta función devuelve el nombre simple del archivo. Es de utilidad cuando nos
interesa eliminar la ruta física de algún archivo y devolver sólo el nombre de dicho
archivo y su extensión:
<?
$ruta = "/home/httpd/html/file.php";
$file = basename($ruta); //devuelve 'file.php'
?>
chmod()
<?
chmod("/directorio/archivo", permiso);
?>
En donde permiso, como ya mencionamos, debe ser el valor chmod que deseamos
otorgar, con un 0 anteponiéndolo.
<?
chmod("archivo.txt", 0777);
?>
copy()
Como su nombre lo indica, esta función permite copiar archivos dentro del servidor.
Muy útil se deseamos hacer un back-up online de modo que tengamos los archivos
antiguos dentro del servidor evitando el peso de descargarlos todos. Aún así, las
aplicaciones son muchísimas.
<?
Autor: Ing. Oscar R. Espeche 39
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
copy($archivo, $destino);
?>
<?
if(!copy("archivo.txt","backup1.txt")){
echo "Error al tratar de copiar el archivo.\n";
}
?>
dirname()
<?
$ruta = "/directorio/archivo";
$dirname = dirname($ruta); //devuelve '/directorio'
?>
diskfreespace()
Esta extraña función devuelve el número de bytes de espacio libre que hay en el
disco. Para verificar, por ejemplo, el espacio libre disponible en el directorio raíz de un
sitio web se utiliza la sintaxis:
<?
$espacio = diskfreespace("/");
?>
readfile()
<?
$archivo = readfile("archivo.txt");
echo $archivo; //escribe el numero de bytes leidos
?>
Esta es una forma muy fácil de leer archivos aunque el problema está en que
devuelve el número de bytes leídos, cosa que nadie desearía, para ello se utiliza más
Autor: Ing. Oscar R. Espeche 40
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
frecuentemente la función file() que devuelve un array con todas las líneas del
archivo. Más adelante veremos cómo utilizarla.
fopen() crea una conexión a algún archivo, especificando el tipo de tratamiento que
se le dará al archivo, es decir, si será de lectura, escritura o ambos. Por defecto, se
puede leer un archivo pero para lograr escribir en él se requieren permisos chmod
755.
$archivo = fopen("archivo.txt",permiso)
permiso equivale a una letra identificadora del tipo de tratamiento que le daremos al
archivo. Existen tres básicamente: r (solo lectura), w (escritura) y a (ambos). En el
caso de escritura el cursor se ubica al inicio del archivo por lo que la escritura afecta
todo el contenido del mismo, mientras que a ubica el cursor al final del archivo para
escribir nuevo contenido sin eliminar el existente.
<?
$fp = fopen("archivo.txt","w"); //abrimos el archivo para escritura
fwrite($fp, "Estoy escribiendo en un archivo!!!");
fclose($fp); //cerramos la conexión y liberamos la memoria
?>
La sintaxis es:
fwrite($conexion, textoaescribir)
Otra de las muchas formas de leer archivos es utilizar la función fread aunque ésta
está un poco limitada, pues sólo lee un archivo hasta determinado número de bytes,
para evitar esto se puede utilizar la función file_size para establecer el número de
bytes totales y así leer todo el archivo. Más adelante encontrarás información sobre
esta función.
<?
$fp = fopen("archivo.txt","r"); //abrimos el archivo como solo lectura
$contenido = fread($fp, 2000); //leemos 2000 bytes del archivo establecido en $fp
fclose($fp);
?>
Autor: Ing. Oscar R. Espeche 41
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
file()
Esta función toma el contenido total de cualquier archivo y lo guarda línea por línea
en un array.
Es la más útil de todas las formas de lectura de archivos pues permite crear scripts
complejos que trabajen en líneas... por ejemplo un rotador de banners que tenga en
cada línea un banner diferente para rotar.
$archivo = file("archivo.txt")
Como $archivo es un array con cada línea de archivo.txt esto quiere decir que cada
elemento en el array equivale en una línea, por ello se puede usar count()
facilmente.
Pero para aclararlo veamos un ejemplo:
<?
$archivo = file("archivo.txt"); //creamos el array con las lineas del archivo
$lineas = count($archivo); //contamos los elementos del array, es decir el total de lineas
for($i=0; $i < $lineas; $i++){
echo $archivo[$i];
}
?>
La ventaja de este método es que podemos leer cualquier línea fácilmente, pues
$archivo es un array. Si deseamos leer la primera línea podemos utilizar $archivo[0] y
así sucesivamente.
file_exists()
Veamos un ejemplo:
Autor: Ing. Oscar R. Espeche 42
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
<?
$archivo = "archivo.txt";
if(file_exists($archivo)){
echo "El archivo $archivo existe.\n";
else{
echo "El archivo $archivo no existe.\n";
}
?>
Hemos hecho uso de una estructura condicional para mostrar un mensaje de acuerdo
a la existencia o no del archivo. Como PHP puede crear conexiones a servidores
externos, es posible verificar la existencia de una URL con file_exists() antes de
dirigir al usuario a dicha dirección.
fileatime()
<?
echo fileatime("archivo.txt");
?>
filesize()
Devuelve el número total de bytes que ocupa cualquier archivo. Es posible modificar
estos valores mediante divisiones para convertirlo a megabytes, kilobytes, etc.
<?
$tam = filesize("imagen.gif");
echo $tam;
?>
El anterior código devolvería el tamaño total en bytes que está ocupando imagen.gif
is_..
<?
funcion($archivo);
?>
mkdir()
mkdir("/ruta/al/nuevo/directorio",permiso)
El primer parámetro debe ser la ruta al nuevo directorio, es decir, al que se trata de
crear y permiso es el permiso chmod en formato octal, es decir, con un 0 antes. El
permiso permite establecer el chmod que deseamos al momento de crear el
directorio. Funciona igual que chmod().
rename()
<?
rename("nombreviejo","nuevonombre");
?>
Una nota de importancia es que en casi todos los ejemplos se ha utilizado como archivo el
nombre archivo.txt pero en realidad puede ser cualquiera.
Siempre que el soporte para la "envoltura URL fopen" esté habilitado cuando se configura
PHP (lo cual ocurre a menos que se use explícitamente la opción --disable-url-fopen-wrapper
en la configuración de PHP para versiones hasta la 4.0.3, ó configurar como "off" el
parámetro allow_url_fopen en php.ini (para las nuevas versiones)) se pueden usar URLs
HTTP y FTP con la mayoría de las funciones que toman un archivo como parámetro,
incluyendo las sentencias require() e include().
Como ejemplo, se puede usar este para abrir un archivo en un servidor web remoto, analizar
en la salida la información que se quiera, y entonces, usar la información en una consulta a
base de datos, o simplemente para sacarlas en un estilo que coincida con el resto de su sitio
web.
<?php
$file = fopen ("http://www.ejemplo.com/", "r");
if (!$file) {
echo "<p>No se puede abrir el archivo remoto.\n";
exit;
}
También se puede conectar con el protocolo FTP y escribir en el servidor remoto, siempre
que se conecte como un usuario con los correctos derechos de acceso, y el archivo no exista
ya.
Se puede usar la misma clase de sintaxis para acceder a archivos via HTTP cuando se
requiera una autenticación.
<?php
$file = fopen ("ftp://ftp.ejemplo.com/path/archivo", "w");
if (!$file) {
echo "<p>No se puede abrir el archivo remoto.\n";
exit;
}
Nota: Se puede captar la idea en el ejemplo anterior de como escribir en un registro remoto,
pero como ya hemos comentado antes, solamente se puede escribir a un archivo nuevo
usando la "envoltura URL fopen" Para registros distribuidos, consultar la función syslog().
Una clase es una colección de variables y de funciones que acceden a esas variables. Las
variables se conocen como “atributos” o “propiedes” y las funciones como “métodos”.
Cuando se personaliza o “instancia” una clase se crea un “objeto” . Esta variable objeto
permite acceder a las propiedades y métodos de la clase que en definitiva actúan sobre las
propiedades de la clase.
Por ejemplo si se quisiera realizar un sistema que administre el tema de reserva de pasajes
de una Línea aérea habría que mantener una serie de valores que indiquen el estado actual
de la reserva y disponibilidad de pasajes. Esto puede hacerse mediante una clase donde se
crean las funciones o métodos para actualizar y mantener dichos valores o propiedades.
La ventaja de la clase que permite el reuso del código ya que el mismo código serviría para
otras Líneas Aéreas simplemente creando nuevas instancias u objetos para el manejo de
otras Líneas.
<?php
class Cart {
var $items; // Items en nuestro carro de la compra
}
?>
El ejemplo define una clase llamada Cart que consiste en un array asociativo de artículos en
el carro y dos funciones para meter y sacar ítems del carro.
Las clases son tipos, es decir, son plantillas para variables. Tienes que crear una variable del
tipo deseado con el operador new.
Este ejemplo crea un objeto $cart de clase Cart. La función add_item() de ese objeto se
llama para añadir un item del artículo número 10 al carro.
Las Clases pueden ser extensiónes de otras clases. Las clases extendidas o derivadas tienen
todas las variables y funciones de la clase base y lo que les añadas al extender la definición.
La herencia múltiple no está soportada.
Ese ejemplo define una clase Carro_con_nombre (carro con nombre o dueño) que tiene
todas las variables y funciones de Cart, y además añade la variable $propietario y una
función adicional establece_propietario(). Un carro con nombre se crea de la forma habitual
y, una vez hecho, puedes acceder al propietario del carro. En los carros con nombre también
puedes acceder a las funciones normales del carro:
En funciones de una clase, la variable $this hace referencia al propio objeto. Tienes que usar
$this->loquesea para acceder a una variable o función llamada loquesea del objeto actual.
Los constructores son funciones de una clase que se llaman automáticamente al crear una
nueva instancia (objeto) de una clase. Una función se convierte en constructor cuando tiene
el mismo nombre que la clase.
Este ejemplo define una clase Auto_Cart que es un Cart junto con un constructor que
inicializa el carro con un item del tipo de artículo "10" cada vez que se crea un nuevo
Auto_Cart con "new". Los constructores también pueden recibir parámetros y estos
parámetros pueden ser opcionales, lo que los hace más útiles.
Atención
Para las clases derivadas, el constructor de la clase padre no es llamado automáticamente
cuando se llama al constructor de la clase derivada.
Esta función devuelve un vector con las propiedades que han sido inicializadas por
defecto en la clase.
formulario.html
password.php
<?
// Comparamos a ver si son correctos
if ($usuario=="juan" && $password=="clavedejuan")
{
$valido="si";
}
else
{
$valido="no";
}
?>
<html>
<head>
<title>Pagina privada</title>
</head>
<body>
<? if ($valido=="si")
{
?>
' A continuación todo el contenido de nuestra pagina privada
<p>BIENVENIDO A LA PAGINA PRIVADA</p>
<? }
else
{
?>
<p>USUARIO O CONTRASEÑA INCORRECTA</p>
<? } ?>
Autor: Ing. Oscar R. Espeche 51
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
</body>
</html>
Como les dije antes, el sistema es muy sencillo, pero puede ser de gran utilidad para quienes
necesitan que alguna información pueda ser vista solamente por personas autorizadas.
En un script de PHP (instalado como módulo de Apache), se puede usar la función header()
para enviar un mensaje de "Autentificación requerida" al navegador cliente haciendo que
muestre una ventana de entrada emergente con nombre de usuario y contraseña.
Una vez que el usuario ha rellenado el nombre y la contraseña, la URL que contiene el script
PHP vuelve a ser llamada con las variables $PHP_AUTH_USER, $PHP_AUTH_PW y
$PHP_AUTH_TYPE rellenas con el nombre de usuario, la contraseña y el tipo de
autentificación respectivamente.
Un fragmento de script de ejmplo que fuerce la autentificación del cliente en una página
sería como el siguiente:
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header("WWW-Authenticate: Basíc realm=\"Mi Sitio\"");
header("HTTP/1.0 401 Unauthorized");
echo "Texto a enviar si el usuario activa el boton Cancel\n";
exit;
} else {
echo "<p>Bienvenido {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Usted está registrado con {$_SERVER['$PHP_AUTH_PW']} su
password.</p>";
}
?>
Nota: Por favor tener cuidado cuando estés programando las líneas de
cabecera HTTP. Para garantizar la maxima compatibilidad con todos los
clientes, la palabra clave "Basíc" debe de ser escrita con "B" mayúscula, la
cadena de texto debe estar incluida entre comillas dobles (no simples) y un
espacio debe preceder el código "401" en la linea de cabecera "HTTP/1.0 401"
Para prevenir que alguien escriba un script que revele la contraseña de una página que ha
sido autentificada a través de algún mecanismo externo tradicional, las variables
PHP_AUTH no serán rellenadas si algún tipo de autentificación externo ha sido activado
para una página en particular. En este caso, la variable $REMOTE_USER puede ser usada
para identificar al usuario autentificado externamente.
A pesar de todo, lo ya dicho no proteje de que alguien que controle una URL
no autentificada robe contraseñas de URLs autentificadas en el mismo servidor.
Tanto Netscape como Internet Explorer borrarán la caché con la información de la ventana
de autentificación en el navegador local, después de recibir una respuesta 401 del servidor.
Esto puede usarse, de forma efectiva, para "desconectar" a un usuario, forzandole a
reintroducir su nombre y contraseña. Algunas personas usan esto para "hacer caducar"
entradas.
2.6 Cookies
PHP soporta cookies HTTP. Las Cookies son un mecanismo que sirve para almacenar datos
en el navegador del usuario remoto, para así poder identificar al usuario cuando vuelva.
Realmente las cookies no son mas que cadenas de texto que son enviadas desde el servidor
al cliente (navegador) y almacenadas en este, luego el navegador envía estas cookies al
servidor permitiendo así la identificación del cliente en el servidor.
El navegador las envía, permitiendo la identificación del usuario por parte del servidor.
A continuación vamos a ver como usar las cookies para nuestro beneficio.
Se pueden poner cookies usando la función setcookie(). Las Cookies son parte de la
cabecera HTTP, por tanto la función setcookie() debe ser llamada antes de que se
produzca cualquier salida al navegador.
En PHP 4.1.0 y posteriores, la array auto-global $_COOKIE será siempre actualizada con
cualquier cookie mandada por el cliente. $HTTP_COOKIE_VARS es también actualizada en
versiones anteriores de PHP cuando la variable de configuración track_vars esté activada.
Setcookie() define una cookie que es enviada junto con el resto de la información de la
cabecera(header).
int setcookie (string Name [, string Value [, int Expire [, string Path [, string
Domain [, int Secure]]]]])
Ejemplo:
En este ejemplo establecemos una cookie de nombre usuario que contiene el valor juan, que
dura 1 hora (3600 segundos) válida para todo el dominio pepe.com.
En este ejemplo vamos a ver como establecer (en forma arbitraria) una cookie y cómo se
recupera el valor establecido. Para ello pediremos al usuario que introduzca su nombre, que
guardaremos en una cookie.
Primero pedimos al usuario que introduzca el valor de su nombre, usamos un formulario que
procesará la página procesar_cookie.phtml.
<html>
<head>
<title>Ejemplo de uso de cookie </title>
</head>
<body>
<H1>Ejemplo de uso de cookie</H1>
Introduzca su nombre:
<FORM ACTION="procesar_cookie.phtml" METHOD="GET">
<INPUT TYPE="text" NAME="nombre"><BR>
<INPUT TYPE="submit" VALUE="Enviar">
</FORM>
</body>
</html>
<?php
setcookie("usuario", $_GET['nombre'], time()+3600,"/","");
?>
<html>
<head>
<title>Ejemplo de uso de cookie</title>
</head>
<body>
<H1>Ejemplo de uso de cookie</H1>
<html>
<head>
<title>Ejemplo de uso de cookie</title>
</head>
<body>
<H1>Ejemplo de uso de cookie</H1>
2.7 Sesiones
Básicamente una sesión comprende el conjunto de la secuencia de páginas que un usuario
visita en un sitio web. Desde que entra en nuestro sitio, hasta que lo abandona.
El término sesión en PHP, session en inglés, se aplica a esta secuencia de navegación, para
ello crearemos un identificador único que asignamos a cada una de estas sesiones de
navegación. A este identificador de sesión se le denomina, comúnmente, como la
sesión.
Y para que no perdamos el hilo de la navegación del usuario deberemos asociar esta sesión
a todas las URLs y acciones de formulario. Podemos también crear un cookie que incluya el
identificador de sesión, pero es conveniente recordar que la disponibilidad o no de las
cookies depende del usuario, y no es conveniente fiarse de lo que un usuario pueda o no
tener habilitado.
Por lo tanto lo comentado a partir de aquí es solo aplicable a PHP4. Si aún desarrollas
PHP3, tendrás que crear tus propias librerías de gestión de sesiones o recurrir a alguna de
las existentes, como la de PHPLIB.
Inicialización de la sesión
<?php
session_start();
echo "He inicializado la sesión";
?>
Esta es la forma más básica, si el usuario tiene los cookies activados, PHP habrá insertado de
forma automática la sesión y ésta será pasada de una página a otra sin hacer nada más.
Desde un punto de vista práctico la sesión es operativa, pero no vemos nada. Podemos
<?php
session_start();
echo 'La sesión actual es: '.session_id();
?>
En este caso session_start() comprueba en los cookies que existe una sesión y continua
con ella, session_id() devuelve el identificador actual.
Ejemplo práctico
<?php
session_register('contador');
echo '<a href="'.$PHP_SELF.'?'.$SID.'">Contador vale: '.++$_SESSION['contador']. '</a>';
?>
Si no has utilizado nunca las sesiones, el concepto de variable de sesión, puede resultar un
poco abstracto. Básicamente es una variable, como cualquiera de las que gestiona PHP4,
pero que reside en un espacio específico en el servidor, junto con el identificador de sesión,
y que pertenece únicamente a un usuario (a la sesión del usuario).
En nuestro ejemplo anterior, registramos la variable $contador en la primera línea del script.
En la segunda línea, entre otras cosas, cada vez que recarguemos la página o hagamos click
sobre el enlace, el valor de $contador se incrementará en 1.
En esta línea hacemos uso de la variable reservada $PHP_SELF, que hace referencia al
propio script en ejecución y una constante propia de PHP4, $SID, que contiene el nombre
de la sesión y el identificador de la misma.
<?php
session_name('misesion');
session_register('contador');
echo '<a href="'.$PHP_SELF.'?'.SID.'">Contador vale:
'.++$_SESSION['contador'].'</a><br>';
echo 'Ahora el nombre es '.session_name().' y la sesión '.$misesion.'<br>';
?>
Autor: Ing. Oscar R. Espeche 59
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
La asignación del nombre de sesión debe realizarse antes que ninguna otra función con
sesiones, antes que session_start() o session_register().
Para ser más genérico debiera considerarse que al deshabilitar register_globals no puede
usarse los nombres de las variables sólo como $variable, sino como $_SESSION[‘variable’].
Error común
Uno de los errores más comunes cuando se utilizan sesiones es dejar líneas en blanco antes
de la inicialización de PHP (o al final de un archivo que se incluye) o enviar alguna salida a la
pantalla. Para probarlo crea una línea en blanco o con cualquier cosa antes de <?php.
Warning: Cannot send session cookie - headers already sent by (output started at
/home/session.php:2) in /home/session.php on line 4
PHP está informando de que no puede activar los cookies en el navegador del usuario,
porque las cabeceras ya han sido enviadas. Simplemente por la existencia de una línea en
blanco. Como medida práctica, no dejes espacios ni antes del inicio del script, ni después de
la finalización.
Si después de todo lo comentado aún no entiendes para que sirven las sesiones, veamos un
ejemplo práctico. Imagina que quisieras crear un sistema de cesta de la compra...
Carrito de compra
Si después de todo lo comentado aún no entiendes para que sirven las sesiones, veamos un
ejemplo práctico. Imagina que quisieras crear un sistema de cesta de la compra, en su forma
básica podría ser algo así:
<?php
session_start();
session_register('itemsEnCesta');
$item=$_POST['item'];
$cantidad=$_POST['cantidad'];
$itemsEnCesta=$_SESSION['itemsEnCesta'];
if ($item){
if (!isset($itemsEnCesta)){
$itemsEnCesta[$item]=$cantidad;
}else{
foreach($itemsEnCesta as $k => $v){
if ($item==$k){
$itemsEnCesta[$k]+=$cantidad; //agrega cantidad aitem existente
$encontrado=1;
}
}
Autor: Ing. Oscar R. Espeche 60
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
</body>
</html>
• 0 - NORMAL
• 1 - ABORTED (Abortado)
• 2 - TIMEOUT (Fuera de tiempo)
Cuando un script PHP se está ejecutando se activa el estado NORMAL. Si el cliente remoto se
desconecta, se pasa al estado ABORTED. Esto suele ocurrir cuando el usuario pulsa en el
botón DETENER del navegador. Si se alcanza el límite de tiempo impuesto por PHP (ver
set_time_limit()), se pasa al estado TIMEOUT.
Puedes decidir si quieres que la desconexión de un cliente cause que tu script sea abortado.
Algunas veces es cómodo que tus scripts se ejecuten por completo, incluso si no existe ya un
navegador remoto que reciba la salida.
El comportamiento por defecto es sin embargo, que tu script se aborte cuando el cliente
remoto se desconecta. Este comportamiento puede ser configurado vía la directiva
ignore_user_abort en el archivo php3.ini, o también con la función
ignore_user_abort().
Con una función de desconexión, cuando un usuario remoto pulsa en el botón DETENER, la
próxima vez que tu script intenta mostrar algo, PHP detecta que la conexión ha sido
abortada y se llama a la función de desconexión.
El script también se puede terminar por un temporizador interno. El timeout por defecto es
de 30 segundos. Se puede cambiar usando la directiva max_execution_time en el archivo
php.ini o la correspondiente directiva php_max_execution_time en la configuración del
servidor de páginas Apache, como también con la función set_time_limit().
Hay que destacar que ambos, el estado ABORTED y el TIMEOUT, se pueden activar al mismo
tiempo. Esto es posible si le dices a PHP que ignore las desconexiones intencionadas de los
usuarios. PHP aún notará el hecho de que el usuario puede haberse desconectado, pero el
script continuará ejecutándose. Si se alcanza el tiempo límite de ejecución será abortado y, si
se ha definido una función de desconexión, esta será llamada. En este punto, encontrarás
que las funciones connection_timeout() y connection_aborted() devuelven verdadero.
Las conexiones persistentes son enlaces SQL que no se cierran cuando termina la ejecución
del archivo de comandos.
Cuando se pide una conexión persistente, PHP comprueba si hay ya una conexión
persistente idéntica (que permanecía abierta desde antes) - y si existe, la usa. Si no existe,
crea un enlace. Una conexión 'idéntica' es una conexión que se abrió hacia el mismo "host",
con el mismo nombre de usuario y la misma contraseña (donde sea aplicable).
La gente que no está familiarizada con el modo como trabajan y distribuyen la carga los
servidores "web" puede confundir que significa conexiones persistentes. En particular, no te
dan la habilidad de abrir 'sesiones de usuario' en el mismo enlace SQL, no dan la habilidad
de construir una transacción de forma eficiente, y no hacen un montón de otras cosas. De
hecho, para ser extremadamente claros sobre el tema las conexiones persistentes no te dan
ninguna functionalidad que no fuera posible con sus hermanas no-persistentes.
Esto tiene que ver con el modo como funcionan los servidores "web". Hay tres modos en que
un servidor "web" puede utilizar PHP para generar páginas web.
El primer método es usar PHP como una capa CGI. Cuando corre de este modo, se crea y
destruye una instancia del intérprete PHP por cada página solicitada (para una página PHP) a
tu servidor. Debido a que se destruye después de cada petición, cualquier recurso que
adquiera (como un enlace a un servidor de base de datos SQL) se cierra cuando es
destruido. En este caso, no se gana nada si se intentan usar conexiones persistentes, ya que
simplemente no persisten.
El segundo, y más popular, método es correr PHP como un módulo en un servidor web
multiproceso, lo cual actualmente sólo incluye Apache. Un servidor multiproceso tiene
típicamente un proceso (el padre) que coordina un conjunto de procesos (sus hijos) que
realmente hacen el trabajo se servir las páginas web. Cuando entra cada petición de un
cliente, es entregada a uno de los hijos que no esté ya sirviendo a otro cliente. Esto significa
que cuando el mismo cliente hace una segunda petción al servidor, puede ser atendido por
un proceso hijo distinto del de la primera vez. Lo que una conexión persistente hace por ti en
Autor: Ing. Oscar R. Espeche 63
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
este caso es hacerlo de tal modo que cada proceso hijo sólo necesita conectar a tu SQL
server la primera vez que sirve una página que hace uso de una conexión así. Cuando otra
página solicita una conexión a SQL server, puede reutilizar la conexión que el hijo estableció
previamente.
El último método es usar PHP como un "plug-in" para un servidor web multihilo. Actualmente
PHP 4 soporta ISAPI, WSAPI y NSAPI (en Windows), lo cual permite a PHP ser utilizado
como "plug-in" para servidores web multihilo como Netscape FastTrack, Internet Information
Server (IIS) de Microsoft, y O'Reilly's WebSite Pro.
Si las conexiones persistentes no aportan ninguna funcionalidad añadida, ¿para qué son
buenas?
Esto significa que por cada hijo que abrió una conexión persistente tendrá su propia
conexión persistente al servidor. Por ejemplo, si tienes 20 procesos hijos distintos que corran
un archivo de comandos que cree una conexión persistente a tu servidor SQL, tendrías 20
conexiones diferentes a ti servidor SQL, una por cada hijo.
No obstante, hay que tener en cuenta que esto puede tener desventajas si se está utilizando
una base de datos con límites de conexión, por debajo del numero de procesos hijo con
conexiones persistentes.
Aviso
Un par de advertencias más a tener en cuenta cuando utilicen conexiones persistentes.
La primera: si utilizan bloqueos en una tabla desde una conexión persistente y por
cualquier causa el script no puede desbloquear la tabla, todos los scripts posteriores
que usen esta conexión, quedarán bloqueados indefinídamente y se requerirá que, ó
bien el servidor httpd ó la base de datos sean arrancados de nuevo.
Lo mejor para evitar problemas es no usar conexiones persistentes en scripts que usen
bloqueos de tablas ó transacciones (para todo lo demás pueden ser usadas sin problemas).
Un resumen importante. Las conexiones persistentes fueron diseñadas para tener una
equivalencia uno-a-uno con las conexiones normales. Eso significa que deberíais siempre ser
capaz de reemplazar las conexiones persistentes por conexiones no persistentes y no
cambiará, el modo como se comporta el archivo de comandos. Puede cambiar la eficiencia
del archivo de comandos (y probablemete lo hará), pero no su comportamiento!
Cuando safe_mode está en On, el PHP verifica si el dueño del script actual coincide con el
dueño del archivo a ser operado por una función de archivo. Por ejemplo:
<?php
readfile('/etc/passwd');
?>
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2
Sin embargo, pueden haber ambientes donde una estricta verificación del UID no es
apropiada, y una relajada verificación del GID es suficiente. Esto es soportado por medio del
switch safe_mode_gid. Seteándolo a On hace la verificación relajada GID, seteándolo a Off
(el valor por omisión) hace la verificación del UID.
Autor: Ing. Oscar R. Espeche 66
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
<Directory /docroot>
php_admin_value open_basedir /docroot
</Directory>
disable_functions readfile,system
Función Limitaciones
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el archivo(s)/directorios
dbmopen()
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
dbase_open() seguro) está activado, PHP
comprueba si el archivo(s)/directorios
Autor: Ing. Oscar R. Espeche 67
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
Función Limitaciones
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el archivo(s)/directorios
filepro()
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el archivo(s)/directorios
filepro_rowcount()
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el archivo(s)/directorios
filepro_retrieve()
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
ifx_*() restricciones sql_safe_mode, (!= safe mode)
ingres_*() restricciones sql_safe_mode, (!= safe mode)
mysql_*() restricciones sql_safe_mode, (!= safe mode)
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el archivo(s)/directorios
pg_loimport()
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
posix_mkfifo() comprueba si los directorios que vas
a utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Obecede las ini-directivas
safe_mode_protected_env_vars y
putenv() safe_mode_allowed_env_vars. Vea
también la documentación de
putenv()
Nota: Cuando safe-mode (modo-
move_uploaded_file() seguro) está activado, PHP
comprueba si el archivo(s)/directorios
Autor: Ing. Oscar R. Espeche 68
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
Función Limitaciones
que vas a utilizar, tienen la misma
UID que el script que está siendo
ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
chdir() comprueba si los directorios que vas
a utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Esta función no está activada en
dl()
safe-mode (modo-seguro)
Esta función no está activada en
backtick operator
safe-mode (modo-seguro)
shell_exec() (equivalencia funcional de Esta función no está activada en
backticks) safe-mode (modo-seguro)
Ud. puede correr sólo ejecutables
dentro delsafe_mode_exec_dir. Por
razones prácticas, no está
exec()
actualmente permitido tener
componentes .. en la ruta del archivo
ejecutable.
Ud. puede correr sólo ejecutatables
dentro delsafe_mode_exec_dir. Por
razones prácticas, no está
system()
actualmente permitido tener
componentes .. en la ruta del archivo
ejecutable.
Ud. puede correr sólo ejecutatables
dentro delsafe_mode_exec_dir. Por
razones prácticas, no está
passthru()
actualmente permitido tener
componentes .. en la ruta del archivo
ejecutable.
Ud. puede correr sólo ejecutatables
dentro delsafe_mode_exec_dir. Por
razones prácticas, no está
popen()
actualmente permitido tener
componentes .. en la ruta del archivo
ejecutable.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
mkdir() comprueba si los directorios que vas
a utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Autor: Ing. Oscar R. Espeche 69
PHP,MySQL y E-COMMERCE Estructuras del lenguaje PHP
Función Limitaciones
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
rmdir()
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
rename()
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si los directorios que vas
a utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
unlink()
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si los directorios que vas
a utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
copy()
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
chgrp()
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
chown()
seguro) está activado, PHP
Función Limitaciones
comprueba si el
archivo(s)/directorios que vas a
utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
archivo(s)/directorios que vas a
chmod() utilizar, tienen la misma UID que el
script que está siendo ejecutado.
Función Limitaciones
setea esta cabecera (usado por
HTTP Authentication).
Nota: Cuando safe-mode (modo-
seguro) está activado, PHP
comprueba si el
archivo(s)/directorios que vas a
highlight_file(), show_source() utilizar, tienen la misma UID que el
script que está siendo ejecutado.