PHP7

PHP 7: Algunas novedades del lenguaje

Sin importar si eres un desarrollador PHP con años de experiencia o simplemente administras un par de sitios basados en Wordpress, lo cierto es que todos estamos pendientes de PHP 7 y su versión final que será publicada en Noviembre de 2015.

Los cambios que existen en el lenguaje son tantos que merecen varios artículos, pero no quería dejar de comentar algunos de los que más me llamaron la atención.

Continuar Leyendo →

PHP Avanzado

Aprende a usar el servidor web interno de PHP

Desde la versión 5.4 de PHP, contamos con una nueva herramienta en nuestro arsenal: un Servidor Web interno en PHP, que nos permite realizar pruebas de una manera sencilla, sin la necesidad de tener un servidor web (ya sea NginX o Apache) corriendo de manera separada.

En este artículo voy a intentar explicar brevemente cómo funciona este servidor web, que opciones tenemos para configurarlo, y finalmente, les mostraré un ejemplo sobre como podemos crear un pequeño proyecto.

Continuar Leyendo →

Quick Tips

Mostrar los resultados de MySQL de manera vertical

Cuando tenemos que acceder remotamente a un servidor y realizar algunas consultas a MySQL, algunas veces esta información es difícil de leer. Esto se debe al formato por defecto que MySQL utiliza en sus resultados a través de la consola:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> select * from wp_users WHERE ID=2;
+----+------------+------------------------------------+---------------+-------
------------------+------------------------------+---------------------+-------
---------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename |
user_email | user_url | user_registered |
user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+-------
------------------+------------------------------+---------------------+-------
---------------+-------------+--------------+
| 2 | webstudio | $P3B/Wr1SUfT7g3SgLZ5vy4AS6.tLrwCr1 | webstudio | direcc
ion.de@gmail.com | http://www.web-studio.com.ar | 2006-05-03 22:27:07 |
EuotpywqoDBeD1fElw0b | 0 | Pablo |
+----+------------+------------------------------------+---------------+-------
------------------+------------------------------+---------------------+-------
---------------+-------------+--------------+
1 row in set (0.06 sec)

mysql>

Pero si el mismo comando, lo ejecutamos finalizandolo con \G en vez del ; habitual, los resultados se vuelven mucho más legibles:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select * from wp_users WHERE ID=2\G
*************************** 1. row ***************************
ID: 2
user_login: webstudio
user_pass: $P3B/Wr1SUfT7g3SgLZ5vy4AS6.tLrwCr1
user_nicename: webstudio
user_email: direccion.de@gmail.com
user_url: http://www.web-studio.com.ar
user_registered: 2006-05-03 22:27:07
user_activation_key: EuotpywqoDBeD1fElw0b
user_status: 0
display_name: Pablo
1 row in set (0.06 sec)

mysql>

Espero que el Tip les sea de utilidad.

Quick Tips

Generando y descargando archivos enormes con PHP

Si bien hace un tiempo escribí sobre como Forzar la descarga de un archivo con PHP, lo cierto es que esto solamente funciona con archivos relativamente pequeños, de no más de 2 Megabytes de tamaño. Archivos más grandes (alrededor de cientos de Megabytes) se verían truncados o vacíos, simplemente porque PHP posee un espacio limitado para hacer output buffering.

Entonces, si quisiéramos extender el ejemplo anterior, pero teniendo en cuenta tamaños de archivo mucho más grandes, deberíamos realizar algo así:

1
2
3
4
5
6
7
8
9
$filename = 'archivo-xml-muy-grande.xml';

header('Content-type: text/xml');
header('Content-length: ' . filesize($filename));
header('Content-Disposition: attachment; filename="'.$filename.'"');

ob_end_flush();
readfile($filename);
exit;
Quick Tips

Ver commits locales que aún no fueron pusheados

No pocas veces pasa que estamos trabajando en algo, realizamos ciertos commits en nuestro repositorio local, y luego de que algo nos distrajo momentáneamente, ya no recordamos qué era eso que habíamos commiteado, pero aún no pusheado al servidor. Si pedimos un git status entonces esto no nos da demasiada información:

1
# On branch origin/master
# Your branch is ahead of 'origin/master' by 1 commit.
#   (use "git push" to publish your local commits)

DIOS! En qué estaba trajando?!

Afortundamente, gracias a git log podemos sacarnos la duda, indicando que queremos ver sólo la diferencia entre nuestro HEAD y el branch remoto origin/master

1
git log origin/master..HEAD

commit 782b5cc03b3e0961c5fa3ec88e3f8a89665b494d
Author: Pablo Rigazzi <pablo.rigazzi@gmail.com>
Date:   Sep 17 00:29:32 2013 +0200
    Unfinished version of User Class

Problema resuelto!

Quick Tips

Crear una tabla reusando la estructura de otra tabla

A pesar de los años, el lenguaje SQL y nuestro viejo y querido motor MySQL nos siguen sorprendiendo. Prueba de ello lo que descubrí de casualidad y no dudé en Twittear.

Esto creará una tabla nueva, pero sin los datos de la tabla anterior. Si queremos además, copiar los datos entre las tablas, podemos realizar luego:

1
INSERT INTO nueva_tabla SELECT * FROM vieja_tabla;
Quick Tips

Volver al branch anterior de git en un suspiro

Si hubiera sabido esto, me hubiera ahorrado al menos algunos meses de tipeo.

Resulta que si uno está trabajando entre dos branches distintos de git, en vez de utilizar el nombre completo del branch…

1
git checkout feature/make-something-better
git checkout master
git checkout feature/make-something-better

Podríamos haber tipeado simplemente…

1
git checkout feature/make-something-better
git checkout master
git checkout -

De seguir realizando checkouts entre estos dos branchs, solamente deberíamos utilizar el caracter - para alternar entre esos dos.

Quick Tips

Forzar la descarga de un archivo con PHP

Ya conocemos la historia. Gracias al poder de PHP generamos contenido que debería ser descargable por el usuario, pero el navegador en vez de ofrecer la descarga de un archivo, muestra el contenido dentro de la ventana donde estamos trabajando.

Por suerte, podemos indicarle muy fácilmente que queremos que este contenido sea tratado como un archivo, y que se ofrezca como una descarga. Si necesitáramos descargar el contenido como xml, entonces deberíamos enviar los headers correctos:

1
2
header('Content-type: text/xml');
header('Content-Disposition: attachment; filename="NombreDelArchivo.xml"');

Y listo. Esto también funciona con otros tipos de contenido, como application/pdf (para archivos PDF), o application/msword (para archivos Word).

Quick Tips

Determinar rápidamente si es el último día del mes

Seguramente en algún momento han tenido que escribir un cron job que realize alguna tarea distinta solo el último día del mes. Con este pequeño script, no puede ser más sencillo.

1
2
3
4
5
<?php
if (gmdate('t') == gmdate('d')) {
echo 'Hurra! Es el último día del mes!';
}
?>

Esto funciona maravillosamente, ya que gmtdate('d') retorna el día actual, y gmtdate('t') retorna el último día del mes actual. Si son iguales, voilá!

Quick Tips

Parsear archivos CSV con fgetcsv

Resulta que hace poco, debido a un pequeño proceso que debíamos correr para importar ciertos valores, encontré dentro de la librería PHP la función fgetcsv() que me vino al pelo, justo cuando estaba por ponerme a implementar mi propia solución.

Funciona exactamente igual que fgets() solo que realiza un rápido parseo de la línea recientemente leída antes de devolverla a PHP. Su modo de uso es realmente simple. Si contáramos con un archivo separado por comas de este tipo:

1, Pablo, Web Developer, Rotterdam
2, Tom, UX Designer, Amsterdam
3, Roberto, Team Lead, Rotterdam
4, Francisco, Papa, Ciudad de El Vaticano

Entonces para leerlo y procesarlo solo necesaríamos el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$counter = 1;
if (($handle = fopen('fgetcsv.csv', 'r')) !== false)
{
while (($datos = fgetcsv($handle, 1000))) {
echo sprintf(
"Se encontraron %d campos dentro de la fila %d\n",
count($datos),
$counter++
);

foreach ($datos as $dato) {
echo $dato . "\n";
}
}
fclose($handle);
}