Git, PHP and C, with great power comes a great responsibility

Ver este artículo en castellano aquí

A few days ago I had the opportunity to share a conversation about version control systems with some colleagues, specifically about git, its complexity and the recommendation or not use them. A strong argument against said that git was a complex tool, which had a higher learning curve than others, that was very easy to make mistakes and that this mistake could mean a loss of data.

This made me think, and while it is true that git is a very powerful tool (with which I have a love-hate relationship for several years), the fact that a tool or language you allow certain liberties, does not imply that they are intended to be used always. Here is an example in this question of Stack Overflow:

http://stackoverflow.com/questions/1488753/how-to-merge-two-branches-without-a-common-ancestor

A -- B -- ... -- K -- L -- M1
                             \
                              M3 -- N' -- .. -- Z'
                             /
               I1 -- I2 -- M2 -- N -- .. -- Z

In this case we have 2 different branches without a common parent, which is a somewhat unusual case according to my (short) experience. Is it bad git for allowing this operation? No, should use an usual branching pattern? Either. In fact the majority of branches management patterns are based on having a /main branch as solid as possible, and have features, users or tasks into separate branches.

Another command that we have is rebase which allows us to rewrite the history of a branch, and integrate their changes in another branch, which may seem a genuine outrage for those who consider that a changeset is a permanent snapshot.

Git is not the only, since we have other tools and programming languages, that by design have allowed us to do certain things that have been heavily over-used:

PHP

The language that is the base of sites like Facebook, Yahoo, and Youtube has not been without controversy in the 18 years that has been on duty (since 1995). Looking for peculiarities of the language, I discovered that, among other things, PHP allows us to define globals from within a function as shown in the following code block:

function foo () {
    global $var;
    // rest of code
}

This breaks all the encapsulation and variable scope rules, that are studied on a standard programming course, and certainly its use has been harshly criticized, Is PHP a bad language by implementing this functionality? No, it is possible to find a specific scenario for this functionality, and then use the features provided by the language

C

The father, grandfather, and common ancestor of many of today’s programming languages and whose main book contains less than 300 pages (the famous K & R), has been receiving criticism since 1972. One of the most criticized features is, without doubt, the *goto** statement:

int big_function()
{
    int ret_val = [success];
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    return ret_val;
}

GoTo allows us to perform an unconditional jump to a portion of the file. To goto detractors state that breaks the flow of execution of a program and that can be a source of errors and hinders readability. On the other hand, it is useful in side scenarios, such as the Elimination of recursion.

Recap

In the same way that we should not use the same tool for all (golden hammer anti-pattern) we must be aware of the peculiarities of the language, and that what it gives us, it provides with a specific reason, not necessarily applicable to all scenarios.

Remember Uncle Ben when using one of these tools and languages:

Uncle ben

With great power comes a great responsibility

More information and interesting articles

And you, what curious things have you spotted in your favourite programming language or tool?

Git, PHP y C: Un gran poder conlleva una gran responsabilidad

Read this article in English here

Hace unos días tuve la ocasión de compartir con algunos compañeros una conversación sobre controles de versiones, concretamente sobre git, su complejidad y la recomendación o no de su uso. Un argumento de peso en contra decía que git era una herramienta compleja, que tenía una curva de aprendizaje mayor que otras, que era muy sencillo equivocarte y que esa equivocación podría implicar una pérdida de datos.

Esto me hizo pensar, y si bien es cierto que git es una herramienta muy poderosa (con la que he tengo una relación de amor-odio desde hace varios años), el hecho de que una herramienta o lenguaje te permita ciertas libertades, no implica que estén pensadas para ser usadas siempre. Veamos un ejemplo en esta pregunta de Stack Overflow:

http://stackoverflow.com/questions/1488753/how-to-merge-two-branches-without-a-common-ancestor

A -- B -- ... -- K -- L -- M1
                             \
                              M3 -- N' -- .. -- Z'
                             /
               I1 -- I2 -- M2 -- N -- .. -- Z

En este caso son 2 ramas sin padre común, lo cual es un caso un tanto atípico según mi (corta) experiencia. Es malo git por permitir esta operación? No, debemos usarlo como patrón de ramas habitual? Tampoco. De hecho la mayoría de patrones de gestión de ramas se basan en tener una rama /main lo más sólida posible, y tener las características, usuarios o tareas en ramas separadas.

Otro comando con el que contamos es rebase que nos permite reescribir la historia de una rama, e integrar los cambios de otra, lo cual puede parecer una auténtica atrocidad para aquellos que consideren que un changeset es una foto inamovible.

Git no es el único, ya que tenemos otras herramientas y lenguajes de programación, que por diseño nos han permitido hacer ciertas cosas que se han ido de las manos:

PHP

El lenguaje que permite que sitios como Facebook, Yahoo, o Youtube no ha estado exento de polémica en los 18 años que lleva prestando servicio (desde nada más y nada menos que 1995). Buscando peculiaridades del lenguaje, descubrí que, entre otras cosas, PHP nos permite definir variables globales desde dentro de una función como muestra el siguiente bloque de código:

function foo () {
    global $var;
    // rest of code
}

Esto rompe con todas las reglas de encapsulación, y de alcance de las variables de una función que se estudian habitualmente, y desde luego, está duramente criticado su uso, Es PHP un mal lenguaje por implementar esta funcionalidad? No, es posible que encontremos un caso de uso específico para esta funcionalidad, y de ahí que el lenguaje nos de el soporte para la misma.

C

El padre, abuelo y antepasado común de muchos de los lenguajes de programación de hoy en día, y cuyo libro de cabecera contiene poco menos de 300 páginas (El famoso K & R), lleva recibiendo críticas desde 1972. Una de las funcionalidades más criticadas es, sin duda, la función goto:

int big_function()
{
    int ret_val = [success];
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    return ret_val;
}

Goto nos permite realizar un salto incondicional a una porción del fichero. Los detractores a goto opinan que rompe el flujo de ejecución de un programa y que puede ser una fuente de errores, además de que dificulta la legibilidad. Por otra parte, es útil en escenarios secundarios, como la eliminación de la recursividad.

Conclusiones

De igual manera que no debemos usar la misma herramienta para todo (antipatrón del martillo) debemos ser conscientes de las peculiaridades de los lenguajes, y en que lo que se nos aporta, se aporta con una razón en concreto, no necesariamente para aplicarlo a todos los escenarios.

Recordemos al Tío Ben cuando estemos desarrollando o usando una herramienta:

tio ben

Un gran poder conlleva una gran responsabilidad

Y tú, qué peculiaridades de estos (u otros) lenguajes te parece que han sufrido abuso por parte de los desarrolladores?

Más información y artículos interesantes

Me he hecho un blog en PHP: Conclusiones

Ha sido una serie interesante, he aprendido mucho y además tenía ganas de cacharrear un poco por debajo

Proyecto GitHub

Lo que he contado en esta serie, y un poco más está disponible en un proyecto en github para que lo bajes, lo copies y/o lo mejores a tu gusto, la estructura es la siguiente:

  • admin
    • add_new_post.php (tercer post)
    • index.php (segundo post)
    • new_post.php (tercer post)
  • backend.php (tercer post)
  • index.php (primer post)
  • login.php (primer post)
  • logout.php (segundo post)

Los artículos:

  • Descubriendo la <?: Comento las bases del procesamiento de las variables por post, y cómo generar cookies.
  • El monstruo de las galletas: Comento cómo se accede a la info de dichas cookies, y cómo se borran.
  • Accediendo a los datos: Nos conectamos a una base de MySQL, obtenemos los datos de los post y agregamos uno nuevo.

Más información:

Me he hecho un blog en PHP: Accediendo a los datos

He trabajado en PHP siempre a muy alto nivel, primero con WordPress, y luego vía Codeigniter, así que me apetecía bajar un poco de nivel y hacer un poco de fontanería, con un objetivo claro, aprender qué hay por debajo de todo lo que trabajo.

En esta serie veremos cómo crear un blog muy simple usando las opciones más básicas que ofrece PHP.

La idea:

Para finalizar esta serie vamos a ver cómo acceder a una base de datos mysql local, obtener la información, y agregar un post nuevo, podremos además, comprobar cómo acceder a funciones que se sitúan en otros ficheros.

La estructura de datos

La estructura será simple: una base de datos (blog) con una única tabla (posts) que a su vez tendrá 3 campos: id, title y text, un identificador numérico auto-incremental, una variable de tipo varchar(128) y la otra de tipo longtext.

Conectando a mySQL

En cierta entrevista de trabajo me preguntaron cómo se accedía a una base de datos mysql desde PHP, y en su momento no supe responder, pues bien, hay tres pasos, el primero conectar al servidor, el segundo seleccionar la base de datos con la que vamos a trabajar y el siguiente es ejecutar la consulta a realizar.

SQL (Structured Query Language) es un lenguaje que se basa en la ejecución de líneas de código denominadas consultas. Una consulta fundamentalmente puede devolver datos, insertar datos, modificarlos o destruirlos, entre otras cosas. En esta primera aproximación únicamente emplearemos dos consultas, una para obtener los datos, y otra para acceder a ellos.

Además para este caso vamos a meter todo el código en una función, de tal manera que tengamos el código HTML (que se ejecuta en el navegador) y el código PHP (que se ejecuta en el servidor) lo más separado posible, así que creamos un nuevo fichero llamado backend.php y colocamos este código:

	function init(){
		mysql_connect('localhost', 'root', 'password');
		mysql_select_db('blog');
		$result = mysql_query('SELECT * FROM posts');
		return $result;
	}

El código anterior se conecta a la base de datos con el usuario root y la contraseña password, seguidamente selecciona la base de datos blog, y finalmente ejecuta la consulta, que viene a significar selecciona todos los elementos de la tabla posts. Desde nuestra web (en este caso el index.php) podremos entonces hacer una llamada a init(); al principio del fichero, y usar el resultado para movernos por la base de datos.

Recorriendo los datos

Para poder recorrer el resultado, lo que hacemos es usar la función mysql_fectch_assoc, que recorre el resultado de la query y devuelve un array asociativo (también llamado diccionario), donde podemos obtener el valor de los distintos campos de la tabla. El código mostrado a continuación muestra el resultado de recorrer el resultado de la consulta:

while ($row = mysql_fetch_assoc($result)) {
    echo "<h1>".$row['title']."</h1>";
    echo "<p>".$row['text']."</p>";
}

Esto nos da como resultado la lista de posts, mostrada por pantalla.

Agregando nuevos posts

La última opción que vamos a agregar a nuestro sistema será la opción de agregar un nuevo post, para ello necesitaremos un par de cosas, un formulario para introducir los datos y un código PHP que agregue los datos.

El formulario que tendremos tendrá el siguiente formato: dos etiquetas, un campo de texto para el título, un campo largo de texto para el contenido, y el siempre útil botón de publicar:

<h1>New Post</h1>
	<form action="add_new_post.php" method="post">
		<label for="title">Title:</label> <input type="text" name="title"></input><br/>
		<label for="text">Text:</label> <textarea name="text" rows="8" cols="40"></textarea><br/>
		<input type="submit"/>
	</form>

Por otro lado, el código para procesar la información se construirá de manera similar a como hemos procesado la información de login, y ejecutará una función que realice una consulta bastante parecida a la anterior, es decir, agregar el contenido de los campos title y text a un nuevo registro de la tabla:

	function add_new_post($title, $text){
		mysql_connect('localhost', 'root', 'password');
		mysql_select_db('blog');
		$result = mysql_query("INSERT INTO posts (title,text) VALUES ('".$title."', '".$text."')");
		echo mysql_error();
		echo "<a href='index.php'>Go to admin</a>";
	}

En caso de que todo vaya bien, debería mostrarnos una pantalla en blanco, con el enlace a la home, si se produjese algún error, se mostraría por pantalla.

Más información:

Me he hecho un blog en PHP: El monstruo de las galletas

He trabajado en PHP siempre a muy alto nivel, primero con WordPress, y luego vía Codeigniter, así que me apetecía bajar un poco de nivel y hacer un poco de fontanería, con un objetivo claro, aprender qué hay por debajo de todo lo que trabajo.

En esta serie veremos cómo crear un blog muy simple usando las opciones más básicas que ofrece PHP.

La idea:

En esta entrega comentaremos cómo leer las cookies (para que el login tenga algo de sentido), y cómo borrarlas (para hacer una función de logout decente).

Consumiendo cookies

Una vez que tenemos nuestra cookie creada, el siguiente paso es consumirla, lo cual se hace de una manera similar a la que hacíamos con las opciones get y post, usando la variable $_COOKIE.

if (!isset($_COOKIE['username'])) {
		echo "You shouldn't be here";
	}

En el código anterior lo que hacemos es comprobar que el valor de la cookie esté fijado usando la función isset. Si no existe mostraremos un mensaje de error al usuario. En caso de que el código sea correcto podremos continuar, mostrando un mensaje de aceptación.

Una de las cosas interesantes de comprobar la cookie es que podemos usarla para ocultar el menú de login, como suelen hacer los blogs habitualmente, de tal manera que podemos ampliar el código del primer artículo que usabamos para hacer login por esto:

<?php if (!isset($_COOKIE['username'])): ?>
	<form action="login.php" method="post">
        ...
	</form>
<?php else : ?>
	<p>Logged in as <?php echo $_COOKIE['username']."." ?> <a href="admin/index.php">Go to admin</a>
	</p>
<?php endif ?>

Para consumir el valor de la cookie podremos usar el siguiente código, que en este caso será un nombre de usuario, y lo mostraremos junto con un mensaje de saludo.

	<p>Welcome <?php echo $_COOKIE['username'];?> <a href='../index.php'>Go home</a></p>

Eliminando cookies

Para eliminar cookies existen varios métodos, pero hubo uno en especial que me llamó la atención cuando estaba haciendo el post, que consiste en establecer otra cookie idéntica, pero con el valor vacío y la fecha anterior a la actual, convirtiendola en errónea (o caducada) y causando que el navegador la borre.

Este proceso lo vamos a realizar con un fichero llamado logout.php que contendrá el código que elimina la cookie, y muestra un mensaje de «Sesión cerrada correctamente».

	setcookie("username","", time() - 3600);

Una vez hayamos pasado por esta página la cookie se borrará, tendremos que autenticarnos de nuevo para poder acceder al panel de administración, y volveremos a ver el panel de identificación . En la próxima entrega veremos cómo podemos enlazar el php que tenemos a una base de datos mysql, y obtener los datos desde ahí.

Más información:

Me he hecho un blog en PHP: Descubriendo la <?

He trabajado en PHP siempre a muy alto nivel, primero con WordPress, y luego vía Codeigniter, así que me apetecía bajar un poco de nivel y hacer un poco de fontanería, con un objetivo claro, aprender qué hay por debajo de todo lo que trabajo.

En esta serie veremos cómo crear un blog muy simple usando las opciones más básicas que ofrece PHP.

La idea:

Simple, lo primero que haremos será un formulario de login, para aprender cómo php maneja las acciones get y post.

Para comenzar, creamos un formulario estándar con 2 etiquetas, dos campos de texto y un botón para enviar los datos. El formulario en su campo action tiene como objetivo la página login.php, y en method especificamos que los valores se pasen mediante POST:

<form>action="login.php" method="post"></form>
		<label for="user">User:</label> <input type="text" name="user" />
		<label for="user">Password:</label> <input type="password" name="password" />
		<input type="text" />type="submit"/>
	</form>

Hasta aquí, HTML estándar, veamos qué pasa en el login.php (el código disponible a continuación va entre los campos <?php y ?>)

	$username = "roberto";
	$password = "3bc2e28ca8940090c3d80c851784a5d5"; //cifrado

	if (($_POST['user'] == $username) && (MD5($_POST['password']) == $password)) {
		setcookie("username","roberto");
	}

En este caso lo primero que hacemos es definir un par de variables, usuario y contraseña, cuyos valores los compararemos con los valores que vienen desde el formulario anterior.

Para comparar los datos, lo que hacemos es obtener el contenido del POST del formulario usando la variable $_POST de php, y comparándolo con el valor almacenado, lo mismo hacemos con la contraseña, pero con un paso intermedio.

Dicho paso consiste en encriptarla generar un hash a partir de ella usando un algoritmo conocido como MD5 (Gracias Vicente por el apunte), de tal manera que no se guarda el dato en texto plano, como medida de seguridad, la función MD5 devuelve una cadena de caracteres con el resultado.

Si la autorización es correcta, el siguiente paso es establecer una cookie con el nombre de usuario en este caso. Las cookies son pequeños ficheros que se guardan en la memoria del ordenador, y que sirven para mantener, por ejemplo, una sesión iniciada en la web.

Tras este primer post hemos visto cómo pasar datos de un fichero index.html a otro login.php, además hemos visto cómo establecer cookies. En la próxima entrega veremos más información sobre el tratamiento de cookies.

Más información: