49
Capítulo 8 Arreglos
8 Arreglos 8.1 ¿Qué es un arreglo? Mientras que las variables numéricas o tipo string son variables escalares (sólo puede tener un valor a la vez), un arreglo es una colección de múltiples valores bajo una misma variable. Un arreglo puede consistir de números y/o cadenas (y/o otros arreglos), lo cual permite que una variable pueda contener más información que un número o una cadena. La sintaxis para el nombre de un arreglo es la misma que para los otros tipos de variables: • • •
Principiar con el signo $. Continuar con una letra o un guión bajo. Terminar con cualquier combinación de letras, números o guiones bajos.
Refiriendo como elementos los datos que contiene un arreglo, cada elemento consiste de un índice o llave y un valor. El índice se utiliza como el punto de referencia o apuntador al valor. Al usar un arreglo se debe agregar entre paréntesis rectangulares [ ] el índice al valor particular que se hace referencia.
8.2 Manejo de arreglos Crear un arreglo
Para crear un arreglo hay que usar la función array( ). Se puede crear de varias maneras: $estados = array (‘Chiapas’, ‘Colima’, ‘Puebla’); Aquí no se especifica un índice para cada elemento. Cuando se declara de esta manera, PHP le asigna automáticamente el índice 0 al primer elemento, el índice 1 al segundo y así sucesivamente. Los arreglos principian automáticamente con el índice = 0 a menos que se indique de otra manera. También se pueden asignar índices al crear el arreglo: $estados = array (1 => ‘Chiapas’, 2 => ‘Colima’, 3 => ‘Puebla’);
Programación
Arturo Ruvalcaba
50
Capítulo 8 Arreglos
$estados = array ( 1 => ‘Chiapas’, 2 => ‘Colima’, 3 => ‘Puebla’ ); El símbolo => se utiliza para indicar la asociación entre el índice o llave y su valor. Se puede definir el índice sólo para el primer elemento, el valor de los siguientes índices continuará secuencialmente. $estados = array (1 => ‘Chiapas’, ‘Colima’, ‘Puebla’); El valor del índice no tiene que ser un número, también se pueden usar palabras: $materias = array ( ‘Lunes’ => ‘Programación’, ‘Martes’ => ‘Bases de datos’, ‘Miercoles => ‘Sistemas operativos’, ); Si el índice no es número se encierra entre comillas simples (pueden ser comillas dobles). Si el índice es una variable o una constante tampoco se encierra entre comillas: $dia = ‘Jueves’; $materias[$dia] = ‘Compiladores’; Un arreglo cuyos índices son números se llama arreglo indexado. Si sus índices son tipo string se le llama arreglo asociativo. También se puede usar la función range( ) para crear un arreglo de elementos con base en un rango de valores. $centena = range (1, 100); $alfabeto = range (‘a’, ‘z’); La versión 5 de PHP incrementos:
incluye en la función range( ) un parámetro para especificar
$pares = range (0, 100, 2); // el contenido del arreglo será (0, 2, 4, 6, …, 100) Para imprimir un arreglo se utilizan las funciones print_r( ) y var_dump( ). La primera función imprime el contenido de un arreglo y su estructura, la segunda función muestra cuántos elementos están en un arreglo y la longitud de cada cadena.
Agregar elementos a un arreglo A un arreglo existente se le pueden agregar datos de una manera similar a como se le asigna un valor a una variable. Al agregar un elemento al arreglo se puede indicar o no el índice del elemento a agregar:
Programación
Arturo Ruvalcaba
51
Capítulo 8 Arreglos
$lenguajes[ ] = ‘php’; $lenguajes[ ] = ‘java’;
$lenguajes[ 4 ] = ‘php’; $lenguajes[ 5 ] = ‘java’;
Si no se especifica un índice el nuevo elemento se agrega al arreglo con el siguiente número secuencial de índices. Contar los elementos de un arreglo Se puede determinar el número de elementos que contiene un arreglo con la función count( ): $num_ele = count($lenguajes); La función sizeof( ) es un alias de la función count( ) y también se puede usar para obtener el número de elementos en un arreglo.
Eliminar elementos de un arreglo y un arreglo Para eliminar un elemento de un arreglo se tiene la función unset( ): unset ($lenguajes[5]); unset ($materias[‘Lunes’]); Esta función elimina una variable y libera la memoria que ocupa. Cuando se aplica a un elemento de un arreglo, ese elemento es eliminado. Si se aplica la función unset( ) a un arreglo entero o a cualquier otro tipo de variable, el arreglo o la variable se elimina. unset($lenguajes); unset($variable); También se puede inicializar y vaciar un arreglo usando la función array( ): $estados = array( ); Con esto se inicializa la variable haciendo que exista su tipo y sin asignarle algún valor. Fusionar arreglos PHP tiene la función array_merge( ) que permite agregar un arreglo a otro, como si fuera una concatenación de arreglos. $nuevo = array_merge($arreglo_a, $arreglo_b); Esto mismo se puede lograr al sumar dos arreglos: $nuevo = $arreglo_a + arreglo_b; Acceso a los elementos de un arreglo El acceso a los elementos de un arreglo se hace con sus índices. Cuando el índice es de tipo string hay que ponerlo entre comillas, lo que causa un problema con las comillas de la función print. Esto se evita poniendo entre llaves { } la referencia al arreglo y el elemento:
Programación
Arturo Ruvalcaba
52
Capítulo 8 Arreglos
Incorrecto:
print “La materia del lunes es $materias [‘Lunes’]”;
Correcto:
print “La materia del lunes es {$materias [‘Lunes’]}”;
El modo más rápido de acceder a todos los elementos de un arreglo es con la sentencia foreach, ésta realiza un ciclo a través de cada elemento del arreglo: foreach ($arreglo as $indice => $valor) { print “Indice es $indice. Valor es $valor”; }
Otras funciones para arreglos •
La función reset( ) rebobina el puntero interno de un arreglo o matriz a su primer elemento y regresa el valor se ese elemento o FALSE si la matriz está vacía. reset ($arreglo);
•
La function current( ) devuelve el elemento actual de la matriz o arreglo. Cada matriz tiene un puntero interno al elemento "actual", que se inicializa al primer elemento insertado en la misma. Esta función simplemente devuelve el elemento de la tabla al que apunta el puntero interno, no cambia el valor del puntero. Si el puntero interno apunta fuera del final de la lista de elementos, current() devuelve FALSE. current($arreglo); Nota: Si la matriz contiene elementos vacíos (0 o "", la cadena vacía) esta función devolverá FALSE también 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().
•
La función key( ) devuelve el elemento índice de la posición actual en la matriz. key($rreglo);
•
La función next( ) 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($arreglo); 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. Nota: Si la matriz contiene elementos vacíos, esta función también devolverá FALSE para dichos elementos. Para recorrer adecuadamente una matriz que pueda contener elementos vacíos, vea la función each().
•
La función prev( ) devuelve el elemento de la matriz que está en la posición anterior a la que apuntaba previamente el puntero interno, o FALSE si no hay más elementos.
Programación
Arturo Ruvalcaba
53
Capítulo 8 Arreglos
prev($arreglo); Nota: Si la matriz contiene elementos vacíos, esta función también devolverá FALSE para dichos elementos. Para recorrer adecuadamente una matriz que puede contener elementos vacíos, vea la función each(). prev() se comporta igual que next(), excepto que rebobina el puntero interno una posición en lugar de avanzarlo. •
La función end() avanza el puntero interno de la matriz al último elemento, y regresa su valor. end($arreglo);
Ejemplo: uso de reset(), current(), next(), prev(), end() <?php $transport = array('foot', 'bike', 'car', 'plane'); $mode = current($transport); // $mode = 'foot'; $mode = next($transport); // $mode = 'bike'; $mode = current($transport); // $mode = 'bike'; $mode = prev($transport); // $mode = 'foot'; $mode = end($transport); // $mode = 'plane'; $mode = current($transport); // $mode = 'plane'; reset($transport); $mode = current($transport); // $mode = ‘foot’; ?>
•
La function is_array( ) permite verificar si una variable particular es o no un arreglo: echo is_array($var); // regresa true/false
•
Las funciones array_keys( ) y array_values( ) se utilizan con los arreglos asociativos, regresan un arreglo con las llaves o los valores del arreglo al que se hace referencia respectivamente. array_keys($var);
•
array_values($var);
La función in_array( ) regresa el valor true/false si un valor particular existe o no en el arreglo. echo in_array(“valor”, $var);
•
La función array_search( ) permite la búsqueda de un valor en un arreglo, si lo encuentra regresa la llave correspondiente. echo array_search(“valor”, $var);
Programación
Arturo Ruvalcaba
Capítulo 8 Arreglos
•
54
La función array_push( ) permite agregar elementos al final del arreglo al que se haga referencia. array_push($var, “valor1”, “valor2”, “valor3”);
•
La función array_pop( ) permite eliminar el elemento que está el final del arreglo al que se haga referencia. array_pop($var);
•
La función array_shift( ) permite eliminar el elemento que está al inicio del arreglo al que se haga referencia. array_shift($var);
•
La función array_unshift( ) permite agregar un elemento al inicio del arreglo al que se haga referencia. array_unshift($var, “valor”);
8.3 Arreglos multidimensionales Un arreglo multidimensional es un arreglo que está compuesto a su vez de arreglos, aunque puede tener otras variables. Ejemplo: $aves = array (‘garza’, ‘loro’, ‘paloma’); $mamiferos = array (‘jirafa’, ‘tigre’, ‘gacela’); $reptiles = (‘cocodrilo’, ‘lagartija’, ‘cobra’); $zoo = array ( ‘aves’ => $aves, ‘mamiferos’ => $mamiferos, ‘reptiles’ => $reptiles, ‘horario’ => ‘9:00 – 17:00’, ‘entrada’ => 50.00 ); El arreglo $zoo consiste de tres arreglos (aves, mamiferos, reptiles), una cadena (horario) y un número de punto flotante (entrada). Para tener acceso a un elemento hay que indicar dentro de paréntesis rectangulares, uno por cada dimensión, el elemento que se quiere obtener. Por ejemplo en el arreglo $zoo, tigre se encuentra en $zoo[‘mamiferos’][1]. Para obtener el valor de cada elemento de cada arreglo se puede hacer con sentencias foreach anidadas. Por ejemplo con el arreglo anterior: foreach ($zoo as $especie => $nombres) { print “<p>$especie”; foreach ($nombres as $nombre) { print “<br /> $nombre”; } print “</p>”;
Programación
Arturo Ruvalcaba
Capítulo 8 Arreglos
55
} Si se tiene duda sobre la estructura del arreglo multidimensional, esta se puede observar imprimiendo el arreglo con las funciones print_r( ) o var_dump( ).
8.4 Ordenamiento de arreglos PHP tiene varias funciones para ordenar un arreglo de diferentes maneras. Al ordenar un arreglo se debe tener en cuenta que el arreglo consiste de pares de llaves o índices y sus valores, y el ordenamiento se puede realizar con base en los índices o en los valores. Un arreglo se puede ordenar por sus valores manteniendo la correspondencia con sus índices o sin mantenerla y creando nuevos índices. Funciones sort( ), rsort( ) Para ordenar un arreglo en orden ascendente sin considerar los índices se utiliza la función sort( ), y para sortearlos en orden inverso se utiliza la función rsort( ). Ejemplo: sort ($arreglo); rsort ($arreglo); Funciones asort( ), arsort( ) Para ordenar los valores manteniendo la correlación entre los valores y sus índices se usa la función asort( ), y para sortearlos en orden inverso manteniendo esa correlación se utiliza la función arsort( ). Funciones ksort( ), krsort( ) El ordenamiento por índices manteniendo la correlación con sus valores se realiza con la función ksort( ), y para sortearlos de la misma manera pero en orden inverso se utiliza la función krsort( ). Función shuffle( ) La función shuffle( ) reorganiza aleatoriamente el orden de un arreglo. Funciones natsort( ), natcasesort( ) La función natsort( ) implementa un algoritmo que ordena cadenas alfanuméricas en un “orden natural”, al mismo tiempo que conserva la relación entre índice y valor. Devuelve TRUE si todo se llevó a cabo correctamente, FALSE en caso de fallo. natsort($arreglo); La función natcasesort( ) implementa un algoritmo que ordena cadenas alfanuméricas en un “orden natural”, al mismo tiempo que conserva la relación entre índice y valor. Devuelve TRUE si todo se llevó a cabo correctamente, FALSE en caso de fallo. Esta función es una versión de natsort( ) que no distingue entre mayúsculas y minúsculas. natcasesort($arreglo);
Programación
Arturo Ruvalcaba
56
Capítulo 8 Arreglos
8.5 Otras funciones para arreglos Función extract( ) La function extract( ) se utiliza para importar variables desde una matriz asociativa. void extract ( array matriz_vars [, int tipo_extraccion [, string prefijo]] ) Toma la matriz asociativa matriz_vars y trata las claves como nombres de variable y los valores como los valores de éstas. Para cada par clave/valor creará una variable en la tabla de símbolos actual, sujeto a los parámetros tipo_extraccion y prefijo. extract() controla las colisiones con las variables que ya existen. La forma de tratar éstas se determina por el tipo_extraccion. Puede tener únicamente uno de los siguientes valores: • • • • • •
• •
•
EXTR_OVERWRITE .- Si hay colisión, sobrescribe la variable existente. EXTR_SKIP .- Si hay colisión, no sobrescribas la variable existente. EXTR_PREFIX_SAME .- Si hay una colisión, añade el prefijo a la nueva variable. EXTR_PREFIX_ALL .- Añade el prefijo a todas las variables. EXTR_PREFIX_INVALID .- Solo agrega el prefijo a nombres de variables invalidas/numéricas. Este fue agregado en PHP 4.0.5. EXTR_IF_EXISTS .- Solo sobrescribe la variable si ya existe en la tabla de símbolos actual, de otra manera no hace nada. Esto es útil para definir una lista de variables validas y entonces extraer solo aquellas variables que estén definidas fuera de $_REQUEST por ejemplo. Esta bandera fue agregada en PHP 4.2.0. EXTR_PREFIX_IF_EXISTS .- Solo crea los nombres de variables con el prefijo si la versión de la variable sin prefijo existe en la tabla de símbolos. Esta bandera fue agregada en PHP 4.2.0. EXTR_REFS .- Extrae las variables como referencias. Esto efectivamente significa que los valores de las variables importadas están aún referenciando a los valores del parámetro matriz_var. Puede usar esta bandera por sí sola o combinada con cualquier otra bandera haciendo (OR) el parámetro tipo_extraccion. Esta bandera fue agregada en PHP 4.3.0. Si no se especifica tipo_extraccion, se asume que vale EXTR_OVERWRITE.
Nótese que el prefijo sólo se necesita si tipo_extraccion vale EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID o EXTR_PREFIX_IF_EXISTS. Si el resultado con prefijo no es un nombre de variable valido, no es importado en la tabla de símbolos. extract() regresa el número de variables exitosamente importadas en la tabla de símbolos. Nota: No use extract() en datos no confiables, como entradas de usuario ($_GET, ...). pero si lo hace, por ejemplo, si quiere correr código anterior que confía temporalmente en register_globals, asegúrese de que usa una de los valores de no-sobrescribir del parámetro tipo_extraccion tales como EXTR_SKIP y asegúrese de extraer las variables $_SERVER, $_SESSION, $_COOKIE, $_POST y $_GET ese orden.
Programación
Arturo Ruvalcaba
57
Capítulo 8 Arreglos
Ejemplo de extract() <?php /* Suponemos que $matriz_var es una matriz devuelta por wddx_deserialize */ $tamano = "grande"; $matriz_var = array ("color" => "azul", “tamano" => "media", "forma" => "esfera"); extract ($matriz_var, EXTR_PREFIX_SAME, "wddx"); print "$color, $tamano, $forma, $wddx_tamano\n"; ?>
El resultado del ejemplo seria: azul, grande, esfera, media La variable $tamano no fue sobrescrita porque se especificó EXTR_PREFIX_SAME, que provocó la creación de $wddx_tamano. Si se hubiera especificado EXTR_SKIP, $wddx_tamano ni siquiera habría sido creada. EXTR_OVERWRITE habría provocado que $tamano tuviera el valor "media", y EXTR_PREFIX_ALL habría provocado que aparecieran nuevas variables llamadas $wddx_color, $wddx_tamano, y $wddx_forma. Debe usar matrices asociativas, las matrices numéricamente indexadas no producirán resultados a menos que use EXTR_PREFIX_ALL o EXTR_PREFIX_INVALID. Esta función se puede usar como una buena herramienta para encontrar errores o como un atajo a los valores de un arreglo. Función list( ) La función list( ) también permite convertir elementos de un arreglo en variables. Se aplica a arreglos o matrices indexadas numéricamente. Se usa para crear variables asignándoles valor en una sola operación. Es muy usada cuando se obtienen valores de una base de datos. Ejemplo: $date = array (‘Jueves, 15, ‘Febrero’); list ($dia, $num_dia, $mes) = $date; Al aplicar la función list al arreglo $date se tiene una variable $dia con el valor de Jueves, una variable $num_dia con el valor de 15 y la variable $mes con el valor de Febrero. Al aplicar la función se debe tener conocimiento de cada elemento del arreglo. En el ejemplo se podría tener:
Programación
Arturo Ruvalcaba
58
Capítulo 8 Arreglos
list ($dia, ,$mes) = $date; list ( , , $mes) = $date; pero no: list ($mes) = $date; Función each( ) La función each( ) devuelve el par clave-valor actual para el arreglo y avanza el apuntador del mismo. Este par clave-valor se devuelve en un arreglo de 4 elementos, con las claves 0, 1, key, y value. Los elementos 0 y key contienen el nombre de clave del elemento del arreglo, y 1 y value contienen los datos. Si el apuntador interno para arreglo apunta después del final del contenido del mismo, each() devuelve FALSE. Ejemplos de each() <?php $amigos = array ("Julio", "Sergio", "Pedro", "Juan"); $un_amigo = each ($amigos); print_r($un_amigo); ?> $un_amigo ahora contiene los siguientes pares de llave/valor: Array ( [1] => Julio [value] => Julio [0] => 0 [key] => 0 ) Para un arreglo asociativo: <?php $foo = array("Francisco" => "Pancho", "José" => "Pepe"); $bar = each($foo); print_r($bar); $bar ahora contiene los siguientes pares de llave/valor: Array ( [1] => Pancho [value] => Pancho [0] => Francisco [key] => Francisco )
each() se usa normalmente de forma conjunta a list() para recorrer una matriz; por ejemplo:
Programación
Arturo Ruvalcaba
Capítulo 8 Arreglos
59
Recorriendo una matriz con each()
<?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); reset($fruit); while (list($key, $val) = each($fruit)) { echo "$key => $val\n"; } ?> El resultado del ejemplo seria: a => apple b => banana c => cranberry
Cuando se ha ejecutado each(), el cursor de la matriz quedará en el siguiente elemento de la misma, o en el último si llega al final de ésta. Tiene que usar reset() si quiere recorrer la matriz otra vez usando each.
8.6 Transformación entre cadenas y arreglos A continuación se explican dos funciones para intercambios entre dos formatos. La primera, implode( ), cambia un arreglo a una cadena. La segunda, explode( ), hace lo opuesto. Estas funciones se utilizan para: • • •
Convertir un arreglo en una cadena para pasar el valor añadido a un URL (lo cual no puede hacerse tan fácilmente como con un arreglo). Convertir un arreglo en una cadena para guardar esa información en una base de datos. Cambiar una cadena en un arreglo para convertir un texto delimitado por comas (por ejemplo la búsqueda de una palabra clave en un formulario) en sus partes separadas.
Función explode( ) array explode ( string separador, string cadena [, int límite] ) Devuelve una matriz de cadenas, cada una de las cuales es una subcadena de cadena formada mediante su división en las fronteras marcadas por la cadena separador. Si se especifica límite, la matriz devuelta contendrá un máximo de límite elementos con el último conteniendo el resto de la cadena.
Programación
Arturo Ruvalcaba
60
Capítulo 8 Arreglos
Si separador es una cadena vacía (""), explode() devuelve un valor igual a FALSE. Si separador contiene un valor que no está presente en cadena, la función explode() devuelve una matriz que contiene la cadena. Si el parámetro límite es negativo, se devuelven todos los valores salvo el último límite. Este comportamiento se incluyó en la versión de PHP 5.1.0. Aunque la función implode() por razones históricas puede aceptar sus parámetros en cualquier orden, no sucede lo mismo con la función explode(). Por tanto, se debe asegurar que el argumento separador se indique antes que el argumento cadena. Nota: El parámetro límite se incluyó en PHP 4.0.1. Ejemplos de explode() <?php // Ejemplo 1 $pizza = "trozo1 trozo2 trozo3 trozo4 trozo5 trozo6"; $trozos = explode(" ", $pizza); echo $trozos[0]; // trozo1 echo $trozos[1]; // trozo2 // Ejemplo 2 $datos = "usuario:*:1023:1000::/home/usuario:/bin/sh"; list($usuario, $contrasena, $uid, $gid, $gecos, $home, $shell) = explode(":", $datos); echo $usuario; // usuario echo $contrasena; // * ?>
Función implode( ) string implode ( string elemento_union, array trozos ) Devuelve una cadena que contiene una representación de todos los elementos de la matriz en el mismo orden, pero con la cadena elemento_union en medio de los mismos. Ejemplo 1. Ejemplo de implode() <?php $array = array('apellido', 'email', 'telefono'); $separado_por_comas = implode(",", $array); echo $separado_por_comas; // apellido,email,telefono ?>
Programación
Arturo Ruvalcaba
Capítulo 8 Arreglos
61
Nota: La función implode() puede, por razones históricas, aceptar sus parámetros en cualquier orden. Sin embargo, para mantener la consistencia con la función explode(), se recomienda emplear los parámetros en el orden indicado. Nota: Desde la versión de PHP 4.3.0, el parámetro elemento_union es opcional y su valor por defecto es una cadena vacía (''). De todas formas, para mantener la compatibilidad con versiones anteriores, se recomienda indicar siempre los 2 parámetros definidos.
Programación
Arturo Ruvalcaba