API is.gd: Encurtando URLs com o PHP

Atenção! Essa postagem foi escrita há mais de 2 anos. Na informática tudo evolui muito rápido e algumas informações podem estar desatualizadas. Embora o conteúdo possa continuar relevante, lembre-se de levar em conta a data de publicação enquanto estiver lendo. Caso tenha sugestões para atualizá-la, não deixe de comentar!

Sobre o site

O site is.gd é um encurtador de URLs. O serviço básico deles é pegar uma URL grande e transformá-la em pequena.
Decidi começar com esse site porque é a API mais simples que eu encontrei.

Sobre a API

Documentação: http://is.gd/api_info.php
Necessita registro: Não
Limite de uso: Encurtamento de 1000 URLs/dia por IP
Termos de uso: http://is.gd/terms.php

Utilizando a API

O uso do is.gd é muito simples: você envia uma URL e recebe outra. A única limitação é quanto a URLs com mais de 2000 caracteres, o que não deve ser um problema já que é muito raro de se ver isso.

Para a nossa experiência, decidi fazer uma classe para trabalhar com o encurtamento de URLs. Para fins didáticos, não irei trabalhar com métodos e propriedades privados (só um :P) e muito menos com padrões de projeto.

A classe vai funcionar da seguinte maneira: instanciamos o objeto, solicitamos o encurtamento da URL e depois trabalhamos com os dados recebidos.

As propriedades que o nosso objeto deve ter serão as seguintes:
url_original: URL original que foi passada para ser encurtada.
url_curta: URL curta retornada pelo servidor.
erro: true ou false, indicando se houve erro durante a tentativa de encurtar a URL.
erro_msg: no caso de ‘erro’ ser true, aqui fica a mensagem de erro, caso contrário fica como NULL.

E os métodos que utilizaremos:
encurtar: obviamente serve para encurtar a URL. :P
desencurtar: método “brinde” para desencurtar a URL, por que na real a própria API não desencurta as URLs.

Mão na massa

O primeiro passo é montar o corpo da nossa classe. Optei por utilizar um método de encurtar a URL para que o mesmo objeto possa ser utilizado para encurtar várias URLs e também te dá a possibilidade de instanciar o objeto apenas para desencurtar URLs.

Vou dar uma breve explicação do que há no código pois todo ele está comentado. :)

Para fazer o encurtamento precisamos enviar a URL para a API através do método GET.
Por exemplo: http://is.gd/api.php?longurl=phpit.com.br

Desta requisição podem retornar duas coisas: o status 200 (OK) com a URL encurtada ou o status 500 (Internal Server Error) com a mensagem de erro.

O método encurtar preenche as propriedades da classe com os dados pertinentes e retorna true para o caso de ter ocorrido tudo bem e false para o caso de ter dado problema.
Já o método desencurtar apenas retorna a URL desencurtada, sem mexer nas propriedades da classe. Pode também retornar false para o caso de a URL ser inválida.

A seguir você tem a classe na versão comentada e na versão não comentários.

Versão comentada:

[php]curl = curl_init();

// Configura o objeto para retornar os dados ao invés de imprimir na tela
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
/* Configura o objeto para responder a redirecionamentos
É utilizado no método de desencurtar URLs, pois precisamos seguir até a URL final */
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, 1);
}

// Método para encurtar a URL
public function encurtar($url) {
// Utilizamos esta função para codificar os caracteres especiais da URL
$urlCodificada = rawurlencode($url);

// Esta é a URL que utilizaremos para acessar a API
$urlApi = ‘http://is.gd/api.php?longurl=’.$urlCodificada;

// Configuramos a URL no cURL
curl_setopt($this->curl, CURLOPT_URL, $urlApi);

// Executamos a requisição
$retorno = curl_exec($this->curl);

// Recebemos os dados da execução
$dados = curl_getinfo($this->curl);

// O http_code pode ser 200 (OK) e 500 (Internal Server Error)
/* Junto com a verificação, é bom olhar também se a URL
possui menos de 20 caracteres, já que o is.gd trabalha
com no máximo 18. Isto ajuda a evitar error arbitrários. */
if ($dados[‘http_code’] == 200 && strlen($retorno) < 20) { // Caso tenha ocorrido tudo bem, resetamos estas propriedades $this->erro = false;
$this->erro_msg = NULL;
$this->url_curta = $retorno;
} else {
// Caso tenha dado algum problema, colocamos os dados aqui
$this->erro = true;
$this->erro_msg = $retorno;
$this->url_curta = NULL;
}

// Colocamos a URL original no seu lugar
$this->url_original = $url;

/* Por fim, para tornar mais fácil ainda, o retorno da função será
true ou false dependendo do resultado que obtivemos no processo */
return $this->erro;
}

// Método para desencurtar a URL
public function desencurtar($url) {
// Primeiro verificamos se a URL é realmente is.gd
if (substr($url, 0, 13) == ‘http://is.gd/’ || substr($url, 0, 6) == ‘is.gd/’) {
// Configuramos a URL no cURL
curl_setopt($this->curl, CURLOPT_URL, $url);

// Executamos a requisição
curl_exec($this->curl);

// Recebemos os dados da execução
$dados = curl_getinfo($this->curl);

// Testamos se o status é 200 e se a URL retornada é diferente da desencurtada
if ($dados[‘http_code’] == 200 && $url != $dados[‘url’]) {
// Retornamos a URL desencurtada
return $dados[‘url’];
}
}
// Caso tenha dado algum problema no meio do caminho, retornamos false
return false;
}

}
?>[/php]

Versão não comentada:

[php]curl = curl_init();

curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, 1);
}

public function encurtar($url) {
$urlCodificada = rawurlencode($url);
$urlApi = ‘http://is.gd/api.php?longurl=’.$urlCodificada;
curl_setopt($this->curl, CURLOPT_URL, $urlApi);
$retorno = curl_exec($this->curl);
$dados = curl_getinfo($this->curl);

if ($dados[‘http_code’] == 200 && strlen($retorno) < 20) { $this->erro = false;
$this->erro_msg = NULL;
$this->url_curta = $retorno;
} else {
$this->erro = true;
$this->erro_msg = $retorno;
$this->url_curta = NULL;
}

$this->url_original = $url;

return $this->erro;
}

public function desencurtar($url) {
if (substr($url, 0, 13) == ‘http://is.gd/’ || substr($url, 0, 6) == ‘is.gd/’) {
curl_setopt($this->curl, CURLOPT_URL, $url);
curl_exec($this->curl);
$dados = curl_getinfo($this->curl);
if ($dados[‘http_code’] == 200 && $url != $dados[‘url’]) {
return $dados[‘url’];
}
}
return false;
}

}

?>[/php]

Utilização

Para utilizar a classe é muito simples.

Encurtando uma URL
[php]encurtar(‘https://phpit.com.br’)) {
echo ‘URL encurtada: ‘;
echo $isgd->url_curta;
} else {
echo $isgd->erro_msg;
}

?>[/php]

Vale ressaltar que quando ocorrer tudo certo, teremos o objeto desta forma:

[sourcecode]isgd Object
(
[url_original] => phpit.com.br
[url_curta] => http://is.gd/9Q9kP
[erro] =>
[erro_msg] =>
[curl:private] => Resource id #2
)[/sourcecode]

E quando houver erro teremos algo parecido com isso:

[sourcecode]isgd Object
(
[url_original] => […] uma url muito longa aqui :) […]
[url_curta] =>
[erro] => 1
[erro_msg] => Error: The URL entered was too long.
[curl:private] => Resource id #2
)[/sourcecode]

Desencurtando uma URL
[php]desencurtar(‘http://is.gd/9Q9kP’);

if ($url) {
echo ‘URL encurtada: ‘;
echo $url;
} else {
echo ‘Nao foi possivel desencurtar a URL.’;
}

?>[/php]

Conclusão

Bom… Acho que pra primeira API explorada tivemos um trabalho bastante interessante.
Espero que você possa aproveitar (e entender, principalmente) esta classe. Se você fizer melhorias nela, por favor, me mande pois eu gostaria muito de ver!

Aguardo sugestões para as próximas APIs exploradas e quem quiser contribuir com experiências, elas são sempre bem vindas.

Um abraço a todos e fiquem com Deus!