Certificación Zend PHP 5.3 (III) – Arrays (II)

Tras unos días de inactividad y Hacker Cups variadas retomamos el hilo normal del blog con la segunda parte de arrays.

En este post hablaremos de algunas funciones interesantes que tiene PHP para tratar arrays y sobretodo de una de las grandes novedades en PHP 5.3, los closures.

Si veis posts sobre gente que ha estado estudiando para la certificación, veréis que mucha gente se queja o duda de la inutilidad de conocer de memoria funciones como array_map, array_splice, array_chunk. Personalmente, no comparto esta afirmación. Es posible que no recordemos todos los parámetros de las funciones, pero desde luego si las conocemos podremos hacer muchas tareas con los arrays que de otra manera haríamos a mano y, además, probablemente de forma incorrecta.

Desde luego, si tenéis pensado presentaros al examen, ya podéis coger http://php.net/manual/en/ref.array.php y estudiárosla de arriba a abajo. Recomiendo además SIEMPRE estudiar PHP con Netbeans o vuestro editor favorito y haciendo pruebas una y otra vez. Solamente así acabaréis entendiendo bien las funciones.

Funciones de ordenación

Muchas veces nos puede interesar ordenar los elementos de un array, según unos criterios. Para ello están las funciones de la familia xsort (sort, rsort, asort, arsort, ksort, krsort…) con sus parámetros.

No me voy a extender mucho sobre ellas, pero de cara al examen, dos cosas MUY importantes.

– El array que le pasamos a estas funciones va por referencia. Eso implica que se modifica el mismo y al terminar la función no podemos recuperar el estado anterior).
– Estas funciones devuelven o true o false.

Y nos podemos encontrar preguntas como:

¿Qué hace el siguiente código?

<?php
   $array = array(2, 1, 5, 0);
   echo count(sort($array));?>
Spoiler
La respuesta es 1. Sort del array, efectivamente ordena el array, pero devuelve true. Y count de algo que no es un array, devuelve 1.

Ordenaciones a medida: usort + callback

Muchas veces, necesitamos ordenar un array de objetos, según algún criterio un poco especial. La forma más sencilla es usar usort. Esta función, además del array, espera un parámetro de tipo Callable, que no es más que una función que recibe dos elementos y devolvemos un entero. Si es positivo, el primer parámetro es mayor en orden que el segundo. Si es 0 son iguales. Y si es negativo, lo contrario.

Para ilustrar esto, vamos a suponer una tienda de ropa ficticia (jejejeje) donde a veces interesa ordenar un array de objetos stock por su tallaje. Y claro, las tallas tienen un orden tipo XS, S, M, L, XL (y además pueden variar según país, añadir XXS y XXL, etc…).

Vamos a definir un array de códigos de talla ordenados, una serie de objetos desordenados y con un closure los vamos a ordenar.

<?php
/* Clase "cutrecilla" para ilustrar el ejemplo */
   class Stock {
       public $art;
       public $talla;
       public function __construct($art, $talla) {
           $this->art = $art;
           $this->talla = $talla;
       }
   }
   /* Definición del orden de las tallas */
   $ordenTallas = array('XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL');
   /* Array de objetos, no soportado por las xxsort */
   $ropa = array(
       new Stock('Pantalones', 'L'),
       new Stock('Blusa', 'M'),
       new Stock('Calcetines', 'XXS'),
       new Stock('Falda', 'XL'),
   );
   // Queremos que ordene ascendiente la ropa según las tallas
   // Vaya, que al final el orden sea Calcetines, Blusa, Pantalones, Falda
   usort($ropa, function($a, $b) use ($ordenTallas) {
       return (array_search($a->talla, $ordenTallas) - array_search($b->talla, $ordenTallas));
   });
   // Et...voilà!
   var_dump($ropa);
?>

Interesante en este caso el constructor use del closure. La variable $ordenTallas está definida en otro ámbito. Si queremos que las variables del ámbito superior estén también en el ámbito de la función, esta es la manera de pasarlo.

En cuanto al tratamiento, con array_search, devolvemos la clave en el array de tallas de la talla (es decir, 0 para XXS, 1 para XS, …) y al devolver la diferencia sabremos cómo terminarán quedando los elementos.

Lo realmente chulo del tema es que todo este código nos vale si queremos introducir nuevas tallas, ya que no hay más que modificar el array $ordenTallas. O incluso extender el código para diferentes países o tipos de mercancía solamente cambiando el array de configuración.

Veréis también que el último elemento del array $ropa tiene una ‘,’ al final, aunque no hay nada detrás. Esto no es una errata, está soportado por PHP y de hecho es una manía mía. Con ello, si alguien poco técnico entra a tocar el array para añadir un nuevo valor, probablemente hará CTRL-C, CTRL-V debajo y editará el valor. De esta manera, no tiene que recordar la , del final. Parece una tontería pero no lo es :).

Funciones para tratar los arrays como un haystack

Estas funciones son bastante útiles para recoger los datos de la Hacker Cup y especialmente cuando recibimos de, por ejemplo, un fichero de texto. Tenemos:
– array_shift: Nos devuelve el primer elemento del array y deja al array sin el mismo.
– array_unshift: Introduce el elemento en la posición 0 del array y si es necesario, desplaza todas las claves numéricas
– array_push: Introduce el elemento al final del array.
– array_pop: Devuelve el último elemento del array y lo elimina del mismo.

Otras funciones que uso a menudo

– shuffle: Reordena el array de forma aleatoria, muy útil!
– array_map: Aplica un tratamiento a todos los elementos de un array. Por ejemplo:

<?php
   // Eliminar espacios de los super-globales
   array_map('trim', $_POST);
   array_map('trim', $_GET);
?>

– array_fill: Para rellenar varios elementos con el mismo valor. A veces es útil.
– array_unique: Viene a ser una especie de “SELECT DISTINCT”.

Cosas que encontraréis 99% en el examen y no he comentado antes

– array_slice: Viene a ser una especie de substring, aplicado a los arrays.
– array_splice: Nunca sabré de memoria lo que hace, pero es probable que os la encontréis.
– extract: Convierte el par ‘clave’ => ‘valor’ a $clave = ‘valor’.

¿Qué da esto?

<?php
  $array = array('a' => 'John', 
                       'b' => 'Coggeshall', 
                       'c' => array('d' => 'John', 
                                        'e' => 'Smith')
                       ); 
  function something($array) {
    extract($array); 
    return $c['e']; 
  } 
  print something($array);
?>
Spoiler
Da Smith. Extract en este contexto es equivalente a escribir $a = ‘John’; $b = ‘Coggeshall’, $c = array(‘d’ => ‘John’, ‘e’ => ‘Smith’));

– list: Asigna a variables los elementos del array.

What would you replace ??????? with, below, to make the string Hello, World! be displayed?

<?php
function myfunction() {
???????
print $string;
}
myfunction("Hello, World!");
?>
Spoiler
Se puede, se puede… haciendo por ejemplo list($string) = func_get_args();

Pues esto es todo por hoy, próximamente más cositas de PHP!

You may also like...

18 Responses

  1. Tenshin says:

    Closures eso es lo que queria ver.
    Como puedo saber si estoy bien preparado para el examen?
    Antes habian examenes asequibles de precio pero ahora no se como practicarlo.
    http://zend-php.appspot.com/questions_list/1
    Aqui hay preguntas para php5 , pueden servir las preguntas de arrays y las basicas?

  2. Ricard Clau says:

    Hola Tenshin

    Esas preguntas que aparecen en el link son un recopilatorio de los antiguos Mock Test, te pueden dar una idea de si estás preparado o no, pero no son definitivos. Además, algunas respuestas están mal, te recomiendo que lo compruebes ejecutándolo con las versiones más recientes de PHP5.3.

    Hace unos cuantos posts, puse un slideshare de Carlos Buenosvinos donde aparecen algunas de las nuevas preguntas y en cuanto a arrays y básicas, las preguntas que voy poniendo son del estilo que te puedes encontrar.

    De todas maneras, es verdad que a día de hoy no hay una guía de estudio definitiva del examen de 5.3 🙁

  3. Antonio says:

    Holas,
    Estan buenos los articulos, sobre la ultima pregunta casi la acierto, puse lo siguiente:

    Al parecer devolvio el Hello, World! tambien 😀
    Estan buenisimos los articulos, continuen con ello…

    Saludos

  4. Antonio says:

    jojo, se borro el codigo que puse XD

    reemplaze estas lineas
    ?????
    por
    $string = func_get_arg(0);

  5. Tenshin says:

    Si ya he visto las preguntas tipo examen , y las que vas poniendo y ayudan mucho.
    😀

  6. Ricard Clau says:

    Antonio, esa respuesta también sería correcta pero tenía que colar el list de alguna manera :mrgreen:. Lo del código me parece que el textarea de comentarios no deja poner los tags de php y se come todo lo que haya dentro.

    Tenshin, lo más importante de cara al examen es no confiarte y sobretodo asegurar muy mucho strings, arrays y la base de PHP. De todas maneras, en próximos días tocaré más temas que salen como XML, etc…

  7. Tenshin says:

    Ok gracias , tengo pensado hacer el examen la semana del 15 de febrero

  8. Tenshin says:

    Hola , al final aplace el examen para hoy 25 de febrero, Despues de unos largos 90 minutos sudando con algunas preguntas me aparecio la palabra congratulations has pasado el examen :mrgreen:
    En el examen encontre preguntas faciles , muchas relacionadas con strings y fileupload, otras dificiles q pusieron a prueba mi logica, y entre 2-4 de ??? esto que es!!!
    De preguntas de arrays me esperaba mas como tambien de clases, namespace salio en tres preguntas.
    El post de php basics me fue muy util , Gracias Ricard! pues salieron bastantes preguntas relacionads.
    Un saludo a todos.

  9. Ricard Clau says:

    Hola Tenshin

    Me alegro de que entres a formar parte del selecto grupo de las PHP Yellow Pages :).

    En strings supongo que te pusieron algunas regexp y demás, pronto haré un post al respecto.

    Las de fileupload, eran así relacionadas tmb con la parte HTML?

    Y en cuanto a namespaces… recuerdas las preguntas cómo eran más o menos? La verdad es que hay poca info al respecto.

    En cualquier caso, reitero mis felicitaciones 😀 y me alegro de que te sirviera alguno de mis posts!

  10. Tenshin says:

    Gracias Ricard 😀
    Las de fileupload estaban relacionadas con html y tambien aspectos de seguridad.
    Respecto a namespace te pedia como abreviar el enlace a una clase namespace\subspace\miclase
    Y la otra era respecto la definicion de namespace que es de tipo envoltorio.
    Hasta ahi llega lo que me acuerdo , no se si me he explicado bien.
    saludos

  11. Ricard Clau says:

    Gracias Tenshin

    La verdad es que hay poca información sobre las nuevas preguntas de 5.3. Una duda, cuando compraste el voucher tenías una guía de estudio actualizada o solamente la beta que hay en la web de zend que está llena de fallos y preguntas incompletas?

    De nuevo felicidades y espero que sigas visitando el blog 😀

  12. Tenshin says:

    Cuando compre el voucher tenia la guia beta que hay en la web, la mejor guia que encontre fue http://www.php.net
    y la mejor pagina que encontre con explicaciones fue la tuya.
    En esta pagina encontre los temas mas importantes para mirar : http://devzone.zend.com/article/12647.
    Porcierto yo tambien soy de barcelona, seria un honor quedar contigo para tomar un cafe/te 😉

  13. Ricard Clau says:

    Sí, es un poco desastre que ni la propia Zend tengan una Guía de Estudio. Eso seguro que provoca que la gente se lo piense antes de soltar los casi 200€ :).

    En cuanto a quedar, cuando quieras. De todas maneras no creo que tarde mucho en haber otra PHP&Beers así que puedes apuntarte y conocer a más PHPeros.

  14. Tenshin says:

    Si ya les vale, podrian poner alguna guia chula.
    Pues respecto a quedar te tomo la palabra , a mi me va bien la semana que viene por la tarde cualquier dia.

  15. Antonio says:

    acabo de conseguir un pdf de una version comprada de killtest.es sobre el examen 200-530, desde mi punto de vista es una total estafa!!, muchas de las preguntas se repiten y son bastante basicas.

  16. Antonio says:

    Si gustan les envio a sus correos electronicos…

  17. Antonio says:

    Y acabo de certificar la ZCE PHP 5.3, ejjeje, la mayor parte de las preguntas era sobre seguridad, cosa que me gusto ya que llevo en temas de seguridad web casi 7 años. Ricard, si tuvieras material para postear en tu blog sobre el Zend Framework certificacion estaria complacido… 😀

    Saludos

  1. 24/01/2011

    […] This post was mentioned on Twitter by Christian Soronellas, ricardclau. ricardclau said: Nuevo post sobre arrays y closures en http://j.mp/fqDIv0 […]