Está en la página 1de 115

Iniciación a

PH P 4

Manual Realizado por:


Gabriel Merín Cubero
ÍNDICE
1.- CONCEPTOS BÁSICOS __________________________________________________ 5
1.1.- Insertar código PHP en HTML _________________________________________ 5
1.2.- Múltiples scripts PHP en un mismo documento ___________________________ 6
1.3.- Comentar el código PHP ______________________________________________ 6
2.- TIPOS DE DATOS Y VARIABLES__________________________________________ 8
2.1.- Enteros _____________________________________________________________ 8
2.2.- Números en coma flotante _____________________________________________ 8
2.3.- Cadenas ____________________________________________________________ 8
2.4.- Conversión de cadenas _______________________________________________ 10
2.5.- Arrays (vectores)____________________________________________________ 11
ARRAYS UNIDIMENSIONALES ________________________________________ 11
ARRAYS MULTIDIMENSIONALES______________________________________ 13
MEZCLANDO ARRAYS ESCALARES Y ASOCIATIVOS ____________________ 15
2.6.- Boolean____________________________________________________________ 18
2.7.- Objetos ____________________________________________________________ 19
2.8.- Identificadores______________________________________________________ 21
2.9.- Variables __________________________________________________________ 21
ÁMBITO DE LAS VARIABLES__________________________________________ 21
TYPE JUGGLING (JUEGO DE TIPOS) ____________________________________ 24
TYPE CASTING (FORZADO DE TIPOS) __________________________________ 25
ASIGNACIÓN POR VALOR Y POR REFERENCIA _________________________ 25
VARIABLES VARIABLES ______________________________________________ 26
CONSTANTES________________________________________________________ 27
VARIABLES PREDEFINIDAS ___________________________________________ 28
3.- OPERADORES Y ESTRUCTURAS DE CONTROL ___________________________ 31
3.1.- Expresiones ________________________________________________________ 31
OPERANDOS_________________________________________________________ 31
OPERADORES________________________________________________________ 31
3.2.- Operadores ________________________________________________________ 31
PRECEDENCIA DE OPERADORES ______________________________________ 31
OPERADORES ARITMÉTICOS__________________________________________ 32
OPERADORES DE ASIGNACIÓN _______________________________________ 32
OPERADORES DE INCREMENTO/DECREMENTO_________________________ 33
OPERADORES LÓGICOS ______________________________________________ 33
OPERADORES DE COMPARACIÓN _____________________________________ 34
OPERADORES BIT A BIT ______________________________________________ 34
OPERADOR DE EJECUCIÓN ___________________________________________ 34
OPERADORES DE CADENAS __________________________________________ 35
3.3.- Estructuras de Control _______________________________________________ 35
if ___________________________________________________________________ 35
else__________________________________________________________________ 35
elseif ________________________________________________________________ 36
Sintaxis Alternativa de Estructuras de Control ________________________________ 36
Página 2/115
while ________________________________________________________________ 37
do..while _____________________________________________________________ 37
for __________________________________________________________________ 38
foreach_______________________________________________________________ 39
switch _______________________________________________________________ 40
break ________________________________________________________________ 42
continue ______________________________________________________________ 42
4.- FUNCIONES __________________________________________________________ 44
4.1.- ¿Qué es una función? ________________________________________________ 44
4.2.- Definición e invocación de funciones____________________________________ 44
4.3.- Anidamiento de Funciones ____________________________________________ 44
4.4.- Funciones recursivas_________________________________________________ 45
4.5.- Parámetros de las funciones___________________________________________ 46
PASAR PARÁMETROS POR REFERENCIA _______________________________ 46
PARÁMETROS POR DEFECTO _________________________________________ 47
LISTA DE LONGITUD VARIABLE DE PARÁMETROS _____________________ 48
DEVOLVER VALORES ________________________________________________ 49
4.6.- Funciones Variable __________________________________________________ 49
4.7.- Acceso a variables globales desde funciones______________________________ 50
4.8.- Creación De Librerías De Funciones ___________________________________ 50
5.- VECTORES____________________________________________________________ 53
5.1.- Estructura interna de los vectores en PHP_______________________________ 53
5.2.- Número de elementos dentro de un vector _______________________________ 54
sizeof ________________________________________________________________ 54
count ________________________________________________________________ 55
array_count_values _____________________________________________________ 56
5.3.- Recorrido de vectores ________________________________________________ 56
FOREACH ___________________________________________________________ 57
LIST Y EACH_________________________________________________________ 59
5.4.- Búsqueda de elementos dentro de un vector _____________________________ 63
5.5.- Ordenación de vectores ______________________________________________ 64
sort y rsort ____________________________________________________________ 65
asort y arsort __________________________________________________________ 66
ksort y rksort __________________________________________________________ 67
usort, uasort y uksort ____________________________________________________ 68
5.6.- Adición y eliminación de elementos (pilas y colas) ________________________ 69
array_push y array_pop__________________________________________________ 70
array_unshift y array_shift _______________________________________________ 70
array_pad_____________________________________________________________ 71
5.7.- Otras funciones interesantes __________________________________________ 71
6.- FICHEROS y Entrada/Salida _____________________________________________ 76
6.1- Trabajar con Ficheros ________________________________________________ 76
Existencia y tamaño de ficheros ___________________________________________ 76
Abrir y Cerrar Ficheros __________________________________________________ 77
Página 3/115
Escritura en Ficheros ____________________________________________________ 78
Lectura de Ficheros _____________________________________________________ 79
Copiar, Renombrar y Borrar Ficheros_______________________________________ 81
6.2.- Trabajar con Directorios _____________________________________________ 82
Existencia de un directorio _______________________________________________ 82
Creación y borrado de directorios __________________________________________ 82
Apertura y cerrado de directorios __________________________________________ 83
Lectura del contenido de un directorio ______________________________________ 84
6.3.- Funciones útiles del Sistema de Ficheros ________________________________ 84
6.4.- Modificación de las características de un archivo _________________________ 86
6.5- Ejecución externa de programas _______________________________________ 86
6.6- Almacenamiento de variables en ficheros ________________________________ 86
6.7.- Otras funciones interesantes __________________________________________ 88
7.- DESARROLLO DINÁMICO DE WEBS_____________________________________ 90
7.1.- Introducción _______________________________________________________ 90
7.2.- Plantillas___________________________________________________________ 90
7.3.- Paso de parámetros entre scripts_______________________________________ 93
Introducción __________________________________________________________ 93
El Método GET ________________________________________________________ 93
Problemas ____________________________________________________________ 93
7.4.- Redireccionamiento _________________________________________________ 95
7.5.- Scripts que se llaman a sí mismos ______________________________________ 96
7.6.- Recomendaciones ___________________________________________________ 97
8.- FORMULARIOS _______________________________________________________ 98
8.1.- Introducción _______________________________________________________ 98
8.2.- Formularios ________________________________________________________ 98
Creación Formularios ___________________________________________________ 98
Entidades _____________________________________________________________ 99
8.3.- Formularios y PHP _________________________________________________ 102
Envío de archivos con el método POST ____________________________________ 104
8.4.- Creación Dinámica de Formularios ___________________________________ 108
9.- SESIONES ___________________________________________________________ 111
9.1.- Introducción ______________________________________________________ 111
9.2.- Manejo de Sesiones _________________________________________________ 111
Iniciar una sesión______________________________________________________ 112
Registrar variables dentro de una sesión ____________________________________ 112
Destruir una sesión ____________________________________________________ 113
Almacenar en disco las variables de una sesión ______________________________ 113

Página 4/115
Iniciación a PHP 4 1.- CONCEPTOS BÁSICOS

1.- CONCEPTOS BÁSICOS

1.1.- Insertar código PHP en HTML


Para interpretar un archivo, php simplemente interpreta el texto del archivo hasta que
encuentra uno de los caracteres especiales que delimitan el inicio de código PHP. El intérprete
ejecuta entonces todo el código que encuentra, hasta que encuentra una etiqueta de fin de código
que le dice al intérprete que siga ignorando el código siguiente. Este mecanismo permite embeber
(insertar) código PHP dentro de HTML: todo lo que está fuera de las etiquetas PHP se deja tal como
está, mientras que el resto se interpreta como código.

Hay cuatro conjuntos de etiquetas que pueden ser usadas para denotar bloques de código
PHP. De estas cuatro, sólo 2 (<?php. . .?> y <script language="php">. . .</script>) están siempre
disponibles; el resto pueden ser configuradas en el fichero de php.ini para ser o no aceptadas por el
intérprete. Mientras que el formato corto de etiquetas (short-form tags) y el estilo ASP (ASP-style
tags) pueden ser convenientes pero no son portables como la versión de formato largo de etiquetas.
Además, si se pretende embeber código PHP en XML o XHTML, será obligatorio el uso del formato
<?php. . .?> para la compatibilidad con XML.
Las etiquetas soportadas por PHP son:

1. <?php echo "si quieres servir documentos XHTML o XML, haz como aquí;\n"; ?>

2. <? echo "Formato Corto de etiquetas \n"; ?>

3. <script language="php">
echo "muchos editores (como FrontPage) no aceptan instrucciones de procesado";
</script>

4. <% echo "Opcionalmente se pueden usar las etiquetas ASP"; %>

El método primero, <?php. . .?>, es el más conveniente, ya que permite el uso de PHP en
código XML como XHTML.
El método segundo no siempre está disponible. El formato corto de etiquetas está disponible con la
función short_tags(), activando el parámetro del fichero de configuración de PHP short_open_tag, o
compilando PHP con la opción --enable-short-tags del comando configure. Aunque esté activa por
defecto en php.ini-dist, se desaconseja el uso del formato corto de etiquetas por temas de
compatibilidad.

El método cuarto sólo está disponible si se han activado las etiquetas ASP en el fichero de
configuración: asp_tags.
Nota: El soporte de etiquetas ASP se añadió en la versión 3.0.4.
Nota: No se debe usar el formato corto de etiquetas cuando se desarrollen aplicaciones o librerías
con intención de redistribuirlas, o cuando se desarrolle para servidores que no están bajo nuestro
control, porque puede ser que el formato corto de etiquetas no esté soportado en el servidor. Para
generar código portable y redistribuíble, asegúrate de no usar el formato corto de etiquetas.

Nota: La etiqueta de fin código php, ?>, lleva implícito el punto y coma y por tanto no es necesario
añadirlo al final de la línea anterior.

PHP permite estructurar bloques como:

<?php
if ($expression){
?>
<strong>Esto es verdadero.</strong>
<?php
} else {
?>
<strong>Esto es falso.</strong>
Página 5/115
Iniciación a PHP 4 1.- CONCEPTOS BÁSICOS

<?php
}
?>

Este ejemplo realiza lo esperado, ya que cuando PHP encuentra las etiquetas ?> de fin de
bloque, empieza a escribir lo que encuentra tal cual hasta que encuentra otra etiqueta de inicio de
bloque. Para escribir bloques grandes de texto generalmente es más eficiente separaros del código
PHP que enviar todo el texto mediante las funciones echo(), print() o similares.

1.2.- Múltiples scripts PHP en un mismo documento


Para permitir un mayor grado de flexibilidad a la hora de construir aplicaciones web
dinámicas, se pueden insertar varios scripts PHP:

<html>
<head>
<title>
<?
print “Ejemplo de Múltiples scripts”;
$var=5;
?>
</title>
</head>
<body>
<?
$var = $var + $var; // Hacemos 5+5
echo “5 + 5 = $var”;
?>
</body>
</html>

1.3.- Comentar el código PHP


PHP soporta el estilo de comentarios de 'C', 'C++' y de la interfaz de comandos de Unix. Por ejemplo:

<?php
echo "Esto es una prueba"; // Esto es un comentario de una sóla línea tipo C/C++
/* Esto es un comentario de
varias líneas */
echo "Esto es otra prueba";
echo "Esta es la última prueba"; # Este es un comentario de tipo línea de comandos (Linux)
?>

Los estilos de comentarios de una linea actualmente sólo comentan hasta el final de la linea
o el bloque actual de código PHP, lo primero que ocurra.

<h1>Esto es un <?php # echo "simple";?> ejemplo.</h1>


<p>La cabecera de arriba imprimirá 'Esto es un ejemplo'.

Página 6/115
Iniciación a PHP 4 1.- CONCEPTOS BÁSICOS

Hay que tener cuidado con no anidar comentarios de estilo 'C', algo que puede ocurrir al
comentar bloques largos de código.

<?php
/*
echo "Esto es una prueba"; /* Este comentario creará un problema*/
*/
?>

Página 7/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

2.- TIPOS DE DATOS Y VARIABLES


En PHP, el tipo de una variable normalmente no lo indica el programador; en su lugar, lo
decide PHP en tiempo de ejecución dependiendo del contexto en el que se utilice esa variable.
Si se quisiese obligar a que una variable se convierta a un tipo concreto, se podría forzar la variable
(type casting) o usar la función settype() para ello.
Nótese que una variable se puede comportar de formas diferentes en ciertas situaciones,
dependiendo de qué tipo sea en ese momento.

Las variables se crean siguiendo este esquema y siempre con el signo de dólar delante:

$nombre = valor;

Los distintos valores que puede tomar un variable se verán a continuación.

2.1.- Enteros
Los enteros se puede especificar usando una de las siguientes sintaxis:

$a = 1234; # número positivo


$a = -123; # número negativo

Enteros en base 8 (Octal) y en base 16 (Hexadecimal) también están permitidos. Los valores
en octal comienzan con el dígito 0 mientras que los valores en hexadecimal comienzan por 0x ó 0X.

$a = 0123; # número octal (equivalente al 83 decimal)


$a = 0x12; # número hexadecimal (equivalente al 18 decimal)

2.2.- Números en coma flotante


Los números en coma flotante ("double") se pueden especificar utilizando la notación
estándar o la científica:

$a = 1.234; // Notación estándar


$a = 1.2e3; // Notación científica

2.3.- Cadenas
Las cadenas de caracteres se pueden especificar usando uno de dos tipos de delimitadores.
Si la cadena está encerrada entre dobles comillas (“”), las variables que estén dentro de la cadena
serán expandidas (se sustituyen por su valor). Como en C y en Perl, el carácter de barra invertida (\)
se puede usar para especificar caracteres especiales:

Caracteres protegidos
secuencia significado
\n Nueva línea
\r Retorno de carro
\t Tabulación horizontal
\\ Barra invertida
\$ Signo del dólar
\" Comillas dobles
\[0-7]{1,3} la secuencia de caracteres que coincida con la expresión regular es un carácter en
notación octal
Página 8/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

\x[0-9A-Fa- la secuencia de caracteres que coincida con la expresión regular es un carácter en


f]{1,2} notación hexadecimal

La segunda forma de delimitar una cadena de caracteres usa el carácter de comilla simple (‘’).
Cuando una cadena va encerrada entre comillas simples, los únicos caracteres de escape que serán
comprendidos son \\ y \'. Esto es por convenio, así se pueden tener comillas simples y barras
invertidas en una cadena entre comillas simples. Las variables no se expandirán dentro de una
cadena entre comillas simples.

$comida=”pizza”;

$frase_1=”Mi comida favorita es la $comida.”;


$frase_2= ‘Mi comida favorita es la $comida.’;

echo $frase_1;
// Dará como salida: Mi comida favorita es la pizza.

echo $frase_2;
// Dará como salida: Mi comida favorita es la $comida.

Otra forma de delimitar cadenas es usando la sintaxis de documento incrustado ("<<<"). Se


debe proporcionar un identificador después de <<<, después escribimos la cadena, y a continuación
escribimos el mismo identificador para indicar el final de cadena.

$str = <<<CAD
Ejemplo de cadena
Expandiendo múltiples líneas
usando sintaxis de documento incrustado.
CAD;

// Donde CAD es el nombre del identificador

Nota: La sintaxis de documento incrustado fue añadida en PHP 4.

Las cadenas se pueden concatenar usando el operador '.' (punto). Nótese que el operador '+'
(suma) no sirve para esto.

// Creamos una cadena


$str = “Esta es una cadena”;

// Le añadimos más texto


$str = $str . “con un poco más de texto.”;

echo $str;
/*
Esto dará como salida:
Esta es una cadena con un poco más de texto
*/

Se puede acceder a los caracteres dentro de una cadena tratándola como un array (vector)
de caracteres indexado numéricamente, usando una sintaxis similar a la de C. Veamos un ejemplo
más abajo.

<?php
/* Obtener el primer carácter de una cadena */
$str = 'Esto es una prueba.';
$first = $str[0];

Página 9/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

/* Obtener el último carácter de una cadena. */


$str = 'Esto es aún una prueba.';
$last = $str[strlen($str)-1];
/* Le restamos 1 porque si la cadena tiene 23 elementos,
el vector irá desde la posición 0 a la posición 22 */

echo $first;
// Dará como salida: E

echo $last
// Dará como salida: .
?>

Como se ha visto en el ejemplo anterior, la función strlen() permite calcular la longitud de una
cadena.

También puede ser conveniente insertar dentro de una cadena código html que describa el
formato de la cadena. Los siguientes ejemplos son equivalentes y darán por pantalla el mismo
resultado:

<?php
/* Ejemplo 1 */
$cadena=”Esta línea debe estar en negrita”;
echo “<strong>$cadena</strong>”;

/* Ejemplo 2 */
$cadena=”<strong>Esta línea debe estar en negrita</strong>”;
echo $cadena;

/* Ejemplo 3 */
$cadena=”Esta línea debe estar en negrita”;
$format_ini=”<strong>”;
$format_fin=”</strong>”;
echo “$format_ini$cadena$format_fin”;

/*
Los tres ejemplos darán la misma salida por pantalla:
Esta línea debe estar en negrita
*/
?>

2.4.- Conversión de cadenas

Cuando una cadena se evalúa como un valor numérico, el valor resultante y el tipo se
determinan como sigue:

La cadena se evaluará como un doble si contiene cualquiera de los caracteres '.', 'e', o 'E'. En
caso contrario, se evaluará como un entero.

El valor viene dado por la porción inicial de la cadena. Si la cadena comienza con datos de
valor numérico, este será el valor usado. En caso contrario, el valor será 0 (cero). Los datos
numéricos válidos son un signo opcional, seguido por uno o más dígitos (que opcionalmente
contengan un punto decimal), seguidos por un exponente opcional. El exponente es una 'e' o una 'E'
seguidos por uno o más dígitos.

Cuando la primera expresión es una cadena, el tipo de la variable dependerá de la segunda


expresión:

Página 10/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

$foo = 1 + "10.5"; // $foo es doble (11.5)


$foo = 1 + "-1.3e3"; // $foo es doble (-1299)
$foo = 1 + "bob-1.3e3"; // $foo es entero (1)
$foo = 1 + "bob3"; // $foo es entero (1)
$foo = 1 + "10 Cerditos"; // $foo es entero (11)
$foo = 1 + "10 Cerditos"; // $foo es entero (11)
$foo = "10.0 cerdos " + 1; // $foo es entero (11)
$foo = "10.0 cerdos " + 1.0; // $foo es double (11)

Si se quisiera probar cualquiera de los ejemplos de esta sección, basta cortar y pegar los ejemplos e
insertar la siguiente línea para ver lo que va ocurriendo:

echo "\$foo==$foo; el tipo es " . gettype( $foo ) . "<br>\n";

2.5.- Arrays (vectores)


ARRAYS UNIDIMENSIONALES

Un vector no es más que una lista de elementos. Existen dos tipos de vectores: aquellos que
son accedidos mediante la posición que ocupa el elemento y aquellos que son accedidos mediante
una clave asociada al elemento en cuestión. Los primeros se llaman arrays escalares y los segundos
arrays asociativos. En realidad php los trata de la misma manera.

Se puede crear una array usando la función array() o bien se puede asignar el valor de cada
elemento del array de manera explícita.

Escalares
Para acceder al vector utilizamos un número entero que denota la posición del elemento:

$nombre_vect[pos]

Un vector unidimensional puede ser creado de forma explícita como sigue:

$comidas[0]=”Tortilla”;
$comidas[1]=”Pollo Frito”;
$comidas[2]=”Tofu”;

De forma alternativa podemos usar la función array() para crear el vector:

$comidas=array(”Tortilla”,”Pollo Frito”,”Tofu”);

También es conveniente comentar que se pueden añadir elementos al final del vector sin más
que asignar un valor al vector pero con los corchetes vacíos:

$comidas[]=”Berenjena”;
$comidas[]=”Pimientos”;

// Berenjena se añadiría en la posición 3 y Pimientos en la 4

Si un vector aún no ha sido creado y usamos la sintaxis anterior no pasa nada, el primer
elemento se introducirá en la posición 0, el siguiente en la 1 y así sucesivamente:

$grabadoras[]=”Lite-On”;
$grabadoras[]=”Sony”;

Página 11/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

$grabadoras[]=”Plextor”;

/* Puesto que grabadoras se acaba de crear y no contenía ningún elemento, Lite-On se añadiría en la
posición 0, Sony en la posición 1 y Plextor en la posición 2. Esta sintaxis puede ser muy útil si no
conocemos de antemano el número de elementos que vamos a insertar */

Asociativos
Los vectores asociativos son particularmente útiles cuando tiene más sentido acceder a un
vector usando palabras (claves) en vez de números enteros.

$nombre_vect[“clave”];
// ó
$nombre_vect[‘clave’];

Por ejemplo, si queremos almacenar información referente a un estudiante (Nombre,


dirección, teléfono, dni, número de matrícula, facultad, curso, etc..) puede ser mucho más
conveniente usar un vector asociativo que uno escalar pues cuando queramos acceder a un dato en
concreto no necesitaremos memorizar la posición dónde está contenido dicho dato. Veamos un
ejemplo:

$alumno[“nombre”]=”José”;
$alumno[“apellidos”]=”Martínez Roca”;
$alumno[“telefono”]=”963 616 654”;
$alumno[“direccion”]=”C/ Arco del triunfo 13”;
$alumno[“dni”]=”22 111 055”;
$alumno[“num_matricula”]=”6666”;
$alumno[“facultad”]=”Facultad Informática”;
$alumno[“curso”]=”5”;

/* Si ahora queremos consultar el nombre de dicho alumno y su número de mátricula


basta hacer: */
echo $alumno["nombre"];

/* Es importante comentar que si hiciésemos echo $alumno[0] el intérprete no daría error, pero no se
imprimiría nada en la pantalla. Es cierto que PHP trata de la misma forma los arrays asociativos y los
escalares, pero el usuario debe acceder convenientemente a cada uno de ellos. */

De nuevo podemos hacer uso de la función array() para crear el vector:

$alumno=array(
“nombre” => ”José”,
“apellidos” => ”Martínez Roca”,
“telefono” => “96 361 66 54”,
“direccion” => “C/ Arco del triunfo 13”,
“dni” => “22 111 055”,
“num_matricula” => “6666”,
“facultad” => “Facultad Informática”,
“curso” => “5” // El último no lleva una coma al final
);

Página 12/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

Muy importante:
Cuando se habló de cadenas se comentó que una de las diferencias entre comillas simples y dobles
residía en que la primera no expandía variables mientras que la segunda sí. Pues bien, si queremos
meter dentro de una cadena el valor de una posición de un vector, tenemos que meter la referencia al
vector entre llaves, tal como se indica en el ejemplo.

// Array Escalar
$vector[0]=”Australia”;
$vector[1]=”España”;
echo “El país que más me gusta es {$vector[0]}”;
echo “aunque yo he nacido en {$vector[1]}”;

// Array Asociativo
$alumno[“Nombre”]=”Vender”;
$alumno[“Tipo”]=”Robot”;

echo “El alumno {$alumno[“Nombre”]} es de tipo {$alumno[“Tipo”]}.”

// Si no usásemos llaves recibiríamos un error de interpretación del tipo:


Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `T_NUM_STRING' in
c:\phpdev\www\pruebas\pruebas.php on line 32

Sin embargo es totalmente correcto hacer lo siguiente

// Continuando el ejemplo anterior....


echo $vector[1];
echo $alumno[“Nombre”];

ya que los vectores no están incluidos dentro de una cadena.

Esto afecta a todos los tipos de arrays: escalares y asociativos, ya sean unidimensionales o
multidimensionales.

ARRAYS MULTIDIMENSIONALES

La idea de un vector multidimensional sería la de un vector dónde dentro de cada posición de


dicho vector se halla otro vector. Dentro de cada posición del segundo vector pueden hallarse a suve
otro vector, y así sucesivamente. No hay ningún tipo de limitación respecto a la dimensión pero es
muy extraño utilizar dimensiones superiores a tres.

Un vector de dimensión 2 se suele representar como una matriz. Para acceder a una celda
basta con suministrar la fila y la columna.

Un vector de dimensión 3 se suele representar como un cubo dividido en celdas. Para


acceder a una celda se le proporciona la fila, la columna y la altura.

A partir de aquí, las representaciones se hacen cada vez más complicadas. Un vector de dimensión 4
podría representarse como un vector dónde cada posición contiene un cubo dividido en celdas.
Estructuras tan complejas no se suelen usar debido a lo difícil que puede llegar a ser su manejo.

Escalares
Tal y como uno se puede imaginar, la sintaxis general es la siguiente:

$nombre_vect[pos_dim_1][pos_dim_2]..[pos_dim_N]

Podemos crear un vector escalar multidimensional de forma explícita o usando la función


array():

Página 13/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

// Vamos a crear una matriz de dimensión 2 de forma explícita:

// Fila 0
$verdurita[0][0]=”Patata”;
$verdurita[0][1]=”Bonitato”;

// Fila 1
$verdurita[1][0]=”Lechuga”;
$verdurita[1][1]=”Pimientos”;

// La función array() suele ser más útil en estos casos:


$verdurita=array(
array("Patata", "Boniato"), // Fila 0
array("Pimiento", "Lechuga") // Fila 1
);

// Si queremos ver el contenido de nuestro vector en forma de matriz basta hacer:


echo "{$vector[0][0]} | {$vector[0][1]} <br>";
echo "{$vector[1][0]} | {$vector[1][1]} <br>";

Asociativos
Funcionan exactamente igual que los escalares salvo que en vez de usar varios índices para
acceder a la información deseada, usamos varias palabras. Por ejemplo, si tenemos una tienda de
informática y vendemos procesadores y discos duros, es evidente que tendremos varias marcas y a
su vez cada marca tendrá varios modelos. Para simplificar, supondremos que sólo tenemos un
modelo de cada marca.

Procesadores:
AMD: K7 XP 1800
PENTIUM: IV 2,5 Ghz
Discos duros:
SEAGATE: 40GB 10000 rpm
SAMSUNG: 40GB 7200 rpm
WESTERN DIGITAL: 60GB 7200 rmp 8MB caché

Queremos almacenar esta estructura en un array multidimensional para que dado una marca
de procesador o de disco duro, podamos consultar el modelo disponible en stock:

Tienda de Informática – Ejemplo 1:


// Usando la declaración explícita:

// 1º los procesadores
$productos[“procesador”][“AMD”]=”K7 XP 1800”;
$productos[“procesador”][“PENTIUM”]=”IV 2,5 Ghz”;

// 2º los discos duros


$productos[“disco_duro”][“SEAGATE”]=” 40GB 10000 rpm”;
$productos[“disco_duro”][“SAMSUNG”]=” 40GB 7200 rpm”;
$productos[“disco_duro”][“WESTERN_DIGITAL”]=” 60GB 7200 rmp 8MB caché”;

// Usando la función array():


$productos=array(
“procesador” => array (
“AMD” => ”K7 XP 1800”,
“PENTIUM” => “IV 2,5 Ghz”
),
“disco_duro” => array(
“SEAGATE” => “40GB 10000 rpm”,
“SAMSUNG” => “40GB 7200 rpm”,
“WESTERN_DIGITAL” => “60GB 7200 rmp 8MB caché”
Página 14/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

)
);

// Si alguien nos pregunta qué disco duro SEAGATE tenemos, basta con hacer:
echo “Disco duro SEAGATE: {$productos[“disco_duro”][“SEAGATE”]}”;

MEZCLANDO ARRAYS ESCALARES Y ASOCIATIVOS

También es posible mezclar arrays escalares y asociativos siendo una estrategia de lo más
útil. Para ver su utilidad ampliaremos el ejemplo anterior. Antes, por simplicidad, se supuso que sólo
teníamos un modelo de cada marca. Esto no suele ser cierto, lo normal es tener varios modelos de
una misma marca:

Procesadores:
AMD:
K7 XP 1900
K7 XP 1800
K7 XP 1700
PENTIUM:
IV 2,5 Ghz
IV 2,4 Ghz
IV 2,3 Ghz
IV 2,2 Ghz
Discos duros:
SEAGATE:
40GB 10000 rpm
80GB 7200 rpm
160GB 7200 rpm
SAMSUNG:
40GB 7200 rpm
WESTERN DIGITAL:
60GB 7200 rpm 8MB cache
80GB 1000 rpm 16MB cache

Veamos cómo implementar ésta estructura de datos en PHP:

Tienda de informática – Ejemplo 2:


// Por sencillez, en éste caso únicamente veremos la declaración explícita:

// 1º los procesadores
$productos[“procesador”][“AMD”][0]=”K7 XP 1900”;
$productos[“procesador”][“AMD”][1]=”K7 XP 1800”;
$productos[“procesador”][“AMD”][2]=”K7 XP 1700”;

$productos[“procesador”][“PENTIUM”][0]=”IV 2,5 Ghz”;


$productos[“procesador”][“PENTIUM”][1]=”IV 2,4 Ghz”;
$productos[“procesador”][“PENTIUM”][2]=”IV 2,3 Ghz”;
$productos[“procesador”][“PENTIUM”][3]=”IV 2,2 Ghz”;

// 2º los discos duros


$productos[“disco_duro”][“SEAGATE”][0]=” 40GB 10000 rpm”;
$productos[“disco_duro”][“SEAGATE”][1]=” 80GB 7200 rpm”;
$productos[“disco_duro”][“SEAGATE”][2]=” 160GB 7200 rpm”;

$productos[“disco_duro”][“SAMSUNG”][0]=” 40GB 7200 rpm”;

$productos[“disco_duro”][“WESTERN_DIGITAL”][0]=” 60GB 7200 rpm 8MB cache”;


$productos[“disco_duro”][“WESTERN_DIGITAL”][1]=” 80GB 10000 rpm 16MB cache”;

Página 15/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

// Si adquirimos nuevos productos, modificar la estructura es muy sencillo.


// Por ejemplo, supongamos que recibimos un nuevo procesador AMD y queremos añadirlo:

$productos[“procesador”][“AMD”][]=”K7 XP 2000”;
// Esto añadiría el nuevo procesador al final de los procesadores AMD, es decir, en la posición 3

// En cualquier momento si deseamos añadir una nueva marca (por ej. QUANTUM) basta hacer:
$productos[“disco_duro”][“QUANTUM”][0]”40GB 10000 rpm”;

/* Es conveniente comentar que no era necesarios indicar los índices. Ya se ha comentado que si se
usan los corchetes vacíos, PHP inserta el dato después de la última posición y si el vector no existía
metía el dato en la posición 0. Así, se podría haber hecho perfectamente: */

$productos[“procesador”][“AMD”][]=”K7 XP 1900”;
$productos[“procesador”][“AMD”][]=”K7 XP 1800”;
$productos[“procesador”][“AMD”][]=”K7 XP 1700”;

$productos[“procesador”][“PENTIUM”][]=”IV 2,5 Ghz”;


.
.
.
// y así sucesivamente

NOTAS IMPORTANTES SOBRE LOS ARRAYS ASOCIATIVOS

Es MUY importante que cuando deseemos acceder a una posición de un vector asociativo
escribamos CORRECTAMENTE la clave, es decir, que la escribamos exactamente como la definimos
al crear el vector. Pensemos que la clave no es más que una cadena de caracteres. Cuando nosotros
escribimos una clave, PHP compara el texto de la clave suministrada con las claves que contiene el
vector. La comparación se hace carácter a carácter. Eso significa que si ponemos un acento de más
(o de menos), o cambiamos una letra mayúscula por una minúscula, PHP no encontrará la clave que
estamos buscando.

Es también importante saber que PHP NO dará ningún tipo de error si escribimos mal la
clave. Si no encuentra la clave, supondrá que no existe y devolverá una cadena vacía.

$bebidas[“refrescantes”]=”Coca-Cola”;
$bebidas[“alcoholicas”]=”Ron”;

// Si hacemos
echo $bebidas[“refrescantes”]; // Daría por pantalla: Coca-Cola
echo $bebidas[“Refrescantes”]; /* No daría nada por pantalla pues PHP considera que la clave no
existe. */

Ya se ha dicho que la clave no es más que una cadena de caracteres. Sabemos que las
cadenas de caracteres pueden ir entre comillas simples o comillas dobles. Esto dota de gran
flexibilidad a la hora de crear claves pues el valor de una clave puede ser proporcionado por el valor
de una variable (para ello tenemos que encerrar la variable entre comillas dobles). Ello permite
incluso crear vectores con claves que ni siquiera sabemos a priori. Veamos un ejemplo:

$marca=”AMD”; /* Pensemos que el valor de la variable $marca no tenemos por qué


conocerlo. */

$usuarios[“$marca”]=”K7 1800”;
// o bien
$usuarios[$marca]=”K7 1800”;
/* la segunda forma tiene más peligro puesto que si no estamos seguros de que la vble
$marca es una cadena de caracteres, podemos estar creando un vector escalar en vez
de uno asociativo y podemos tener problemas a la hora de acceder a los datos. Por lo

Página 16/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

tanto, es más recomendable usar la primera forma.*/

echo $usuarios[“AMD”]; // daría por pantalla: K7 1800

NOTAS IMPORTANTES SOBRE LOS ARRAYS EN GENERAL

PHP permite jugar enormemente con los vectores. Si queremos igualar un vector a otro, lo
único que tenemos que hacer es igualar la nueva variable al vector.

$piezas[0]=”monitor”;
$piezas[1]=”cpu”;
$piezas[2]=”placa base”;
$piezas[3]=”RAM”;

// Si queremos crear un nuevo vector llamado $mi_pc y que sea igual a $piezas basta hacer:
$mi_pc=$piezas;
// $mi_pc será una copia de $piezas.

Si tenemos un vector multidimensional, podemos quedarnos con un trozo de él de la siguiente


forma:

// Vamos a seguir con el ejemplo2 de la tienda de informática

// Imaginemos que queremos un vector dónde sólo tengamos los discos duros:

$discos_duros=$productos[“disco_duro”];
// Con esto conseguiríamos un vector bidimensional con los discos duros únicamente.
// Podemos acceder a uno de ellos sin más que hacer:
echo $discos_duros[“SEAGATE”][0];

// También podríamos quedarnos únicamente con los procesadores AMD

$AMD=$productos[“procesadores”][“AMD”];
/* Con esto hemos creado un vector unidimensional con los modelos de procesador que tenemos de
AMD. Para acceder a uno de ellos basta hacer: */
echo $AMD[2];

Hay otro punto importante que debe ser tratado. PHP no dará error si se trata de acceder a
una posición del vector que no exista (al igual que si tratamos de acceder a una variable que no
existe o que aún no ha sido definida). Además, no tenemos por qué comenzar los vectores en la
posición 0. Es más, en un vector escalar, podemos ir metiendo datos en las posiciones 3, 5, 9, 12,
etc...(es decir, en posiciones totalmente arbitrarias) Pero ojo, las posiciones que se quedan vacías no
quedan rellenadas con nada, ni son inicializadas a 0, más bien todo lo contrario. Para PHP esas
posiciones no existen y de hecho si usamos la función count() para contar los elementos de un vector
sólo nos contará aquellas posiciones dónde hay datos. Un ejemplo seguro que aclara este asunto:

/* Nos definimos un vector $prueba pero comenzando por la posición 2


aunque bien podíamos haber comenzado por cualquier otra posición. */

$prueba[2]=”dato1”;
$prueba[5]=”dato2”;
$prueba[6]=”dato3”;
$prueba[1024]=”dato4”;
$prueba[2220]=”dato5”;

// Si ahora hacemos
echo ‘El número de elementos del $prueba es: ’;
echo count($prueba);

Página 17/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

/* ¿Cuál crees que será la salida de este script?


El número de elementos del vector $prueba es: 5

Precisamente por esta razón PHP suministra potentes herramientas de


recorrido de vectores. De esa forma dado un vector cualquiera, podemos
recorrerlo de cabo a rabo sin necesidad de conocer su tamaño, la posición
de inicio y fin, si los valores han sido insertados en orden o de forma
salteada, etc...
*/

Hasta aquí hemos visto los diferentes tipos de vectores que hay, su construcción y el acceso
a los datos pero no hemos visto ni las estrategias de rellenado ni las formas de recorrer los vectores.
Esto se verá más adelante (una vez hallamos visto las estructuras de control) dentro de un tema
dedicado únicamente a vectores. Además se verán muchas de las funciones que PHP tiene para
realizar ordenaciones, búsquedas, eliminación de elementos, troceado de vectores, contabilidad de
los elementos de un vector, etc...

2.6.- Boolean
El tipo bolean sirve para representar, únicamente, dos estados CIERTO (TRUE) o FALSO
(FALSE). Ello permite utilizar variables como flags (indicadores, banderas). De esa forma podemos
hacer comprobaciones y dependiendo de si el indicador es cierto o no, hacer una cosa u otra.

PHP, al igual que C o Perl, también interpreta como CIERTO cualquier valor entero distinto de
0 y como FALSO el valor 0.

Esta dos formas de representar valores de verdad nos facilita las cosas y nos da más juego.
Veamos algunos ejemplos:

// Todos los ejemplos que vamos a ver a continuación son equivalentes:

// -----------------------------------------------------------------------------------------
// Ejemplo 1
$flag_euros=TRUE;

if ($flag_euros== TRUE) echo “El resultado se mostrará en euros”;


else “El resultado se mostrará en pesetas”;
// -----------------------------------------------------------------------------------------
// Ejemplo 2
$flag_euros=TRUE;

if ($flag_euros) echo “El resultado se mostrará en euros”;


else “El resultado se mostrará en pesetas”;
// -----------------------------------------------------------------------------------------
// Ejemplo 3
$flag_euros=1; // aunque podríamos poner -56

if ($flag_euros==1) echo “El resultado se mostrará en euros”;


else “El resultado se mostrará en pesetas”;
// -----------------------------------------------------------------------------------------
// Ejemplo 4
$flag_euros=1;

if ($flag_euros) echo “El resultado se mostrará en euros”;


else “El resultado se mostrará en pesetas”;
// -----------------------------------------------------------------------------------------

Página 18/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

// Ejemplo 5
$flag_euros=1;

if ($flag_euros==TRUE) echo “El resultado se mostrará en euros”;


else “El resultado se mostrará en pesetas”;
// -----------------------------------------------------------------------------------------

/* Todos estos ejemplos son correctos y darían como salida:


El resultado se mostrará en euros
*/

/* La sentencia if se explicará en el tema 3 (Operadores y Estructuras


de Control)*/

2.7.- Objetos
PHP permite también la programación orientada a objetos. Podemos considerar un objeto
como una variable que ha sido instanciada a partir de un tipo de plantilla (clase). Esto se sale fuera
del propósito de este manual y por tanto sólo se verán algunos conceptos generales.

Una clase es una colección de variables y de funciones que acceden a esas variables. Una
clase se define con la siguiente sintaxis:

<?php
class Cart {
var $items; // Items en nuestro carro de la compra

// Añadir $num artículos de tipo $artnr al carro

function add_item ($artnr, $num) {


$this->items[$artnr] += $num;
}

// Sacar $num artículos del tipo $artnr del carro

function remove_item ($artnr, $num) {


if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} else {
return false;
}
}
}
?>

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.

$cart = new Cart;


$cart->add_item("10", 1);

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 extensiones 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.

Página 19/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

class Named_Cart extends Cart {


var $owner;

function set_owner ($name) {


$this->owner = $name;
}
}

Ese ejemplo define una clase Named_Cart (carro con nombre o dueño) que tiene todas las
variables y funciones de Cart, y además añade la variable $owner y una función adicional
set_owner(). 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:

$ncart = new Named_Cart; // Creamos un carro con nombre


$ncart->set_owner ("kris"); // Nombramos el carro
print $ncart->owner; // Imprimimos el nombre del propietario
$ncart->add_item ("10", 1); // Funcionalidad heredada de Cart

Entre 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.

class Auto_Cart extends Cart {


function Auto_Cart () {
$this->add_item ("10", 1);
}
}

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.

class Constructor_Cart extends Cart {


function Constructor_Cart ($item = "10", $num = 1) {
$this->add_item ($item, $num);
}
}

// Compramos las mismas cosas aburridas de siempre

$default_cart = new Constructor_Cart;

// Compramos las cosas interesantes

$different_cart = new Constructor_Cart ("20", 17);

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.

Página 20/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

2.8.- Identificadores
Un identificador es un término general aplicado a las variables, funciones y objetos
definidos por el usuario. Hay diversas propiedades que han de cumplir los identificadores en PHP:

o Un identificador consiste en uno más caracteres y debe comenzar con una letra del
abecedario o un carácter de subrayado (“_”). Además, los identificadores sólo pueden estar
constituidos por letras, números caracteres de subrayado y otros caracteres ASCII
comprendidos del 127 a 255.

o Los identificadores son sensibles a mayúsculas y minúsculas. Por lo tanto, una variable
llamada $nombre es diferente a otra llamada $Nombre, $nombrE ó $NoMbRe.

o Por último, un identificador no puede ser idéntico a ninguna de las palabras clave predefinidas
en PHP.

Veamos algunos ejemplos:


VALIDO INVÁLIDO
mi_funcion() $ruta&precio
$_info $!contador
$Tamaño 2_a_2_funcion()
cuad_2() $func_<_ab

2.9.- Variables

Hasta ahora hemos venido jugando con las variables de una forma relativamente sencilla. En
realidad no hemos hecho más que asignaciones y acceso a los contenidos de las variables. El
propósito de este punto es el de entrar en detalle sobre el maravilloso mundo de la manipulación de
variables.

ÁMBITO DE LAS VARIABLES

Podríamos definir el ámbito de una variable como el ámbito de disponibilidad de dicha


variable dentro del programa. Hay tres tipos de ámbitos:

o Variables Locales
o Variables Globales
o Variables Estáticas

Variables Locales

Una variable declarada dentro de una función es considerada como local, es decir, sólo
puede ser referenciada dentro de la función. Cualquier asignación fuera de la función será
considerada como la asignación de un valor a una variable totalmente diferente a la contenida dentro
de la función (aunque tengan el mismo nombre). Es importante saber que cuando finaliza una
función, todas las variables locales contenidas en ella son destruidas.

Veamos un pequeño ejemplo:

<?php

$x=0;

function asigna_x()
{
Página 21/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

$x=5;
echo “\$x dentro de la función vale: $x <br>”;
}

echo “\$x fuera de la función vale: $x <br>”;


/* -------------------------------------
Esto dará como resultado:

$x dentro de la función vale: 5


$x fuera de la función vale: 0
----------------------------------------- */
?>

Variables Globales

A diferencia de las variables locales, una variable Global puede ser accedida y modificada
desde cualquier parte del programa. Sin embargo, para llevar esto a efecto, una variable global debe
ser explícitamente declarada como tal dentro de la función. Esto se consigue colocando la palabra
reservada GLOBAL delante de la variable que debe ser reconocida como tal. Veamos un ejemplo:

<?php

$var=25;

function incrementa_var()
{
GLOBAL $var;
$var++;
}

incrementa_var();
echo $var; // Esto dará como resultado: 26

?>

La sintaxis anterior puede dar lugar a confusión. En funciones extremadamente largas, puede
llegar a ocurrir que olvidemos que la variable $var es global y no local. Para evitar este tipo de
problemas, PHP proporciona un tipo de sintaxis alternativa que consiste en usar su vector de
variables globales llamado $GLOBALS. La sintaxis es:

$GLOBALS[“nombre_var_global”];
o
$GLOBALS[‘nombre_var_global’];

La diferencia entre comillas dobles y simples es la ya comentada. Veamos un ejemplo de


cómo usar dicho vector:

<?php

$var=25;

function incrementa_var()
{
$GLOBALS[‘var’]++;
}

incrementa_var();
echo $var; // Esto dará como resultado: 26

Página 22/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

// Dentro del programa principal también podemos acceder a la variable $var usando el vector
// $GLOBALS. Es poco útil, pero totalmente válido:

echo $GLOBALS[‘var’]; // Volverá a imprimir 26


?>

También podemos crear variables globales dentro de las funciones usando cualquiera de los
dos métodos anteriores:

<?php <?php

// Ejemplo 1 // Ejemplo 2: sintaxis alternativa

function crea_global_var() function crea_global_var()


{ {
GLOBAL $var; $GLOBALS[‘var’]=25;
$var=25; }
}
// Creamos una variable global $var=25
// Creamos una variable global $var=25 crea_global_var();
crea_global_var();
// La imprimimos por pantalla
// La imprimimos por pantalla echo $var;
echo $var;
// Esto imprimirá por pantalla: 25
// Esto imprimirá por pantalla: 25
?> ?>

Es evidente que ambos ejemplos son válidos y darán por salida los mismos resultados.
También se podía haber usado en ambos casos echo $GLOBALS[‘var’]; en vez de echo $var;
dentro del programa principal.

Sólo queda comentar que aunque el uso de variables globales puede ser bastante útil,
siempre han sido una fuente de interminables problemas para los programadores. Por lo tanto, se
recomienda un uso prudente de las mismas.

Variables Estáticas

En pocas palabras, una variable estática es una es una especie variable local que no es
destruida cuando finaliza la función y que por tanto mantiene su valor. De esa forma si volvemos a
llamar a la función, dicha variable tendrá el valor mantenido. Para declarar una variable estática, sólo
tenemos que poner la palabra reservada STATIC delante del nombre de la variable e inicializarla al
valor que queremos que tenga inicialmente (valga la redundancia). Un ejemplo seguro que aclara su
uso:

<?php

function inc_contador()
{
STATIC $count = 0;
$count++;
echo $count;
}

inc_contador(); // Imprimirá 1
inc_contador(); // Imprimirá 2
inc_contador(); // Imprimirá 3

?>

Página 23/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

TYPE JUGGLING (JUEGO DE TIPOS)

PHP no requiere (o soporta) la declaración explícita del tipo en la declaración de variables; el


tipo de una variable se determina por el contexto en el que se usa esa variable. Esto quiere decir que
si se asigna un valor de cadena a la variable var, var se convierte en una cadena. Si después se
asigna un valor entero a la variable var, se convierte en una variable entera.

Un ejemplo de conversión de tipo automática en PHP es el operador suma '+'. Si cualquiera


de los operandos es un doble, entonces todos los operandos se evalúan como dobles, y el resultado
será un doble. En caso contrario, los operandos se interpretarán como enteros, y el resultado será
también un entero. Nótese que esto NO cambia los tipos de los operandos propiamente dichos, el
único cambio está en cómo se evalúan los operandos.

$foo = "0"; // $foo es una cadena (ASCII 48)


$foo++; // $foo es la cadena "1" (ASCII 49)
$foo += 1; // $foo ahora es un entero (2)
$foo = $foo + 1.3; // $foo ahora es un doble (3.3)
$foo = 5 + "10 Cerditos Pequeñitos"; // $foo es entero (15)
$foo = 5 + "10 Cerditos"; // $foo es entero (15)

Si quisiese probar cualquiera de los ejemplos de esta sección, puede cortar y pegar los
ejemplos e insertar la siguiente línea para ver por sí mismo lo que va ocurriendo:

echo "\$foo==$foo; el tipo es " . gettype( $foo ) . "<br>\n";

Si los últimos dos ejemplos anteriores parecen confusos, ver Conversión de cadenas.

Dado que PHP determina los tipos de las variables y los convierte (generalmente) según
necesita, no siempre resulta obvio de qué tipo es una variable dada en un momento concreto. PHP
incluye varias funciones que descubren de qué tipo es una variable. Son gettype(), is_long(),
is_double(), is_string(), is_array(), y is_object().

Si se desea obligar a que una variable sea evaluada con un tipo concreto, hay que hacer un
Forzado de tipos (que se verá a continuación). Si se desea cambiar el tipo de una variable, se puede
usar la función settype().

Nota: La posibilidad de una conversión automática a array no está definida actualmente.

$a = 1; // $a es un entero
$a[0] = "f"; // ¿ $a se convierte en un array, en el que $a[0] vale "f" ?

Aunque el ejemplo anterior puede parecer que claramente debería resultar en que $a se
convierta en un array dónde el primer elemento es 'f', consideremos esto:

$a = "1"; // $a es una cadena


$a[0] = "f"; // ¿Qué pasa con los índices de las cadenas? ¿Qué ocurre?

Dado que PHP soporta indexación en las cadenas mediante desplazamientos usando la
misma sintaxis que la indexación de arrays, el ejemplo anterior nos conduce a un problema: ¿debería
convertirse $a en un array cuyo primer elemento sea "f", o debería convertirse "f" en el primer carácter
de la cadena $a?
Por esta razón, tanto en PHP 3.0.12 como en PHP 4.0b3-RC4, el resultado de esta conversión
automática se considera que no está definido. Los parches se están discutiendo.

Por lo visto, si se desea reutilizar una variable para estos propósitos, se puede usar la función
unset() que se encarga de destruir la variable. Una vez destruida la podemos volver a crear
asignándole el valor que mejor nos convenga.

Página 24/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

TYPE CASTING (FORZADO DE TIPOS)

El forzado de tipos en PHP funciona como en C: el nombre del tipo deseado se escribe entre
paréntesis antes de la variable a la que se pretende forzar.

$foo = 10; // $foo es un entero


$bar = (double) $foo; // $bar es un doble

Los forzados de tipo permitidos son:

o (int), (integer) - fuerza a entero (integer)


o (real), (double), (float) - fuerza a doble (double)
o (string) - fuerza a cadena (string)
o (array) - fuerza a array (array)
o (object) - fuerza a objeto (object)

Nótese que las tabulaciones y espacios se permiten dentro de los paréntesis, así que los siguientes
ejemplos son funcionalmente equivalentes:

$foo = (int) $bar;


$foo = ( int ) $bar;

Es importante saber que cuando un real es forzado a convertirse en un entero, la parte


decimal es eliminada (no se redondea en función del valor decimal).

$var = 14.7;
$var = ( int ) var; // $var ahora valdrá 14

Puede no ser obvio que ocurrirá cuando se fuerce entre ciertos tipos. Por ejemplo, lo
siguiente debería ser tenido en cuenta. Cuando se fuerza el cambio de un escalar o una variable de
cadena a un array, la variable se convertirá en el primer elemento del array:

$var = 'ciao';
$arr = (array) $var;
echo $arr[0]; // produce la salida 'ciao'

Cuando se fuerza el tipo de una variable escalar o de una cadena a un objeto, la variable se
convertirá en un atributo del objeto; el nombre del atributo será 'scalar':

$var = 'ciao';
$obj = (object) $var;
echo $obj->scalar; // produce la salida 'ciao'

ASIGNACIÓN POR VALOR Y POR REFERENCIA

En PHP, las variables siempre se asignan por valor. Esto significa que cuando se asigna una
expresión a una variable, el valor íntegro de la expresión original se copia en la variable de destino.
Esto quiere decir que, por ejemplo, después e asignar el valor de una variable a otra, los cambios que
se efectúen a una de esas variables no afectará a la otra
1
PHP ofrece, además, otra forma de asignar valores a las variables: asignar por referencia .
Esto significa que la nueva variable simplemente referencia (en otras palabras, "se convierte en un
alias de" o "apunta a") la variable original. Los cambios a la nueva variable afectan a la original, y

1
PHP3 no permite este tipo de asignación. Esta novedad está incluida a partir de la versión 4.
Página 25/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

viceversa. Esto también significa que no se produce una copia de valores; por tanto, la asignación
ocurre más rápidamente. De todos modos, cualquier incremento de velocidad se notará sólo en los
bucles críticos cuando se asignen grandes arrays u objetos.

Para asignar por referencia, simplemente se antepone un ampersand (&) al comienzo de la variable
cuyo valor se está asignando (la variable fuente).

<?php
$postre = 'Tárta de arándanos'; // Asigna el valor 'Tárta de arándanos' a $postre
$p_postre = &$postre; // $p_postre es un puntero a la variable $postre.
echo "Mi postre preferido es: $postre"; // Daría por salida: Mi postre preferido es: Tárta de arándanos
$p_postre = ‘Tarta de queso’; // Cambiamos nuestro postre preferido
echo "Mi postre preferido es: $postre"; // Ahora la salida será: Mi postre preferido es: Tárta de queso
?>

Algo importante a tener en cuenta es que sólo las variables con nombre pueden ser
asignadas por referencia.

<?php
$foo = 25;
$bar = &$foo; // Esta es una asignación válida.
$bar = &(24 * 7); // Inválida; referencia una expresión sin nombre.

function test() {
return 25;
}

$bar = &test(); // Inválida.


?>

VARIABLES VARIABLES

A veces es conveniente tener nombres de variables variables. Dicho de otro modo, son
nombres de variables que se pueden establecer y usar dinámicamente. Una variable normal se
establece con una sentencia como:

$a = "hola";

Una variable variable toma el valor de una variable y lo trata como el nombre de una variable.
En el ejemplo anterior, hola, se puede usar como el nombre de una variable utilizando dos signos de
dólar. p.ej.

$$a = "mundo";

En este momento se han definido y almacenado dos variables en el árbol de símbolos de


PHP: $a, que contiene "hola", y $hola, que contiene "mundo". Es más, esta sentencia:

echo "$a ${$a}";

produce el mismo resultado que:

echo "$a $hola";

p.ej. ambas producen el resultado: hola mundo.

Para usar variables variables con arrays, hay que resolver un problema de ambigüedad. Si se
escribe $$a[1] el intérprete necesita saber si nos referimos a utilizar $a[1] como una variable, o si se
pretendía utilizar $$a como variable y el índice [1] como índice de dicha variable. La sintaxis para
Página 26/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

resolver esta ambiguedad es: ${$a[1]} para el primer caso y ${$a}[1] para el segundo. Veamos un
ejemplo:

<?php

$a = array (‘salchichas’, ‘bacon’, ‘patatas fritas’); // Vector de comida rápida

// Si ahora hacemos:
${$a[0]}=’frankfurt’;

/* Primero resolvemos lo que está entre llaves y luego se resuelve el resto. Es decir, creamos una
nueva variable de nombre el valor de la posición 0 y cuyo contenido es frankfurt. Lo de arriba es
equivalente a hacer: $salchichas = ‘frankfurt’; */

echo $salchicha; // la salida será: frankfurt


echo ${$a[0]}; // la salida también será: frankfurt

// Mientras que si ahora hacemos:


${$a}[0]=’bradburst’; // ¿Cuál es el nombre de la nueva variable?

/* Algo bastante raro y que no conviene hacer. {$a[0]} devuelve el valor de la posición 0 del vector $a
pero {$a} devuelve el tipo de la variable $a y que es Array. Por tanto creamos una nueva variable de
nombre Array (de tipo vector porque hemos puesto [0]) y en cuya posición 0 metemos la cadena
bradburst. Es decir, es como si hiciéramos directamente: $Array[0] = ‘bradburst’; */

echo $Array[0]; // La salida será: bradburst


echo ${$a}[0]; // La salida también será bradburst

?>

CONSTANTES

Se puede definir una constante usando la función define(). Una vez definida, no puede ser
modificada ni eliminada.

Solo se puede definir como constantes valores escalares (boolean, integer, float y string ).
Para obtener el valor de una constante solo es necesario especificar su nombre. A diferencia de las
variables, no se tiene que especificar el prefijo $. También se puede utilizar la función constant() para
obtener el valor de una constante. Podemos usar la función get_defined_constants() parar obtener
array asociativo con el nombre de todas las constantes y sus respectivos valores.

Nota: Las constantes y las variables (globales) se encuentran en un espacio de nombres distinto.
Esto implica que por ejemplo TRUE y $TRUE son diferentes.

Aunque se pude definir constantes en cualquier parte del código, es conveniente hacerlo al principio
del script para evitar problemas. Para poder usar un constante, previamente tiene que haver sido
declarada como tal. Si uno no se da cuenta y define la función más debajo de dónde la usa, el
intérprete considerará que la constante referencia no existe pudiendo dar lugar a resultados no
deseados. Usar la función defined() para comprobar la existencia de dicha constante.

Estas son las diferencias entre constantes y variables:


o Las constantes no son precedidas por un símbolo de dolar ($)
o Las constantes solo pueden ser definidas usando la función define() , nunca por simple
asignación
o Las constantes pueden ser definidas y accedidas sin tener en cuenta las reglas de alcance
del ámbito.
o Las constantes no pueden ser redefinidas o eliminadas después de establecerse,
o Las constantes solo puede albergar valores escalares

Página 27/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

<?php
define("PI", "3.141592");
echo PI; // Da como salida: 3.141592
?>

VARIABLES PREDEFINIDAS

PHP proporciona una gran cantidad de variables predefinidas a cualquier script que se
ejecute. De todas formas, muchas de esas variables no pueden estar completamente documentadas
ya que dependen de sobre qué servidor se esté ejecutando, la versión y configuración de dicho
servidor, y otros factores. Algunas de estas variables no estarán disponibles cuando se ejecute PHP
desde la línea de comandos.

Las siguientes variables son creadas por el propio PHP (a partir de PHP 4.1.0). Son
denominadas superglobales porque se puede acceder a ellas desde cualquier parte del código del
programa, da igual que estemos dentro de una función o dentro del método de un objeto.

$GLOBALS
Contiene una referencia a cada variable disponible en el espectro de las variables del script. Las
claves de esta matriz son los nombres de las variables globales. $GLOBALS existe desde PHP 3.

$_SERVER
Variables definidas por el servidor web ó directamente relacionadas con el entorno en donde el script
se esta ejecutando. Análoga a la antigua matriz $HTTP_SERVER_VARS (la cual está todavía
disponible, aunque no se use).

$_GET
Variables proporcionadas al script por medio de HTTP GET. Análoga a la antigua matriz
$HTTP_GET_VARS (la cual está todavía disponible, aunque no se use).

$_POST
Variables proporcionadas al script por medio de HTTP POST. Análoga a la antigua matriz
$HTTP_POST_VARS (la cual está todavía disponible, aunque no se use).

$_COOKIE
Variables proporcionadas al script por medio de HTTP cookies. Análoga a la antigua matriz
$HTTP_COOKIE_VARS (la cual está todavía disponible, aunque no se use).

$_FILES
Variables proporcionadas al script por medio de la subida de ficheros via HTTP . Análoga a la antigua
matriz $HTTP_POST_FILES (la cual está todavía disponible, aunque no se use). Vea también
Subiendo ficheros por método POST para más información.

$_ENV
Variables proporcionadas al script por medio del entorno. Análoga a la antigua matriz
$HTTP_ENV_VARS (la cual está todavía disponible, aunque no se use).

$_REQUEST
Variables proporcionadas al script por medio de cuaquier mecanismo de entrada del usuario y por lo
tanto no se puede confiar en ellas. La presencia y el orden en que aparecen las variables en esta
matriz es definido por la directiva de configuración variables_order. Esta matriz no tiene un análogo
en versiones anteriores a PHP 4.1.0. Ver también import_request_variables().

Nota: Cuando se utiliza la linea de comandos aparecerán dos nuevas variables globales llamadas
$argv y $argc.

$_SESSION
Variables registradas en la sesión del script. Análoga a la antigua matriz $HTTP_SESSION_VARS (la
cual está todavía disponible, aunque no se use).
Las antiguas matrices $HTTP_*_VARS siguen existiendo pero tienen un comportamiento
distinto. No son superglobales y por tanto, si se quiere acceder a ellas desde una función o un
Página 28/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

método, se ha de poner delante la palabra reservada GLOBAL. Aunque inicialmente contienen la


misma información, son variables completamente distintas. Actualmente están en desuso y se
recomienda usar las primeras.

Si register_globals está activado, PHP registrará, además de las matrices anteriores, un


gran número de variables adicionales. En esencia, aparecerá una variable por cada elemento
contenido en los vectores anteriores.

Si se desea ver una lista completa de las variables del servidor, del entorno y de PHP basta hacer:

while ( list($var, $valor) = each($GLOBALS))


echo “<br>$var => $valor”;

Saldrá algo como esto (Realizado sobre un servidor Apache en Windows XP):

ALLUSERSPROFILE => C:\\Documents and Settings\\All Users


APPDATA => C:\\Documents and Settings\\Gabi\\Datos de programa
CLIENTNAME => Console
CommonProgramFiles => C:\\Archivos de programa\\Archivos comunes
COMPUTERNAME => ELANDAR
ComSpec => C:\\WINDOWS\\system32\\cmd.exe
HOMEDRIVE => C:
HOMEPATH => \\Documents and Settings\\Gabi
LOGONSERVER => \\\\ELANDAR
NUMBER_OF_PROCESSORS => 1
OS => Windows_NT
Path => C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem
PATHEXT => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE => x86
PROCESSOR_IDENTIFIER => x86 Family 6 Model 5 Stepping 2, GenuineIntel
PROCESSOR_LEVEL => 6
PROCESSOR_REVISION => 0502
ProgramFiles => C:\\Archivos de programa
PROMPT => $P$G
SESSIONNAME => Console
SystemDrive => C:
SystemRoot => C:\\WINDOWS
TEMP => C:\\DOCUME~1\\Gabi\\CONFIG~1\\Temp
TMP => C:\\DOCUME~1\\Gabi\\CONFIG~1\\Temp
USERDOMAIN => ELANDAR
USERNAME => Gabi
USERPROFILE => C:\\Documents and Settings\\Gabi
windir => C:\\WINDOWS
COMSPEC => C:\\WINDOWS\\system32\\cmd.exe
DOCUMENT_ROOT => c:/phpdev/www/
HTTP_ACCEPT => image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-
flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
HTTP_ACCEPT_ENCODING => gzip, deflate
HTTP_ACCEPT_LANGUAGE => es
HTTP_CONNECTION => Keep-Alive
HTTP_HOST => localhost
HTTP_REFERER => http://localhost/public/pruebas/
HTTP_USER_AGENT => Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
PATH => C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem
REMOTE_ADDR => 127.0.0.1
REMOTE_PORT => 1387
SCRIPT_FILENAME => c:/phpdev/www/public/pruebas/prueba1.php
SERVER_ADDR => 127.0.0.1
SERVER_ADMIN => server_admin@httpd.conf
SERVER_NAME => localhost
SERVER_PORT => 80

Página 29/115
Iniciación a PHP 4 2.- TIPOS DE DATOS Y VARIABLES

SERVER_SIGNATURE =>
Apache/1.3.27 Server at localhost Port 80

SERVER_SOFTWARE => Apache/1.3.27 (Win32) PHP/4.2.3


WINDIR => C:\\WINDOWS
GATEWAY_INTERFACE => CGI/1.1
SERVER_PROTOCOL => HTTP/1.1
REQUEST_METHOD => GET
QUERY_STRING =>
REQUEST_URI => /public/pruebas/prueba1.php
SCRIPT_NAME => /public/pruebas/prueba1.php
PATH_TRANSLATED => c:/phpdev/www/public/pruebas/prueba1.php
PHP_SELF => /public/pruebas/prueba1.php
argv => Array
argc => 0
HTTP_POST_VARS => Array
_POST => Array
HTTP_GET_VARS => Array
_GET => Array
HTTP_COOKIE_VARS => Array
_COOKIE => Array
HTTP_SERVER_VARS => Array
_SERVER => Array
HTTP_ENV_VARS => Array
_ENV => Array
HTTP_POST_FILES => Array
_FILES => Array
_REQUEST => Array
GLOBALS => Array
valor => Array
var => valor

Nota: Las variables en negrita, son variables que ha creado el propio script.

Página 30/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

3.- OPERADORES Y ESTRUCTURAS DE CONTROL


En este capítulo introduciremos aspectos cruciales de cualquier lenguaje de programación:
expresiones, operadores y estructuras de control. El conocimiento de dichos aspectos es totalmente
imprescindible para poder construir aplicaciones grandes y complejas en PHP puesto que, al fin y al
cabo, acabarán siendo gran parte de nuestro código. Si lenguajes tales como C o JAVA te resultan
familiares, este capítulo será más bien un repaso a dichos aspectos.

3.1.- Expresiones
Una expresión es, básicamente, a un línea de código representando una acción en un
programa. Todas las expresiones constan de al menos un operando y uno o más operadores.

OPERANDOS

Un operando es una de las entidades que es manipulada dentro de una expresión. Un


operando válido es cualquiera de los tipos de datos visto en el capítulo 2.

$a++; // $a es un operando
$sum = $valor1 + $valor2 // $sum, $valor1 y $valor2 son operandos

OPERADORES

Un operador es un símbolo que especifica una acción en una expresión. Muchos de los
operadores que se verán son sencillos y pueden resultar familiares. Es importante comentar que la
conversión automática de tipos que PHP posee, convertirá los tipos de los operandos según el tipo de
operador utilizado.

$a++; // ++ es un operador
$sum = $valor1 + $valor2 // = y + son operadores

La precedencia y la asociatividad de operadores es significativa en todo lenguaje de


programación y es algo que veremos dentro de este capítulo.

3.2.- Operadores
PRECEDENCIA DE OPERADORES

La precedencia de operadores especifica cómo se agrupan las expresiones. Por ejemplo, en


la expresión 1 + 5 * 3, la respuesta es 16 y no 18 porque el operador de multiplicación ("*") tiene una
mayor precedencia que el de adición ("+").
La siguiente tabla lista la precedencia de operadores, indicándose primero los de menor precedencia.

Asociatividad Operadores
izquierda ,
izquierda or
izquierda xor
izquierda and
derecha print
izquierda = += -= *= /= .= %= &= |= ^= ~= <<= >>=
izquierda ?:
izquierda ||
izquierda &&
izquierda |
izquierda ^
izquierda &
Página 31/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

no asociativo == != ===
no asociativo < <= > >=
izquierda << >>
izquierda +-.
izquierda */%
derecha ! ~ ++ -- (int) (double) (string) (array) (object) @
derecha [
no asociativo new
no asociativo ()

La asociatividad de un operador indica en qué orden son evaluados las operaciones con el
mismo grado de precedencia. La asociatividad puede ser realizada en dos direcciones de izquierda a
derecha o de derecha a izquierda.

OPERADORES ARITMÉTICOS

Son los operadores más sencillos y más comunes. Suelen ser usados bastante dentro de
cualquier programa.

ejemplo nombre resultado


$a + $b Adición Suma de $a y $b.
$a - $b Substracción Diferencia entre $a y $b.
$a * $b Multiplicación Producto de $a and $b.
$a / $b División Cociente de $a entre $b.
$a % $b Módulo Resto de $a dividido entre $b.

Algunas notas importantes:

o El operador Módulo sólo tiene sentido si ambos operandos son números enteros pues, a fin
de cuentas, devuelve el resto de la división entera. Por tanto el tipo del resultado también
será un entero.
o El operador división puede funcionar de dos formas dependiendo del tipo de los operandos.
Si los dos operandos son números enteros, entonces dará por resultado el cociente de la
división entera (es decir, sin decimales) y por tanto el resultado también será un número
entero. En cambio, si alguno de los dos operandos en un número en coma flotante, el
resultado es la división entre números reales y devolverá un real (es decir, un número con
decimales).

OPERADORES DE ASIGNACIÓN

El operador básico de asignación es "=" (distinto al operador de comparación "igual que").


Pero no. Significa, por tanto, que el operando de la izquierda toma el valor de la expresión a la
derecha.

El valor de una expresión de asignación es el propio valor asignado. Esto es, el valor de "$a =
3" es 3. Esto permite hacer cosas curiosas como:

$a = ($b = 4) + 5; // ahora $a es igual a 9, y $b vale 4.

Además del operador básico de asignación, existen los "operadores combinados" para todas
las operaciones aritméticas y de cadenas que sean binarias. Este operador combinado te permite, de
una sola vez, usar una variable en una expresión y luego establecer el valor de esa variable al
resultado de la expresión.

ejemplo nombre resultado


$a = $b Asignación $a toma el valor de $b
$a += $b Suma y asignación $a = $a + $b
$a *= $b Multiplicación y asignación $a = $a * $b
$a /= $b División y asignación $a = $a / $b
$a .= $b Concatenación y asignación $a = $a . $b

Página 32/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

Veamos algunos ejemplos:

$a = 3;
$a += 5; // establece $a a 8, como si hubiésemos escrito: $a = $a + 5;
$b = "Hola ";
$b .= "Ahí!"; // establece $b a "Hola Ahí!", igual que si hiciésemos $b = $b . "Ahí!";

Fíjate en que la asignación realiza una nueva copia de la variable original (asignación por
valor), por lo que cambios a la variable original no afectan a la copia.

OPERADORES DE INCREMENTO/DECREMENTO

PHP soporta los operadores de predecremento y post incremento al estilo de C.

ejemplo nombre efecto


++$a Preincremento Incrementa $a en uno y después devuelve $a.
$a++ Postincremento Devuelve $a y después incrementa $a en uno.
--$a Predecremento Decrementa $a en uno y después devuelve $a.
$a-- Postdecremento Devuelve $a y después decrementa $a en uno.

He aquí un listado de ejemplo:

<?php
echo "<h3>Postincremento</h3>";
$a = 5;
echo "Debería ser 5: " . $a++ . "<br>\n";
echo "Debería ser 6: " . $a . "<br>\n";

echo "<h3>Preincremento</h3>";
$a = 5;
echo "Debería ser 6: " . ++$a . "<br>\n";
echo "Debería ser 6: " . $a . "<br>\n";

echo "<h3>Postdecremento</h3>";
$a = 5;
echo "Debería ser 5: " . $a-- . "<br>\n";
echo "Debería ser 4: " . $a . "<br>\n";

echo "<h3>Predecremento</h3>";
$a = 5;
echo "Debería ser 4: " . --$a . "<br>\n";
echo "Debería ser 4: " . $a . "<br>\n";
?>

OPERADORES LÓGICOS

Al igual que los operadores aritméticos, los operadores lógicos ocupan un gran protagonismo
dentro de cualquier aplicación pues proporcionan un método para la toma de decisiones basado en el
cumplimiento o no de ciertas condiciones.

ejemplo nombre resultado


$a and $b Y Cierto si tanto $a como $b son ciertos.
$a or $b O Cierto si $a o $b son ciertos.
$a xor $b O exclusiva Cierto si $a es cierto o $b es cierto, pero no ambos a la vez.
! $a Negación Cierto si $a no es cierto.
$a && $b Y Cierto si tanto $a como $b son ciertos.
$a || $b O Cierto si $a o $b son ciertos.

Página 33/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

La razón de las dos variaciones de "y" y "o" es que operan con distinta precedencia (ver
Precedencia de Operadores.)

OPERADORES DE COMPARACIÓN

Los operadores de comparación, como su nombre indica, permiten comparar dos valores.

Operadores de Comparación
ejemplo nombre resultado
$a == $b Igualdad Cierto si $a es igual a $b.
$a === $b Identidad Cierto si $a es igual a $b y si son del mismo tipo (sólo PHP4)
$a != $b Desigualdad Cierto si $a no es igual a $b.
$a < $b Menor que Cierto si $a es estrictamente menor que $b.
$a > $b Mayor que Cierto si $a es estrictamente mayor que $b.
$a <= $b Menor o igual que Cierto si $a es menor o igual que $b.
$a >= $b Mayor o igual que Cierto si $a es mayor o igual que $b.

Otro operador condicional es el operador "?:" (o ternario), que funciona como en C y otros muchos
lenguajes.

(expr1) ? (expr2) : (expr3);

La expresión toma el valor expr2 si expr1 se evalúa a cierto, y expr3 si expr1 se evalúa a falso.

OPERADORES BIT A BIT

Los operadores bit a bit te permiten activar o desactivar bits individuales de un entero.

ejemplo nombre resultado


$a & $b Y Se activan los bits que están activos tanto en $a como $b.
$a | $b O Se activan los bits que están activos en $a o que lo están en $b.
$a ^ $b Xor ("o exclusiva") Se activan los bits que están activos en $a o en $b pero no en
ambos a la vez.
~ $a No Se activan los bits que no están activos en $a.
$a << Desplazamiento a Desplaza los bits de $a, $b posiciones hacia la izquierda (por
$b la izquierda aritmética binaria, cada posición desplazada equivale a multiplicar
por dos el valor de $a)
$a >> Desplazamiento a Desplaza los bits de $a, $b posiciones hacia la derecha (por
$b la derecha aritmética binaria, cada posición desplazada equivale a dividir entre
dos el valor de $a)

Nota: Un bit activo es un bit a 1.

OPERADOR DE EJECUCIÓN

PHP soporta un operador de ejecución: el apóstrofe invertido (``). ¡Fíjate que no son
apostrofes normales! PHP intentará ejecutar la instrucción contenida dentro de los apóstrofes
invertidos como si fuera un comando del shell; y su salida devuelta como el valor de esta expresión
(es decir, no tiene por qué ser simplemente volcada como salida, puede asignarse a una variable).

$output = `ls -al`;


echo "<pre>$output</pre>";

Ver también system(), passthru(), exec(), popen(), y escapeshellcmd().

Página 34/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

OPERADORES DE CADENAS

Hay dos operadores de cadenas. El primero es el operador de concatenación ('.'), que


devuelve el resultado de concatenar sus operandos izquierdo y derecho. El segundo es el operador
de concatenación y asignación ('.='), visto ya en los operadores de asignación.

$a = "Hola ";
$b = $a . "Mundo!"; // ahora $b contiene "Hola Mundo!"

$a = "Hola ";
$a .= "Mundo!"; // ahora $a contiene "Hola Mundo!"

3.3.- Estructuras de Control


Todo archivo de comandos PHP se compone de una serie de sentencias. Una sentencia
puede ser una asignación, una llamada a función, un bucle, una sentencia condicional e incluso una
sentencia que no haga nada (una sentencia vacía). 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. En este capítulo se
describen los diferentes tipos de sentencias.

if

La construcción if es una de las más importantes características de muchos lenguajes,


incluido PHP. Permite la ejecución condicional de fragmentos de código. PHP caracteriza una
estructura if que es similar a la de C:

if (expr)
sentencia

Como se describe en la sección sobre expresiones, expr se evalúa a su valor condicional. Si


expr se evalúa como TRUE, PHP ejecutará la sentencia, y si se evalúa como FALSE la ignorará.

El siguiente ejemplo mostraría a es mayor que b si $a fuera mayor que $b:

if ($a > $b)


print "a es mayor que b";

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:

if ($a > $b) {


print "a es mayor que b";
$b = $a;
}

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 del
programa.

else

A menudo queremos ejecutar una sentencia si se cumple una cierta condicion, y una
sentencia distinta si la condición no se cumple. Esto es para lo que sirve else. La sentencia else se
Página 35/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

ejecuta solamente si la expresión if se evalúa 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:

if ($a > $b) {


print "a es mayor que b";
} else {
print "a NO es mayor que b";
}

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úe
como FALSE. No obstante, a diferencia de else, ejecutará esa expresión alternativa solamente si la
expresión condicional elseif se evalúa como TRUE. Por ejemplo, el siguiente código mostraría a es
mayor que b, a es igual a b o a es menor que b:

if ($a > $b) {


print "a es mayor que b";
}
elseif ($a == $b) {
print "a es igual que b";
}
else {
print "a es mayor que b";
}

Pueden haber varios elseif’s 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).

En resumen, la sentencia elseif se ejecuta sólo si la expresión if precedente y cualquier


expresión elseif precedente se evalúan como FALSE, y la expresión elseif actual se evalúa como
TRUE.

Sintaxis Alternativa de Estructuras de Control

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.

<?php if ($a==5): ?>


A es igual a 5
<?php endif; ?>

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;

Página 36/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

while

Los bucles while son los tipos de bucle más simples en PHP. Se comportan como su como
en C. La forma básica de una sentencia while es:

while (expr) sentencia

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). Puede ocurrir que la expresión
while se evalúe como FALSE desde el principio del todo, en ese caso 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:

while (expr): sentencia ... endwhile;

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;

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).

Hay una sola sintaxis para los bucles do..while:

$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.
Página 37/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

Los usuarios avanzados de C pueden estar familiarizados con un uso distinto del bucle
do..while, para permitir parar la ejecución en medio de los bloques de código, encapsulándolos con
do..while(0), y usando la sentencia break. El siguiente fragmento de código demuestra esto:

do {
if ($i < 5) {
print "i no es lo suficientemente grande";
break;
}
$i *= $factor;
if ($i < $limite_minimo) {
break;
}
print "i es correcto";
...procesa i...
} while(0);

for

Los bucles for son los bucles más complejos en PHP. Se comportan como en C. La sintaxis
de un bucle for es:

for (expr1; expr2; expr3) sentencia

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.
Al final de cada iteración, se evalúa (ejecuta) expr3.
Cada una de las expresiones puede estar vacía. Que expr2 esté vacía significa que el bucle debería
correr indefinidamente (PHP implícitamente 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 */

for ($i = 1; $i <= 10; $i++) {


print $i;
}

/* ejemplo 2 */

for ($i = 1;;$i++) {


if ($i > 10) {
break;
}
print $i;
}

/* ejemplo 3 */

$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
}

Página 38/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

/* ejemplo 4 */

for ($i = 1; $i <= 10; print $i, $i++) ;

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.

for (expr1; expr2; expr3): sentencia; ...; endfor;

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:

foreach(nombre_array as $value) sentencia


foreach(nombre_array as $key => $value) sentencia

LA VEREMOS CON MÁS DETALLE EN EL TEMA DE VECTORES JUNTO CON LA FUNCIÓN LIST
Y EACH

La primera forma recorre el array dado por nombre_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: Cuando foreach comienza su primera ejecución, el puntero interno a la lista (array) se reinicia
automáticamente al primer elemento del array. Esto significa que no se necesita llamar a reset()
antes de un bucle foreach.

Nota: Hay que tener en cuenta que foreach funciona 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.

Puede haber observado que las siguientes son funcionalidades idénticas:

reset( $arr );
while( list(,$value ) = each( $arr ) ) {
echo "Valor: $value<br>\n";
}

foreach( $arr as $value ) {


echo "Valor: $value<br>\n";
}

Las siguientes también son funcionalidades idénticas:

reset( $arr );
while( list( $key, $value ) = each( $arr ) ) {
echo "Key: $key; Valor: $value<br>\n";
}

foreach( $arr as $key => $value ) {


echo "Key: $key; Valor: $value<br>\n";
Página 39/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

Algunos ejemplos más para demostrar su uso:

/* foreach ejemplo 1: sólo valor*/


$a = array(1, 2, 3, 17);

foreach($a as $v) {
print "Valor actual de \$a: $v.\n";
}

/* foreach ejemplo 2: valor (con clave impresa para ilustrar) */


$a = array(1, 2, 3, 17);

$i = 0; /* sólo para propósitos demostrativos */

foreach($a as $v) {
print "\$a[$i] => $k.\n";
}

/* foreach ejemplo 3: clave y valor */


$a = array(
"uno" => 1,
"dos" => 2,
"tres" => 3,
"diecisiete" => 17
);

foreach($a as $k => $v) {


print "\$a[$k] => $v.\n";
}

switch

La sentencia switch es similar a una serie de sentencias if en la misma expresión. En


muchas ocasiones, se quiere comparar la misma variable (o expresión) con muchos 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";

Página 40/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

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";
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 condició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";
}

Página 41/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

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.

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;

break

break escapa de la estructuras de control iterantes (bucles) actuales: for, while, do..while, o
switch. break accepta un parámetro opcional, el cual determina cuantas estructuras de control hay
que escapar.

/* Sin usar el argumento opcional. */

$arr = array ('uno', 'dos', 'tres', 'cuatro', 'stop', 'cinco');


while (list (, $val) = each ($arr)) {
if ($val == 'stop') {
break; /* También hubiera valido poner 'break 1;' */
}
echo "$val<br>\n";
}

/* Usando el argumento opcional. */

$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "Estamos en \$i=5 <br>\n";
break 1; /* Salir solo del switch. */
case 10:
echo "Estamos en \$i=10; saliéndonos <br>\n";
break 2; /* Salir del switch y del while. */
default:
break;
}
}

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 acepta un parámetro
opcional, el cual determina cuantos niveles (bucles) hay que saltar antes de continuar con la
ejecución.

Página 42/115
Iniciación a PHP 4 3.- OPERADORES Y ESTRUCTURAS DE CONTROL

$i = 0;
while ($i++ < 5)
{
echo "Fuera<br>\n";
while (1)
{
echo "-Medio<br>\n";
while (1)
{
echo "--Dentro<br>\n";
continue 3;
}
echo "Ésto nunca saldrá.<br>\n";
}
echo "Ni tampoco ésto.<br>\n";
}

Página 43/115
Iniciación a PHP 4 4.- FUNCIONES

4.- FUNCIONES

4.1.- ¿Qué es una función?


Una función es una sección de código con un propósito específico a la cuál se le asigna un
único nombre. Esto permite reutilizar dicha sección de código en varios puntos del programa sin más
que llamar a dicha función. Esto es extremadamente útil pues permite que dicha sección de código
sea escrita una única vez lo cual facilita el mantenimiento. También incrementa la legibilidad del
código y permite la reutilización de código, posteriormente, en otras aplicaciones.

4.2.- Definición e invocación de funciones


La creación de funciones en PHP es un proceso bastante sencillo. Se pueden crear funciones
desde cualquier punto del código del programa. Sin embargo, por propósitos organizativos, suele
resultar conveniente colocar todas las funciones de un script al principio del mismo. Otro método
alternativo bastante interesante es el de colocar todas las funciones dentro de un fichero distinto (al
que llamaremos librería y que describiremos más adelante). Esto es de lo más conveniente puesto
que permite reutilizar funciones en aplicaciones totalmente distintas, sin necesidad de duplicar el
código y sin correr el riesgo de que una función esté actualizada en una aplicación y en otra no.

Las sintaxis de una función es la que sigue:

function foo ($arg_1, $arg_2, ..., $arg_n) {


echo "Función de ejemplo.\n";
return $retval;
}

El nombre de una función debe seguir las reglas descritas en el capítulo 2 respecto a los
identificadores.

Debido a la flexibilidad de PHP respecto a que no es necesario definir los tipos de las
variables, tampoco es necesario especificar el tipo de los argumentos que son pasados a una función.
Es cierto que esto tiene sus ventajas, pero hay que tener en cuenta que el motor de PHP no hará
comprobaciones para saber si la función podrá manejar los tipos de datos que se le han pasado,
pudiendo llevar a resultados inesperados.

Algunas notas importantes:

o Cualquier instrucción válida de PHP puede aparecer en el cuerpo de la función, incluso otras
funciones y definiciones de clases.
o En PHP3, las funciones deben definirse antes de que se referencien. En PHP4 no existe tal
requerimiento.
o PHP no soporta la sobrecarga de funciones, y tampoco es posible redefinir u ocultar
funciones previamente declaradas.
o PHP3 no soporta un número variable de parámetros, aunque sí soporta parámetros por
defecto. PHP4 soporta ambos y las referencias de las funciones func_num_args(),
func_get_arg(), y func_get_args() (Todo esto se verá más adelante).

4.3.- Anidamiento de Funciones


PHP permite la declaración de funciones dentro de funciones. Sin embargo esto no produce
que éstas últimas estén protegidas, es decir, que sólo puedan ser usadas dentro de la función dónde
has sido declaradas. PHP nos soporta el concepto de funciones protegidas. Cualquier función,
independientemente de dónde haya sido declarada, puede ser llamada desde cualquier parte del
programa. De hecho, las funciones anidadas no heredan los parámetros de entrada de la función
padre dónde fueron declaradas. De todos modos, el anidamiento de funciones puede ser útil para
propósitos de mantenimiento de código y claridad.

Página 44/115
Iniciación a PHP 4 4.- FUNCIONES

Aunque las funciones anidadas no están protegidas y pueden ser utilizadas desde cualquier
punto del programa, no pueden ser llamadas hasta que su función padre haya sido llamada.

<?php

function pie()
{
function copyright($nombre,$ano,$correo)
{
echo "<br><a href='mailto:$correo'>$nombre $ano</a><br>";
}

$alineamiento_ini="<center>";
$alineamiento_fin="</center>";
$home="<a href='home.php'>Inicio</a>";
$links="<a href='enlaces.php'>Enlaces</a>";
$contact="<a href='contacta.php'>Contacta con nosotros</a>";

echo <<<HTML
$alineamiento_ini\n
$home | $links | $contact\n
$alineamiento_fin\n
HTML;

echo "$alineamiento_ini";
copyright("Gabriel Merín","2002","gabmecu@inf.upv.es");
echo "$alineamiento_fin";
}

// Llamada a la función copyright antes de llamar a su función padre


copyright("Gabriel Merín","2002","gabmecu@inf.upv.es");
/*
devuelve un error:
Fatal error: Call to undefined function: copyright() in c:\phpdev\www\pruebas\fciones_anidadas.php on
line 28
*/

// Llamada a la función padre


pie();

// Ahora ya podemos llamar a la función copyright


copyright("Gabriel Merín","2002","gabmecu@inf.upv.es");
?>

4.4.- Funciones recursivas


El hecho de que una función se llame a sí misma una vez y otra, es lo que se denomina
recursividad. Es una poderosa herramienta que, usada convenientemente, permite la resolución de
problemas relativamente complejos de una forma rápida y sencilla. Los algoritmos de búsqueda
(como la búsqueda binaria/dicotómica), ordenación (Fusión, Quicksort, etc..) y creación de fractales
son buenos ejemplos de su utilidad. PHP soporta perfectamente el uso de funciones recursivas.

Veamos el típico ejemplo de calcular el factorial de un número de forma recursiva e iterativa:

<?php

function fact_recur($num)
{
// Cálculo del factorial de forma recursiva
if ($num==0) return 1;

Página 45/115
Iniciación a PHP 4 4.- FUNCIONES

else return ($num*fact_recur($num-1));


}

function fact_iter($num)
{
// Cálculo del factorial de forma iterativa
$result=1;
for($i=$num; $i>0; $i--) $result*=$i;
return $result;
}

// Número del cual queremos calcular el factorial


$num=5;

// Ambos factoriales deben proporcionar el mismo resultado


echo "El factorial de $num es: " , fact_recur($num) , " (forma recursiva)<br>\n";
echo "El factorial de $num es: " , fact_iter($num) , " (forma iterativa)<br>\n";

?>

Como se puede observar, la forma recursiva suele ser mucho sencilla de implementar. Sólo
es necesario fijar un caso base e ir haciendo llamadas recursivas hasta alcanzar el caso base. La
forma iterativa (sencilla en este caso) suele ser más complicada de implementar y con bastantes más
líneas de código. Pese a que suele ser más deseable usar algoritmos iterativos por un tema de
eficiencia computacional, algunos algoritmos requieren una implementación recursiva debido a la alta
complejidad que puede resultar la implementación iterativa.

4.5.- Parámetros 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. Además, PHP4 permite una lista de longitud variable de parámetros. Un
efecto similar puede conseguirse en PHP3 pasando un array de parámetros a la función:

function toma_array($input) {
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}

PASAR PARÁMETROS POR REFERENCIA

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 pon_mas_texto(&$string) {
$string .= ' y algo más.';
}
$str = 'Esto es una cadena, ';
pon_mas_texto($str);
echo $str; // Saca 'Esto es una cadena, 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:

Página 46/115
Iniciación a PHP 4 4.- FUNCIONES

function foo ($bar) {


$bar .= ' y algo más.';
}
$str = 'Esto es una cadena, ';
foo ($str);
echo $str; // Saca 'Esto es una cadena, '
foo (&$str);
echo $str; // Saca 'Esto es una cadena, y algo más.'

PARÁMETROS POR DEFECTO

Una función puede definir valores por defecto para los parámetros escalares estilo C++:

function haz_cafe ($tipo = "cappucino") {


return "Hacer una taza de $tipo.\n";
}
echo haz_cafe ();
echo haz_cafe ("espresso");

La salida del fragmento anterior es:

Hacer una taza de cappucino.


Hacer una taza de espresso.

El valor por defecto tiene que ser una expresión constante, y no una variable o miembro de
una clase.

Destacar que cuando se usan parámetros por defecto, estos tienen que estar a la derecha de
cualquier parámetro sin valor por defecto; de otra manera las cosas no funcionarán de la forma
esperada. Considera el siguiente fragmento de código:

function haz_yogurt ($tipo = "acidophilus", $sabor) {


return "Haciendo un bol de $tipo $sabor.\n";
}

echo haz_yogurt ("mora"); // No funcionará de la manera esperada

La salida del ejemplo anterior es:

Warning: Missing argument 2 in call to haz_yogurt() in


/usr/local/etc/httpd/htdocs/php3test/functest.html on line 41
Haciendo un bol de mora.

Y ahora, compáralo con:

function haz_yogurt ($sabor, $tipo = "acidophilus") {


return "Haciendo un bol de $tipo $sabor.\n";
}

echo haz_yogurt ("mora"); // funciona como se esperaba

La salida de este ejemplo es:

Haciendo un bol de acidophilus mora.

Página 47/115
Iniciación a PHP 4 4.- FUNCIONES

LISTA DE LONGITUD VARIABLE DE PARÁMETROS

PHP4 soporta las listas de longitud variable de parámetros en las funciones definidas por el
usuario. Es realmente fácil, usando las funciones func_num_args(), func_get_arg(), y
func_get_args(). 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.

func_num_args
(PHP 4 )
func_num_args -- Devuelve el número de argumentos pasados a la función.

Descripción:

int func_num_args ( void )

Devuelve el número de argumentos pasados a la función actual definida por el usuario.


func_num_args() generará un aviso si es llamada desde fuera de la definición de la función.

<?php
function print_num_args() {
$numargs = func_num_args();
echo "Número de argumentos: $numargs\n";
}
print_num_args( 1, 2, 3 ); // Saca por pantalla 'Número de argumentos: 3'
?>

func_get_arg
(PHP 4 )

func_get_arg -- Devuelve un elemento de la lista de argumentos.

Descripción:

int func_get_arg ( int arg_num)

Devuelve el argumento que está en la posición arg_num en la lista de argumentos de una función
definida por el usuario. Los argumentos de la función se cuentan comenzando por la posición cero.
func_get_arg() generará un aviso si se llama desde fuera de la definición de la función.
Si arg_num es mayor que el número de argumentos pasados realmente, se generará un aviso y
func_get_arg() devolverá FALSE.
<?php
function print_args() {
$numargs = func_num_args();
for ($i=0; $i<$numargs; $i++) echo “Argumento $I: “,func_get_arg($i),”<br>\n”;
}
print_args( 1, 2, 3 ); // Saca por pantalla 'Número de argumentos: 3'
?>

func_get_args
(PHP 4 )

func_get_args -- Devuelve un array que contiene la lista de argumentos de una función.

Descripción:

int func_get_args ( void )


Devuelve un array en el que cada elemento es el miembro correspondiente de la lista de argumentos
de la función definida por el usuario actual. func_get_args() generará un aviso si es llamada desde
fuera de la definición de la función.

Página 48/115
Iniciación a PHP 4 4.- FUNCIONES

<?php
function get_args() {
$numargs = func_num_args();

$arg_list = func_get_args();
for ( $i = 0; $i < $numargs; $i++ ) {
echo "El argumento $i vale: " . $arg_list[$i] . "<br>\n";
}
}

foo( 1, 2, 3 );

DEVOLVER VALORES

Los valores se retornan usando la instrucción opcional return. Puede devolverse cualquier
tipo de valor, incluyendo listas y objetos.

function cuadrado ($num) {


return $num * $num;
}
echo cuadrado (4); // saca '16'.

No puedes devolver múltiples valores desde una función, pero un efecto similar se puede
conseguir devolviendo una lista.

function numeros() {
return array (0, 1, 2);
}
list ($cero, $uno, $dos) = numeros();

Aunque puede resultar más cómodo quedarnos con el vector (pudiera ser que no supiéramos
cuántos elementos nos va a devolver la función):

function numeros() {
return array (0, 1, 2);
}
$vect = numeros();

4.6.- 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 nada() {
echo "Estamos dentro de la función nada()<br>\n";
}

function algo( $arg = ‘’ ) {


echo "Estamos dentro de la función algo() a la cual se le ha pasado el parámetro '$arg'.<br>\n";
}

Página 49/115
Iniciación a PHP 4 4.- FUNCIONES

$func = 'nada';
$func(); // Esto sacará por pantalla: Estamos dentro de la función nada()
$func = 'algo;
$func( 'test' ); // Esto sacará por pantalla:
// Estamos dentro de la función algo() a la cual se le ha pasado el parámetro 'test'.
?>

4.7.- Acceso a variables globales desde funciones


Algo extremadamente importante y dónde uno no suele caer es en el modo de acceder a las
variables globales desde funciones. El acceder de forma inapropiada a una variable global dentro de
una función llevará a que la función no se comporte de la forma deseada.

En el punto 2.9.- VARIABLES – ÁMBITO DE LAS VARIABLES – Variables Globales se


explicó el procedimiento para acceder a las variables globales dentro de funciones. Es importante no
olvidarlo o de lo contrario nuestras funciones no se comportarán de la forma esperada y no sabremos
el por qué.

4.8.- Creación De Librerías De Funciones


Las librerías de funciones son una de las maneras más eficientes a la hora de construir
aplicaciones.

Por ejemplo, si uno ya ha creado un serie de funciones para obtener y tratar determinados
ficheros dentro de un directorio, es probable que esas funciones nos puedan resultar de utilidad en
varias aplicaciones o scripts. En vez de estar continuamente copiando y pegando el código de dichas
funciones, es mucho más interesante meter todas esas funciones dentro de un fichero aparte. A
continuación se le puede dar a ese fichero el nombre lib_manejo_ficheros.php e incluirlo en todos los
scripts que requieran el uso de dichas funciones.

Ejemplo:

<?php
// Librería de manejo de ficheros
// Última actualización: 20-4-2003

function saca_ficheros($dir)
{
...
}

function saca_directorios($dir)
{
...
}

function saca_todos_fich($dir)
{
...
}

function saca_fich_jpg($dir)
{
...
}

Página 50/115
Iniciación a PHP 4 4.- FUNCIONES

function saca_fich_gif($dir)
{
...
}

?>

Si ahora queremos incluir la librería anterior dentro nuestro script basta hacer:

<?php
// Script que muestra todos los ficheros que hay dentro de nuestra web y da trato especial
// a los ficheros de imágenes.

// Suponiendo que el archivo de librerías estuviera dentro de la carpeta libs, hacemos:


include “./libs/lib_manejo_ficheros.php”;
// ó
require “/libs/lib_manejo_ficheros.php”;
....
$vect_fich_jpg=saca_fich_jpg(“./imagenes/”); // sacamos el nombre de nuestras imágenes


$vect_directories=saca_directorios(“./”) // sacamos los directorios dentro de la carpeta actual
...

?>

Tanto include() como require() tienen la misma estructura, aunque su comportamiento no es


idéntico.

include (path/filename);
require (path/filename);

include “path/filename”;
require “path/filename”;

La sentencia require() se sustituye a sí misma con el archivo especificado, tal y como


funciona la directiva #include de C (en tiempo de pre-compilación).

La sentencia include() incluye y evalúa el archivo especificado (durante la ejecución del


código).

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 (con include() sí que es
posible, aunque nosotros no lo vamos a ver); intentar leer un valor de retorno de una llamada a un
require() resulta en un error del intérprete.

A diferencia de include(), require() siempre leerá el archivo referenciado, incluso si la línea


en que está no se ejecuta nunca. Si se quiere incluir condicionalmente un archivo, se usa include().
La sentencia conditional no afecta a require().

De forma similar, las estructuras de bucle no afectan la conducta de require(). Aunque el


código contenido en el archivo referenciado está todavía sujeto al bucle, el propio require() sólo
ocurre una vez.

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().

Página 51/115
Iniciación a PHP 4 4.- FUNCIONES

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.

/* Esto es ERRÓNEO y no funcionará como se desea. */

if ($condicion)
include($archivo);
else
include($otro);

/* Esto es CORRECTO. */

if ($condicion) {
include($archivo);
} else {
include($otro);
}

Un punto importante sobre su funcionamiento es que tanto si un archivo se incluye con


include() o se requiere con require(), el intérprete sale del modo PHP y entra en modo HTML al
principio del archivo referenciado, y vuelve de nuevo al modo PHP al final. Por esta razón, cualquier
código dentro del archivo referenciado que debiera ser ejecutado como código PHP debe ser
encerrado dentro de etiquetas válidas de comienzo y fin de PHP.

PHP no soporta la sobrecarga de funciones y eso significa que dos funciones no pueden estar
declaradas con el mismo nombre. Por lo tanto, si una librería con funciones es incluida o requerida
varias veces, el parseador dará error alegando a que no se puede redeclarar una función (y dará el
error con la primer función que encuentre declarada dos veces). Por tanto, hay que tener mucho
cuidado de no incluir o requerir una librería de funciones varias veces dentro de un script, o incluir o
requerir dos librerías diferentes pero que compartan el nombre de algunas funciones.

Para hacer la vida del programador un poco más fácil, PHP permite usar require_once() e
include_once() que funcionan igual que las anteriores salvo que antes de requerir o incluir el archivo,
primero comprueban si ya se ha requerido o incluido con anterioridad. Si este es el caso, no se
requiere o incluye de nuevo.

Página 52/115
Iniciación a PHP 4 5.- VECTORES

5.- VECTORES
En el capítulo 2 se explicó los tipos de vectores existentes en PHP, así como la forma de
crearlos, pero no se vieron las posibles formas de recorrerlos. Tampoco se describió la estructura
interna de los vectores en PHP.

Además de lo anterior, este capítulo pretende introducir algunas de las funciones más
interesantes y comúnmente usadas de las que PHP dispone con respecto al tema de vectores.

5.1.- Estructura interna de los vectores en PHP


Los vectores en PHP son bastante más complejos que en el resto de lenguajes. Puesto que
en PHP el usuario no dispone de herramientas para el manejo dinámico de la memoria, los vectores
(y los objetos) tienen que suplir esta carencia. Así, un vector puede funcionar como tal o como lista
enlazada, pila, cola, estructura (el struct de C), etc.. Esta flexibilidad que, en principio, puede parecer
extremadamente interesante, puede convertirse en un quebradero de cabeza si no se entiende muy
bien cómo está montado un vector internamente. El gran problema reside en que no existe
demasiada información al respecto y uno tiene que sacarla de entrelíneas, por experiencia propia,
foros, etc..

Acostumbrados a trabajar en C o PASCAL, cuando uno define un vector, lo de hace de un


tamaño determinado. Incluso suponiendo que uno se defina un vector dinámicamente, el tamaño del
vector queda fijado. Así si uno hace en C:

int vect[25]; // Hemos creado un vector de enteros de 25 elementos

int *vect = malloc(sizeof(int)*25); // Hemos creado un vector de enteros, dinámicamente, de 25


// elementos

Pero en ambos casos, la longitud del vector queda fija. Si queremos vectores de longitud
variable dónde podamos crear y borrar elementos a nuestras anchas, tendremos que acudir a listas
enlazadas.

En ambos casos vect apunta al inicio del vector. Dicho de otra manera, vect contiene la dirección de
memoria dónde está contenido el primer elemento del vector.

Además, cuando en C queremos acceder a la posición 5 de dicho vector hacemos:

vect[5];

Internamente lo que se hace es multiplicar 5 x los bytes que ocupa un entero y hacer ese
desplazamiento a partir de la posición de memoria dónde vect apunta.

Toda esta gestión se puede realizar gracias a que se sabe lo que ocupa (en bytes) cada
elemento del vector.

En PHP, las variables no tienen un tipo fijo. Así, una variable que líneas anteriores se había
considerado como un entero, ahora puede estar funcionando como un carácter. Ello conlleva a que
no haya ningún tipo de restricción con respecto al tipo de los elementos de un vector. De hecho en la
posición 0 puede estar almacenado un número mientras que en la posición 3 puede estar
almacenado un vector o una cadena de caracteres. Todo esto implica que el funcionamiento de los
vectores en PHP sea mucho más sofisticado que el funcionamiento visto en C.

Un vector en PHP no sólo almacena los valores que le damos, también almacena la clave que
hace referencia a dicho valor. Veámoslo con un ejemplo:

$vect[0]=25;
$vect[1]=”hola”;
$vect[7]=2.25;

Página 53/115
Iniciación a PHP 4 5.- VECTORES

o En la posición 0 almacenamos un elemento de tipo entero cuyo valor es 25 y cuya clave es 0.


o En la posición 1 almacenamos un elemento de tipo cadena cuyo valor es hola y cuya clave
es 1.
o En la posición 2 almacenamos un elemento de tipo float cuyo valor es 2.25 y cuya clave es 7.

Luego en resumen, lo que se pone entre los corchetes, es la clave que identifica al valor. Lo
elementos se van poniendo en el mismo orden en que se insertan en el vector, independientemente
del valor de la clave.

$nom_vect[$key]=$value;

Ahora ya se puede entender por qué en PHP existen los llamados vectores asociativos. La
clave no tiene por qué se únicamente numérica, puede ser una cadena de texto. PHP los trata igual.
Todo esto permite una flexibilidad enorme. PHP incorpora funciones tanto para ordenar los elementos
por valor como para ordenarlos por clave. Incluso incorpora funciones para intercambiar cada valor
por su respectiva clave (es decir, las claves pasan a ser valores y los valores pasan a ser claves).

Aunque este sistema puede parecer de lo más extraño, optimiza mucho la implementación
interna de los vectores. Imagina que un programador crea un vector de 10 elementos e introduce los
datos de la siguiente manera:

$vect[2000]=”Oscar”;
$vect[1]=”Margarita”;
$vect[50]=”Roberto”;
$vect[100]=”David”;
$vect[0]=”José”;

¿Qué crees que debe hacer PHP? ¿definir un vector de 2000 elementos? ¿y de qué tamaño?
cada elemento puede tener tipos distintos y de tamaños diferentes.

La mejor solución es ir añadiendo elemento a elemento de forma continua tal y cómo se


puede ver en la tabla:

$vect
Posición 0 1 2 3 4
Clave 2000 1 50 100 0
Valor Oscar Margarita Roberto David José

De esta forma siempre se le permite al programador acceder por la clave que desee o
también se le da la alternativa de recorrer el vector por el orden en que los elementos se insertaron.
Esto se verá en detalle dentro del apartado RECORRIDO DE VECTORES.

Además de todo lo anterior, es conveniente comentar que cada vector dispone de un puntero
interno que apunta al elemento actual. Dicho puntero sólo puede ser manipulado con funciones que
PHP suministra. Más adelante veremos la utilidad de dicho puntero.

5.2.- Número de elementos dentro de un vector


El conocimiento del tamaño de un vector suele ser muy interesante sobre todo para tema de
recorrido de vectores aunque no es imprescindible (PHP suministra métodos para recorrer vectores
sin necesidad de conocer el tamaño del vector).

Para conocer el número de elementos dentro de un vector, PHP suministra 3 funciones:


sizeof(), count() y array_count_values();

sizeof

int sizeof ( array matriz)

Devuelve el número de elementos contenidos dentro del vector matriz. Lo que se le pasa a
sizeof no tiene por qué ser un vector unidimensional, se le puede pasar una matriz (vector

Página 54/115
Iniciación a PHP 4 5.- VECTORES

bidimensional) o un vector k-dimensional. Eso sí, sizeof sólo devuelve el número de elementos de la
primera dimensión. Veamos un ejemplo:

<?php
// Vamos a crear un vector unidimensional
$vect_uni = array (‘X-men’,’Matrix’,’Simpsons’);

sizeof($vect_uni); // Devolverá 3

// Ahora uno bidimensional


$vect_bi[‘X-men’][0]=’Lobezno’;
$vect_bi[‘X-men’][1]=’Rondador Nocturno’;
$vect_bi[‘X-men’][2]=’Coloso’;
$vect_bi[‘X-men’][3]=’Tormenta’;
$vect_bi[‘X-men’][4]=’Cíclope;’

$vect_bi[‘Matrix’][0]=’Trinity’;
$vect_bi[‘Matrix’][1]=’Neo’;
$vect_bi[‘Matrix’][2]=’Morpheus’;

$vect_bi[‘Simpons’][0]=’Homer’;
$vect_bi[‘Simpons’][1]=’Lisa’;
$vect_bi[‘Simpons’][2]=’Bart’;
$vect_bi[‘Simpons’][3]=’Maggie’;

sizeof($vect_bi);
// También devolverá 3, pues devuelve el número de elementos de la primera dimensión.

// Pero gracias a la flexibilidad de PHP, si dentro de una posición de un vector se encuentra otro
// vector, sizeof devuelve el tamaño de ese vector. Veámoslo con el caso anterior:

sizeof($vect_bi[‘X-men’]);
/* Puesto que en la posición identificada por ‘X-men’ hay un vector y no un valor, sizeof devolverá el
número de elementos de ese vector, esto es 5 */

sizeof($vect_bi[‘Matrix’]);
/* Ocurrirá lo mismo que en el caso anterior, sólo que ahora con el vector ‘Matrix’. Devolverá, por
tanto 3 */

// Si tuviéramos más dimensiones dentro de $vect_bi, podríamos hacer lo mismo sobre cada una
// de ellas.
?>

count

int count ( array matriz)

Funciona exactamente igual que sizeof() aunque, a diferencia de la anterior, devuelve un


poco más de información:

o Si la variable existe y es un vector (no tiene por qué ser de una dimensión!), count()
devolverá el número de elementos contenidos dentro del vector.
o Si la variable existe pero no es un vector, se devolverá el valor 1.
o Si la variable no existe, se devolverá el valor 0.

IMPORTANTE: count() puede devolver 0 para una variable no definida, pero también puede devolver
0 para una variable ya inicializada pero con un vector vacío. Habría que utilizar isset() para
comprobar si una variable está definida o no.

NOTA: A isset() se le pasa un variable. Si la variable existe devuelve TRUE en caso contrario
devuelve FALSE. Si se quisiera destruir una variable, se puede usar la función unset().
Página 55/115
Iniciación a PHP 4 5.- VECTORES

array_count_values

array array_count_values ( array vector_uni)

Esta función es una variante de las dos anteriores. En vez de devolver el número de
elementos, cuenta la frecuencia con que se da cada elemento. Para que esta función no de un error,
se le ha de pasar un vector unidimensional. Veamos un ejemplo:

<?php

$notas = array(4,5,4,5,6,8,7,8,9,7,10,4,7,3,2,7,5,6);
$c_notas = array_count_values($notas);

// Si ahora hacemos:
print_r($c_notas);

/* En pantalla se nos muestra:


Array ( [4] => 3 [5] => 3 [6] => 2 [8] => 2 [7] => 4 [9] => 1 [10] => 1 [3] => 1 [2] => 1 )

Y que significa que el valor 4 está repetido 3 veces, el valor 5 está repetido 3 y así sucesivamente
*/

// También lo podemos usar para cadenas de texto:


$nombres = array(‘Jose’,’Gabriel’,’Paco’,’Jose’,’Manuel’,’Angel’,’Jose’,’Angel’,’Aitana’,’María’);
$c_nombres = array_count_values($nombres);

print_r($c_nombres);

/* En pantalla se nos mostrará:


Array ( [Jose] => 3 [Gabriel] => 1 [Paco] => 1 [Manuel] => 1 [Angel] => 2 [Aitana] => 1 [María] => 1 )

La interpretación es que Jose aparece 3 veces, Gabriel aparece 1 vez, y así sucesivamente.
*/
?>

IMPORTANTE:
array_count_values solo funciona con vectores de números enteros o cadenas de caracteres.
Si se trata de utilizar con cualquier otra cosa dará el siguiente error: Warning: Can only count
STRING and INTEGER values! in c:\phpdev\www\pruebas\sizeof_y_count.php on line 39

5.3.- Recorrido de vectores


Hasta el momento, la única forma de recorrer vectores es mediante el uso de bucles (while o
for). El único requisito es conocer el número de elementos. Veamos un ejemplo:

<?php

$vect=array(1,2,3,4,5,6,7,8,9,10);
/*
Recordemos que cuando creamos un array como está descrito arriba, PHP genera las claves
automáticamente y es equivalente a hacer:

$vect[0] = 1;
$vect[1] = 2;

$vect[9] = 10;

Página 56/115
Iniciación a PHP 4 5.- VECTORES

*/

$num_elements = count($vect);

for ($i=0; $i<$num_elements; $i++)


{
// Vamos a mostrar el vector de la siguiente forma: [1, 2, 5, 8, …., N]
switch ($i)
{
case 0: echo “[$i, ”; break;
case ($num_elements-1): echo “$i]”; break;
default: echo “$i, ”; break;
}
}

// Dará la siguiente salida: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


?>

Este sistema es el más conocido y usado pero debido a la flexibilidad de PHP este sistema
tiene algunas pegas. En PHP los vectores NO tienen por qué comenzar en 0. Podríamos crear un
vector cuyos índices (recordemos que en PHP se llaman claves) fueran 1, 3, 5, 100, 1000 y 777. Al
intentar recorrer el vector de la manera anterior tendríamos un problema: count($vect) devolverá 6
(hay 6 elementos en el vector) y trataríamos de acceder a los elementos 0, 1, 2, 3, 4 y 5. Cómo sólo
existen 3 de esos elementos PHP sólo mostraría los elementos cuyas claves existen, en el resto no
haría nada.

Si se trata de acceder a un elemento mediante una clave que no existe en el vector, PHP no
dará error. Si se trata de imprimir tampoco dará error, simplemente no se mostrará nada.

NOTA: Si se trata de acceder a una variable que no está definida (es decir, que no existe), al igual
que en el caso de los vectores, PHP no dará ningún error. Lo mismo pasa a la hora de imprimirla por
pantalla: PHP no mostrará nada.

Además de lo anterior, tenemos un problema adicional: ¿cómo recorremos vectores cuya


clave no sea numérica? En el capítulo 2 vimos que en PHP existen vectores asociativos (aquellos
cuya clave no es numérica, si no una cadena de texto).

En el capítulo 3, cuando se vieron las estructuras de control, se vio de pasada la construcción


foreach() que se usa precisamente en estos casos. Además de dicha construcción PHP suministra
una larga lista de funciones para jugar y recorrer los vectores.

En PHP existen dos formas adicionales a la ya vista. Además son válidas para cualquier tipo
de vector, tanto asociativos como no asociativos

FOREACH

Recordemos cómo se usaba mediante un ejemplo:

foreach(nombre_array as $value) sentencia


foreach(nombre_array as $key => $value) sentencia

<?php
// Jugamos con el mismo vector que antes
$vect=array(1,2,3,4,5,6,7,8,9,10);

$i=0;
foreach($vect as $value)
{
switch ($i)
{

Página 57/115
Iniciación a PHP 4 5.- VECTORES

case 0: echo "[$value"; break;


default: echo ", $value"; break;
}
$i++;
}
// Falta cerrar el último corchete
echo "]";
?>

El ejemplo anterior producirá el mismo resultado que cuándo hemos usado el bucle for() pero
con una gran diferencia VALE PARA CUALQUIER TIPO DE VECTOR, independientemente de si el
vector es asociativo, no asociativo, mixto o no asociativo pero con las claves puestas arbitrariamente.

Además, se garantiza el acceder a los datos exactamente en el mismo orden en que fueron
insertados en el vector (lo cual puede ser MUY interesante para determinadas tareas).

Foreach permite, además, conocer la clave del valor actual. Veamos otro ejemplo;

<?php
$regiones_dvd = array(
1 => 'USA, Canada, territorios USA ',
2 => 'Japón, Europa, Sur África, Medio Este (incluyendo Egipto)',
3 => 'Sureste de Asia y Este de Asia (incluye Hong Kong)',
4 => 'Australia, Nueva Zelanda, Islas de Pacifico, América Central, Sudamérica, Caribe.',
5 => 'Europa del Este (Unión Soviética), subcontinente Indio, África, Corea del Norte, Mongolia',
6 => 'China',
7 => 'Reservado',
8 => 'Especial para usos internacionales (aviones, cruceros, etc...)'
);

foreach($regiones_dvd as $cod_reg => $zona)


{
// Vamos a mostrar los códigos regionales y su/s respectiva/s zona/s geográfica/s
echo "Región $cod_reg: $zona <br>\n";
}
?>

Como se puede observar, foreach() simplifica mucho el recorrido de los vectores y permite
crear funciones que recorran o jueguen con los vectores independientemente de cómo estén
construidos.

Es importante comentar que foreach() también funciona bien si cada elemento del vector es,
a su vez, un nuevo vector. Veamos un ejemplo:

<?php

// Cine

// Ejemplo con un vector multidimensional que en la primera dimensión guarda los géneros y cada
// género almacena un vector asociativo dónde la clave es el nombre de la película y el valor es su
// puntuación:

$pelis['Terror']=array(
'The Eye' => 7.5,
'Dark Water' => 8.5,
'DeathWatch' => '?',
'Dreamcatcher' => 7,
'Dog Soldiers' => '?',
'Darkness' => 9
);

Página 58/115
Iniciación a PHP 4 5.- VECTORES

$pelis['Comedia']=array(
'Yo yo mismo e Irene' => 8,
'La máscara' => 8.5,
'Colega, Dónde está mi coche?' => 7.5
);

$pelis['Fantasia']=array(
'El señor de los anillos' => 9.8,
'Matrix' => 10,
'Final Fantasy' => 8.75,
'Hero' => 9, 'Legend of Zu' => 8.5
);

// Ahora recorremos el vector

foreach($pelis as $nom_genero => $vect_pelis)


{
// Mostramos primero el género y las películas en él contenidas
echo "Género: $nom_genero <br>\n";

// Puesto que cada elemento es un vector, usamos otro foreach


foreach($vect_pelis as $nom_peli => $puntuacion)
{
echo "- $nom_peli | Puntuación: $puntuacion<br>\n";
}

// Dejamos otro espacio entre géneros para más claridad


echo "<br>\n";
}
?>

LIST Y EACH

Cuando se habló de la construcción interna de los vectores, se comentó de pasada que cada
vector en PHP disponía de un puntero interno. Hasta el momento no hemos visto la utilidad que tiene
esto ni cómo manejar dicho puntero. Pues bien, ahora veremos cómo recorrer un vector haciendo uso
de dicho puntero. Veamos primero las funciones each() y list() :

each
(PHP 3, PHP 4 )

each -- Devuelve el par clave/valor actual de una matriz y avanza el puntero de la misma.

Descripción:

array each ( array matriz)


Devuelve el par clave/valor actual para la matriz y avanza el puntero de la misma. Esta pareja se
devuele en una matriz de 4 elementos, con las claves 0, 1, key, y value. Los elementos 0 y key
contienen el nombre de clave del elemento de la matriz, y 1 y value contienen los datos.
Si el puntero interno para la matriz apunta pasado el final del contenido de la matriz, each() devuelve
FALSE.
$chorrada = array ("bob", "fred", "jussi", "jouni", "egon", "marliese");
$tonteria = each ($chorrada);

$tonteria contiene ahora los siguientes pares clave/valor:


0 => 0
1 => 'bob'

Página 59/115
Iniciación a PHP 4 5.- VECTORES

key => 0
value => 'bob'

list
(PHP 3, PHP 4 )

list -- Asigna valores a variables que se le pasan, a partir de los elementos de un vector.

Descripción:

void list ( mixed ...)


Como array(), esta no es realmente una función, sino una construcción del lenguaje. list() se usa
para asignar una lista de variables en una sola operación. Lo que realmente se hace es dada N
variables y un vector, coge los N primeros elementos del vector y los asigna en orden a las N
variables.
// Nos definimos un vector con una fecha
$fecha = array('2003','Abril',25,12,16,30);

// Sólo nos queremos quedar con el año, mes y día pero en variables separadas
// para poder trabajar con ellas más comodamente
list($ano,$mes,$dia) = $fecha;

echo "$dia de $mes de $ano"; // Devolverá: 25 de Abril de 2003

IMPORTANTE: list() sólo funciona con vectores no asociativos (es decir, cuyas claves son
puramente numéricas) o vectores mixtos (con claves numéricas y de texto, aunque se saltará los
elementos con clave no numérica). Si se le pasa un vector puramente asociativo, no dará error pero
no les asignará nada a las variables pasadas.

Como se puede apreciar, list() y each() se complementan perfectamente para recorrer un


vector: mientras que each saca la clave y el valor de un elemento, list se lo asigna a las variables que
queramos. Veamos un ejemplo:

<?php

// Animación Japonesa

// Al igual que en el ejemplo de cine, almacenamos en la primera dimensión los géneros


// y dentro de cada género metemos un vector asociativo dónde la clave de cada elemento
// es el nombre de la película y el valor es la puntuación.
$anime=array(
'Accion' => array('Spriggan' => 8, 'X' => 8, 'Akira' => 9, 'Ghost in The Shell' => 10, 'Berserk' => 8.5),
'Comedia' => array('Golden Boy' => 10, 'Ranma 1/2' => 9.5, 'Chobits' => 10),
'Aventuras' => array('Escaflowne' => 9.8, 'Evangelion' => 8, 'Fushigi Yugi' => 7.5)
);

echo ".: Películas de Animación Japonesa :.<br><br>\n";

// Ahora lo recorrermos y presentamos adecuadamente los resultados


// A la clave la llamaremos $genero pues es lo que representa
// Al valor lo llamaremos $vect_pelis pues, a fin de cuentas, no es un valor, es un vector de pelis
reset($anime); // Colocamos el puntero al principio
while (list($genero, $vect_pelis) = each($anime))
{
echo $genero,"<br>\n";
reset($vect_pelis); // Colocamos el puntero al principio
while (list($nom_peli, $puntuacion) = each($vect_pelis))
{
echo "::: $nom_peli => $puntuacion<br>\n";

Página 60/115
Iniciación a PHP 4 5.- VECTORES

// Dejamos un espacio más entre género y género


echo "<br>\n";
}
?>

Aunque este método de recorrer vectores es muy similar al realizado con foreach(), hay
algunas diferencias significativas que hay que comentar:

foreach usa una copia del vector y por tanto no modifica la posición interna del puntero
del vector. Además, nada más hacer la copia, hace un reset() para colocar el puntero al
principio del vector.
each va modificando el puntero interno del vector y, por lo tanto, cuando acaba de
recorrer el vector, el puntero apunta al último elemento. Además, si cortamos la ejecución
del bucle a mitad del while, el puntero se quedará apuntando al elemento siguiente del
último elemento accedido. Siempre que comencemos a recorrer un vector con each y list
hay que hacer un reset del vector puesto que nadie nos garantiza que el puntero interno
apunte al primer elemento.

A parte de reset, existen otras funciones que permiten mover el puntero interno hacia la posición
que más nos convenga:

reset
(PHP 3, PHP 4 )

reset -- Coloca el puntero interno de una matriz a su primer elemento y devuelve el valor de éste.

Descripción:

mixed reset ( array matriz)


reset() retrocede el puntero interno de la matriz a su primer elemento y devuelve el valor del primer
elemento de la matriz (sólo el valor, no su clave).

end
(PHP 3, PHP 4 )

end -- Mueve el puntero interno de una tabla al último elemento

Descripción:

mixed end ( array matriz)


end() avanza el puntero interno de la matriz al último elemento y devuelve el valor del último
elemento.

current
(PHP 3, PHP 4 )

current -- Devuelve el valor del elemento actual de una matriz apuntado por el vector interno

Descripción:

mixed current ( array matriz)

current() devuelve el elemento de la tabla al que apunta el puntero interno. No mueve el puntero de
ninguna manera. Si el puntero interno apunta fuera del final de la lista de elementos, current()
devuelve FALSE.

Página 61/115
Iniciación a PHP 4 5.- VECTORES

AVISO: Si la matriz contiene elementos vacíos (0 ó "", la cadena vacía) esta función devolverá
FALSE para dichos elementos. Esto hace imposible determinar si se está realmente al final de la lista
en tales matrices usando current(). Para recorrer adecuadamente una matriz que pueda contener
elementos vacíos, utilice la función each().

next
(PHP 3, PHP 4 )

next -- Avanza el puntero interno de una matriz al siguiente elemento y devuelve su valor

Descripción:

mixed next ( array matriz)


Devuelve el elemento de la matriz que ocupa el lugar siguiente al apuntado por el puntero interno, o
FALSE si no hay más elementos.

next() se comporta como current(), con una diferencia. Avanza el puntero interno de la matriz en una
posición antes de devolver el elemento. Eso significa que devuelve el siguiente elemento de la matriz
y que avanza el puntero interno en uno. Si al avanzar se pasa del final de la lista de elementos, next()
devuelve FALSE.

AVISO: Si la matriz contiene elementos vacíos (0 ó "", la cadena vacía) esta función devolverá
FALSE para dichos elementos. Esto hace imposible determinar si se está realmente al final de la lista
en tales matrices usando current(). Para recorrer adecuadamente una matriz que pueda contener
elementos vacíos, utilice la función each().

prev
(PHP 3, PHP 4 )

prev -- Retrocede el puntero interno de una matriz al elemento anterior y devuelve su valor

Descripción:

mixed prev ( array matriz)


Retrocede el puntero interno al elemento anterior al que previamente apuntaba y devuelve su valor. Si
no hay más elementos devuelve FALSE.

AVISO: Si la matriz contiene elementos vacíos (0 ó "", la cadena vacía) esta función devolverá
FALSE para dichos elementos. Esto hace imposible determinar si se está realmente al final de la lista
en tales matrices usando current(). Para recorrer adecuadamente una matriz que pueda contener
elementos vacíos, utilice la función each().

key
(PHP 3, PHP 4 )

key – Devuelve el valor de la clave del elemento actual apuntado por el vector interno

Descripción:

mixed key ( array matriz)


key() devuelve el valor de la clave del elemento apuntado por el vector interno. No modifica la
posición del puntero interno. Si el puntero interno apunta fuera del final de la lista de elementos,
current() devuelve FALSE.

A diferencia de current(), si el elemento actual apuntado tiene un valor vacío (0 ó "", la cadena vacía)
la clave se devuelve correctamente.

Página 62/115
Iniciación a PHP 4 5.- VECTORES

A parte de estas funciones, existe una última llamada array_walk() que permite aplicar una
función a cada elemento del vector. Esto puede ser extremadamente útil si, por ejemplo, tenemos que
elevar al cuadrado todos los elementos, pasar todos los elementos a mayúsculas/minúsculas, o
eliminar elementos que no cumplan alguna condición.

array_walk
(PHP 3>= 3.0.3, PHP 4 )

array_walk -- Aplica una función del usuario a cada elemento de una matriz.

Descripción:

int array_walk ( array vector, string func, mixed datosvarios)


Aplica la función llamada func a cada elemento del vector. La función func recibirá el valor del
elemento actual como primer parámetro y la clave como segundo. Si se proporciona el parámetro
datosvarios será pasado como tercer parámetro a la función de usuario.
Si func necesita más de dos o 3 argumentos, dependiendo de datosvarios, se generará un aviso cada
vez que array_walk() llama a func. Estos avisos pueden suprimirse si se pone '@' antes de la
llamada a array_walk(), o usando la función error_reporting().
Nota: Si func precisa trabajar con los valores reales del vector, especifique que el valor del primer
parámetro de func debe pasarse por referencia. Desde ese instante, los cambios realizados sobre
dichos elementos también serán realizados en el propio vector.
Nota: El pasar la clave y los datos de usuario a func fue una característica añadida en PHP 4.0.
En PHP 4 se debe llamar reset() las veces necesarias, pues array_walk() no coloca el puntero
interno al principio del vector al inicio de ejecución.

<?php

function test_alterar (&$item1, $clave, $prefix) {


$item1 = "$prefix: $item1";
}

function test_ver ($item2, $clave) {


echo "$clave. $item2<br>\n";
}

$frutas = array ("l"=>"limón", "n"=>"naranja", "p"=>"plátano", "m"=>"manzana");

reset ($frutas);
// Este reset no haría falta pues siempre que un vector es creado, el puntero interno
// apunta a la primer elemento.
array_walk ($frutas, 'test_ver');

reset ($frutas);
array_walk ($frutas, 'test_alterar', 'fruta');

// Dejamos un línea de espacio


echo "<br>\n";

reset ($frutas);
array_walk ($frutas, 'test_ver');

?>

5.4.- Búsqueda de elementos dentro de un vector

Página 63/115
Iniciación a PHP 4 5.- VECTORES

Existen, fundamentalmete, dos funciones que permiten buscar un elemento dentro de un


vector. Estas dos funciones son array_search() y in_array(). Aunque devuelven cosas distintas, su
misión es, dado un valor, buscar si algún elemento dentro del vector tiene ese mismo valor.

Puesto que también puede ser interesante buscar una clave en vez de un valor, PHP
suministra la siguiente función: array_key_exists() que realiza una función similar a la anterior sólo
que con las claves del vector.

in_array
(PHP 4 )

in_array -- Devuelve TRUE si un valor está en una vector

Descripción:

bool in_array ( mixed aguja, array pajar)


Busca la aguja en el pajar, y devuelve TRUE si se encuentra y FALSE en caso contrario.

NOTA: Se busca EXACTAMENTE la aguja. Eso significa que si es una cadena de caracteres, las
2
cadenas deben ser idénticas (sensible a mayúsculas y minúsculas). Las expresiones regulares no
están permitidas.

array_search
(PHP 4 >= 4.0.5)

array_search -- Busca dentro de un vector un determinado valor y devuelve la clave si se encuentra

Descripción:

mixed array_search ( mixed aguja, array pajar [, bool strict])


Busca la aguja en el pajar y devuelve el valor de la clave si se encuentra, si no se devuelve FALSE.

NOTA: En versiones anteriores a PHP 4.2.0, array_search() devuelve NULL en vez de FALSE.
Si el tercer parámetro opcional strict se pone a TRUE entonces array_search() comprobará también
los tipos de la aguja y los elementos del pajar. Es decir, para que la búsqueda acabe con éxito no
sólo se ha de encontrar la aguja, los elementos deben coincidir también en el tipo. Tampoco se
permite el uso de expresiones regulares.

array_key_exists
(PHP 4 >= 4.1.0)

array_key_exists -- Comprueba si la clave dada existe en el vector

Descripción:

bool array_key_exists ( mixed clave, array vector)


array_key_exists() devuelve TRUE si la clave dada se encuentra en el vector. La clave buscada
puede ser tanto numérica como de texto.

NOTA: Tampoco están permitidas las expresiones regulares.

5.5.- Ordenación de vectores


Puesto que en la gran mayoría de los casos usaremos vectores para albergar cantidades
grandes información (nombres de usuarios, de ficheros etc...), el poder realizar ordenaciones es una

2
Las expresiones regulares permiten comprobar si un string cumple un determinado patrón. Por ejemplo que la
primera letra comience por “a”, que acabe en “ia” o que contenga el trozo “orden”.
Página 64/115
Iniciación a PHP 4 5.- VECTORES

necesidad importante (sobre todo a la hora de mostrar los datos al usuario). Siempre podemos
implementar nuestras propias funciones de ordenación: quicksort, mergesort, etc... Pero, para
simplificarnos la vida, PHP ya lleva implementadas unas cuantas funciones que realizan estas tareas.

sort y rsort

Son las funciones más básicas de ordenación. Las dos funciones son idénticas salvo que una
ordena en sentido ascendente (sort) y la otra en sentido descendente (rsort – reverse sort).

void sort ( array vector)


void rsort ( array vector)

Es muy importante comentar al realizar la ordenación NO se mantiene la relación clave/valor.


Veámoslo con un ejemplo:

<?php
// Con vector no asociativo
$vect = array ('banana', 'pera', 'manzana', 'kiwi', 'uva', 'mango', 'paraguaya');

// Imprimimos el vector antes de ordenarlo


print_r($vect);

/* Dará por pantalla:


Array ( [0] => banana [1] => pera [2] => manzana [3] => kiwi [4] => uva [5] => mango [6] => paraguaya
)
*/

// Ordenamos el vector
sort($vect);

// Dejamos algo de espacio


echo "<br><br>\n";

// Ahora imprimimos el vector ya ordenado


print_r($vect);

/* Dará por pantalla:


Array ( [0] => banana [1] => kiwi [2] => mango [3] => manzana [4] => paraguaya [5] => pera [6] => uva
)
*/
?>

Como se puede observar en el ejemplo, la relación clave = 2 | valor = manzana se pierde al


hacer la ordenación. Ahora manzana tiene por clave 3 y ocupa la posición 3.

Si tratamos de hacer lo mismo pero con un vector asociativo, nos encontramos con lo
siguiente:

<?php
// Con un vector asociativo
$vect = array ("Spriggan" => 7.5, "Akira" => 9, "3x3 Ojos" => 8, "Shadow Skill" => '?');

// Imprimimos el vector antes de ordenarlo


print_r($vect);

/* Dará por pantalla:


Array ( [Spriggan] => 7.5 [Akira] => 9 [3x3 Ojos] => 8 [Shadow Skill] => ? )
*/

// Ordenamos el vector
sort($vect);
Página 65/115
Iniciación a PHP 4 5.- VECTORES

// Dejamos algo de espacio


echo "<br><br>\n";

// Ahora imprimimos el vector ya ordenado


print_r($vect);

/* Dará por pantalla:


Array ( [0] => ? [1] => 7.5 [2] => 8 [3] => 9 )
*/
?>

Todas las claves de texto se pierden y se sustituyen por claves numéricas. Ahora cada clave
coincide con la posición que cada elemento ocupa dentro del vector ordenado.

IMPORTANTE: El vector que se le pase a sort() debe ser un vector unidimensional, si no PHP dará
un error (sólo se ordena la primera dimensión).

asort y arsort

Funcionan de forma similar a las dos anteriores: asort ordena ascendentemente y arsort
descendentemente. La diferencia estriba en que aquí SÍ que se mantiene la relación clave/valor.

void asort ( array vector)


void arsort ( array vector)

Veamos un ejemplo de su funcionamiento:

<?php
// Con vector no asociativo
$vect = array ('banana', 'pera', 'manzana', 'kiwi', 'uva', 'mango', 'paraguaya');

// Imprimimos el vector antes de ordenarlo


print_r($vect);

/* Dará por pantalla:


Array ( [0] => banana [1] => pera [2] => manzana [3] => kiwi [4] => uva [5] => mango [6] => paraguaya
)
*/

// Ordenamos el vector
asort($vect);

// Dejamos algo de espacio


echo "<br><br>\n";

// Ahora imprimimos el vector ya ordenado


print_r($vect);

/* Dará por pantalla:


Array ( [0] => banana [3] => kiwi [5] => mango [2] => manzana [6] => paraguaya [1] => pera [4] => uva
)
*/
?>

Ahora las claves sí que se mantienen asociadas a su valor. Veamos un último ejemplo con un
vector asociativo:

<?php
// Con un vector asociativo

Página 66/115
Iniciación a PHP 4 5.- VECTORES

$vect = array ("Spriggan" => 7.5, "Akira" => 9, "3x3 Ojos" => 8, "Shadow Skill" => '?');

// Imprimimos el vector antes de ordenarlo


print_r($vect);

/* Dará por pantalla:


Array ( [Spriggan] => 7.5 [Akira] => 9 [3x3 Ojos] => 8 [Shadow Skill] => ? )
*/

// Ordenamos el vector
asort($vect);

// Dejamos algo de espacio


echo "<br><br>\n";

// Ahora imprimimos el vector ya ordenado


print_r($vect);

/* Dará por pantalla:


Array ( [Shadow Skill] => ? [Spriggan] => 7.5 [3x3 Ojos] => 8 [Akira] => 9 )
*/
?>

ksort y rksort

Hasta ahora venimos ordenando valores pero más importante que ordenar por valores puede
serlo ordenar por claves. En el último ejemplo visto estábamos ordenando un vector que contenía
películas de animación (clave) y la puntuación respectiva (valor). Puede ser igual de interesante hacer
la ordenación por puntuación que por el nombre de las películas. Pensemos que si el usuario quiere
buscar una película en particular le resultará más sencillo encontrarla si las películas se muestran
ordenadas por nombre que por la puntuación.

Como de costumbre, ksort ordena el vector por claves ascendentemente mientras que rksort
lo hace descendentemente.

void ksort ( array vector)


void krsort ( array vector)

Por descontado que aquí SE MANTIENE la relación clave/valor, si no esto no tendría sentido.
Veamos un ejemplo:

<?php

// Vector asociativo de películas


$pelis = array(
'Memento' => 9.5,
'El viaje de Chihiro' => 8.5,
'El paciente inglés' => 8,
'El cazador de Sueños' => 7,
'Star Wars: El ataque de los clones' => 7.7
);

// Mostramos el vector antes de ordenarlo


print_r($pelis);

/* Salida por pantalla:


Array ( [Memento] => 9.5 [El viaje de Chihiro] => 8.5 [El paciente inglés] => 8 [El cazador de Sueños]
=> 7 [Star Wars: El ataque de los clones] => 7.7 )
*/

// Ordenamos ascendentemente por clave


Página 67/115
Iniciación a PHP 4 5.- VECTORES

ksort($pelis);

// Dejamos un poco de espacio


echo "<br><br>\n";

// Imprimimos el vector ya ordenado


print_r($pelis);

/* Salida por pantalla


Array ( [El cazador de Sueños] => 7 [El paciente inglés] => 8 [El viaje de Chihiro] => 8.5 [Memento] =>
9.5 [Star Wars: El ataque de los clones] => 7.7 )
*/
?>

usort, uasort y uksort

A parte de las funciones ya vistas, existen otras tres que permiten realizar ordenaciones
según nuestro propio criterio.

void usort ( array vector, function func_comparar)


void uasort ( array vector, function func_comparar)
void uksort ( array vector, function func_comparar)

La diferencia entre las tres es sencilla:


o usort ordena por valores SIN mantener la relación clave/valor.
o uasort ordena por valores MANTENIENDO la relación clave/valor.
o uksort ordena por claves MANTENIENDO la relación clave/valor.

Estas funciones ordenaran un vector utilizando una función suministrada por el usuario. La
función de comparación deberá devolver un entero menor, igual, o mayor que cero, si el primer
argumento se considera respectivamente menor que, igual que, o mayor que el segundo. Si dos
miembros resultan ser iguales, su orden en la matriz ordenada será cualquiera.

Resumiendo, la idea es suministrarle una función que indique como quedarían un par de
valores ordenados (llamémosles $a y $b):

o Si la función de usuario devuelve 0 da igual el orden de $a y $b


o Si devuelve un nº > 0 primero $a y luego $b
o Si devuelve un nº < 0 primero $b y luego $a

Por ejemplo, nos puede interesar ordenar un vector en función del tamaño de la cadena de
texto. Es decir, lo que queremos es que las cadenas más cortas estén al principio y las más largas al
final del vector. Luego en nuestro caso:

o Si la longitud de la cadena $a es menor que la longitud de la cadena $b, $a irá antes que $b
o Si la longitud es idéntica, nos da igual el orden
o Si la longitud de la cadena $a es mayor que la longitud de la cadena $b, $b irá antes que $a

Después de desmenuzar al completo este ejemplo, veamos su implementación:

<?php

// Función que imprime el vector dado


function imprime_vector($vect)
{
foreach($vect as $valor)
echo $valor, " | ", strlen($valor), " letras. <br>\n";
}

function ord_tam_cad($a, $b)


{
Página 68/115
Iniciación a PHP 4 5.- VECTORES

// Primero sacamos el tamaño de cada cadena.


// Para ello usaremos la función strlen que devuelve el tamaño de una cadena de caracteres.
$tam_a = strlen($a);
$tam_b = strlen($b);

// Si las cadenas tienen el mismo tamaño, nos da igual el orden


if ($tam_a == $tam_b) return 0;
// Si $a es más grande que $b, entonces primero $a y luego $b
if ($tam_a > $tam_b) return 1;
// en caso contrario, primero $b y luego $a
else return -1;
}

// Nos definimos un vector de nombres


$vect_nombres = array ('Ana', 'Jose', 'Paco', 'Rafael', 'Miguel', 'Roberto', 'Vicente', 'María', 'Laura',
'Rosa', 'Gabriel');

// Imprimimos antes de ordenar


imprime_vector($vect_nombres);

// Vamos a hacer una ordenación por el tamaño de los nombres.


// Primero irán los cortos y luego los largos:
usort($vect_nombres, "ord_tam_cad");

// Dejamos un par de líneas en blanco


echo "<br><br>\n";

// Imprimimos el vector ordenado


imprime_vector($vect_nombres);
?>

5.6.- Adición y eliminación de elementos (pilas y colas)


En lenguajes como el C, uno no puede “eliminar” elementos de un vector. Una vez que uno
crea el vector (estática o dinámicamente), el vector es una unidad. Si el vector es de 10 elementos,
no podemos hacer que ahora su tamaño sea 6 (bueno, no al menos de forma directa).

El caso es distinto cuando trabajamos con listas enlazadas. Puesto que cada elemento es
una entidad diferente, basta con colocarse sobre el nodo a eliminar, actualizar los punteros y luego
proceder a su borrado.

Puesto que en PHP los vectores son ya de por sí elementos dinámicos y que pueden
funcionar de muchas formas diferentes, el borrado de elementos es posible. Podemos borrar
elementos de la forma más sencilla posible: usando la función unset(). Unset destruye cualquier tipo
de variable, incluso elementos de un vector. PHP ya se encarga de reestructurar el vector por dentro.
Veamos un ejemplo:

<?php
// Definimos un sencillo vector de enteros
$vect = array (5, 7, 7, 8, 9, 0, 6, 1);

// Lo imprimimos por pantalla


print_r($vect); // Array ( [0] => 5 [1] => 7 [2] => 7 [3] => 8 [4] => 9 [5] => 0 [6] => 6 [7] => 1 )

// Borramos la posición 0
unset($vect[0]);

// Dejamo una línea en blanco

Página 69/115
Iniciación a PHP 4 5.- VECTORES

echo "<br>\n";

// Volvemos a imprimir el vector


print_r($vect); // Array ( [1] => 7 [2] => 7 [3] => 8 [4] => 9 [5] => 0 [6] => 6 [7] => 1 )
?>

En el siguiente ejemplo vamos a borrar todos aquellos elementos que sean múltiplos de 2:

<?php
// Creamos un vector de números enteros
$vect_nums = array (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);

// Lo mostramos por pantalla


print_r($vect_nums);
/*
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 [9] => 10 [10] => 11
[11] => 12 )
*/

// Eliminamos todos los elementos que sean múltiplos de 2


foreach ($vect_nums as $clave => $valor)
if ($valor % 2 == 0) unset($vect_nums[$clave]);

// Dejamos una línea en blanco


echo "<br>\n";

// Lo volvemos a mostrar por pantalla


print_r($vect_nums);
/*
Array ( [0] => 1 [2] => 3 [4] => 5 [6] => 7 [8] => 9 [10] => 11 )
*/
?>

PHP suministra, además, otras funciones que facilitan el uso de un vector como si de una pila
o cola se tratase.

array_push y array_pop

int array_push ( array vector, mixed var [, mixed var2, ...])


mixed array_pop ( array vector)

array_push() considera vector como una pila, e inserta las variables que se le pasan al final de éste.
La longitud de la vector se incrementa en el número de variables insertadas. Tiene el mismo efecto
que ejecutar:

$matriz[] = $var;

Devuelve el nuevo número de elementos de la matriz.

array_pop() realiza el procedimiento inverso: extrae y devuelve el último valor del vector, acortando
el vector en un elemento. Ejemplo:

$pila = array ("naranja", "manzana", "frambuesa");


$fruta = array_pop ($pila);

Tras esto, $pila contiene sólo 2 elementos: "naranja" y "manzana", y $fruta contiene "frambuesa".

array_unshift y array_shift

Página 70/115
Iniciación a PHP 4 5.- VECTORES

int array_unshift ( array vector, mixed var [, mixed var2, ...])


mixed array_shift ( array vector)

Estas dos funciones son exactamente iguales a las ya vistas, excepto que las de arriba
insertan los elementos al final y éstas al principio.

array_pad

array array_pad ( array vector, int tam_relleno, mixed valor_relleno)

array_pad() Devuelve una copia del vector rellenada hasta el tamaño tam_relleno con el valor
valor_relleno. Si tam_relleno es positivo, entonces la matriz es rellenada por la derecha, y si es
negativo, por la izquierda. Si el valor absoluto de tam_relleno es menor o igual que el tamaño del
vector no se produce relleno alguno. Ejemplo:

$entrada = array (12, 10, 9);

$resultado = array_pad ($entrada, 5, 0);


// el resultado es array (12, 10, 9, 0, 0)

$resultado = array_pad ($entrada, -7, -1);


// el resultado es array (-1, -1, -1, -1, 12, 10, 9)

$resultado = array_pad ($entrada, 2, "no");


// no rellenado

5.7.- Otras funciones interesantes


Aunque existen gran cantidad de funciones para manipular vectores, aquí se comentarán
brevemente aquellas que pueden considerarse de mayor utilidad:

o range()

o array_keys() | array_values()

o array_reverse() | array_flip()

o array_merge | array_slice | array_splice

o shuffle()

range
(PHP 3>= 3.0.8, PHP 4 )

range -- Crea un vector que contiene un rango de elementos

Descripcion:

array range ( int inferior, int superior [, int paso])

range() devuelve un vector de elementos desde inferior hasta superior, ambos incluidos. Si inferior >
superior, la secuencia se generará descendentemente. Si inferior < superior, la secuencia se
generará ascendentemente.

Nuevo Parámetro: El parámetro opcional paso fué añadido en la versión 5.0.0.


Si se le proporciona el valor paso, será usado como el incremento entre elementos de la secuencia.
Su valor ha de ser positivo. Si no se especifica ningún valor, paso valdrá 1.

Página 71/115
Iniciación a PHP 4 5.- VECTORES

<?php
// array(0,1,2,3,4,5,6,7,8,9)
foreach(range(0, 9) as $number) {
echo $number;
}

// The step parameter was introduced in 5.0.0


// array(0,10,20,30,40,50,60,70,80,90,100)
foreach(range(0, 100, 10) as $number) {
echo $number;
}

// Use of characters introduced in 4.1.0


// array('a','b','c','d','e','f','g','h','i');
foreach(range('a', 'i') as $letter) {
echo $letter;
}
// array('c','b','a');
foreach(range('c', 'a') as $letter) {
echo $letter;
}
?>
Nota: Con anterioridad a la versión 4.1.0, la función range() sólo generaba vectores ascendentes de
enteros. El soporte para generar vectores descendentes y vectores de caracteres fue añadido en la
versión 4.1.0.

array_keys
(PHP 4 )

array_keys -- Devuelve todas las claves de una matriz

Descripción:

array array_keys ( array entrada [, mixed val_a_buscar])


array_keys() devuelve las claves, numéricas y de cadena, de la matriz entrada.
Si se especifica el parámetro opcional val_a_buscar, sólo se devuelven las claves para dicho valor.
De otro modo, se devuelven todas las claves de la entrada.
$matriz = array(0 => 100, "color" => "rojo");
array_keys ($matriz); // devuelve array (0, "color")

$matriz = array(1, 100, 2, 100);


array_keys ($matriz, 100); // devuelve array (0, 2)

array_values
(PHP 4 )

array_values -- Devuelve todos los valores de una matriz

Descripción:

array array_values ( array entrada)


array_values() devuelve todos los valores de la matriz entrada.

$matriz = array("talla" => "XL", "color" => "dorado");


array_values($matriz); // devuelve array("XL", "dorado")

Página 72/115
Iniciación a PHP 4 5.- VECTORES

array_reverse
(PHP 4 )

array_reverse -- Devuelve una matriz con los elementos en orden inverso

Descripción:

array array_reverse ( array matriz)


array_reverse() toma la matriz de entrada y devuelve una nueva matriz con los elementos en orden
inverso.
$entrada = array ("php", 4.0, array ("verde", "rojo"));
$resultado = array_reverse ($entrada);

Esto hace que $resultado contenga array (array ("verde", "rojo"), 4.0, "php").

array_flip
(PHP 4 )

array_flip -- Intercambia el par clave/valor de una matriz.

Descripción:

array array_flip ( array trans)


array_flip() intercambia las claves por los valores y viceversa.
<?php
// Vector original
$original = array('A' => 'a', 'B' => 'b', 'C' => 'c');
// Lo imprimimos por pantalla
print_r($original); echo "<br>"; // Array ( [A] => a [B] => b [C] => c )

// Ahora lo transponemos
$trans = array_flip ($trans);
// Imprimimos por pantalla la transposición
print_r($trans); echo "<br>"; // Array ( [a] => A [b] => B [c] => C )

array_merge
(PHP 4 )

array_merge -- Combina dos o más matrices

Descripción:

array array_merge ( array matriz1, array matriz2 [, ...])


array_merge() combina los elementos de dos o más matrices conjuntamente de modo que los
valores de una son agregados al final de los valores de la anterior. Devuelve la matriz resultante.
Si las matrices de entrada tienen las mismas claves de cadena, el último valor para cada clave
reemplazará el valor previo de la misma. Si, por el contrario, las matrices tienen la misma clave
numérica, esto no pasa y los valores son simplemente agregados.

$matriz1 = array ("color" => "rojo", 2, 4);


$matriz2 = array ("a", "b", "color" => "verde", "forma" => "trapezoide");
array_merge ($matriz1, $matriz2);

Página 73/115
Iniciación a PHP 4 5.- VECTORES

array_slice
(PHP 4 )

array_slice -- Extrae una porción de la matriz

Descripción:

array array_slice ( array matriz, int desplazamiento [, int tamano])


array_slice() devuelve una secuencia de elementos de la matriz especificada por los parámetros
desplazamiento y tamano.
Si el desplazamiento es positivo, la secuencia comenzará en dicha posición de la matriz. Si el
desplazamiento es negativo, la secuencia comenzará en esa posición desde el final de la matriz.
Si se especifica el tamano y éste es positivo, la secuencia contendrá tantos elementos como se diga
en él. Si fuese negativo, la secuencia se detendrá a tantos elementos del final de la matriz. Si se
omite, la secuencia contendrá todos los elementos desde el desplazamiento hasta el final de la
matriz.

$entrada = array ("a", "b", "c", "d", "e");

$salida = array_slice ($entrada, 2); // devuelve "c", "d", y "e"


$salida = array_slice ($entrada, 2, -1); // devuelve "c", "d"
$salida = array_slice ($entrada, -2, 1); // devuelve "d"
$salida = array_slice ($entrada, 0, 3); // devuelve "a", "b", y "c"

array_splice
(PHP 4 )

array_splice -- Suprime una porción de la matriz y la sustituye por otra cosa

Descripción:

array array_splice ( array entrada, int desplazamiento [, int tamano [, array sustitucion]])
array_splice() suprime los elementos designados por el desplazamiento y el tamano de la matriz
entrada, y los sustituye con los elementos de la matriz de sustitucion si se especifica.
Si el desplazamiento es positivo, el comienzo de la parte suprimida sería en esa posición desde el
comienzo de la matriz de entrada. Si el desplazamiento es negativo, se cuenta la posición desde el
final de la matriz de entrada.
Si se omite tamano, se suprime todo desde el desplazamiento hasta el final de la matriz. Si se
especifica el tamano y es positivo, se suprimirán tantos elementos como se especifica. Si fuera
negativo, el final de la porción eliminada estará a tantos elementos del final de la matriz. Truco: para
eliminar todo desde el desplazamiento hasta el final de la matriz cuando también se especifica
sustitucion, utilice count($entrada) como tamano.
Si se especifia la matriz de sustitucion, entonces los elementos suprimidos son reemplazados con los
elementos de dicha matriz. Si los valores de desplazamiento y tamano son tales que nada es borrado,
los elementos de la matriz sustitucion se insertarán en la posición indicada por el desplazamiento.
Truco: si sólo se va a sustituir algo por un elemento nada más, no hace falta poner array() alrededor
del mismo, salvo que dicho elemento sea una matriz en sí mismo.
Las siguientes funciones son equivalentes:

Página 74/115
Iniciación a PHP 4 5.- VECTORES

array_push($entrada, $x, $y) u array_splice($entrada, count($entrada), 0, array($x, $y))


array_pop($entrada) u array_splice($entrada, -1)
array_shift($entrada) u array_splice($entrada, 0, 1)
array_unshift($entrada, $x, $y) u array_splice($entrada, 0, 0, array($x, $y))
$a[$x] = $y u array_splice($entrada, $x, 1, $y)

Devuelve una matriz que tiene los elementos eliminados:


$entrada = array("rojo", "verde", "azul", "amarillo");

array_splice($entrada, 2); // $entrada vale ahora array("rojo", "verde")


array_splice($entrada, 1, -1); // $entrada vale ahora array("rojo", "amarillo")
array_splice($entrada, 1, count($entrada), "naranja");
// $entrada vale ahora array("rojo", "naranja")
array_splice($entrada, -1, 1, array("negro", "marrón"));
// $entrada vale ahora array("rojo", "verde",
// "azul", "negro", "marrón")

shuffle
(PHP 3>= 3.0.8, PHP 4 )

shuffle -- Mezcla una matriz

Descripción:

void shuffle ( array matriz)


Esta función mezcla (cambia aleatoriamente el orden de los elementos de) una matriz.

$numeros = range (1,20);


srand (time());
shuffle ($numeros);
while (list(, $numero) = each ($numeros)) {
echo "$numero ";
}

Nota: srand() inicializa el generador de números aleatorios con la semilla pasada. Siempre es mejor
trabajar con una semilla aleatoria que con una por defecto.

Página 75/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

6.- FICHEROS y Entrada/Salida


PHP suministra gran cantidad de funciones para poder trabajar con el sistema de ficheros. De
hecho, incluso suministra funciones para abrir procesos y realizar conexiones a sockets. Nosotros
sólo veremos cómo trabajar con el sistema de ficheros.

6.1- Trabajar con Ficheros


Existencia y tamaño de ficheros

Antes de trabajar con un fichero, lo más normal es comprobar su existencia. Esto lo podemos
hacer con la función file_exists(). El único inconveniente que tiene ésta función, es que no distingue
entre ficheros y directorios. Eso significa que si en lugar de pasarle un fichero se le pasa un directorio,
file_exists devolverá cierto si el directorio existe.

Cuando deseamos comprobar si el fichero que se nos pasa es realmente un fichero y no un


directorio, tendremos que usar la función is_file(). Si el fichero que se nos pasa existe, es realmente
un fichero y se puede leer y escribir, entonces is_file devolverá cierto. Esto es extremadamente útil
cuando recorremos el contenido de un directorio. De esta forma podemos reconocer aquellos
elementos que son ficheros y los que no lo son (existe una función homóloga para reconocer
directorios).

Si además necesitamos conocer el tamaño de un fichero, basta con hacer una llamada a la
función filesize(). Ésta se encarga de devolver el tamaño del fichero en bytes.

Veamos en detalle el funcionamiento de cada una de éstas funciones:

file_exists
(PHP 3, PHP 4 )

file_exists -- Verifica si un fichero existe

Descripción:

int file_exists ( string filename)


Devuelve TRUE si el fichero especificado por filename existe; y FALSE en otro caso.
El resultado de esta función es cacheado.

NOTA: Las funciones que sacan información sobre el estado de un fichero suelen ser muy costosas.
Para ahorrar algo de tiempo, PHP “cachea” (almacena) el resultado. Eso significa que si se vuelve a
preguntar por el mismo archivo, no se vuelve ha realizar la comprobación, se usa el resultado
anterior. Si se desea forzar un nuevo chequeo del estado del fichero (por si el fichero puede cambiar
o desaparecer) hay que usar la función clearstatcache().

is_file
(PHP 3, PHP 4 )

is_file -- Dice si el fichero nombrado es un fichero regular

Descripción:

bool is_file ( string filename)


Devuelve TRUE si el fichero nombrado existe y es un fichero regular.
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

IMPORTANTE: Aunque no se indique por ninguna parte, esta función no se comporta de la forma
esperada. Cuando se la pasa el nombre de un fichero, sólo se mira si ese fichero existe en el
directorio actual de trabajo. No vale pasarle el path completo del archivo. Eso significa que si se
desea comprobar la existencia del fichero “./docs/quijote.txt”, primero habrá que hacer un cambio de

Página 76/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

directorio al directorio docs chdir(“./docs”) y luego hacer is_file(“quijote.txt”). Si se hace de


cualquier otra forma, is_file no se comportará de la manera esperada.

Se puede consultar más sobre esto en la página www.php.net. Basta con buscar la función is_file y
luego leer las notas colgadas por otros programadores.

Es posible que el resto de funciones de la familia is_xxx tengan el mismo problema (De echo is_dir
también lo tiene).

filesize
(PHP 3, PHP 4 )

filesize -- Obtiene el tamaño del fichero

Descripción:

int filesize ( string filename)


Devuelve el tamaño del fichero (en bytes), o FALSE en caso de error.
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

NOTA: Puesto que al preguntar el tamaño de archivos grandes pueden aparecer cifras grandes, lo
que se puede hacer es poner las unidades. Eso se puede conseguir dividiendo el tamaño del archivo
entre:
10
2 (1024) para obtener los KBytes
20
2 (1048576) para obtener los Mbytes
30
2 (1073741824) para obtener los GBytes

Abrir y Cerrar Ficheros

Siempre que se desea leer o escribir sobre un archivo, hay que abrirlo antes. Una vez abierto,
y dependiendo de las propiedades al abrir el fichero, podremos escribir o leer de él. Una vez que
hayamos acabado de trabajar con él, es importante que lo volvamos a cerrar. Como se puede
suponer, fopen() abre un fichero y fclose() lo cierra.

fopen
(PHP 3, PHP 4 )

fopen -- Abre un fichero o una URL

Descripción:

int fopen ( string filename, string mode [, int use_include_path])


Si filename comienza con "http://" (no es sensible a mayúsculas), se abre una conexión HTTP 1.0
hacia el servidor especificado y se devuelve un apuntador de fichero al comienzo del texto de
respuesta.
No maneja redirecciones HTTP, por eso se debe incluir una barra final cuando se trata de directorios.
Si filename comienza con "ftp://" (no es sensible a mayúsculas), se abre una conexión ftp hacia el
servidor especificado y se devuelve un apuntador al fichero requerido. Si el servidor no soporta ftp en
modo pasivo, esto fallará. Se pueden abrir fichero via ftp para leer o para escribir (pero no ambas
cosas simultáneamente).
Si filename no comienza con nada de lo anterior, el fichero se abre del sistema de ficheros, y se
devuelve un apuntador al fichero abierto.
Si el abrir el fichero falla, la función devuelve FALSE.
mode puede ser cualquiera de lo siguiente:

'r' - Abre para sólo lectura; sitúa el apuntador del fichero al comienzo del mismo.
'r+' - Abre para lectura y escritura; situa el apuntador del fichero al comienzo del fichero.
'w' - Abre para sólo escritura; sitúa el apuntador del fichero al comienzo del fichero y trunca el fichero
con longitud cero. Si el fichero no existe, trata de crearlo.

Página 77/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

'w+' - Abre el fichero para lectura y escritura; sitúa el apuntador del fichero al comienzo del fichero y
trunca el fichero con longitud cero. Si el fichero no existe, trata de crearlo.
'a' - Abre sólo para escribir (añadir); sitúa el apuntador del fichero al final del mismo. Si el fichero no
existe, trata de crearlo.
'a+' - Abre para lectura y escritura (añadiendo); sitúa el apuntador del fichero al final del mismo. Si el
fichero no existe, trata de crearlo.

Además, mode puede contener la letra 'b'. Esto es útil para sistemas que diferencian entre ficheros
binarios y de texto (ej. es inútil en Unix). Si no se necesita, será ignorado.
Puede usarse el tercer parámetro opcional y fijarlo a "1", si también se quiere buscar el fichero en el
include_path.

$fp = fopen("/home/rasmus/file.txt", "r");


$fp = fopen("http://www.php.net/", "r");
$fp = fopen("ftp://user:password@example.com/", "w");

Si experimentas problemas a la hora de leer y escribir a ficheros y estas usando la versión de PHP
como módulo para el servidor, recuerda que debes asegurar que los ficheros y directorios que estas
usando son accesibles al proceso servidor.

fclose
(PHP 3, PHP 4 )

fclose -- Cierra el apuntador a un fichero abierto

Description:

int fclose ( int fp)


Se cierra el fichero apuntado por fp.
Devuelve TRUE en caso de éxito y FALSE en caso de fallo.
El apuntador al fichero debe ser válido y debe apuntarse a un fichero abierto con éxito con fopen() o
con fsockopen().

Escritura en Ficheros

Antes de abrir un archivo, puede ser interesante saber si podemos escribir sobre él. Ya
hemos visto que la función is_file, a parte de comprobar si el elemento pasado es realmente un
fichero, también comprueba si sobre el fichero destino se puede leer y escribir. Como pudiera darse el
caso que tuviéramos permisos de escritura y no de lectura, la función anterior no nos valdría. La
función is_writeable() nos dice, exclusivamente, si el fichero existe y se puede escribir sobre él.

Una vez que el fichero ha sido abierto con éxito usaremos la función fwrite() para escribir
sobre él.

is_writeable
(PHP 3, PHP 4 )

is_writeable -- Dice si se puede escribir en el fichero indicado

Descripción:

bool is_writeable ( string filename)


Devuelve TRUE si el fichero indicado existe y se puede escribir en él. El argumento filename puede
ser el nombre de un directorio, lo que permite verificar si un directorio tiene permiso de escritura.
Recuerda que PHP puede acceder al fichero con el identificador de usuario con el que el servidor web
se ejecuta (a menudo 'nobody'). No se tienen en cuenta las limitaciones de modos seguros.
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

Página 78/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

fwrite
(PHP 3, PHP 4 )

fwrite -- Escribe ficheros en plan binario

Descripción:

int fwrite ( int fp, string string [, int length])


fwrite() escribe el contenido de string al fichero apuntado por fp. Si se da el argumento length, la
escritura acaba antes de que length bytes sean escritos o se alcance el final de string, lo que ocurra
primero.

Lectura de Ficheros

Al igual que en el caso anterior, antes de abrir un fichero para leer datos, puede ser
interesante comprobar si podemos leer de él. is_readable() comprueba si un fichero existe y
podemos leer de él.

Una vez que el fichero se ha abierto correctamente, disponemos de bastantes maneras para
leer de él:

o fread() lee tantos bytes como le digamos


o fgetc() lee un único carácter
o fgets() permite leer una línea completa
o fgetss() funciona igual que fgets salvo que ésta última se encarga de borrar todas las
etiquetas PHP y HTML que encuentre en la línea.

A parte de estas funciones, existen otras que pueden resultar igual de interesantes. file() lee
un fichero y lo almacena en un vector dónde cada fila del vector es una línea del fichero. Por otro
lado, si lo que queremos es que un archivo se lea y se muestre directamente por pantalla, readfile()
nos soluciona la papeleta.

is_readable
(PHP 3, PHP 4 )

is_readable -- Dice si el fichero indicado se puede leer

Descripción:

bool is_readable ( string filename)


Devuelve TRUE si el fichero indicado existe y se puede leer.
Recuerda que PHP puede acceder al fichero con el identificador de usuario con el que el servidor web
se ejecuta (a menudo 'nobody'). No se tienen en cuenta las limitaciones de modos seguros.
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

fread
(PHP 3, PHP 4 )

fread -- Lee ficheros en plan binario

Descripción:

string fread ( int fp, int length)


fread() lee hasta length bytes del apuntador de fichero referenciado por fp. La lectura acaba cuando
length bytes se han leido o se alcanza EOF, lo que ocurra primero.

Página 79/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

// Mete el contenido de un fichero en una cadena


$filename = "/usr/local/something.txt";
$fd = fopen ($filename, "r");
$contents = fread ($fd, filesize ($filename));
fclose ($fd);

fgetc
(PHP 3, PHP 4 )

fgetc -- Obtiene un caracter del fichero apuntado

Descripción:

string fgetc ( int fp)


Devuelve una cadena (string) conteniendo un simple caracter leido del fichero apuntado por fp.
Devuelve FALSE para EOF (como hace feof()).
El apuntador al fichero debe ser valido, y debe apuntar a un fichero abierto con éxito por fopen(),
popen(), o fsockopen().

fgets
(PHP 3, PHP 4 )

fgets -- Obtiene una línea del fichero apuntado

Descripción:

string fgets ( int fp, int length)


Devuelve una cadena de como mucho length - 1 bytes leidos del fichero apuntado por fp. La lectura
acaba cuando son leidos length - 1 bytes, cuando se llega a una nueva línea (el caracter de nueva
línea se incluye en el valor devuelto), o cuando se llega a un EOF (lo que ocurra primero).
Si ocurre un error, devuelve FALSE.
Fallos Comunes:
Los que hayan usado la semantica de 'C' de la función fgets deben darse cuenta de la diferencia que
hay en como el EOF es devuelto por esta función.
El apuntador al fichero debe ser válido, y debe apuntar a un fichero abierto con éxito con fopen(),
popen(), o fsockopen().
A continuación un ejemplo sencillo:

$fd = fopen ("/tmp/inputfile.txt", "r");


while (!feof($fd)) {
$buffer = fgets($fd, 4096);
echo $buffer;
}
fclose ($fd);

fgetss
(PHP 3, PHP 4 )

fgetss -- Obtiene una línea del fichero apuntado y quita las etiquetas HTML

Descripción;

string fgetss ( int fp, int length [, string allowable_tags])


Idéntica a fgets(), excepto que fgetss trata de quitar cualquier etiqueta HTML y PHP del texto que lee.
Se puede utilizar el tercer parámetro opcional para especificar etiquetas que no deben de quitarse.

Página 80/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Nota: allowable_tags fue añadido en PHP 3.0.13.

file
(PHP 3, PHP 4 )

file -- lee un fichero completo hacia un array

Descripción:

array file ( string filename [, int use_include_path])


Idéntica a readfile(), excepto que file() devuelve el fichero en un array. Cada elemento del array
corresponde a una línea del fichero, con el caracter de nueva línea incluido.
Se puede utilizar el segundo parámetro opcional y ponerle el valor "1", si también se quiere buscar el
fichero en el include_path.

readfile
(PHP 3, PHP 4 )

readfile -- Muestra el contenido de un fichero

Descripción:

int readfile ( string filename [, int use_include_path])


Lee un fichero y lo escribe a la salida estándar.
Devuelve el número de bytes leidos del fichero. Si ocurre un error, se devuelve FALSE y a menos
que la función fuera llamada como @readfile, se imprime un mensaje de error
Si filename comienzo por "http://" (no es sensible a mayúsculas), se abre una conexión HTTP 1.0 al
servidor especificado y el texto de la respuesta se escribe a la salida estándar.
No maneja redirecciones HTTP, por eso se debe incluir una barra final cuando se trata de directorios.
Si filename comienza con "ftp://" (no es sensible a mayúsculas), se abre una conexión ftp al servidor
especificado y el fichero que se pide se escribe en la salida estándar. Si el servidor no soporta ftp en
modo pasivo, la función fallará.
Si filename no comienza con ninguna de las cadenas anteriores, el fichero será abierto del sistema de
ficheros y su contenido escrito en la salida estándar.
Se puede usar el segundo parámetro opcional y fijarlo a "1", si si quieres que también se busque el
fichero en el include_path.

Copiar, Renombrar y Borrar Ficheros

PHP permite copiar, renombrar y borrar archivos, todo de forma dinámica y según las
necesidades de nuestra web. Cuando necesitamos crear archivos temporales para mostrar datos o
queremos recibir ficheros de usuarios, este tipo de funciones se vuelven totalmente imprescindibles.

copy
(PHP 3, PHP 4 )

copy -- Copia un fichero

Descripción:

int copy ( string source, string dest)


Hace una copia de un fichero. Devuelve TRUE si la copia tiene éxito, y FALSE en otro caso.

rename
(PHP 3, PHP 4 )

rename -- Renombra un fichero


Página 81/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Descripción:

int rename ( string oldname, string newname)


Trata de renombrar oldname como newname.
Devuelve TRUE en caso de éxito y FALSE en caso de fallo.

unlink
(PHP 3, PHP 4 )

unlink -- Borra un fichero

Descripción:

int unlink ( string filename)


Borra el fichero filename. Es similar a la función unlink() del Unix C.
Devuelve 0 o FALSE en caso de error.

6.2.- Trabajar con Directorios


Existencia de un directorio

Al igual que nos ocurría con los ficheros, cuando estamos recorriendo el contenido de un
directorio, suele ser interesante saber si el elemento actual es un fichero o un directorio. is_dir()
devuelve cierto si el fichero que se le pasa es un directorio.

is_dir
(PHP 3, PHP 4 )

is_dir -- Dice si el fichero nombrado es un directorio

Descripción:

bool is_dir ( string filename)


Devuelve TRUE si el nombre del fichero existe y es un directorio.
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

Creación y borrado de directorios

mkdir
(PHP 3, PHP 4 )

mkdir -- Crea un directorio

Descripción:

int mkdir ( string pathname, int mode)


Trata de crear el directorio especificado por pathname.
Ten en cuenta que debes especifiar el modo como un número octal, lo que significa que debes
anteponerle un 0 al número.

mkdir ("/path/to/my/dir", 0700);

Devuelve TRUE en caso de éxito y FALSE en caso de fallo.

NOTA: Evidentemente mode sólo es valido en sistemas donde los ficheros tengan permisos. Si se
trabaja sobre windows, esto no tiene sentido.

Página 82/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

NOTA: Para aclararse con el tema de los permisos, haremos un poco de memoria. Ya hemos dicho
que el primer carácter (el 0) es el que indica el número octal, los siguientes siguen esta estructura U
G O (User Group Others, es decir Usuario Grupo Otros). Luego en el ejemplo anterior U=7, G=0 y
O=0. Ese 7 (o 0) es la representación en octal del conjunto de permiso que U tiene. Recordemos que
cada uno puede tener los siguientes permisos r w x (Read Write eXecute, es decir lectura escritura
ejecución). La idea es poner un 1 dónde se le quiera dar permiso y un 0 dónde no. Esa ristra de tres
dígitos binarios se traduce a octal y ese es el conjunto de permisos que se le ha otorgado (7octal =
111 en binario. Luego el usuario U tiene todos los permisos: lectura, escritura y ejecución). Veamos
una tabla aclaratoria
r w x = Octal Significado
000 0 Sin permisos
001 1 Sólo permiso de ejecución
010 2 Sólo permiso de escritura
011 3 Permiso de escritura y ejecución
100 4 Sólo permiso de lectura
101 5 Permiso de lectura y ejecución
110 6 Permiso de lectura y escritura
111 7 Todos los permisos: lectura, escritura y ejecución

rmdir
(PHP 3, PHP 4 )

rmdir -- Elimina un directorio

Descripción:

int rmdir ( string dirname)


Trata de eliminar el directorio indicado por pathname. El directorio debe estar vacio, y los permisos
relevantes deben permitir esto.
Si ocurre un error, devuelve 0.

Apertura y cerrado de directorios

opendir
(PHP 3, PHP 4 )

opendir -- abre el manejador de directorios

Descripcion:

int opendir ( string path)


Devuelve un manejador de directorio para ser usado con las llamadas closedir(), readdir() y
rewinddir().

closedir
(PHP 3, PHP 4 )

closedir -- cierra el manejador de directorios

Descripcion:

void closedir ( int dir_handle)


Cierra la secuencia de directorio determinada por dir_handle. La secuencia debe de haber sido
abierta previamente con opendir().

Página 83/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Lectura del contenido de un directorio

readdir
(PHP 3, PHP 4 )

readdir -- lee las entradas del manejador de directorios

Descripcion:

string readdir ( int dir_handle)


Devuelve el nombre del siguiente fichero en el directorio. Los nombres de ficheros no son devueltos
en ningún orden especial.

Hay que tener en cuenta que readdir() devolverá también las entradas . y ..
Si no se quieren estas entradas, hay que borrarlas manualmente.

<?php <?php
// Con entradas . y .. // Sin entradas . y ..
$handle=opendir('.'); $handle=opendir('.');
echo "Manejador del directorio: $handle\n"; echo "Manejador del directorio: $handle\n";
echo "Archivos:\n"; echo "Archivos:\n";
while ($file = readdir($handle)) { while ($file = readdir($handle)) {
echo "$file\n"; if ( ($file != “.”) && ($file != “..”))
} echo "$file\n";
closedir($handle); }
closedir($handle);
?>

rewinddir
(PHP 3, PHP 4 )

rewinddir -- rebobinar el manejador de directorios

Descripcion:

void rewinddir ( int dir_handle)


Inicializa la secuencia de directorio determinada por dir_handle al principio del directorio.

chdir
(PHP 3, PHP 4 )

chdir -- cambia de directorio

Description:

int chdir ( string directory)


Cambia el directorio PHP actual a directory. Devuelve FALSE si no puede cambiar al directorio,
TRUE si todo va bien.

6.3.- Funciones útiles del Sistema de Ficheros

basename
(PHP 3, PHP 4 )

basename -- Devuelve la parte del path correspondiente al nombre del fichero

Página 84/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Descripción:

string basename ( string path)


Dada una cadena (string) que contiene el path de un fichero, esta función devuelve el nombre base
del fichero.
En Windows, tanto la barra (/) como la barra inversa (\) pueden usarse como caracter separador en el
path. En otros entornos, se usa la barra directa (/).

$path = "/home/httpd/html/index.php3";
$file = basename($path); // $file toma el valor "index.php3"

dirname
(PHP 3, PHP 4 )

dirname -- Devuelve la parte del path correspondiente al directorio

Descripción:

string dirname ( string path)


Dada una cadena (string) conteniendo el path a un fichero, esta función devolverá el nombre del
directorio.
En Windows, tanto la barra (/) como la barra inversa (\) son usadas como separadores de caracteres.
En otros entornos, debe usarse la barra directa (/).
$path = "/home/httpd/html/index.php3";
$file = basename($path); // $file toma el valor "/home/httpd/html"

stat
(PHP 3, PHP 4 )

stat -- Da información sobre un fichero

Descripción:

array stat ( string filename)


Recoge los datos sobre el fichero indicado por filename.
Devuelve un array conteniendo los datos del fichero con los siguientes elementos:
1. dispositivo (device)
2. inode
3. modo de protección del inode
4. número de enlaces
5. id de usuario del propietario
6. id de grupo del propietario
7. tipo de dispositivo si es un inode device *
8. tamaño en bytes
9. fecha del último acceso access
10. fecha de la última modificación
11. fecha del último cambio
12. tamaño del bloque para el sistema I/O *
13. número de bloques ocupados
* - sólo válido en sistemas que soportan el tipo st_blksize --otros sistemas (Windows) devuelven -1
Los resultados de esta función son cacheados. Ver clearstatcache() para más detalles.

Página 85/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

<?php
$stat=stat("./errors.txt");
print_r($stat);
/* Y la salida es:
Array ( [0] => 2 [1] => 0 [2] => 33206 [3] => 1 [4] => 0 [5] => 0 [6] => 2 [7] => 254 [8] =>
1062870622 [9] => 1062857346 [10] => 1062857056 [11] => -1 [12] => -1 [dev] => 2 [ino] => 0
[mode] => 33206 [nlink] => 1 [uid] => 0 [gid] => 0 [rdev] => 2 [size] => 254 [atime] => 1062870622
[mtime] => 1062857346 [ctime] => 1062857056 [blksize] => -1 [blocks] => -1 )
*/
?>

6.4.- Modificación de las características de un archivo


(Consultar la ayuda de PHP para más información)

chgrp -- Cambia el grupo de un fichero


filegroup -- Obtiene el grupo de un fichero
chmod -- Cambia permisos de un fichero
fileperms -- Obtiene los permisos del fichero
chown -- Cambia el propietario de un fichero
fileowner -- Obtiene el propietario del fichero

6.5- Ejecución externa de programas


(Consultar la ayuda de PHP para más información)

exec -- Ejecuta un programa externo


backtickts (comillas simples invertidas)
passthru -- Ejecuta un programa externo y muestra su salida literal
system -- Ejecuta un programa externo y muestra su salida

6.6- Almacenamiento de variables en ficheros

Permite la conversión de una variable en una cadena de caracteres. Esto puede resultar
extremadamente útil si lo que deseamos es almacenar en un fichero o base de datos variables con
una estructura compleja (arrays n-dimensionales, objetos, etc...) de forma directa.

Por ejemplo, imaginemos que tenemos montada una tienda electrónica. Lo normal es que
vayamos almacenando en algún tipo de estructura todos lo objetos que el usuario quiera comprar. Si
nuestro usuario cierra la sesión sin comprar, puede resultar interesante almacenar los objetos que iba
a comprar y recordárselo la próxima vez que inicie sesión. La función serialize agiliza mucho el
proceso pues podemos guardar la estructura tal y como está pero en formato texto. Cuando
queramos recuperar los datos, leemos la cadena y usamos unserialize que nos reconstruye la
estructura tal y como estaba inicialmente.

serialize
(PHP 3>= 3.0.5, PHP 4 )

serialize -- Genera una representación almacenable de una variable

Description:

string serialize ( mixed var)


serialize() devuelve una cadena de caracteres que representa a la variable var y que puede ser
almacenado en cualquier lugar.
Esto resulta muy útil para almacenar variables PHP sin que pierdan su tipo y estructura.

Página 86/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Para volver a convertir la cadena serializada en una variable PHP basta con usar la función
unserialize().
serialize() maneja cualquier tipo (excepto si son recursos). Se pueden serializar incluso
vectores/objetos que contengan referencias a sí mismo, las referencias también serán almacenadas.

Nota: En PHP 3, las propiedades de los objetos eran serializadas, pero se perdían los métodos. PHP
4 elimina dicha restricción.

Conviene consultar la sección Serializando Objetos (Serializing Objects) del punto Clases y Objetos
(Classes and Objects) para más información.

unserialize
(PHP 3>= 3.0.5, PHP 4 )

unserialize -- Crea una variable PHP a partir de una representación serializada anteriormente

Description:

mixed unserialize ( string str)


Se le pasa una cadena de caracteres (correspondiente a la serialización de una variable) y la
convierte en una variable PHP. La variable devuelta corresponderá a uno de los siguientes tipos:
integer, float, string, array o object. En caso que la cadena pasada no se puede deserializar, se
devuelve FALSE.

Ejemplo:
<?php
// $v es un vector
$v[]="A";
$v[]="B";
$v[]="C";
$v[]="D";
$v[]="E";
$v[]="F";

// Imprimimos el vector
print_r($v);
// SALIDA: Array ( [0] => A [1] => B [2] => C [3] => D [4] => E [5] => F )

// Serializamos el vector
$v=serialize($v); // Ahora $v es una cadena de caracteres

// Imprimimos el vector serializado


echo "<br><br>".$v."<br><br>";
// SALIDA:
a:6:{i:0;s:1:"A";i:1;s:1:"B";i:2;s:1:"C";i:3;s:1:"D";i:4;s:1:"E";i:5;s:1:"F";}

// Realizamos el proceso inverso


$v=unserialize($v); // $v vuelve a ser un vector
print_r($v);
// SALIDA: Array ( [0] => A [1] => B [2] => C [3] => D [4] => E [5] => F )
?>

Página 87/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

6.7.- Otras funciones interesantes

tempnam
(PHP 3, PHP 4 )

tempnam -- Crea un fichero de nombre único

Descripción:

string tempnam ( string dir, string prefix)


Crea un fichero temporal de nombre único en el directorio especificado. Si el directorio no existe
tempnam() puede generar un fichero en el directorio temporal del sistema.

Devuelve el nombre del nuevo fichero temporal, o una cadena nula en caso de fallo.
$tmpfname = tempnam ("/tmp", "tmp_");

tmpfile
(PHP 3>= 3.0.13, PHP 4 )

tmpfile – Crea un fichero temporal

Description:

int tmpfile ( void)


Crea un fichero temporal de nombre único en modo escritura y devuelve un manejador de fichero
similar al que se devuelve con fopen(). Si el fichero no es renombrado o movido, es automáticamente
borrado cuando se cierre el fichero (fclose) o finalice el script.
$temp = tmpfile();
fwrite($temp, "Escribiendo en un archive temporal.");
fclose($temp); // this removes the file

parse_ini_file
(PHP 4 )

parse_ini_file – Parsea un fichero de configuración del tipo “ini”.

Description:

array parse_ini_file ( string filename [, bool process_sections])


parse_ini_file() carga el archive ini especificado en filename, y devuelve los datos en un array
asociativo. Si el último parámetro process_sections (procesar secciones) se pone a TRUE, se
devuelve un array multidimensional con el nombre de las secciones incluido. Si no se indica nada,
process_sections está por defecto a FALSE.

Nota: Esta función no tiene nada que ver con el archivo de configuración de php “php.ini”. Dicho
archivo es cargado de forma automática cuando se ejecuta el servidor. Esta función sólo tiene utilidad
para cargar nuestros propios archivos de configuración en nuestros scripts.

IMPORTANTE: Cualquier valor en el archivo de configuración que contenga caracteres que no sean
alfanuméricos ha de estar entre comillas dobles (“”).

Nota: A partir de la versión 4.2.1 de PHP, esta función es afectada por safe_mode and
open_basedir. (Para más información consultar el archivo la ayuda de PHP)

Página 88/115
Iniciación a PHP 4 6.- FICHEROS Y Entrada/Salida

Archivo ejemplo.ini

; <?php die(); ?>


; La primera línea sirve para que nadie pueda acceder a nuestro archivo ini desde fuera del server
; Este es un ejemplo de un archive de configuración
; Las secciones van entre corchetes y los comentarios comienzan con ;

[first_section]
one = 1
five = 5
animal = BIRD

[second_section]
path = /usr/local/bin
URL = "http://www.example.com/~username"

Archivo encargado de parsear el archivo ini:

<?php
// Parsear sin secciones
$ini_array = parse_ini_file("sample.ini");
print_r($ini_array);

// Parsear con secciones


$ini_array = parse_ini_file("sample.ini", TRUE);
print_r($ini_array);
?>

Tendrá la siguiente salida por pantalla:


Array
(
[one] => 1
[five] => 5
[animal] => Dodo bird
[path] => /usr/local/bin
[URL] => http://www.example.com/~username
)
Array
(
[first_section] => Array
(
[one] => 1
[five] => 5
[animal] = Dodo bird
)

[second_section] => Array


(
[path] => /usr/local/bin
[URL] => http://www.example.com/~username
)

Página 89/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

7.- DESARROLLO DINÁMICO DE WEBS

7.1.- Introducción
Hasta el momento no hemos visto más que los pilares del lenguaje PHP, y aunque ya se
pueden intuir las aplicaciones, no hemos visto ningún ejemplo de utilidad real. Una de las
capacidades más interesantes de PHP es la capacidad de crear las páginas que el internauta verá “al
vuelo”.

Una de las primeras ventajas con la que nos encontramos es la capacidad de separar el
diseño de la página de su contenido (mediante Plantillas), evitándonos el costoso trabajo de hacer
copia/pega del código HTML común de cada página. Con este método conseguimos que retocar el
diseño no implique ir archivo por archivo modificando su código. Además, hasta el propio diseño de la
página puede ser dinámico e ir cambiando dependiendo de las fechas o días, según nos pueda
interesar.

Lo segundo es la capacidad para crear contenidos totalmente dinámicos y personalizables.


Así, si el usuario quiere hacer una consulta a una base de datos, o mostrar el contenido de un
determinado fichero, lo que se muestre es algo que nuestro script no sabrá a priori. Incluso puede que
dos usuarios distintos, solicitando la misma información, visualicen cosas diferentes dependiendo de
los permisos que tengan.

Todo esto se puede realizar gracias a que los archivos HTML que nuestro internauta verá son
los que genere nuestro código PHP.

7.2.- Plantillas

Es la base para separar diseño y contenido. Una vez encontrado un diseño web que nos
guste, no tenemos más que trocearlo en partes (secciones) y meter cada parte en una función PHP.
Las partes de un diseño Web suelen ser del tipo: INICIO, TÍTULO, MENU, CONTENIDO,
PIE_DE_PAGINA y FIN. Veamos un ejemplo que aclare lo anterior:

Página HTML dividida en secciones


<!-- Inicio del documento HTML -->
<!doctype html public "-//W3C//DTD HTML 4.0 //ES">
<html>

<!-- Título -->


<head>
<title>Mi primera Plantilla</title>
</head>
<body>

<!-- Menu -->


<p align="center"><a href="http://www.php.net">PHP</a> |
<a href="http://www.mysql.com">MySQL</a> | <a href="http://www.apache.org">
Apache</a> | <a href="http://www.hotscripts.com">Scripts</a></p>

<!-- Contenido -->


<p>&nbsp;</p>
<p align="center"><b><font face="Arial">Ésta es una sencilla página<br>
Con un contenido sencillo</font></b></p>
<p align="center">&nbsp;</p>

<!-- Pie de Página -->


<p align="center"><b><font face="Arial" size="1">Mi pie de página</font></b></p>
</body>

Página 90/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

<!-- Fin del documento HTML -->


</html>

Ahora vamos a crear una función por cada sección, excepto la del contenido:

Archivo “lib_design.php”:

<?php
// Librería de Diseño

function ini_HTML(){
echo <<<ini_HTML
<!-- Inicio del documento HTML -->
<!doctype html public "-//W3C//DTD HTML 4.0 //ES">
<html>
ini_HTML;
}

function titulo($titulo){
echo <<<TITULO
<!-- Título -->
<head>
<title>$titulo</title>
</head>
<body>
TITULO;
}

function menu(){
echo <<<MENU
<p align="center"><a href="http://www.php.net">PHP</a> |
<a href="http://www.mysql.com">MySQL</a> | <a href="http://www.apache.org">
Apache</a> | <a href="http://www.hotscripts.com">Scripts</a></p>
MENU;
}

function pie(){
echo <<<PIE
<!-- Pie de Página -->
<p align="center"><b><font face="Arial" size="1">Mi pie de página</font></b></p>
</body>
PIE;
}

function fin_HTML(){
echo <<<fin_HTML
<!-- Fin del documento HTML -->
</html>
fin_HTML;
} ?>

Página 91/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

Ahora veamos la estructura de la plantilla “plantilla.php”:


<?php
// Plantilla. Es decir, todos nuestros scripts tendrán la siguente estructura:

// Includes y requires
include("./lib_design.php");

ini_HTML();
titulo($título);
menú();

// Contenido o cuerpo del script


/* ... */

pie();
fin_HTML();

Ahora, para ir creando los scripts de nuestra web basta con abrir el fichero anterior, añadirle
el contenido deseado y guardarlo con el nombre que nos interese.

Añadiremos el contenido de la página HTML inicial a nuestra plantilla para ver qué tal queda:
“index.php”:
<?php
// Includes y requires
include("./lib_design.php");
menú();

ini_HTML();
titulo($título);

// Contenido o cuerpo del script


echo <<<HTML
<!-- Contenido -->
<p>&nbsp;</p>
<p align="center"><b><font face="Arial">Ésta es una sencilla página<br>
Con un contenido sencillo</font></b></p>
<p align="center">&nbsp;</p>
HTML;

pie();
fin_HTML();
?>

Como se puede observar a simple vista, las ventajas son múltiples. La primera es que el
código queda mucho más claro. En nuestro caso no se procesa información ni se realizan grandes
tareas, pero si éste fuera el caso, el código quedaría mucho más sencillo de entender. Por ejemplo, si
tuviéramos que acceder a un fichero, procesar los datos y luego mostrarlos por pantalla, el esquema
de nuestro archivo PHP quedaría muy limpio:

1. Se adquieren los datos


2. Se procesan
3. Usamos nuestra plantilla para mostrar los resultados

La segunda es la independencia de cada parte: retocar el diseño, el contenido o el código que


genera nuestro contenido es extremadamente sencillo.

Página 92/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

7.3.- Paso de parámetros entre scripts


Introducción

Cada script es independiente del resto. Es decir, cuando un script acaba, todas las variables
que habían sido definidas son destruidas. De hecho, si había archivos abiertos que se habían dejado
sin cerrar, también se cierran. Igual ocurre con los enlaces abiertos a bases de datos y similares (a no
ser que se hubieran abierto enlaces persistentes, algo implica cierto riesgo).

Normalmente un sitio web está compuesto por diversos scripts que van procesando las
peticiones del usuario. Es importante tener en cuenta que un script no tiene por qué devolver una
página html. Es habitual encontrarse scripts que no muestren salida por pantalla y sólo procesan
datos o que muestren 3 o 4 páginas diferentes según las elecciones del usuario. Si las variables se
crean y se destruyen con cada script, es evidente que deben existir métodos de intercambio de
información entre ellos.

PHP suministra tres métodos: GET (mediante la URL), POST (mediante formularios) y
SESSION_VARS (mediante variables de sesión). El primer método lo veremos en este tema, el resto
en los temas 8 y 9 respectivamente.

El Método GET

La idea es mandar la información a través de la URL. El método es muy sencillo y resulta


extremadamente útil aunque tiene como inconveniente que el usuario puede ver los datos que se
envían e incluso podría modificarlos.

Una URL tiene una estructura similar a ésta:


http://www.mipagina.com

Si queremos abrir el archivo links.php basta escribir:


http://www.mipagina.com/links.php

Si queremos mandarle al archivo links algunas variables basta hacer lo siguiente:


http://www.mipagina.com/links.php?var1=valor1&var2=valor2& …. & varN=valorN

Por ejemplo, queremos mandarle al archivo links dos variables: SO de valor WIN y proc de valor
AMD. Para ello haríamos:
http://www.mipagina.com/links.php?SO=WIN&proc=AMD

Cuando el archivo links se abra, las variables $SO y $proc estarán ya definidas y con valor
WIN y AMD respectivamente (¡OJO! PHP sí que hace distinción entre mayúsculas y minúsculas tanto
en el nombre de las variables como en sus valores).

Para mostrar estas dos variables desde el archivo links simplemente usaríamos el vector global
$_GET:
echo “Sistema Operativo: {$_GET[‘SO’]}<br>\nProcesador del Tipo: $_GET[‘proc’]”;

Si en el archivo php.ini la opción register_globlals está a On, también se podrían llamar sin más:
echo “Sistema Operativo: $SO<br>\nProcesador del Tipo: $proc”;

Problemas

El hecho que el usuario pueda ver las variables no es importante a no ser que se envíe
información que haga peligrar la seguridad del usuario o del mismo sitio web. Si éste es el caso, se
debería utilizar un método más seguro como el método POST o haciendo uso de variables de sesión.

El principal problema reside en que los caracteres ? y & son caracteres protegidos y no
deben estar contenidos dentro de ninguna variable (Es decir ..?tienda=Marks&Spencer es erróneo
pues crearía dos variables: tienda de valor Marks y Spencer de valor nulo). Incluso un simple
espacio en blanco nos podría dar problemas. Para evitar lo anterior, PHP dispone de dos funciones:
urlencode() y urldecode().

Página 93/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

La primera se encarga en codificar cualquier carácter que no sea “-”, “_” y “.” Por un símbolo
de porcentaje y dos dígitos hexadecimales. La segunda función realiza la tarea inversa. Veámoslo
con el ejemplo anterior:

$tienda=“Marks & Spencer”;


$tienda_urlcod=urlencode($tienda);
echo “<a href=’./tiendas.php?tienda=$tienda_urlcod’>Ver: $tienda</a>”;

$tienda_urlcod valdrá Marks+%26+Spencer


Los espacios en blanco se han sustituidos por signos + y el ampersand por %26.

NOTA: Si no se desea que el usuario visualice o modifique lo que se envía, la información se puede
cifrar o codificar.

NOTA: Los formularios también admiten el método GET.

NOTA: Aunque es poco habitual, si no conociéramos a priori el número de argumentos que se le van
a pasar a nuestro script, o si no conocemos ni siquiera los nombres de las variables que se nos
pasarán, tenemos varias alternativas aunque la más sencilla e interesante sería hacer un recorrido
del vector $_GET mediante un foreach() sacando el par clave-valor.

NOTA: El vector global $_SERVER almacena una variable interesante llamada QUERY_STRING que
se encarga de almacenar toda la cadena que hay después del ?. Es decir, si tenemos:

www.mipagina.com/listar_usuario.php?nombre=Gabi&mail=gabmecu@inf.upv.es

$_SERVER[‘QUERY_STRING’] = nombre=Gabi&mail=gabmecu@inf.upv.es

Las utilidades son varias. Nos puede servir por si queremos mandar la información codificada o
cifrada a través de la URL. La cadena cuando llega se decodifica o desencripta y luego se trata
convenientemente con funciones como split() o explode() para sacar los pares clave-valor. Veamos
un ejemplo que aclaratorio:

script1.php

<?php
// Script 1: Codificamos la información para el envío

$nombre='Gabi';
$mail='gabmecu@inf.upv.es';

// Vamos a codificar la información en formato mime64 por sencillez.


// Si lo que se desea es seguridad, habría que usar alguna función de encriptación.

$string_query=base64_encode("nombre=$nombre&mail=$mail");

echo <<<HTML
<a href='script2.php?$string_query'>Mandar datos codificados</a>
HTML;
?>

Página 94/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

script2.php
<?php
// Script 2: Nos llega la información, la decodificamos y la mostramos por pantalla

// Mostramos la cadena codificada


echo "Cadena codificada: ", $_SERVER['QUERY_STRING'],"<br>\n";

// La decodificamos
$query_string=base64_decode($_SERVER['QUERY_STRING']);
// $query_string contendrá "nombre=Gabi&mail=gabmecu@inf.upv.es"

// Gracias a la función split, almacenamos el par vble-valor en una componente de un vector


$var_vect=split('&', $query_string);
// $var_vect[0] contendrá "nombre=Gabi" y $var_vect[1] contendrá "mail=gabmecu@inf.upv.es"

// Recorremos el vector anterior


foreach($var_vect as $par_vble_valor)
{
list($vble, $valor)=split('=', $par_vble_valor);
echo "Variable <b>$vble</b> tiene el valor <b>$valor</b><br>\n";
}

/*
Mostrará por pantalla:

Cadena codificada: bm9tYnJlPUdhYmkmbWFpbD1nYWJtZWN1QGluZi51cHYuZXM=


Variable nombre tiene el valor Gabi
Variable mail tiene el valor gabmecu@inf.upv.es
*/
?>

7.4.- Redireccionamiento

Como ya se ha comentado con anterioridad, es frecuente encontrarse con scripts que sólo
procesan información o que realizan determinadas tareas y al finalizar llaman a otros scripts. Para
poder realizar el redireccionamiento hay que hacer uso de la función headers().

La función header() se utiliza para mandar el texto de la cabecera HTTP al comienzo de un


fichero HTML. Aunque no nos interesa profundizar sobre los tipos de cabecera existentes, es
necesario comentar la cabecera de redireccionamiento: Location.

header("Location: http://www.php.net");
exit;

La primera línea realiza la redirección y la segunda evita que se sigan ejecutando el resto de
instrucciones del script.
3
IMPORTANTÍSIMO: La función header() debe llamarse antes de que se genere salida alguna , bien
con etiquetas HTML normales o con PHP. Un error muy frecuente consiste en leer código con
include() que inserta código html y luego se trata de hacer uso de la función header. Si éste es el
caso, PHP da un error al interpretar el código indicando que las cabeceras ya han sido enviadas
antes de llamar a la función header() (El hecho de mostrar código HTML genera de forma automática
un tipo de cabecera que indica al navegador que va a recibir código HTML).

3
es decir, usando funciones como echo, printf o cualquier otra función que genere salida (código HTML) por
pantalla.
Página 95/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

Los scripts de PHP a menudo generan HTML dinámico que no debe almacenarse en la caché
del navegador cliente o en la caché de cualquier proxy situado entre el servidor y el navegador cliente
(información confidencial o privada). Se puede obligar a muchos proxies y clientes a que deshabiliten
el almacenamiento en caché. Para ello podemos hacer uso de cualquiera de las siguientes
cabeceras:

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Fecha pasada


header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // Siempre se modifica
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Pragma: no-cache"); // HTTP/1.0

7.5.- Scripts que se llaman a sí mismos

Hay que evitar pensar que un script PHP equivale a una página HTML. Dependiendo de
nuestras preferencias, puede resultarnos útil tener varias páginas contenidas en un mismo script.
Veamos un sencillo ejemplo que muestra un menú y dependiendo de las elecciones del usuario,
muestra una información u otra:

<?php
// La variable que indica la elección del usuario se llamará $opc

// Si la variable opc no está definida, es porque el usuario no ha elegido ninguna opción.


if (!isset($_GET['opc']))
{
// El usuario no ha elegido ninguna opción. Mostramos el menú:
echo <<<MENU
<a href="{$GLOBALS['PHP_SELF']}?opc=1">CONTENIDO 1</a>
<a href="{$GLOBALS['PHP_SELF']}?opc=2">CONTENIDO 2</a>
<a href="{$GLOBALS['PHP_SELF']}?opc=3">CONTENIDO 3</a>
MENU;
}
else
{
// El usuario ha elegido una opción
switch($_GET['opc'])
{
case 1:
// CONTENIDO 1
echo "Aquí iría el contenido de la opción 1";
break;

case 2:
// CONTENIDO 2
echo "Aquí iría el contenido de la opción 2";
break;

case 3:
// CONTENIDO 3
echo "Aquí iría el contenido de la opción 3";
break;

default:
// Si vale cualquier otra cosa, volvemos a mostra el menu
header("Location: {$GLOBALS['PHP_SELF']}");
exit;
break;
}
}
?>

Página 96/115
Iniciación a PHP 4 7.- DESARROLLO DINÁMICO DE WEBS

7.6.- Recomendaciones
En el método GET se comentó que en el script destino se podía acceder a las variables
enviadas de dos formas: una mediante el vector global $_GET y otra poniendo register_globals a
On y accediendo a las variables como si fueran simples variables locales. Este último método es el
menos recomendable pues es el más peligroso. Lleva a fallos de seguridad (que pueden consultarse
en http://www.php.net/manual/en/security.registerglobals.php ) y a partir de la versión 4.2.0 de PHP,
register_globals viene a off por defecto.

La opción no es insegura de por sí, el problema reside en posibles despistes del


programador. Por ejemplo, podría darse el caso que nuestro script usara una variable del mismo
nombre que una de las variables que puede llegar. Si algún usuario malintencionado ha visto nuestro
código y ha encontrado algún fallo, podría intentar colarse en alguna sección protegida. Veamos un
ejemplo:

autorizar.php
<?php

if (usuario_autorizado($nombre, $password)) {
$autorizado = true;
}

// Como NO hemos inicializado la variable $autorizado a FALSE al inicio del script,


// gracias a register_globals, alguien podría llamar a este archivo de la siguiente forma:
// autorizar.php?autorizado=1

if ($autorizado) {
include "/info/privilegiada/data.php";
}
?>

Como se puede observar, debido a un fallo nuestro (no hemos inicializado la variable
$autorizado=FALSE al principio del script), nos podemos encontrar con que gente no autorizada
acceda a información privilegiada.

Si se desea acceder a cualquier variable mandada por el método GET, POST o cookies se
puede usar el vector global $_REQUEST, aunque siempre es recomendable usar su vector
específico: $_GET, $_POST, $_COOKIE o $_FILES. Los métodos GET y POST también pueden
utilizar los vectores $HTTP_GET_VARS y $HTTP_POST_VARS. Consultar la ayuda de PHP para
más información.

Página 97/115
Iniciación a PHP 4 8.- FORMULARIOS

8.- FORMULARIOS
8.1.- Introducción
Hasta el momento hemos visto las estructuras para tratar y almacenar los datos del usuario,
pero aún no hemos visto la forma de recogerlos.

La obtención de datos está ampliamente desarrollada mediante los formularios HTML. Todos
estamos acostumbrado a los cajetines, áreas de texto y listas desplegables existentes en casi todas
las Webs y que permiten identificarnos, almacenar datos personales, escribir en foros, firmar libros de
visita, etc..

Debido a que éste método es ampliamente conocido y extremadamente sencillo de utilizar,


PHP hace uso de él, recogiendo los datos y suministrándoselos al programador de forma sencilla,
para que éste los pueda tratar fácilmente.

8.2.- Formularios
Aunque los formularios no forman parte de PHP si no de HTML, haremos un breve repaso a
los formularios y a sus entidades.

Creación Formularios

Un formulario se crea mediante las siguientes etiquetas HTML:

<form action=”script.php” method=”metodo” {enctype="multipart/form-data"}>


.. Entidades del formulario ..
</form>

Aunque existen más atributos, los más importantes y los que utilizaremos nosotros son dos:
o action: Indica el nombre del script que procesará los datos del formulario. También es
válido poner action=”malito: gabmecu@inf.upv.es“ para que los datos sean enviados
directamente a una dirección de correo, aunque no todos los navegadores lo soportan.
Aquí es dónde nosotros pondremos el nombre del archivo PHP que se encargará de
procesar los datos.

o method: Método de envío de datos entre el formulario y el servidor. Puede tener dos
valores: GET y POST. El método GET (que ya hemos visto) envía los datos a través de la
URL mientras que el método POST envía los datos del formulario en el cuerpo de una
petición HTTP POST. El método GET tiene un gran inconveniente: la cantidad de
información que puede ser enviada está limitada al tamaño máximo de la URL que
navegador y servidor pueden manejar. Además, el método GET no soporta el envío de
caracteres que no sean ASCII (cómo "é" y"©"). El método POST siempre es más seguro y
más cómodo. Si se va a trabajar con URL’s de más de 100 caracteres o que contengan
caracteres no ASCII el uso del método POST es imperativo para evitar posibles
problemas.

o enctype: Indica el tipo de contenido que va a ser enviado por el formulario. A no ser que
se vayan a enviar ficheros, este atributo es innecesario. Si este fuera el caso, es
IMPRESCINDIBLE añadir este atributo y con el valor de arriba. Si no existe el atributo, o
si su valor es diferente a "multipart/form-data", los datos no serán enviados
correctamente.

Falta por añadir que dentro de una misma página podemos tener todos los formularios que
necesitemos.

Página 98/115
Iniciación a PHP 4 8.- FORMULARIOS

Entidades

ENTIDADES ORIENTADAS AL TECLADO

Para la inserción de texto por parte del usuario disponemos de dos tipos de entidades: Text
Box (Cajetín de texto) y el Text area box (Cajetín con área de texto).

TEXT BOX
Sirve para entradas de texto cortas y de una sola línea. Su sintaxis es:

<input type=”text” name=”nombre” size=”tam_caja” maxlength=”max_car” value=”val_por_defecto”>

Descripción de los atributos:


o type: Indica la forma en que debe mostrarse el texto. Si se pone “text”, las letras serán
visibles por el usuario. En cambio, si se pone “password”, cada carácter será sustituido por un
asterisco (o un punto, dependiendo del SO).
o name: Nombre del cajetín. Es importante ponerle un nombre significativo ya se verá más
adelante el por qué.
o size: Tamaño del cajetín en caracteres. Es decir, si size=”7”, el explorador mostrará un
cajetín dónde sólo serán visibles los 7 primeros caracteres que el usuario escriba.
o maxlength: Número máximo de caracteres que se podrán insertar en el cajetín. No ha de
coincidir con size.
o value: Valor por defecto. En otras palabras, cuál es el texto inicial que queremos que
aparezca en el cajetín.

TEXT AREA BOX


Útil cuando tenemos entradas de texto largas. Su sintaxis es:

<textarea name=”nombre” rows=”num_filas” cols=”num_columnas” >Texto Inicial</textarea>

Descripción de los atributos:


o name: Nombre del área de texto. Al igual que antes, debe tener un valor significativo.
o rows: Número de filas visibles por el usuario.
o cols: Número de columnas visibles por el usuario.
o Texto Inicial: Valor inicial que se mostrará en el área de texto.

ENTIDADES ORIENTADAS AL RATÓN

Para la selección de opciones mediante el uso del ratón disponemos de tres entidades:
Checkbox (Confirmación de una opción), Radio Button (Botones de Opción) y los Pull-Down Menu
(Listas desplegables).

CHECKBOX
Permite la confirmación de una determinada opción que se le muestra al usuario. Su sintaxis es:

<input type=”checkbox” name=”nombre_1” value=”valor_1” {checked}>Texto Cuadro Conf. 1


<input type=”checkbox” name=”nombre_2” value=”valor_2” {checked}> Texto Cuadro Conf. 2
...
<input type=”checkbox” name=”nombre”_N value=”valor_N” {checked}> Texto Cuadro Conf. N

Descripción de los atributos:


o type: En este caso, type sólo puede valer “checkbox”.
o name: Nombre de cuadro de confirmación. Debe ser significativo.
o value: Único valor posible que tomará este cuadro de confirmación. Si el cuadro de
confirmación ES marcado, entonces su valor será el que indique value. En caso contrario su
valor es nulo.
o {checked}: Es un parámetro opcional. Si se pone, el cuadro de confirmación viene marcado
inicialmente.

Página 99/115
Iniciación a PHP 4 8.- FORMULARIOS

RADIO BUTTON
Permite la selección de una opción entre un grupo de opciones que son mostradas al usuario. Su
sintaxis es:

<input type=”radio” name=”nombre_grupo1” value=”valor_1” {checked}>Texto de la Opción 1


<input type=”radio” name=”nombre_grupo1” value=”valor_2”>Texto de la Opción 2

<input type=”radio” name=”nombre_grupo1” value=”valor_N”>Texto de la Opción N

Descripción de los atributos:


o type: En este caso, type sólo puede valer “radio”.
o name: Nombre del grupo de opciones. Debe ser significativo.
o value: Valor que tomará el conjunto de opciones si se selecciona esta opción.
o {checked}: Es un parámetro opcional. Indica cual de las opciones de grupo viene
seleccionada por defecto. Puesto que con los botones de selección el objetivo es que el
usuario marque (de forma obligada) una de las opciones mostradas, suele ser imperativo (si
no conveniente) que alguna de las opciones venga seleccionada por defecto.

IMPORTANTE:
Si nos fijamos, la diferencia fundamental entre los cuadros de confirmación y los botones de
radio reside en que en el primero cada opción es independiente del resto y TODAS podrían estar
marcadas (cada cuadro de confirmación debe tener un nombre diferente con respecto al resto de
cuadros de confirmación), de ahí que todas puedan llevar el atributo checked.

En cambio, en la selección por opción, sólo se puede seleccionar UNA de las opciones
mostradas (todas las opciones del mismo grupo deben tener el mismo nombre), de ahí que sólo una
de las opciones del grupo pueda llevar el atributo checked.

PULL-DOWN MENU
Genera una lista desplegable de opciones. Su sintaxis es:

<select name=”nombre” {multiple} {size=”num_opciones_a_mostrar”}>


<option {selected} value=”Valor_opción_1”>Texto Opción 1
<option value=”Valor_opción_2”>Texto Opción 2

<option value=”Valor_opción_N”>Texto Opción N
</select>

Descripción de los atributos:


o name: Nombre de la lista desplegable.
o value: Valor de la opción actual. No tiene por qué coincidir con el texto de la opción. Es el
valor que tomará la lista si se selecciona dicha opción.
o {selected}: Es un parámetro opcional. Indica qué opción de la lista vendrá seleccionada por
defecto.

Los atributos opcionales {multiple} y {size} modifican el comportamiento de la lista desplegable.

Si multiple existe, la lista deja de ser desplegable y se convierte en un cuadro de selección


dónde el usuario puede seleccionar múltiples elementos. Para que multiple funcione correctamente,
hemos de cambiar “nombre” por “nombre[]”. Esto es así porque vamos a asignar varios valores a una
misma entidad (variable a efectos de PHP). La única forma de hacer ésto es indicándole a PHP que
almacene los diversos valores de la entidad en forma de vector. Si no se hace así, PHP sólo se
quedará con el último elemento seleccionado ya que todos los elementos tendrán el mismo nombre y
por tanto se irán sobrescribiendo los valores.

Si size existe, la lista deja de ser desplegable y se convierte en un cuadro de selección de


tamaño fijo donde num_opciones_a_mostrar indica el número de opciones a mostrar. A no ser que
multiple también exista, el usuario sólo podrá seleccionar una opción.

NOTA:
Si el número de opciones a mostrar es menor que el número total de opciones, al cuadro de
selección le aparecerá una barra de desplazamiento vertical.
Página 100/115
Iniciación a PHP 4 8.- FORMULARIOS

ENTIDAD ORIENTADA AL ENVÍO DE ARCHIVOS

Más adelante veremos cómo PHP gestiona el envío de ficheros, de momento veremos qué
entidad suministra HTML para tal fin.

<input type="file" name="fichero" size="tam_cajetín">

Descripción de los atributos:


o type: En este caso type sólo puede valer “file”.
o name: Nombre de la entidad.
o size: Tamaño del cajetín (en caracteres) que indica la ubicación del fichero seleccionado por
el usuario.

ENTIDAD ORIENTADA A LA PERSISTENCIA DE DATOS

Si a un formulario le queremos añadir datos adicionales ocultos al usuario, también


disponemos de una entidad para tal fin: Hidden Values (Valores Ocultos)

HIDDEN VALUES
La idea es poder mandar información, obtenida previamente, de un script a otro. Su sintaxis es:

<input type=”hidden” name=”nombre” value=”valor”>

Descripción de los atributos:


o type: En este caso type sólo puede valer “hidden”.
o name: Nombre de la entidad oculta.
o value: Valor de la entidad oculta.

Podemos añadir todas las entidades ocultas que nos interesen. Basta con poner nombres
distintos a cada entidad oculta.

Aunque la información es aparentemente oculta, si el usuario se interesa por ver el código


fuente, podrá ver toda la información oculta que se va a enviar. El uso de estas entidades suele tener
como finalidad la de enviar datos poco importantes que o bien han sido recopilados previamente
mediante otros formularios o mediante algún algoritmo o función concreta.

Siempre que necesitemos enviar información poco importante entre scripts, podemos recurrir
al uso de estas entidades. Proporcionan un sencillo mecanismo para la persistencia de datos sin
tener que recurrir a cookies o variables de sesión.

ENTIDADES GENERALES

Para terminar, veremos dos entidades que permiten enviar los datos o reestablece el valor de
todas las entidades a sus valores por defecto: Submit (Envío de Datos) y Reset (Reestablecer
valores).

SUBMIT
Envía los datos de todas las entidades del formulario al script indicado en action. Su sintaxis es:

<input type=”submit” value=”texto_del_boton”>

Descripción de los atributos:


o type: En este caso type sólo puede valer “submit”.
o Value: Texto del botón. Típicamente “Enviar”.

Página 101/115
Iniciación a PHP 4 8.- FORMULARIOS

RESET
Restaura el valor de todas las entidades a su valor por defecto. Su sintaxis es:

<input type=”reset” value=”texto_del_boton”>

Descripción de los atributos:


o type: En este caso type sólo puede valer “reset”.
o Value: Texto del botón. Típicamente “Reestablecer”

A parte de los atributos ya vistos, existe una atributo opcional común a TODAS las entidades
vistas: tabindex=”num_orden”.

Aunque no suele ser habitual que el usuario se desplace a través de la página mediante el
teclado (usando el tabulador), si este fuera el caso, cuando llegase al formulario el orden en el que se
recorrerán las entidades puede no ser el esperado.

Para evitar esto, podemos añadir a cada entidad el atributo tabindex. El número al que se iguala
este atributo indica el orden en que se recorrerá dentro del formulario.

NOTA:
Así como el botón de envío es imprescindible si queremos que los datos se envíen, el botón
de reestablecer es totalmente opcional.

8.3.- Formularios y PHP


PHP trata de una forma muy sencilla la información que llega a un script a través de un
formulario. Crea una variable por cada entidad, de nombre name y de valor value (el valor de la
entidad), dentro del vector correspondiente ($_GET si el método de envío es get y $_POST si el
método es post). Por ello es importante darle un nombre significativo a cada entidad, a fin de cuentas,
el nombre de la entidad será el nombre de la variable que representará a dicha entidad.

Si en el fichero de configuración php.ini register_globlals está a on, también se podrá


acceder a las variables como si fueran variables locales (con el riesgo que ello conlleva). Veamos un
sencillo ejemplo:

Página 102/115
Iniciación a PHP 4 8.- FORMULARIOS

ejemplo_sencillo.php

<?php
// Sencillo ejemplo que muestra la interacción de PHP con HTML

if (isset($_POST["seenform"]))
{
echo "Nombre: ".$_POST["nombre"]."<br>\n";
echo "Apellidos: ".$_POST["apellido_1"]."&nbsp;".$_POST["apellido_2"]."<br>\n";
echo "<a href='{$GLOBALS['PHP_SELF']}'>Volver al formulario</a>";
}
else
{
echo <<<FORM
<html>
<head>
<title>Formulario Simple</title>
</head>
<body>
<form method="POST" action="{$GLOBALS["PHP_SELF"]}">
Nombre: <input type="text" name="nombre" size="20"><br>
Apellido 1: <input type="text" name="apellido_1" size="20">
Apellido 2: <input type="text" name="apellido_2" size="20"></p>
<input type="hidden" name="seenform" value="TRUE">
<p>
<input type="submit" value="Enviar">
<input type="reset" value="Restablecer">
</p>
</form>

</body>
</html>
FORM;
}
?>

Página 103/115
Iniciación a PHP 4 8.- FORMULARIOS

Envío de archivos con el método POST

Antes de explicar cómo gestiona PHP el envío de ficheros, es conveniente saber cómo
habilitar esta opción.

Para poder enviar ficheros al servidor (file uploads), tenemos que configurar el archivo php.ini
Si hacemos BUSCAR w FILE UPLOADS encontraremos las siguientes líneas:

1. ;;;;;;;;;;;;;;;;
2. ; File Uploads ;
3. ;;;;;;;;;;;;;;;;

4. ; Whether to allow HTTP file uploads


5. file_uploads = On

6. ; Temporary directory for HTTP uploaded files (will use system


default if not specified)
7. upload_tmp_dir = “C:\phpdev\www\public\temp”

8. ; Maximum allowed size for uploaded files


9. upload_max_filesize = 2M

En la línea 5 indicamos si permitimos al usuario enviar ficheros al servidor.

En la línea 7 indicamos el directorio temporal donde se almacenarán los ficheros enviados. Si se


deja en blanco, se usará el directorio temporal del sistema.

En la línea 9 indicamos el tamaño máximo de los ficheros enviados (expresado en Mega Bytes).

Ya hemos visto que para enviar ficheros hacemos uso de la entidad file de HTML. El
tratamiento que PHP hace de esta entidad es bastante intuitivo: crea un archivo temporal en el
servidor y almacena la siguiente información dentro de los vectores globales $_FILES y
$HTTP_POST_FILES:

$HTTP_POST_FILES['fichero']['name'] ó $_FILES['fichero']['name']
El nombre original del fichero en la máquina cliente.

$HTTP_POST_FILES['fichero']['type'] ó $_FILES[' fichero ']['type']


El tipo mime del fichero (si el navegador lo proporciona). Un ejemplo podría ser "image/gif".

$HTTP_POST_FILES['fichero']['size'] ó $_FILES[' fichero ']['size']


El tamaño en bytes del fichero recibido.

$HTTP_POST_FILES['fichero']['tmp_name'] ó $_FILES[' fichero ']['tmp_name']


El nombre del fichero temporal que se utiliza para almacenar en el servidor el archivo recibido.

Donde fichero es el nombre que le dimos a la entidad HTML encargada del envío de ficheros.

Si además register_globals = on, las siguientes variables también serán creadas:

$fichero: Nombre del fichero temporal que sirve para almacenar en el servidor el archivo recibido.

$fichero_name: El nombre original que el fichero tenía en la máquina cliente (usuario).

$fichero_size: El tamaño en bytes del fichero recibido.

$fichero_type: El tipo mime del fichero (si el navegador lo proporciona). Un ejemplo podría ser
"image/gif".

Si en el transcurso del script, el fichero no es ni renombrado ni movido, éste es borrado al


acabar el script.

Página 104/115
Iniciación a PHP 4 8.- FORMULARIOS

Disponemos de dos funciones interesantes para trabajar con ficheros que han sido subidos al
servidor:
is_uploaded_file($fichero_subido) para comprobar si un fichero ha sido subido al servidor mediante
el método POST.

move_uploaded_file($fichero_subido, $fichero_destino) mueve un fichero subido mediante el


método POST hasta el lugar deseado.

Siempre que enviemos ficheros mediante el método POST (existe otro método llamado PUT
que no veremos) es conveniente agregar la siguiente entidad oculta antes de la entidad file:

<input type="hidden" name="MAX_FILE_SIZE" value="tam_max_en_bytes">

Con ella es posible conseguir que el navegador haga una primera comprobación del tamaño del
fichero. Así como el navegador puede saltarse esta comprobación, hay que recordar que PHP tiene
configurado un tamaño máximo para los archivos enviados y rechazará aquellos que superen dicho
tamaño.

Hay que recordar que no se nos puede olvidar añadir el atributo enctype="multipart/form-
data" dentro de la etiqueta del formulario. Veamos un ejemplo completo:

enviar_fichero.html

<html>
<head>
<title>Envío de Ficheros</title>
</head>
<body>
<form enctype="multipart/form-data" action="recibe_fichero.php" method="post">
<!-- El navegador rechazará cualquier fichero que exceda de 1000 bytes,
independientemente del tamaño máximo configurado en php.ini -->
<input type="hidden" name="MAX_FILE_SIZE" value="1000">
Enviar el siguiente archivo: <input name="fichero" type="file"><br>
<input type="submit" value="Enviar Fichero">
</form>
</body>
</html>

Página 105/115
Iniciación a PHP 4 8.- FORMULARIOS

recibe_fichero.php

<?php
// Nombre de la entidad HTML que nos envia el fichero
$nombre='fichero';
// Carpeta dónde moveremos el fichero recibido
$carpeta_destino='./ficheros_recibidos/';

// Si se nos ha enviado un fichero


if (isset($_FILES[$nombre]))
{
// Comprobamos que el fichero ha sido enviado apropiadamente
if (is_uploaded_file($_FILES[$nombre]['tmp_name']))
{
echo "Datos del fichero recibido:<br>\n";
echo "<b>Nombre: </b>".$_FILES[$nombre]['name']."<br>\n";
echo "<b>Tipo MIME: </b>".$_FILES[$nombre]['type']."<br>\n";
echo "<b>Tamaño: </b>".$_FILES[$nombre]['size']." bytes<br>\n";
echo "<b>Temporal: </b>".$_FILES[$nombre]['tmp_name']."<br>\n";

$fich_destino=$carpeta_destino.$_FILES[$nombre]['name'];

// Las dos lineas de abajo son equivalentes


//if (copy($_FILES[$nombre]['tmp_name'], $fich_destino))
if (move_uploaded_file($_FILES[$nombre]['tmp_name'], $fich_destino))
echo "El fichero ha sido subido a la carpeta $carpeta_destino";
else
echo "ERROR: El fichero no ha podido ser movido";
}
}
?>

También se permite el envío múltiple de ficheros. Para hacer esto, se utiliza la misma sintaxis
que cuando tenemos listas múltiples, es decir, basta con cambiar el nombre de “fichero” por el de
“fichero[]” en cada entidad “file” de HTML. Veamos un ejemplo:

enviar_varios_ficheros.html
<html>
<head>
<title>Envío de Ficheros</title>
</head>
<body>
<form action="recibe_varios_ficheros.php" method="post" enctype="multipart/form-data">
Enviar los siguiente ficheros:<br>
<input type="hidden" name="MAX_FILE_SIZE" value="1000">
<input name="fichero[]" type="file" size="30"><br>
<input name="fichero[]" type="file" size="30"><br>
<input name="fichero[]" type="file" size="30"><br>
<input name="fichero[]" type="file" size="30"><br>
<input type="submit" value="Enviar Ficheros">
</form>
</body>
</html>

Página 106/115
Iniciación a PHP 4 8.- FORMULARIOS

recibe_varios_ficheros.php
<?php
// Nombre de las entidades HTML que nos envian los ficheros
$nombre='fichero';
// Carpeta donde moveremos el fichero recibido
$carpeta_destino='./ficheros_recibidos/';

// Si se nos ha enviado un fichero


if (isset($_FILES[$nombre]))
{
// Contaremos el número máximo de ficheros nos pueden haber enviado:
$num_fich_max=count($_FILES[$nombre]['name']);
// Digo máximo porque si había 4 entidades HTML de tipo file, se habrán
// creado cuatro componentes name, cuatro type, etc..
// Pero el usuario puede haber dejado alguna de las entidades en blanco y
// por tanto esas componentes estarán vacías.

// Con esta vble contaremos los ficheros se han enviado en realidad.


$num_fich_real=0;

// Vamos fichero por fichero mostrando sus datos


for ($i=0; $i<$num_fich_max; $i++)
{
// Comprobamos que el fichero ha sido enviado apropiadamente
if (is_uploaded_file($_FILES[$nombre]['tmp_name'][$i]))
{
echo "Datos del fichero <b>$i</b>:<br>\n";
echo "<b>Nombre: </b>".$_FILES[$nombre]['name'][$i]."<br>\n";
echo "<b>Tipo MIME: </b>".$_FILES[$nombre]['type'][$i]."<br>\n";
echo "<b>Tamaño: </b>".$_FILES[$nombre]['size'][$i]." bytes<br>\n";
echo "<b>Temporal: </b>".$_FILES[$nombre]['tmp_name'][$i]."<br>\n";

$fich_destino=$carpeta_destino.$_FILES[$nombre]['name'][$i];

if (move_uploaded_file($_FILES[$nombre]['tmp_name'][$i], $fich_destino))
echo "SUBIDO<br>\n";
else
echo "NO subido<br>\n";

$num_fich_real++;
}
}
}
// Mostramos el número máximo de posibles ficheros enviados y el real.
echo "<br>"; // Línea en blanco
echo "Máximo número de Ficheros recibidos: <b>$num_fich_max</b><br>\n";
echo "Número real de Ficheros recibidos: <b>$num_fich_real</b><br>\n";
?>

Página 107/115
Iniciación a PHP 4 8.- FORMULARIOS

8.4.- Creación Dinámica de Formularios


Sólo queda comentar que, gracias a PHP, la construcción dinámica de formularios puede ser
algo extremadamente útil. Por ejemplo: tenemos una lista desplegable con las opciones más
interesantes que ofrece nuestra web. Si dichas opciones se encuentran en una base de datos o en un
fichero, podemos hacer que la lista desplegable se construya de forma dinámica. Gracias a este
método, cuando queramos modificar el contenido de la lista, no tendremos que tocar nuestro código
PHP, basta con que vayamos a la base de datos o al fichero y modifiquemos su contenido.

Hay que pensar que la creación dinámica de páginas web permite evitar la redundancia e
inconsistencia de los datos, sobre todo cuando se muestra información que es compartida y
modificada por diversos usuarios.

Vamos a ver un ejemplo que crea un formulario de forma totalmente dinámica, en función del
4
contenido de un fichero .ini de configuración:

config.php (archivo ini)

; <?php die("No está permitido el acceso a este fichero"); ?>


; Este es un fichero de configuración.
; El hecho que tenga extensión .php es para evitar accesos indeseados.
; La primera línea se encarga de ello.

; LISTA 1: Lista desplegable simple


[secciones]
; Configuracion de la lista
TEXTO = "Elije la sección a la que te quieres dirigir"
SELECCION =
TAMANYO = 1
; Elementos de la lista
Inicio = "index.php"
Noticias = "noticias.php"
Ofertas = "productos_en_oferta.php"
Productos = "productos_nuevos.php"
Quienes Somos = "quienes.php"
Ayuda = "help.php"

; LISTA 2: Lista de selección múltiple


[mejores_paginas]
; Configuracion de la lista
TEXTO = "Elija sus sitios favoritos"
SELECCION = multiple
TAMANYO = 5
; Elementos de la lista
Apache = www.apache.org
PHP = www.php.net
MySQL = www.mysql.net
FirePages = www.firepages.com.au
WebDesigns = www.oswd.org
HotScripts = www.hotscripts.com

; Podríamos seguir añadiendo todas las listas que necesitáramos

4
Por razones de seguridad, se ha cambiado la extensión .ini a .php. Con un sencillo truco, evitamos que el
usuario pueda descargarse el contenido del archivo.
Página 108/115
Iniciación a PHP 4 8.- FORMULARIOS

formulario_dinamico.php
<?php
// Incluimos el archivo que contiene la función "crea_lista_desp($vect, $l_nombre)"
include("./func_crea_lista.php");

// Creación de un formulario en función del contenido de un fichero INI


// Nombre del fichero
$fich_conf="./config.php";

// Queremos secciones? En nuestro caso SÍ, es imprescindible pues cada sección


// representa una lista desplegable
$secciones=TRUE;

// Parseamos su contenido
$contenido=parse_ini_file($fich_conf, $secciones);

// Primero creamos el formulario


echo "<form method='POST' action='./procesa_form.php'>\n";

// Creamos una lista por seccion


foreach($contenido as $nom_lista => $vect_elements)
{
echo "\n<p>";
crea_lista_desp($vect_elements, $nom_lista);
echo "</p>\n";
}

// Creamos el botones de envio y de reestablecer


echo "\n<p><input type='submit' value='Enviar'>
<input type='reset' value='Restablecer'></p>\n";

// También creamos la entidad oculta seenform para que funcione procesa_form.php


echo "<input type='hidden' name='seenform' value='TRUE'>\n";

// Cerramos el formulario
echo "\n</form>\n";
?>

Página 109/115
Iniciación a PHP 4 8.- FORMULARIOS

func_crea_lista.php
<?php
// Creamos una función que crea una lista desplegable a partir de un vector.
// El vector debe contener tres componentes que configuran la lista:
// TEXTO (indica el texto de la lista), SELECCION (indica si se permite
// la selección múltiple) y TAMANYO (número de elementos a mostrar)
// El orden no importa.
// El resto de componentes son consideradas como los elementos de la lista
function crea_lista_desp($vect, $l_nombre)
{
// Sirve para contar el número de elementos
$i=0;

// Numero de la lista. Indicamos que es estática para no perder su valor


// en la siguiente llamada a la función.
STATIC $l_numero=1;

// Inicialmente la lista no tiene elementos


$l_elementos="";

// Recorremos el vector
foreach($vect as $clave => $valor)
{
switch($clave)
{
case "TEXTO":
$l_texto=$valor;
break;

case "SELECCION":
$l_seleccion=$valor;
// Si la selección es múltiple, los datos han de guardarse
// en un vector
if ($l_seleccion=="multiple") $l_nombre.='[]';
break;

case "TAMANYO":
$l_tamanyo=$valor;
break;

default:
// Sólo el primer elemento estará seleccionado
if ($i==0) $sel_elem="selected";
else $sel_elem="";
// Agregamos un elemento a la lista
$l_elementos.="<option value='$valor' $sel_elem>$clave</option>\n";
// Incrementamos el número de elementos
$i++;
break;
}
}
// Ya tenemos toda la información de la lista. La mostramos por pantalla:
echo "$l_texto<br>\n";
echo "<select size='$l_tamanyo' name='$l_nombre' $l_seleccion tabindex='$l_numero'>\n";
echo $l_elementos;
echo "</select>\n";

// Incrementamos el numero de lista


$l_numero++;
}
?>
Página 110/115
Iniciación a PHP 4 9.- SESIONES

9.- SESIONES

9.1.- Introducción
Hoy en día resulta extremadamente útil el poder hacer un seguimiento del usuario dentro de
nuestra web. Eso permite el poder mostrar información más personalizada atendiendo a los gustos de
nuestro usuario. Pensemos en sitios web que se encarguen de vender productos. Si tenemos una
tienda de libros y hacemos un seguimiento de los libros que consulta, podemos intuir los géneros que
le resultan más atractivos. De este modo, la próxima vez que nos visite, lo primero que le
mostraremos son las novedades y ofertas de los libros pertenecientes sus géneros favoritos.

A parte de las ventajas comerciales y de marketing, también tiene fines de privacidad. Por
ejemplo, podemos mostrar contenidos diferentes atendiendo al tipo de usuario que acceda a nuestra
web. Un ejemplo claro lo tenemos dentro de la web de la universidad.

Una forma sencilla de realizar este seguimiento es mediante las conocidas “cookies”
(galletas). Una cookie no es más que un pequeño fichero de texto que se envía desde el servidor al
navegador del usuario dónde se puede almacenar información. Esto permite que la información entre
usuario y servidor sea persistente. En la actualidad existen cientos de sitios que usan este sencillo
sistema para realizar compras on-line, crear webs personalizadas o mostrar publicidad selectiva.

Pese a ser un método sencillo, las cookies tienen algunos inconvenientes: pueden ser
desactivadas desde el explorador del usuario y, además, tienen un tamaño limitado (máximo
4KBytes). A parte de todo ésto, la información contenida puede no ser del todo fiable pues el usuario
tiene acceso a ella y puede, por tanto, manipularla.

PHP admite el uso de cookies de una forma extremadamente sencilla, pero añade otro
método mucho más flexible, potente y fácil para realizar el seguimiento del usuario: SESIONES.

9.2.- Manejo de Sesiones


La idea es bastante sencilla: cuando un usuario accede a nuestra web, se comprueba si ya
había creado una sesión. Si no lo había hecho, se le crea un identificador único llamado “session id”
(identificador de sesión). Dicho identificador es almacenado en la máquina del usuario (mediante una
cookie). Si el usuario tuviera deshabilitadas las cookies, PHP propagará el identificador de sessión a
través de la URL.

El servidor guardará los datos de esa sesión creando un fichero (en el directo indicado por
session.save_path en php.ini ) cuyo nombre será el identificador de la sesión y cuyo contenido será
las variables que el usuario de dicha sesión vaya registrando.

El usuario siempre podrá acceder a sus variables de sesión registradas gracias a los vectores
$_SESSION y $HTTP_SESSION_VARS (en desuso). Si register_globals está activado, también se
podrán acceder de forma directa a las variables. Recordar que no se aconseja el uso de
register_globals debido a los problemas de seguridad y eficiencia.

NOTA: Se puede configurar PHP para que que cualquier script que se ejecute, inicie
automáticamente sesión. Eso se puede conseguir poniendo session.auto_start = 1 en el fichero
php.ini, aunque no es muy recomendable.

Cuando el usuario haya acabado de usar nuestra web, basta con que cierre su sesión de
para que las variables registradas sean borradas y el fichero en el servidor también sea destruido. La
cookie (si se ha usado) no se destruirá por el hecho de cerrar la sesión, aguantará el tiempo que esté
configurado en session.cookie_lifetime. Si su valor es 0, indica que el tiempo de vida de la cookie
expira cuando se acabe la sesión. Es lo que suele estar puesto por defecto.

Veamos ahora las funciones para el manejo de sesiones:

Página 111/115
Iniciación a PHP 4 9.- SESIONES

Iniciar una sesión

Para iniciar una sesión, basta con llamar a la función session_start(). Crea una sesión o
continúa una existente basandose en el session id pasado por GET o mediante una cookie. Antes de
trabajar con sesiones, siempre hemos de llamar a esta función.

NOTA: session_start() siempre devuelve TRUE, por tanto no tiene sentido usarla dentro de
sentencias condicionales.

Si queremos conocer el identificador que se le ha dado a la sesión, podemos usar


session_id() que devuelve el identificador de la sesión. En un principio, no se puede cambiar este
valor, aunque las últimas versiones de PHP (a partir de la 4.3.2) suministran la función
session_regenerate_id() que permite generar un nuevo identificador conservando la información que
había en la sesión.

Las sesiones también tienen un nombre. Es utilizado para albergar el valor del identificador de
sesión en cookies y URL’s. Por ejemplo, si tenemos desactivadas las cookies en nuestro explorador y
hemos iniciado sesión, cuando cambiemos de script veremos algo similiar a lo siguiente:

http://localhost/public/9-
sesiones/ejemplo_sencillo/mod_sesion.php?PHPSESSID=b51fb8d0c0c1b57eba42876a157e8823

Podemos conocer el nombre de la sesión llamando a la función session_name($nuevo_nombre) que


devuelve el nombre de la sesión actual. Si se le suministra el parámetro opcional $nuevo_nombre,
cambiará el nombre de la sesión. Debido a que al finalizar cada script el nombre de la sesión se
restaura al valor por defecto, guardado en session.name, tendremos que llamar a la función
5
session_name($nuevo_nombre) en cada script y después de llamar a la función session_start().

Si nos interesara cambiar el nombre por defecto, lo podemos realizar cambiando el atributo
session.name en el fichero de configuración (que por defecto vale PHPSESSID).

Registrar variables dentro de una sesión

Registrar variables es un proceso sencillo, pues sólo tenemos que ir creando elementos
dentro del vector superglobal $_SESSION (o $HTTP_SESSION_VARS).

Por ejemplo, si queremos registrar el vector de usuarios $vect_usuario basta hacer:

$_SESSION[‘vect_usuario’]=$vect_usuario;

Si queremos saber si una variable está registrada en la sesión usamos la función isset(), tal y
cómo hacemos habitualmente cuando queremos conocer la existencia de una variable.

Si queremos saber si el vector de películas $vect_pelis está registrado en la sesión haremos:

if (isset($_SESSION[‘vect_pelis’])) echo “El vector EXISTE”;


else echo “El vector NO existe”;

Borrar una variable de la sesión es igual de fácil que cuando borrábamos elementos de un
vector. Hay que hacer una llamada a la función unset():

// Queremos borrar la variable $mail de la sesión


unset($_SESSION[‘mail’]);

IMPORTANTE: Hay que tener en cuenta que $vect_usuario y $_SESSON[‘vect_usuario’] son


variables distintas. Por tanto si modificamos o borramos una de ellas, la otra no se verá afectada.

5
Si se llama a session_name() para cambiar el nombre de la sesión antes de haberla iniciado, el intérprete
considerará que lo que queremos hacer es crear una nueva sesión, con lo que perderemos los datos de la sesión
anterior y crearemos una sesión nueva (y con distinto identificador, evidentemente).
Página 112/115
Iniciación a PHP 4 9.- SESIONES

Aunque el procedimiento anterior es el más cómodo y seguro, si register_globals está


activado, tenemos un método alternativo. En vez de usar los vectores anteriores, podemos registrar
las variables, preguntar por su existencia y borrarlas mediante las siguientes funciones:

session_register(‘variable’); // Registra $variable en la sesión


session_is_registered(‘variable’); // Pregunta si $variable está registrada en la sesión
session_unregister(‘variable’); // Borra $variable de la sesión

Al estar register_globals activado, se puede acceder y modificar las variables de sesión como si de
variables locales se tratasen, aunque si se trata de acceder a ellas dentro de alguna función o un
método habrá que poner delante la palabra reservada GLOBAL.

No vamos a ver cómo manejar las variables de sesión mediante estas funciones. Como ya se ha
comentado antes, no es conveniente trabajar con register_globals activado y si lo está, trabajaremos
como si no lo estuviese.

Destruir una sesión

Destruir una sesión pasa por dos simples pasos: llamar a la función session_unset() que se
encarga de borrar todas las variables de sesión, y seguidamente llamar a session_destroy() que
destruye la sesión y borra el archivo del servidor que almacenaba los datos de la sesión.

Almacenar en disco las variables de una sesión

Cada vez que una sesión es destruida, sus datos son borrados. Si deseamos no perder los
datos de la sesión, PHP nos suministra dos funciones: session_encode() y session_decode(). La
primera codifica todos los datos de la sesión en una cadena de caracteres que puede ser almacenada
en una base de datos o en un fichero. La segunda realiza el procedimiento inverso: se le pasa una
cadena codificada y restaura su contenido creando las variables necesarias en la sesión actual. La
función devuelve TRUE si todo ha ido bien y FALSE en caso contrario.

Es evidente que esto puede resultar extremadamente útil si queremos que el usuario continúe
con la sesión anterior. Por ejemplo, imaginemos que tenemos una tienda electrónica y que vendemos
discos. Si el usuario había metido 4 discos en el carrito de la compra pero no se había decidido a
comprarlos, es interesante que la próxima vez que inicie sesión en nuestra tienda, le dejemos el
carrito tal y como estaba.

< ?php
// Iniciamos sesión
session_start();

// Registramos algunas variables


$_SESSION['nombre']="Gabriel";
$_SESSION['mail']="gabmecu@inf.upv.es";

// Imprimimos el contenido de $_SESSION


print_r($_SESSION);
echo”<br>”;

// Guardamos los datos de la sesión en una variable


$datos_sesion=session_encode();

// Mostramos los datos codificados por pantalla:


echo $datos_sesion; // nombre|s:7:"Gabriel";mail|s:18:"gabmecu@inf.upv.es";
echo”<br>”;

// Ahora vaciamos los datos de la sesión


$_SESSION=Array();

// Restauramos los datos guardados en $datos_sesion

Página 113/115
Iniciación a PHP 4 9.- SESIONES

session_decode($datos_sesion);

// Comprobamos que había lo mismo que antes en $_SESSION


print_r($_SESSION);

// Destruimos la sesión
session_unset();
session_destroy();
?>

Veamos a continuación un ejemplo general que ilustra el manejo completo de las sesiones:

crear_sesion.php
<?php
// Script que crea una sesión y registra una serie de variables dentro de ella
session_start();

$_SESSION['nombre']="Gabriel";
$_SESSION['mail']="gabmecu@inf.upv.es";

// Obtenemos el identificador de sesión


$sesion_id=session_id();
// Obtenemos el nombre de la sesión
$sesion_nombre=session_name();

// Lo imprimimos por pantalla


echo "<b>Identificador de sesión:</b> $sesion_id<br>\n";
echo "<b>Nombre de la sesión:</b> $sesion_nombre<br>\n";

// Modificar el nombre de la sesión y mostrar datos


echo "<br><a href='mod_sesion.php'>Modificar el nombre de la sesión
y mostrar las variables de sesión</a><br>\n";
?>

mod_sesion.php
<?php
// Script que continúa con la sesión anterior. Le cambia el nombre de la sesión
// y muestra las variables registradas en la sesión.
session_start();
session_name("GANDALF_WebSite");

// Obtenemos el identificador de sesión


$sesion_id=session_id();
// Obtenemos el nombre de la sesión
$sesion_nombre=session_name();

// Lo imprimimos por pantalla


echo "<b>Identificador de sesión:</b> $sesion_id<br>\n";
echo "<b>Nombre de la sesión:</b> $sesion_nombre<br>\n";

// Imprimimos TODAS las variables registradas


echo "<br>Las siguientes variables están registradas en la sesión:<br>\n";
foreach($_SESSION as $nombre => $valor) echo "<b>$nombre</b> => $valor<br>\n";

// Enlace para destruir la sesión actual


echo "<br><a href='del_sesion.php'>Destruir la sesión actual</a>";
?>

Página 114/115
Iniciación a PHP 4 9.- SESIONES

del_sesion.php
<?php
// Este script sólo se encarga de guardar los datos de la sesión en un fichero
// y destruir la sesión actual.
session_start();

// Guardamos las variables de la sesión en una cadena


$datos_sesion=session_encode();
echo "Datos de la sesión codificados:<br>$datos_sesion<br><br>";

// Guardamos la cadena en un fichero


$fp=fopen("./sesion.dat", "w");
if (fwrite($fp,$datos_sesion)) echo "Los datos han sido guardados en disco<br>";
else echo "ERROR: Los datos NO se han podido guardar en disco<br>";
fclose($fp);

// Destruimos las variables de sesión


session_unset();

// Ahora ya podemos destruir la sesión actual


if (session_destroy()) echo "La sesión se ha destruido satisfactoriamente";
else echo "ERROR: No se ha podido destruir la sesión";
?>

rebuild_sesion.php
<?php
// Script que inicia sesión y trata de restaurar los datos de la sesión anterior
// contenidos en el fichero sesion.dat
session_start();

// Obtenemos el identificador de sesión


$sesion_id=session_id();
// Obtenemos el nombre de la sesión
$sesion_nombre=session_name();

// Lo imprimimos por pantalla


echo "<b>Identificador de sesión:</b> $sesion_id<br>\n";
echo "<b>Nombre de la sesión:</b> $sesion_nombre<br>\n";

// Ahora restauramos los datos de la sesión anterior


$fp=fopen("sesion.dat", "r");
$datos_sesion=fread($fp, filesize("sesion.dat"));
fclose($fp);

// Descodificamos los datos y los restauramos


session_decode($datos_sesion);

// Imprimimos TODAS las variables registradas


echo "<br>Las siguientes variables están registradas en la sesión:<br>\n";
foreach($_SESSION as $nombre => $valor) echo "<b>$nombre</b> => $valor<br>\n";

// Enlace para destruir la sesión actual


echo "<br><a href='del_sesion.php'>Destruir la sesión actual</a>";
?>

Página 115/115

También podría gustarte