Czasami zdarza się, że użytkownik przeglądający Twoją stronę chciałby się podzielić adresem ze swoimi znajomymi. W tym celu może najzwyczajniej w świecie skopiować adres strony z paska adresu przeglądarki.
Co jeśli adres bieżącej strony jest bardzo długi i użytkownik nie będzie miał możliwości wklejenia tego adresu w całości (np. na gadu gadu, które ogranicza długość opisu)? W niniejszym wpisie zaradzimy temu problemowi.
Problem jest dość błahy, bowiem tego typu „skracaczy” linków jest multum w sieci. Dlatego też postanowiłem nie pisać kolejnego (choć wydaje się być to prostym przedsięwzięciem, jednak nie zamierzam wynajdować koła na nowo).
W celu skrócenia linków wykorzystamy istniejące i sprawdzone już serwisy udostępniające swoje API, niezawodne i często wykorzystywane przez innych.
Postaramy się napisać dość rozszerzalny i uniwersalny kod, aby móc z łatwością w razie potrzeby przebudować kod (np. w przypadku, gdy serwis skracający linki padnie lub zawiedzie nasze oczekiwania).
Założenia projektu
Na początku napiszmy klasę bazową, która będzie stanowić wzorzec dla klas dziedziczących i implementujących konkretne rozwiązania serwisów.
Można by tutaj zastosować także interfejs, jednak wybrałem klasę abstrakcyjną, aby móc od razu wrzucić tu trochę kodu i nie powielać go w klasach dziedziczących.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | abstract class ShortLink { // long link protected $url; protected $login; protected $key; /** * ShortLink Constructor * * @param string $login login from api * @param string $key key from api **/ public function __construct($login='', $key='') { $this->login = $login; $this->key = $key; } /** * Create shortlink * * @param string $url long url to tiny * @return string shortlink **/ public function create($url) { // bind url $this->url = rawurlencode($url); // get shortlink from chosen page $_shortlink = $this->getShortLink(); // check shorturl is valid if ($this->checkResult($_shortlink)) { return $_shortlink; } } /** * Check shorturl is valid * * @param string $shortlink shortlink * @return boolean result validation **/ protected function checkResult($shortlink) { return (strpos('_' . $shortlink, $this->page) > 0); } /** * Get short link * empty method to implement in subclass **/ public function getShortLink() { } } |
Powyższy kod jest prosty i względnie opisany, także nie powinno być problemów w analizie.
Dla pewności jednak opiszę jego działanie:
- tworząc instancję klasy mamy możliwość dodania w parametrach loginu i klucza użytkownika – dodane tutaj, ponieważ często wykorzystywane,
- pobiera adres strony do skrócenia,
- wywołuje funkcje getShortLink, która będzie definiowana w podklasach, a której zadaniem będzie pobranie skróconego adresu,
- sprawdza czy skrócony link jest prawidłowy,
- zwraca skrócony adres.
Czas na definiowanie konkretnych podklas, które będą odpowiedzialne za rzecz najważniejszą – pobranie skróconego adresu.
TinyURL.com
Zacznijmy od najprostszego serwisu. Pobierzemy teraz skrócony adres z TinyURL.com z wykorzystaniem ich API, które jest genialnie proste.
1 2 3 4 5 6 7 8 9 10 | class TinyURL extends ShortLink { public $page = 'http://tinyurl.com/'; // create short link public function getShortLink() { return file_get_contents("http://tinyurl.com/api-create.php?url=" . $this->url); } } |
W klasie tej dziedziczymy z wcześniej utworzonej klasy abstrakcyjnej ShortLink. Tworzymy w tej klasie także publiczną właściwość page, która jest wykorzystywana przez walidator poprawności utworzonego adresu.
Jak więc widać, wystarczy skierować żądanie do strony „api-create.php” z parametrem url zawierającym adres strony, a zwrócony wynik będzie skróconym adresem! Idealne.
bit.ly
Kolejnym serwisem, który weźmiemy za przykład będzie bardzo popularny bit.ly (popularność chyba wynika z bardzo krótkiego adresu).
Niestety, aby skorzystać z ich usługi będziemy potrzebowali założyć konto. Na szczęście nie jest to żaden problem, a nawet pozwala kontrolować utworzone przez nas linki.
W ten sposób uzyskujemy login i key potrzebne do zdalnego skrócenia linku. Kod wygląda natomiast bardzo podobnie do TinyURL.com:
1 2 3 4 5 6 7 8 9 | class BitLy extends ShortLink { public $page = 'http://bit.ly/'; public function getShortLink() { return file_get_contents("http://api.bit.ly/v3/shorten?login=" . $this->login . "&apiKey=" . $this->key . "&longUrl=" . $this->url . "&format=txt"); } } |
tiny.cc
Kolejnym serwisem udostępniającym swoje API do skracania linków jest tiny.cc. Jest to ostatni serwis, ponieważ na potrzeby ww. przykładu więcej już raczej nie trzeba.
Działanie również jest bardzo podobne, przy czym dane zwracane przez ten serwis są w formacie JSON. Przetwarzanie tego formatu również jest banalnie proste, więc i poniższy kod nie wymaga komentarza:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class TinyCC extends ShortLink { public $page = 'http://tiny.cc/'; public function getShortLink() { // get response $_response = file_get_contents("http://tiny.cc/?c=rest_api&m=shorten&version=2.0.1&format=json&longUrl=" . $this->url . "&login=" . $this->login . "&apiKey=" . $this->key); // convert json to php object try { $_response = json_decode($_response); } catch (Exception $e) { } $_url = rawurldecode($this->url); return $_response->results->$_url->short_url; } } |
Nie obsługuję tutaj błędów, a zastosowanie try {} catch {} dałem jedynie w celu ukrycia ewentualnych błędów.
W zastosowaniu produkcyjnych warto by pomyśleć nad obsługą wyjątków (być może, jeśli jeden serwis zaszwankuje, zadanie wygenerowania linku przerzucić do innego serwisu).
Przykładowe wykorzystanie
Gdy mamy już utworzone klasy, możemy przystąpić do napisania krótkiego przykładu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $url = 'http://blog.kamilbrenk.pl/automatyczne-skracanie-linkow/'; echo ' <pre>'; // full link echo "Pełen adres: \n" . $url . "\n\n"; // TinyURL.com $shortlink = new TinyURL; echo "TinyURL.com: \n" . $shortlink->create($url) . "\n\n"; unset($shortlink); // Bit.ly $shortlink = new BitLy('kamil', '[tajny]'); echo "Bit.ly: \n" . $shortlink->create($url) . "\n\n"; unset($shortlink); // Tiny.cc $shortlink = new TinyCC('kamil', '[tajny]'); echo "Tiny.cc: \n" . $shortlink->create($url) . "\n\n"; unset($shortlink); echo '</pre> '; |
Powyższy kod wypluje do okienka przeglądarki:
1 2 3 4 | Pełen adres: http://blog.kamilbrenk.pl/automatyczne-skracanie-linkow/ TinyURL.com: http://tinyurl.com/25rco93 Bit.ly: http://bit.ly/cHIMJJ Tiny.cc: http://tiny.cc/esmzz |
Oczywiście w prawdziwym przypadku generowanie adresu dla wszystkich tych serwisów jest rzeczą zbędną – wystarczy jeden serwis, który skróci nasz adres.
Ja poproszę o pomoc w utworzeniu interfejsu do serwisu
http://tnij.us
Serwis ten jest dosyć rozbudowany, i ma wiele opcji.
misiek, tnij.us nie udostępnia API, a nie chce mi się parsować całej strony celem wydobycia pożądanych danych. zwłaszcza, że jest tak wiele ciekawej konkurencji :-)
Właśnie nie mogę znaleźć implementacji dla tnij.us, a serwis jako jedyny udostępnia możliwość zassania kodu QR (http://tnij.us/fotokody) a na tym mi bardzo zależy. Z tego co wiem, to udostępnia on swoje API(http://tnij.us/API) natomiast nie potrafię napisać kodu żeby móc wykorzystać te opcje.
@misiek:
Generalnie tnij.us ma coś spieprzone to API, natknąłem się na kilka błędów:
– będąc zalogowany i przechodząc do działu API wywala błąd: „nie masz uprawnień do oglądania tej strony”, podczas gdy będąc niezalogowany mogę oglądać,
– wybierając typ zwracanych danych (parametr output) nic się nie zmienia, więc nie chce zwracać w formacie JSON czy XML.
Generalnie amatorka ten serwis i poszukałbym lepszej konkurencji (np. Google). Tak czy siak, masz odpowiednią klasę (banalny kod, nie wiem czego tu nie mogłeś zrobić):
2
3
4
5
6
7
8
9
10
11
12
13
public $page = 'http://tnij.us/';
public function getShortLink() {
// get response
$_response = file_get_contents("http://tnij.us/ShortURL/Add/?mode=API&url=" . $this->url . "&to_user=" . $this->login . "&key=" . $this->key);
return $_response;
}
}
I później to wywołujesz w następujący sposób:
2
echo $shortlink->create('http://jakis-url.pl/');
@dupa:
faktycznie, nie zabezpieczyłem się przed tym, słabo :) dzięki za zwrócenie uwagi na problem!