Un acortador de enlaces es una herramienta que permite de enviar direcciones de webs a través de las redes sociales ahorrando espacio en el mensaje. Se popularizaron mucho con twitter ya que solo se dispone de 140 caracteres por mensaje.
Hay muchísimos acortadores de url en internet, algunos son bit.ly, tinyurl, goo.gl, …
¿Porque tener un acortador de urls propio?
Por independencia sobre todo, ¿que pasaría si [pon aquí tu acortador de urls preferido] le diera por poner publicidad antes de ir a la pagina de destino? ¿y si tu quieres poner publicidad? ¿y si no te fías de las estadísticas que te dá o de como las calcula?
Pero lo que realmente me convenció a hacerlo: ¿realmente para una redirección necesito usar un servicio externo? Quiero decir: ¿que valor añadido saco de tener bit.ly/aAaAaA comparado con link.xhiena.net/aAaAaA o xhiena.net/link/aAaAaA?
A parte de que es mas corto no saco nada más, pero sinceramente, link.xhiena.net/aAaAaA es mas corto que xhiena.net/index/crea-tu-propio-acortador-de-enlaces-con-api-en-php-y-mysql
Pensando el sistema
Un pequeño resumen general de lo que debe hacer:
- Mi sistema acortador de enlaces va a recibir una url y la va a codificar en un código de 6 caracteres.
- El código estará compuesto por minúsculas, mayúsculas, números, ‘_’ y ‘-’.
- Los caracteres se podrán repetir, es decir, el código ‘——’ será feo, pero válido.
- Tendrá una API para poder añadir enlaces desde otras aplicaciones.
- Dibujo de como funcionará:

funcionamiento del acortador de urls
Es un sistema muy simple, por lo que solo crearé un diagrama simple de flujo de datos

Flujo de datos de Add
Entendiendo mi código
Cada uno tenemos una forma de programar, yo suelo crearme una carpeta “includes” en la que meto todos los archivos con la conexión a la base de datos, idiomas, sesiones, … y me creo un top.php que incluye todo asi que:
require("include/top.php");
Crea una sesión, crea la conexión a la base de datos, incluye el archivo de idiomas, incluye el archivo de funciones, …
Definiendo el sistema
Base de datos
Esta es una versión mínima de un acortador de urls, así que solo tendrá una tabla

tabla de links
Add.php
El sistema realmente solo tiene un proceso, que es el generar el código y guardarlo en la base de datos (que en un alarde de originalidad he llamado: ADD)
Add tiene que:
- Recoger variables
- Generar el código único
- Guardarlo todo en la base de datos
<?php
require("include/top.php");
$u_sql=urldecode($_GET['u']);
$formatos_return=Array("html","xml","json","txt");
$r=isset($_GET["r"])?($_GET['r']):($formatos_return[0]);
$r=(in_array($r,$formatos_return))?($r):($formatos_return[0]);
$u=addUrl($u_sql);
if ($u){
header("location: /added/".$r."/".$u);
}
?>
funciones.php
El archivo que tiene todas las funciones
/**
* Entrada: url a codificar
* Salida: el código único o false
*/
function addUrl($url){
global $db;
if (!checkUrl($url)){
echo TXT_ERROR_URL_FORMAT;
return false;
}
$code=getCode();
$sql="insert into link values ('','$url','$code','0')";
if($db->query($sql)){
return $code;
}
else{
echo $db->error;
return false;
}
}
Comprueba la url, genera un código y lo mete en la base de datos, poco más que explicar
/**
* entrada: url
* salida: true o false
*/
function checkUrl($url){
//return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
return true;
}
Por ahora devuelve siempre true a expensas de mejorar la expresión regular para que pille todas las url, ya que las que tienen símbolos raros no pasan este test
/**
* entrada: nada
* salida: código
*/
function getCode(){
$cadena_base="abcdefghijklmnopkrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-";
$i=0;
$c="";
while ($i<6){
$c.=$cadena_base[rand(0,strlen($cadena_base)-1)];
$i++;
}
if (getUrl($c)!=false){
return getCode();
}
else return $c;
}
En base a nuestra especificación del código, se genera un código de 6 caracteres compuesto por minúsculas, mayúsculas, números, ‘_’ y ‘-’. getUrl devuelve false si no existe el código así que si no devuelve false, existe el código, así que se genera de nuevo.
/**
* entrada: codigo
* salida: url o false
/*
function getUrl($code){
global $db;
$sql="select url from link where shortcode like '$code'";
$result=$db->query($sql);
if ($result!=false){
$row = $result->fetch_object();
if ($row){
return $row->url;
}
else{
return false;
}
}
else{
return false;
}
}
Busca el código en la base de datos y devuelve la url o false si no existe.
added.php
La pagina para mostrar el código generado:
require("include/top.php");
$r=isset($_GET["r"])?($_GET['r']):("html");
switch ($r){
default:
case "html":
echo TXT_ADDED.": ".BASE_LINK_URL."".$_GET['code'];
break;
case "xml":
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<response>\n <data>".BASE_LINK_URL."".$_GET['code']."</data>\n</response>";
break;
case "json":
echo "{data : \"".BASE_LINK_URL."".$_GET['code']."\"}";
break;
case "txt":
echo BASE_LINK_URL.$_GET['code'];
break;
}
He elegido tener 4 formatos de salida: html, xml, json y txt.
Con estas funciones ya tenemos todo el sistema. podemos añadir enlaces y con getUrl($code) podemos recuperar una dirección web guardada:
go.php
require("include/top.php");
$u_sql=$db->real_escape_string($_GET['u']);
$u=getUrl($u_sql);
if ($u){
addVisit($u_sql);
header("location: ".$u);
}
addVisit($code) simplemente incrementa el campo visited:
function addVisit($code){
global $db;
$sql="Update link set visited=visited+1 where shortcode like '$code'";
$result=$db->query($sql);
return $result;
}
Recapitulamos lo que tenemos hasta ahora
Tenemos el sistema completo: una página que añade una url a la base de datos: add.php y otra que va a la url pasandole el codigo.
es decir: add.php?u=http://xhiena.net&r=xml devuelve:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<data>http://xxxxxxxx.xhiena.net/yyyyyy</data>
</response>
add.php?u=http://xhiena.net&r=html en modo pagina web, add.php?u=http://xhiena.net&r=txt solo el enlace generado y add.php?u=http://xhiena.net&r=json en formato json.
y si vamos a http://xxxxxxxx.xhiena.net/go.php?u=yyyyyy nos redireccionará a xhiena.net :D
Haciéndolo bonito
Para acortar mas la url vamos a usar htaccess y rewriterule:
#si llegan 6 caracteres con minusculas, mayusculas, numeros, '_' o '-' nos vamos a go.php
RewriteRule ^([0-9a-zA-Z_-]{6})$ go.php?u=$1 [L]
#esta es solo para hacer mas bonita la url del added.php
#lo que hace es que convierte xxx.xhiena.net/html/xxxxxx en added.php?code=xxxxxx&r=html
RewriteRule ^added/([a-zA-Z]+)/([0-9a-zA-Z_-]{6})$ added.php?code=$2&r=$1 [L]
y ya lo tenemos!
El api
el api ya esta hecho!! al hacer add.php por get lo podemos llamar directamente :D
Aunque si quieres algo mas bonito, puedes añadir al htaccess:
RewriteRule ^api/add/([a-zA-Z]+)/(/+)$ add.php?u=$2&r=$1 [L]
Os imagináis que hace? xD (no lo he probado asi que puede que no vaya como debería ir)
PD: podeis compartir esta entrada como http://go.xhiena.net/bLQTMT :P




[...] URL: http://xhiena.net/index/crea-tu-propio-acortador-de-enlaces-con-api-en-php-y-mysql/ [...]
Muy interesante la entrada definitivamente lo voy a recomendar, gracias por tan excelente contenido.
Me alegro que te guste :D
Informaci�n de BlogESfera.com……
Puedes valorar este post en BlogESfera.com haciendo click aqui….
[...] http://xhiena.net/index/crea-tu-propio-acortador-de-enlaces-con-api-en-php-y-mysql/comment-page-1/ [...]
Saludos, listo compartido en:
http://medennysoft.com/2012/08/08/crea-tu-propio-acortador-de-enlaces/
like it :)
El return true de la función checkUrl es lo mejor de todo el post!!!!
PD: Ná…es solo meterme contigo…yo con las expresiones regulares me pierdo mucho x’D
PDD: Mola el post nen, cúrrate más de estos que yo de PHP soy azúcar.
ejem ejem … xDDD “Por ahora devuelve siempre true a expensas de mejorar la expresión regular para que pille todas las url, ya que las que tienen símbolos raros no pasan este test”
PD: mamona xD
Oye, pues mola :) Aunque yo con mis conocimientos actuales no pueda aprovecharlo, se entiende xD
Pero te escribo sobre todo para comentarte que, ya que lo has escrito… ¿no sería lo suyo aprovecharlo?
Es decir, si le das a compártelo en twitter, por ejemplo, sigues utilizando la url larga Ô_ó
¿O no es del todo funcional?
Básicamente era una especie de “a ver si lo puedo hacer” es completamente funcional y si vas a http://go.xhiena.net/bLQTMT se dirige a este post.
Otro tema es integrarlo con el pluggin de wordpress que saca lo de compartir en redes sociales que ya es otro tema digno de otro post xD
Excelente POSTEO te felicito!!!
Lo que sí al igual que alguien más arriba, me quedó en duda el checkurl ya que yo tampoco tengo soltura con las expresiones regulares, como se podría mejorar para los caracteres extras?
Por favor una ayuda ya que lo estoy probando pero esto no se como arreglarlo.
Gracias!!!!!!!!