The unset($args[0]) PHP Pattern

Suppose you are working on a system, and want to allow users to use so-called hooks to hook into the system and change it’s behavior. Think of it as wordpress’ filter/action kind-of-thing. This is in a way, something similar to events in javascript, and the purpose is basically the same: you want to do, or let others do something when something else happens, and potentially change the way the system works, or extend its functionality.

Implementing this kind of feature is surprisingly simple. All you need is a way to let people subscribe to your hooks, and a way to call all subscribed members for a certain hook at some point. The implementation details are not really our concern right now, but what happens when you call each subscribed member.

In order for hooks to be useful, you need to be able to pass relevant information to the subscribed members at call time. For example, in Javascript, native events get passed an event object that contains all sorts of useful information. The way you pass this information to the subscribed members will depend on your implementation of the subscribe method you use.

One pattern I’ve noticed working with drupal is unset($args[0]).

Drupal uses a hook system that allows developers to hook into the system simply by following some function naming conventions. The drupal specifics are not important right now. What is important is the way drupal calls its hooks: it uses a function called module_invoke_all.

The module_invoke_all function, in its definition, takes a single argument: the name of the hook. We already mentioned the importance that being able to pass information to the subscribed member has, so why is it that the drupal function to invoke hooks takes only the name of the hook as argument? How do you pass the relevant information?

PHP, just like other programming languages allows you to pass more arguments to a function that its formal parameters. The way you access the extra arguments passed to the function varies depending on the language. In php all arguments passed to a function are kept in the $args array.

Lets say you call module_invoke_all as follows:

module_invoke_all(‘my_hook’, ‘something cool’, ‘something interesting’);

Inside the function, the $args array will have 3 members, one for each argument passed to it. So, if you want to pass those values, minus the hook name to the subscribed members, all you need to do is get rid of that, and pass the resulting array to the subscribed members. That is why unset($args[0]) does.

I’m not sure this is the best way to do it, but it is certainly interesting. If you want to read the full code for the module_invoke_all function, just check out the drupal documentation on it (https://api.drupal.org/api/drupal/includes!module.inc/function/module_invoke_all/7)

Shoot Yourself on the Foot by Using PHP’s Extract

PHP’s extract function is one of those function that we use mostly because we are lazy. It makes it really easy to access associative arrays’ members without having to write too much. For example, imagine you have to process a form submitted by the user that has 50 different fields. You would have to do something like this in order to access the field values:


$name = $_POST['name'];
$meail = $_POST['email'];
$company = $_POST['company'];
.....

You would have to write 50 lines that look like those ones above to access every field value in the submitted form. I don’t think I need to mention what a pain that is. In fact, it is such a burden that on a lazy evening we might just write something like this:


extract($_POST);

Which is a really nice way to shoot yourself on the foot.

The problem with that is that it may end up overwriting variables defined previously. I guess you could argue that the first piece of code in this post does the same thing. For example if $name is already defined, it would be overwritten, which is certainly true. However, you are aware of that, and even if you are not, you will notice it a some point. The problem with extract is that another variable could be inserted and you would never know it. Lets see an example of what I mean:

Yesterday, while working on a project, I realized the security risks of extract. I have been working on this project for the last few days, and I was using extract in a few places on the code, but I was feeling uneasy about that. I thought there might be security implications with extract. In my experience, any function that makes handling unsafe data easy has some security implications. I decided to look into that, and sure enough there are security risks if extract is used carelessly, and just because you are too lazy to do things the long, usually right, way.

The applications that I’m working on has members, so we need a way to log them in and we do it through a form. This for is posted to a file on the application’s engine that takes care of processing it and determining whether the user should be logged in or not. For testing purposes I was using a variable a flag for users being logged in or not. Usually you would use sessions to do that, but for testing purposes a variable was good enough. Lets imagine the code looked like this:


$logged_in;

if(logged_in){
   //render screen for logged in users
}else{
   //render log in form
}

As I mentioned before, the log in form posts to a file that takes care of the log in logic. Then, if something goes wrong, it redirects to the log in page, and sends the submitted data using GET. The log in page then checks if that data is been submitted via GET, and if so, it uses it to display the submitted values on the form so the user doesn’t have to write all his info again. With that in mind, lets modify the code a bit:


$logged_in;

if($_GET && isset($_GET['data'])){
    userialize($_GET['data']);
    extract($data);//This makes getting the data information easy.
}

if(logged_in){
   //render screen for logged in users
}else{
   //render log in form
}

You can see where we are using extract. It will create variables based on the indexes of the data array. Now, what happens if someone modifies that data array? Suppose the array looks like this:


$data = array('name'=>'John Doe', 'email'=>'john@doe.com');

When we use extract this would create two variables. This is what we want, so that instead of doing $data['name'] we can access the value directly by doing $name. But if someone modifies the array to something like this:


$data = array('name'=>'John Doe', 'email'=>'john@doe.com', 'logged_in'=>true);

Then we have problems. This will create a logged_in variable with true as its value. This would overwrite whatever value is set on our $logged_in variable, and let the user log in without the right credentials. Now, remember that the code above is all just for the sake of this example. I don’t think anyone who knows what they are doing would write code like that. However, it serves the purpose of showing how dangerous it can be to use extract carelessly.

The extract function can be called with parameter that specify how it should handled variable collisions. But in my opinion, you should just avoid using it when processing user submitted data or any other kind of unsafe data.

I recommend reading the extract documentation if you plan on using it.

add_theme_support Generates call_user_func_array Error

While working on a theme I encountered the following error:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, function ” not found or invalid function name in /path/to/themesite/wp-includes/plugin.php on line 403

At first I thought it was because of the way I’m building the theme. You may remember I’ve mentioned core a few times. core is a library I built to help speed HTML development. I have a class that makes building head elements very easy. The “problem” is that wordpress requires you to call the wp_head function on the head of your templates. I solved this by including a method on the class that can be used to call any function.

My first reaction was to change my header.php file for the one included on the twentyeleven theme, but the problem did not get solved. This hinted me that the problem was not in the way I was calling wp_head. Once I realized that, I started commenting parts of the code out. I have a line of code that takes care of including a file, which in turn includes a few more files. Each file adds a certain feature to the theme, like custom header, or background color. Commenting out the line that includes the first file solved the problem.

Once I realized that the problem was in one of the files that was being included which add features to the theme, I went on and started commenting out individual include lines to see which feature was causing the problem. This way I found out that the feature causing the problem was the custom background feature.

That file had the following code:


//Custom Background documentation: http://codex.wordpress.org/Custom_Backgrounds

$color = '1d1d1d';

$defaults = array(
        'default-color'          => $color,
        'default-image'          => '',
        'wp-head-callback'       => '',
        'admin-head-callback'    => '',
        'admin-preview-callback' => ''
);

add_theme_support('custom-background', $defaults);
?>

As you can see, the wp-head-callback is empty. Which was causing the problem, since this callback gets registered somewhere in wordpress, and then wordpress tries to call this callback, but it is empty. If you review the source code of add_theme_support you will see that it has a default callback. In this case, you have to either specify a call back or do not include that array element at all.

This is a pretty simple error, but it took me a good 20 minutes to figure out.

xkcd comic
Comic by XKCD

Instaling WordPress From the Command Line – Just for Fun

Today I decided to do a fun exercise. Lets install wordpress entirely from the command line. We will download wordpress, unzip it, and create the database and user, all from the command line.

Downloading and Setting Up wordpress

To download wordpress we are going to use wget.
wget is a non-interactive network downloader. It is a pretty neat tool. If you have never used it, I recommend you read the man page for it, and to give it a try.

In order to download wordpress we need to run the following command:

wget http://wordpress.org/latest.zip

Be sure to be on the directory in which you want wordpress to be downloaded. In my case I’m using my in-house server, so I have access to all of it. I download everything to the Downloads directory.

Once wget is finished downloading wordpress you should have a new zip file named latest.zip. We need to unzip this file:

unzip latest.zip

This will extract the zipped files. You should end up with a newly created wordpress directory. Remember that at this point I am still on the Downloads directory, so I need to move the wordpress directory to public_html, which is the directory that apache uses as root. I will also change the name of the newly created wordpress directory to something more meaningful. Since I will be using this installation to develop a theme, I will just name it as the theme:

mv wordpress/ ../public_html/cafe

We are done with this step. Now we need to create the database and mysql user for this installation of wordpress.

Creating MySQL Database and User

We need to start mysql cli in order to create the database and user:

mysql -u user_name -p

user_name is the user name that you use to connect to your MySQL server. You will be required to enter your password. Once you do, you will be logged into the MySQL server and you will be able to run commands.

Creating the Database

Creating the database is simple:
CREATE DATABASE databasename;
You will need to change database for the name you want to give to your database.

Creating the User

Creating the user is also very simple:
CREATE USER 'user'@'localhost' IDENTIFIED BY 'passwd';
You need to change user for the user name you want to use. If you will be accessing the database from a different server, then change localhost for the host name that from which you will be accessing the database.

Now we need to grant the newly created user enough privileges to manage the database:

GRANT ALL PRIVILEGES ON databasename.* TO 'user'@'localhost';

Since this is just an exercise, we are granting all privileges. On a production site, you may want to not do this, and just grant enough privileges to the user so it can function properly.

Lastly, edit the wp-config.php file, and add the database and user information.

We are done. All that is left to do is run the wordpress installation program. Just use your browser to navigate to your wordpress installation, and install wordpress as you usually do.

Some reads you may be interested on:

http://dev.mysql.com/doc/refman/5.1/en/adding-users.html
http://dev.mysql.com/doc/refman/5.5/en/creating-database.html

Responsive Web Design.

Lately, I’ve been working on some responsive layouts. My task on these projects is to make a fixed-width layout into a responsive one. I’ve found it to be an engaging process.

Responsive web design is one of the “modern” big ideas of web development. It is becoming increasingly popular, and there is no sign of it going away anytime soon. The reason, I believe, is that responsive web design is just what we need on this era of small devices and huge screens. There has been an increased usage of big screens in the last few years. Whereas a few years ago 1024 was almost a standard, and we were all designing for those screens, nowadays people seem to have a tendency for much wider screens. Most laptops today come with at least 1200px resolutions, and people who work with desktop machines usually prefer even greater resolutions.

Along with this tendency for higher screen resolutions however, there is also an ever increasing usage of a wide variety of devices, each with different screen resolution, and many of them with portrait and landscape modes. This has presented a new challenge for designers and developers. Whereas in the past we could easily decide for 1024 and leave out a few old timers with 600px resolutions, now we cannot do that anymore. If we continue on that path, we are leaving out the increasing amount of people who browse the web on mobile devices daily.

The question then became: How do we deal with this new challenge? The answer is responsive layouts. Responsive layouts started earlier than we realize. They have their origins on the old, and never popular liquid layouts. Liquid layouts was the first step we took on dealing with the problem of different screen resolutions. However, they were never really popular because they presented a few challenges that, although not impossible to overcome, made fluid layouts more of a hassle tan static (fixes-width) ones. I think one of the reasons for this preference for static layouts is that web designers are mostly not real web designers, but graphic designers that saw an opportunity to make a few, and sometimes more than a few extra bucks. Graphic designers have some kind of obsession with pixel perfection. In itself that is not a bad thing at all, but when you bring that idea to the web, really bad things can happen. One of those things is that we are much too used to pixel units that we have almost forgotten how to work with percentages, and ems. This is a problem because those units are the building blocks of responsive web layouts.

I know I’ve been a bit aggressive towards graphic designers. Maybe I just envy their ability to create beautiful things out of a white canvas, but I prefer to think that my reasons are legitimate rather than selfish. I know that if you know and love web as much as I do, you will agree with me. Back to our topic of concern, how is responsive web design different from liquid layouts?

Responsive web design has been made possible thanks to new CSS3 features. Specifically media queries. Media queries are something somehow old and new at the same time. CSS2 offered the possibility to set different stylesheets for different mediums like screen, print, and screen readers, but CSS3 offers the awesome possibility of detecting the width, max-width, orientation (landscpape or portrait), and device width. This offers web designers/developers the chance of applying different styles depending on the width of the device, or the screen, or even the orientation. A two column layout can be easily converted into a single column layout when the size of the screen makes the columns too narrow to look beautiful or to be even readable. That is just awesome.

No longer do we need to have two or more versions of a single site to serve different devices. As programmers (I like to believe the web is build buy programmers, please let me continue deceiving myself), most of us are lazy. Moreover, we really hate doing the same thing twice. That is why we build libraries, and frameworks that simplify our work. I don’t think there is anything good, or fun about having to maintain two or more versions of the same site.

There is also another problem associated with these multiple-site approach. Often some sniffing techniques are used to decided which version to serve. I really have no idea of what they sniff for, but my guess is they check browser, and/or OS. This is a problem because sometimes you end up serving mobile versions of a site to devices that are fully capable of handling desktop versions of such site. For example, I have an Asus transformer tablet with 1200px(?) screen resolution, but sometimes I’m served little layouts that waste most my screen. One could argue that is still a good idea to serve such version to a mobile device given the cost of mobile internet, and the capabilities of it, but my tablet can connect to the internet only via wifi, so there is no real reason to do such thing. I would love to have the developers of those sites in front of me and tell them to stop sniffing and to start looking at the capabilities of my device, or at the very least give me an option to use the full site, not a semi functional version of it. This is why responsive layouts arise a champion on this matter.

Responsive layouts do not assume anything, but rather they set a few rules that apply or not depending on the device and window size. Moreover, responsive designs has a mobile first philosophy, which I see as the layout version of progressive enhancement. Mobile first is a great idea because it forces the designer into thinking about what is really important on each page. Mobile first lets us consider the content in a more responsible way, and to realize what is important, and what is not.

There is much more to talk about on this matter, and not everything is perfect. There are some parts of responsive web design that are not necessarily good, but overall, responsive web design is definitely one of the great ideas of web design that the modern world has come up with.

IF you wish to read more on this matter, I recommend the following articles:

http://friendly-machine.com/posts/2011/when-a-trickle-becomes-a-flood

http://unstoppablerobotninja.com/entry/fluid-images

http://www.alistapart.com/articles/howtosizetextincss/

http://webdesignerwall.com/tutorials/css3-media-queries

http://www.alistapart.com/articles/responsive-web-design/

Some of them are not necessarily about responsive web design, but about some of the things that make responsive web design possible, like fluid images.

Would You Please Learn How to Design Websites

I’d like to start by saying that I am not, nor do I pretend to be a graphic designer. I don’t do beautiful illustrations, logos, or graphics. I am not in the business of creating nice business cards, or great corporate identities. I do web.

I see a lot of graphic designers who develop wordpress themes, and other kinds of web related designs. I want to concentrate on wordpress themes, because that is what I’ve been dealing with lately. It really makes me tired, bored, sick, and it frustrates me when some guy who has been doing graphic design all his life comes to me and tells me: “The sidebar looks 2 pixels to the left on IE6.” The web is like that; dealt with it.

The beautiful web is more and more populated with sites that use too much resources. Websites nowadays load a stylesheet for modern browsers; one for IE7; another for IE6; another for hand-held devices; and tons of javascript to force their own font and to add shadows to sucky IE version. Seriously, that is not the way to do web.

I blame the guys who like everything with tons of eye candy. Those people who think it is really cool to have a stupid menu flying around are the ones destroying the precious web. What ever happened to sites that just worked? That were beautiful, functional, user friendly, and resources friendly. I admit it, it is pretty cool to have webGL, CSS animations, canvas coolness, and other tons of nice features, but you don’t have to use them all at once. Those tools should be only that: tools, but instead, they’ve become the website itself.

The root of the problem, I believe, is graphic designers, and graphic designer wannabies that once learned about jQuery, or some other of those toys. They thought, “look, I can make a big poster that moves!” I would like to salute them all with a huge facepalm.

When real web designers design, magic happens. We think in elements, not just colors and lines. Real web designers have a pretty good idea, not only of what is possible, and what is not, but of the amount of work and resources that something would take. We don’t think about an animation in terms of $(‘#elem’).animate(), but in terms of timeouts, loops, calculations, site repaints, usability, and accessibility. How does this animation help the user? How does it not help? What happens if the user is blind? What happens if the user has some kind of body movement difficulties? What happens if the user has and old computer? What happens if the user is using an old device/software? What happens if the user’s computer is doing some sort of heavy computation? At what point do we stop this animation and fall back to a more resources friendly version of the site? There is much to consider to have time to worry about 2 pixels on the sidebar.

Real web designers know their site won’t look the same everywhere. This shadow won’t come out on IE6, but that is OK, because I’ve designed the site in such a way that even without the shadow the site looks beautiful, and more importantly it works. Real web designers know that it is more important to save an http request and a few KB than to force that shadow to appear on IE6. The website will not look the same everywhere, and real web designers know that. This is what allows them to designs websites that look beautiful everywhere, even if they don’t look the same. We build for the user.

You are more likely to receive a complaint saying “Your website takes ages to load,” than one that says “on firefox the sidebar looks 2px to the right.” Please, learn how to design websites.

Those People Will Kill the Web, We Should Kill Them Frist.

I must say right away that I’m angry. If you don’t like to read posts where people just go on ranting about something that really pisses them off, you should move along. Go watch some cool video on youtube or read a more interesting blog.

Today I’m finally going to do it. I’m going to publicly express my anger against you people who call yourselves web developers when you know nothing about development. You know nothing about how the browsers work, you know nothing about how the servers work, and finally, you know nothing about how the web works. You are just lucky you found out about wordpress and wordpress plugins.

Let me be clear here that this is not a post against wordpress. I find wordpress to be quite interesting, and one of the best pieces of software of its kind around. Although, I do find it a bit annoying how easy it has made it for people who are completely ignorant about web development to call themselves “web developers”.

If you are a real web developer, a real programmer, I’m sure you will agree. Personally, I have attended a few meetups for wordpress developers, and have been completely disappointed to find that most of the people who attended were completely ignorant about the most basic web development related topics. People asking how to restore a site from a back up that they have of their database, people asking how you change the color of the header, people asking how to insert an image in a text widget. Those kind of people is whom I’m talking about. And not, I’m not referring to the young mom who wants to starts her own business, or at the man who recently got laid off and wants to try to make it on the web by selling his paintings. I am talking about people who say “My client wants a different color on the header, how do I do that?”. This are people talking about clients, and whatnot. People who should get as far from the computer as possible and repeat, “I am not a web developer. I am harming the web by doing what I do.”

And why it makes me so mad you ask? Because these “developers” load 20 plugins on a wordpress installation, a beautiful theme, with lots of options, copy and paste code from different places over the web, load mootools, jquery, yui, and “custom code”, and charge 300 USD. The site looks great, but it is piece of crap when you look beyond the pretty interface.

Don’t believe me? I invite you to go around the web and start checking the code of some of the websites you visit, especially if you suspect they are wordpress.

Right now I am looking at a site that has a of almost 200 lines. Loads up at least 10 CSS files, and some 12 javascript files. Has over 100 lines of hard coded CSS, and in the body loads more Javascript. It loads at least 2 version of jQuery and a different Javascript file for each version of IE. And all there is on the page is a contact form. This makes me want to kill somebody.

Sometimes I wish wordpress weren’t so easy. People go stupid with it. They load tons of plugins, and each plugin loads tons of other stuff. I ask myself, what would be the performance improvement if this website were actually developed by a real web developer. Someone who understands that http connections are to be reduced as much as possible, that javascript is to be loaded asynchronously or at the end of the document, that you don’t need 2 different ajax libraries, and definitely no two different versions of the same library. Some one who doesn’t need to load jQuery to do this:

$('#link').click(function(){
    alert('hey you');
);

Someone who knows how to load resources only when they are needed, who doesn’t need to install a new plugin each time a new featured is to be added to the site.

If you are as passionate about the web as I am, you understand my frustration. Every time someone tells me that the web is more and more built on wordpress I can only say, unfortunately. And not because wordpress is bad, but because wordpress has made it easy for people to make bad websites. I cannot even say write bad websites, because that implies they are being written, but they are not. They are being put together like some kind of weird web-based Frankenstein.

And then they ask why the pretty photo stopped working.

Como Establecer Relaciones en las Bases de Datos.

Cuando se trata de Bases de datos, a muchos les da miedito. La verdad es que hay razón justificada para ese medito: una mala decisión puede hacer la diferencia entre un sistema funcional y flexible y uno que simplemente no da para más.

Una de las principales áreas en las que hay que tener cuidado es al establecer las relaciones entre las diferentes tablas que conforman nuestra base de datos.

En RDBMS’s como lo es MySQL existen tres tipos de relaciones entre las bases de datos. Dos de ellos son muy sencillos, el tercero es un poco más complejo y puede tumbar de su silla a unos cuantos. En esta ocasión solo tomaré los dos sencillos, que son los conocidos como one to one y one to many.

Una relación one to one (1:1) o one to many (1:m) se logra agregando uno de los campos de la tabla padre (generalmente el que se usa como Primary Key) a la tabla hija. Por ejemplo, si tenemos una tabla usuarios y otra perfiles, entonces en nuestra tabla perfiles pondríamos un campo usuarioID, que correspondería con el campo usuarioID de la tabla usuarios. De este modo, cuando guardamos un perfil nuevo, dentro de Perfiles.usuarioID almacenamos el valor del id de usuario correspondiente al usuario cuyo perfil estamos almacenando. Este valor es le mismo que tenemos dentro de Usuarios.usuarioID. Al hacer esto podemos hacer algo como:

SELECT perfilNombre FROM perfiles WHERE usuarioID = 2

En este caso lo que obtendríamos es el nombre del perfil correspondiente al usuario cuyo id es 2.

Ahora, la pregunta viene, como decidimos que tabla es la tabla padre y que tabla es la tabla hija. En otras palabras, a que tabla le vamos a agregar el campo extra? La respuesta es muy sencilla. Todo basta con ver que tabla pertenece a cual. En nuestro ejemplo, un perfil pertenece a un usuario, pero no viceversa. Es decir, que un usuario no puede pertenecer a un perfil. Muchas veces ayuda si mentalmente creamos la sentencia SQL que usaríamos para recibir los datos de la tabla. En nuestro caso, es claro que si vamos a pedir un perfil, lo vamos a hacer basados en el id del usuario cuyo perfil queremos obtener. De esta forma podemos ver claramente que la tabla usuarios es Padre de la tabla perfiles ya que usuarios es un campo más amplio. Un usuario puede tener un perfil publico, un perfil privado, una dirección postal, un carrito de compras etc.

Como vez, determinar que tabla es padre y que tabla es hija es muy sencillo, pero muchas veces, si no tenemos este tip a la mano, puede ser un poco confuso, especialmente cuando estamos trabajando con muchas tablas cuyas relaciones son complejas. Siempre ayuda de mucho ver que tabla pertenece al grupo más grande. Por ejemplo, la tabla perfiles es un “sub-grupo” de la tabla usuarios.

Espero que les sirva este tip, y si tu tienes una forma favorita de definir tus relaciones en las bases de datos, por que no nos comentas un poco?

HTML forms y PHP arrays. (Analizando la mejor forma de implementar arrays en formularios)

Probablemente sepas manejar formularios. Probablemente también sepas implementar php para manejar los datos enviados a través de esos formularios y, por ejemplo, guardar dichos datos en una base de datos. Lo que quizá no sepas es que hay formas muy eficientes de hacer dicho trabajo, como puede ser, por ejemplo, agrupar distintos datos en un solo array de modo que sea más fácil manejarlos.

Yo personalmente soy entusiasta de esta técnica. Siento que mi trabajo es más organizado cuando tengo conjuntos de datos agrupados en arrays a los que me puedo referir de forma sencilla. Sin embargo, puede ser que en tu intento por hacer lo mismo termines haciéndolo de la forma incorrecta.

Consideremos el siguiente ejemplo:

Supongamos que tenemos un formulario, y una de las secciones es acerca de los gustos del usuario. Para esto tenemos los siguientes opciones:

Correr
Leer
Ir al cine
Hacer Yoga
Cocinar
Patinar
Besar bajo la luna
Otros

Como es probable que un usuario guste de más de una de estas actividades, lo mejor sería usar checkboxs que permitan al usuario elegir tantas actividades como guste. La forma común de hacer esto se representa con el siguiente markup:

<input type="checkbox" name="correr" value="correr" /> Correr
<input type="checkbox" name="leer" value="leer" /> Leer
<input type="checkbox" name="ir_al_cine" value="ir al cine" /> Ir al cine
<input type="checkbox" name="hacer_yoga" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="cocinar" value="cocinar" /> Cocinar
<input type="checkbox" name="patinar" value="patinar" /> Patinar
<input type="checkbox" name="besar_bajo_la_luna" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="otros" value="otros" /> Otros
Nótese que estoy omitiendo muchos elementos aquí, como lo puede ser <label> por considerarlos no relevantes para el ejemplo. Por favor no intenten esto en casa lol.

Si te das cuenta, cuando queramos manejar estos datos con php tendremos un montón de datos sueltos. Esta no es una forma realmente inteligente de hacer las cosas ya que dentro del formulario puede que estos datos tengan mucho sentido, pero una vez los sacamos del formulario para empezar a procesarlos con PHP pueden volverse realmente confusos. Por ejemplo, que se supone que “leer” representa una vez lo sacamos de su contexto?

La forma de resolver este problema con los datos sueltos es muy sencilla. Todo consiste en agregar un array mediante HTML. Mira el ejemplo siguiente:

<input type="checkbox" name="gustos_usuario[]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[]" value="leer" /> Leer
<input type="checkbox" name="gustos_usuario[]" value="ir al cine" /> Ir al cine
<input type="checkbox" name="gustos_usuario[]" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="gustos_usuario[]" value="cocinar" /> Cocinar
<input type="checkbox" name="gustos_usuario[]" value="patinar" /> Patinar
<input type="checkbox" name="gustos_usuario[]" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="gustos_usuario[]" value="otros" /> Otros

Como vez hemos creado una estructura un tanto diferente que agrupa todas las diferentes opciones dentro de un solo array, lo cual no hace mucho más fácil el acceso y manejo de esta información. Piensa en la infinidad de posibilidades nuevas ahora que en lugar de tener datos sueltos tenemos un conjunto de elementos relacionados en el cual podemos aplicar loops y demás. Simplemente hermoso. Sin embargo, hay un problema. Que pasa cuando queremos ver si dicha opción fue seleccionada? Por ejemplo, si quiero saber si al usuario le gusta cocinar, como rayos hago referencia a dicha opción?

Un atentado totalmente novato sería ya sea un loop, o hacer referencia a la opción en base a su posición. Ambas opciones son novatadas que deberían evitarse a toda costa. Veamos por que.

Opción 1: Utilizar un loop

El usuario novato promedio haría lo siguiente:

foreach($opciones as $opcion){
     if($opcion == 'cocinar'){
          echo "Le gusta cocinar";
     }
}

Porqué esta no es una buena solución? Simplemente por que consume recursos innecesario chequeando cada una de las opciones que han sido elegidas por el usuario para determinar si al usuario le gusta cocinar. Como  regla general, si estás usando un loop para determinar si un valor está presente en un array, probablemente estás haciendo algo mal.

Opción 2: Utilizar la posición del elemento.

Este es probablemente un intento aún más novato, y que, a diferencia del anterior, no producirá resultados, pero hay quienes lo intentarían. La idea es determinar cual es la posición del elemento a buscar dentro del array y ver si su valor es el deseado. Esto no funciona por que los elementos no aparecerán en el mismo orden dentro del array que dentro del markup. Un novato pensaría que el array producido reflejaría todas y cada una de las opciones existentes sin importar si fueron seleccionadas o no. La verdad es que elementos como checkbox no son enviados a menos que hayan sido seleccionados, por lo que este intento es simplemente fallido. Sería mejor salir a la calle dirigirse hacia el tipo más grande que se encuentre y propinarle una patada en el trasero. Después de todo, si lo que queremos es problemas, más vale que no sean tan grandes.

Como solucionamos el problema?

La solución es usar arrays asociativos. Sin embargo, esto se vuelve ‘tricky’.

Si sabes algo sobre buenas prácticas en php, sabrás que la forma correcta de crear arrays asociativos es esta:

$miArray[‘mi_elemento’] = ‘mi valor’;

El énfasis aquí lo quiero hacer en las comillas al rededor del identificador al cual esta asociado el valor dentro del array. Esto es importante en php ya que esta es la forma correcta de hacerlo. Si no pones las comillas, php tomará el identificador como una constante indefinida y no como una cadena de texto. Sin embargo, si haces lo mismo dentro del formulario de php, estarás haciendo lo equivalente a:

$miArray[“‘mi_elemento'”] =’mi valor’;

Como vez las comillas pasan a ser parte del identificador.

Por que es esto importante?

Si usamos el primer ejemplo, el que usa las comillas dentro del array en php, podemos hacer lo siguiente:

array_key_exists(‘mi_elemento’,$miArray);//regresa true;

Pero si definimos el elemento en el formulario:

<input tytpe=”checkbox” name=”miArray[‘mi_elemento’]”….

Notense las comillas al rededor del identificador,

entonces:

array_key_exists(‘mi_elemento’,$miArray);//regresa false

Esto es por que dicho identificador no existe. Lo que tenemos que hacer es no usar las comillas dentro de nuestros formularios, de modo que el formulario completo quedaría así:

<input type="checkbox" name="gustos_usuario[correr]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[leer]" value="leer" /> Leer
<input type="checkbox" name="gustos_usuario[ir_al_cine]" value="ir al cine" /> Ir al cine
<input type="checkbox" name="gustos_usuario[correr]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[hacer_yoga]" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="gustos_usuario[cocinar]" value="cocinar" /> Cocinar
<input type="checkbox" name="gustos_usuario[patinar]" value="patinar" /> Patinar
<input type="checkbox" name="gustos_usuario[besar_bajo_la_luna]" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="gustos_usuario[otros]" value="otros" /> Otros

De este modo si podemos usar nuestras funciones para arrays confiando en que se comportarán tal como si el array hubiera sido definido en php directamente.

Explicando <col />

Creo que poca gente sabe de la existencia de un elemento muy útil en HTML. Ese elemento es <col />, el cual sirve para asignar estilos a toda una columna en las tablas. Esto nos ahorra un montón de trabajo cuando queremos asignar estilos similares a una sola columna.

Consideremos el siguiente markup:

<table>
      <tr>
          <td>Col 1</td>
          <td>Col 2</td>
          <td>Col 3</td>
     </tr>
     <tr>
           <td>Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
     <tr>
           <td>Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
</table>

Esto nos hace una tabla así:

Col 1 Col 2 Col 3
Col 1 Col 2 Col 3
Col 1 Col 2 Col 3

Ahora supongamos que queremos que toda la primer columna apareciera con un fondo de color diferente. Si somos como la mayoría de la gente, seguramente empezaríamos a poner una clase al primer elemento de cada tr:

<table>
      <tr>
          <td class="primerCol">Col 1</td>
          <td>Col 2</td>
          <td>Col 3</td>
     </tr>
     <tr>
           <td class="primerCol">Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
     <tr>
           <td class="primerCol">Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
</table>

y luego en CSS haríamos lo siguiente:

.primerCol{
     background-color: olive;
}

Eso está bien, pero no es la forma más inteligente de hacerlo, ya que puede traer problemas cuando estemos editando nuestras tablas, además de que en una tabla gigante, con un montón de columnas,  donde cada columna tiene que tener sus propios estilos, hacer esto sería una pesadilla.  Es aquí donde el elemento <col /> entra en acción. Primero veamos el resultado que obtenemos con el código de arriba.

Col 1 Col 2 Col 3
Col 1 Col 2 Col 3
Col 1 Col 2 Col 3

Una mejor forma de hacerlo es usando <col />. Para usar col, tienes que tener un elemento col por cada columna en tu tabla, en este caso necesitamos tres elementos col:

<table>
      <col class="primerCol" />
      <col class="segCol" />
      <col class="terCol" />
      <tr>
          <td>Col 1</td>
          <td>Col 2</td>
          <td>Col 3</td>
     </tr>
     <tr>
           <td>Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
     <tr>
           <td>Col 1</td>
           <td>Col 2</td>
           <td>Col 3</td>
      </tr>
</table>

Y aplicamos estilos diferentes para cada columna:

.primerCol{
     background-color: olive;
}

Y no tenemos que hacer nada más.

De esta manera es mucho más fácil controlar los estilos de las columnas. Hay algunas cosas interesantes acerca de los elementos col. Por ejemplo, si usas firebug, fíjate en la pestaña de HTML y pon tu mouse sobre alguno de los elementos col y verás que se ilumina la columna a la que dicho elemento hace referencia. Esto resulta muy útil en ocasiones. Otra cosa a tomar en cuenta es que no es necesario poner todos los elementos col. En nuestro caso, por ejemplo, solo necesitamos el primero ya que los otros dos no nos estás siendo útiles para nada.

Espero que les sea de utilidad la información. Conoces algún elemento que crees poca gente sabe de su existencia?