PHP Trackback – Bir “Geri İzleme” sınıfı
Geri İzleme (Trackback) nedir? başlıklı yazımda, PHP Trackback adlı geri izleme sınıfından bahsedeceğimi söylemiştim. Bu sınıfı baştan sona inceleyerek, hem geri izleme teknolojisinin teknik altyapısını kavrayacağız, hem de bu tür bir sistemin PHP ile nasıl kodlanabileceğini görmüş olacağız.
Yazı; hem kodları yayınlamamdan, hem fonksiyonlardan ayrı ayrı bahsetmemden dolayı biraz uzun oldu. Kaynak kodları içinde örnekler olduğundan dolayı birkaç fonksiyon dışında bu örneklere yer vermedim, onları incelemeyi size bırakıyorum. Sizi daha fazla cümlelerle sıkmadan hemen sınıfı incelemeye başlıyorum...
Öncelikle sınıf hakkında genel bilgilerle konuya girelim. İsrail'de yaşayan Ran Aroussi adlı arkadaş tarafından kodlanan bu sınıf, geri izleme teknolojisinin hemen hemen bütün gereklerini yerine getirebiliyor. Sınıfın kod mimarisine baktığımızda ise PHP4 ile kodlandığını görüyoruz. PHP5'e geçen arkadaşların da dert etmesine gerek yok; PHP, geriye dönük uyumlu sürümler çıkardığı için bu sınıf, platform sorunu çıkarmayacaktır (Ben PHP5.2.x sunucu üzerinde denedim).
Sınıfın ingilizce olarak kaynak kodlarını görmek için tıklayınız...
Sınıfı indirmek için tıklayınız...
Ran Aroussi arkadaşımız kodları hazırlarken hem açıklamalarını kolay anlaşılır bir biçimde yazmış, hem de her fonksiyon için ayrı ayrı kullanım örnekleri iliştirmiş. İngilizcesi olan arkadaşlar rahatlıkla kaynak kodlarına bakarak sınıfı kullanabilir ama biz yine de tüm fonksiyonları ayrı ayrı inceleyeceğiz.
SINIFIN ÖZELLİKLERİ
-
/**
-
* Geri izleme - Asıl sınıf
-
*
-
* @param string $blog_name
-
* @param string $author
-
* @param string $encoding
-
*/
-
class Trackback {
-
var $blog_name = ''; // Sınıf boyunca kullanılacak varsayılan günlük adı (örn. Shapcy.com)
-
var $author = ''; // Sınıf boyunca kullanılacak varsayılan yazar adı (örn. Mustafa ŞAPÇILI)
-
var $encoding = ''; // Sınıf boyunca kullanılacak varsayılan karakter kodlaması(örn. UTF-8)
-
var $get_id = ''; // $_GET['id'] değerini geri alır ve tutar (boş değilse)
-
var $post_id = ''; // $_POST['id'] değerini geri alır ve tutar (boş değilse)
-
var $url = ''; // $_POST['url'] değerini geri alır ve tutar (boş değilse)
-
var $title = ''; // $_POST['title'] değerini geri alır ve tutar (boş değilse)
-
var $expert = ''; // $_POST['expert'] değerini geri alır ve tutar (boş değilse)
-
/**
-
* Sınıf yapıcısı
-
*
-
* @param string $blog_name
-
* @param string $author
-
* @param string $encoding
-
* @return
-
*/
-
function Trackback($blog_name, $author, $encoding = "UTF-8")
-
{
-
$this->blog_name = $blog_name;
-
$this->author = $author;
-
$this->encoding = $encoding;
-
-
// $_POST bilgisini topla
-
$this->get_id = $HTTP_GET_VARS['id'];
-
}
-
$this->post_id = $HTTP_POST_VARS['id'];
-
}
-
$this->url = $HTTP_POST_VARS['url'];
-
}
-
$this->title = $HTTP_POST_VARS['title'];
-
}
-
$this->expert = $HTTP_POST_VARS['expert'];
-
}
-
}
Dosyayı parça parça koyacağım. Bu yüzden söz dizimi hatası varmış gibi durabilir
Sınıfımızın tanımıyla ve özellikleriyle başlıyoruz. Sınıfımız 3 değişkenle çağrılabiliyor: $blog_name, $author ve $encoding. Bunlar string tipinde veri taşıyor. 3 değişken ile çağrılabilmesini sağlayan yapılandırıcı fonksiyonumuz. Zaten görüldüğü gibi sınıfımız ile aynı isme sahip ve bu 3 değişkeni parametre olarak alıp sınıfımızın ilgili özelliklerine geçiriyor. Yapılandırıcı fonksiyonumuz bununla da kalmayıp diğer özellikler için gerekli veriler oluşturulmuşsa, onları da sınıfımızın özelliklerine geçiriyor. Özelliklerin bilgilerini, yanlarında açıklama olarak verdiğim için tekrar yazmıyorum.
Sınıfı oluşturmak için örnek vermek gerekirse:
-
<?php
-
include('trackback_cls.php');
-
$trackback = new Trackback('Shapcy.com', 'Mustafa ŞAPÇILI', 'UTF-8');
-
?>
Değinmek istediğim ufak bir nokta daha var. Orjinal kaynakta şu kısma bakarsak:
-
$this->title = $HTTP_POST_VARS['url'];
Görüldüğü gibi, $_POST['title'] oluşturulmuş mu diye bakıyor ama değer olarak $HTTP_POST_VARS['url']'yi atıyor. Ben bunu yukarıda "title" olarak düzelttim. Bilginize...
SINIFIN METODLARI
ping metodu
Belirtilmiş bir geri izleme adresine(URL) bir sinyal(ping) gönderir.
-
function ping($tb, $url, $title = "", $excerpt = "")
-
{
-
$response = "";
-
$reason = "";
-
// Varsayılan değerleri ata
-
$title = "Yazınız geri izlemeye alındı...";
-
}
-
$excerpt = "Yazınızı ilginç buldum, bundan dolayı bir geri izleme oluşturuyorum
"; -
}
-
// Hedefi ayrıştır
-
-
$target["query"] = "?" . $target["query"];
-
} else {
-
$target["query"] = "";
-
}
-
-
$target["port"] = 80;
-
}
-
// Soketi aç
-
// Birşeyler çözülemedi, döndür
-
return '$trackback->ping: can\'t connect to: ' . $tb . '.';
-
exit;
-
}
-
// Göndermek istediklerimizi bir araya topla
-
$tb_send = "url=" . rawurlencode($url) . "&title=" . rawurlencode($title) . "&blog_name=" . rawurlencode($this->blog_name) . "&excerpt=" . rawurlencode($excerpt);
-
// Geri izlemeyi yolla
-
// Sonuçları al
-
}
-
// Soketi kapa
-
// Geri izleme sinyali çalıştı mı
-
// Sonucu gönder
-
return $return;
-
}
Fonksiyonumuz 4 adet string tipinde parametre alıyor:
$tb parametresi: geri izleme yapılacak adres
$url parametresi: bizim adresimiz
$title parametresi: geri izleme başlığı
$excerpt parametresi: geri izlemedeki alıntı yazısı
Fonksiyon başlangıçta, parametrelere değer atanıp atanmadığını göz önüne alarak varsayılan değerleri atıyor. Daha sonra girdiğimiz geri izleme adresini ayrıştırıyor. Ayrıştırma yaparken "query(sorgu)" denen, adresteki "?"den sonraki kısım eğer oluşturulmuş ve boş değilse, başına "?" ekleyerek kendine eşitliyor. Aksi durumda boş değer atıyor. Daha sonra "port" kısmını kontrol ediyor. Port kısmı oluşturulmuş ve numerik değilse, veya oluşturulmamışsa "80" değeri atanıyor.
Kontrol ve düzenlemeler bittikten sonra soket "host" ve "port" verileri sayesinde açılıyor. Eğer bağlanmada bir problem varsa, burada hata döndürülüyor. Hata yoksa; tüm göndermek istediğimiz veriler bir araya toplanıyor ve uygun formata çevrilip gönderiliyor. Önceki yazımızda bahsettiğimiz gibi sinyal gönderdikten sonra, bir de yanıt sinyali geliyordu. İşte biz verileri gönderdikten sonra, sıra geldi bize gelen yanıtı almaya...
Veriyi alıyoruz ve hata olup olmadığını kontrol ediyoruz. Geri izleme işlemimiz başarıyla tamamlandıysa "true (doğru)", tamamlanmadıysa "false (yanlış)" döndürüyoruz.
Fonksiyonun kullanılışını bir örnekle pekiştirmek gerekirse;
-
<?php
-
-
include('trackback_cls.php');
-
$trackback = new Trackback('Shapcy.com', 'Mustafa ŞAPÇILI', 'UTF-8');
-
if ($trackback->ping('http://www.shapcy.com/geri-izleme-trackback-nedir/trackback', 'http://www.shapcy.com/', 'Örnek Geri İzleme','"PHP Trackback - Bir “Geri İzleme” sınıfı" başlıklı yazıda geçen ping metodu ile yapılmış bir geri izleme örneği...')) {
-
echo "Geri izleme başarıyla gönderildi...";
-
} else {
-
echo "Geri izleme gönderiminde hata var....";
-
}
-
?>
Bu örneğin sonucunda "Geri İzleme (TrackBack) Nedir?" başlıklı yazımda şu geri izleme oluşturuldu.
recieve metodu
Geri İzlemeciler için tamam/hata mesajlarıyla birlikte XML yanıtları üretir.
-
function recieve($success = false, $err_response = "")
-
{
-
// Problemler olduğu takdirde kullanılacak varsayılan hata mesajları...
-
$err_response = "Geri izlemenizi kayıda almayı denerken bir problem oluştu...";
-
}
-
// Geri izlemeci için olan yanıtı başlat...
-
$return = '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n";
-
$return .= "<response> \n";
-
// Cevabı geri gönder...
-
if ($success) {
-
// Geri izleme başarıyla alındı...
-
$return .= " <error>0</error> \n";
-
} else {
-
// Birşeyler ters gitti...
-
$return .= " <error>1</error> \n";
-
$return .= " <message>" . $this->xml_safe($err_response) . "</message>\n";
-
}
-
// Geri izlemeci için olan yanıtı bitir...
-
$return .= "</response>";
-
-
return $return;
-
}
Fonksiyonumuz 2 adet parametre alıyor:
$success parametresi: işlem başarısını saklayan değer (veri tipi: boolean)
$err_response parametresi: hata varsa bu hatayı açıklayan değer (veri tipi: string)
Fonksiyon başlangıçta, $success değeri "yanlış(false)" olarak ayarlanmışsa ve $err_response değeri boşsa varsayılan hata mesajını ayarlıyor. Daha sonra XML formatlı döndüreceğimiz yanıtımızı oluşturmaya başlıyor. $success değerine göre hata oluşup oluşmadığı da yanıtımıza dahil ediliyor ve bu değeri döndürüyor.
fetch metodu
Geri izleme bilgisini getirir ve bir RSS-0.91 beslemesi üretir.
-
function fetch($success = false, $response = "")
-
{
-
$response = "Geri izleme bilgisi tekrar alınmaya çalışılırken bir hata oluştu...";
-
}
-
// Arayana yanıtı başlat
-
$return = '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n";
-
$return .= "<response> \n";
-
// Yanıtı geri gönder...
-
if ($success) {
-
// Geri izleme başarıyla geri alındı...
-
// Bir RSS (0.91) geri gönderiliyor -$response (array) değerinden geri izleme bilgisi...
-
$return .= " <error>0</error> \n";
-
$return .= " <rss version=\"0.91\"> \n";
-
$return .= " <channel> \n";
-
$return .= " <title>" . $this->xml_safe($response['title']) . "</title> \n";
-
$return .= " <link>" . $this->xml_safe($response['trackback']) . "</link> \n";
-
$return .= " <description>" . $this->xml_safe($response['expert']) . "</description> \n";
-
$return .= " <item> \n";
-
$return .= " <title>" . $this->xml_safe($response['title']) . "</title> \n";
-
$return .= " <link>" . $this->xml_safe($response['permalink']) . "</link> \n";
-
$return .= " <description>" . $this->xml_safe($response['expert']) . "</description> \n";
-
$return .= " </item> \n";
-
$return .= " </channel> \n";
-
$return .= " </rss> \n";
-
} else {
-
// Birşeyler ters gitti - $response (string) değerinden nedeni sağla...
-
$return .= " <error>1</error> \n";
-
$return .= " <message>" . $this->xml_safe($response) . "</message>\n";
-
}
-
// Geri izlemeci için olan yanıtı bitir
-
$return .= "</response>";
-
-
return $return;
-
}
Fonksiyonumuz 2 adet parametre alıyor:
$success parametresi: işlem başarısını saklayan değer (veri tipi: boolean)
$err_response parametresi: hata varsa bu hatayı açıklayan değer (veri tipi: string)
Fonksiyon başlangıçta, $success değeri "yanlış(false)" olarak ayarlanmışsa ve $response değeri boşsa varsayılan hata mesajını ayarlıyor. Daha sonra XML formatlı döndüreceğimiz yanıtımızı oluşturmaya başlıyor. $success değerine göre değişen yanıtımızı oluşturuyor ve bu değeri döndürüyor.
rdf_autodiscover metodu
Yazı hakkında RDF ile ifade edilmiş gömülü meta verisi üretir, Geri İzleme Sinyali Adresi'ni otomatik keşfeden istemcilere izin verir.
-
function rdf_autodiscover($RFC822_date, $title, $expert, $permalink, $trackback, $author = "")
-
{
-
if (!$author) {
-
$author = $this->author;
-
}
-
-
$return = "<!-- \n";
-
$return .= "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" \n";
-
$return .= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\" \n";
-
$return .= " xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\"> \n";
-
$return .= "<rdf:Description \n";
-
$return .= " rdf:about=\"" . $this->xml_safe($permalink) . "\" \n";
-
$return .= " dc:identifier=\"" . $this->xml_safe($permalink) . "\" \n";
-
$return .= " trackback:ping=\"" . $this->xml_safe($trackback) . "\" \n";
-
$return .= " dc:title=\"" . $this->xml_safe($title) . "\" \n";
-
$return .= " dc:subject=\"TrackBack\" \n";
-
$return .= " dc:description=\"" . $this->xml_safe($this->cut_short($expert)) . "\" \n";
-
$return .= " dc:creator=\"" . $this->xml_safe($author) . "\" \n";
-
$return .= " dc:date=\"" . $RFC822_date . "\" /> \n";
-
$return .= "</rdf:RDF> \n";
-
$return .= "--> \n";
-
-
return $return;
-
}
Fonksiyonumuz 6 adet parametre alıyor:
$RFC822_date parametresi: RFC822 formatındaki tarih bilgisi (veri tipi: string)
$title parametresi: başlık bilgisi (veri tipi: string)
$expert parametresi: alıntı değeri(veri tipi: string)
$permalink parametresi: adres değeri (veri tipi: string)
$trackback parametresi: geri izleme adresini saklayan değer (veri tipi: string)
$author parametresi: yazar bilgisi (veri tipi: string)
auto_discovery metodu
Yazıdaki bağlantıları ve bu bağlantılardaki geri izleme adreslerini arar.
-
function auto_discovery($text)
-
{
-
// Yazıdaki eşsiz bağlantıların bir listesini al
-
// ---------------------------------------
-
// (Değişimde 0=>link, 4=>host) için düzenli ifade
-
$reg_exp = "/(http)+(s)?:(\\/\\/)((\\w|\\.)+)(\\/)?(\\S+)?/i";
-
// Her bağlantının boşlukla bittiğine emin ol
-
// Eşsiz bağlantılarla bir dizi oluştur
-
foreach($array[0] as $key => $link) {
-
}
-
$uri_array[] = ($link);
-
}
-
}
-
// Bu linklerden Geri izleme URI'larını al...
-
// ------------------------------------------
-
// URI dizisi boyunca dön ve RDF parçalarını yapıştır
-
foreach($uri_array as $key => $link) {
-
}
-
}
-
}
-
}
-
// RDF dizisi boyunca dön ve geri izleme URI'larını yapıştır
-
}
-
}
-
}
-
// Geri izlemeleri dön
-
return $tb_array;
-
}
Fonksiyonumuz 1 adet parametre alıyor:
$text parametresi: taranacak yazı (veri tipi: boolean)
Fonksiyon başlangıçta düzenli ifadeler ve belirlenmiş özel durumlara göre girilmiş parametreyi tarıyor ve eşsiz bağlantıların listesini bir dizide topluyor. Sonra bu dizideki liste taranıp RDF parçaları listesi oluşturuluyor. Bu işlemden sonra da bu RDF parçaları dizisi taranak geri izleme bağlantıları bulunuyor ve bu liste bir dizi olarak döndürülüyor.
YARDIMCI FONKSİYONLAR
Sınıfta, metodlar içinde kullanılan 3 adet yardımcı fonksiyon bulunuyor. Bunlar zaten basit işlemleri yerine getiren ufak fonksiyonlar. Bu yüzden detaylı anlatmayacağım, sadece ne işe yaradıklarını tek cümleyle belirtip kodları vereceğim.
RFC822_from_datetime
MySQL tarih-zaman değerini, standart RFC 822 tarih formatına dönüştürür.
xml_safe
Bir dizgiyi, XML için güvenli bir dizgiye dönüştürür.(&, <, >, " ve ' karakterlerini değiştirir)
-
function xml_safe($string)
-
{
-
}
cut_short
Bir dizgiyi $max_length değerine uygun olacak şekilde kısaltır ("..." ile)
SONUÇ OLARAK
Geri izleme konusunda bilgi yetersizliğimizi daha da azalttığımızı düşünüyorum. Artık hemen hemen herşeyi kodlayabiliriz bu teknoloji ile ilgili. Belki bu sınıf incelemesinden sonra kendi örnek geri izleme sistemimi kodlarsam onu da sizinle paylaşmayı düşünüyorum. Umarım yazı, bu konudaki merakını gidermeye çalışanlara, böyle bir sistem kodlaması gerekenlere yardımcı olur.
PHP ile bir başka yolculuğumuzda görüşmek üzere...

Yazı bir uzun olduğundan, ablamın evliliği nedeniyle olan düğün telaşından dolayı bilgisayar başına oturamamdan, rehavete kapılmamdan, afrika sıcaklarından, boş zaman bulduğumda ticari bir projem için kod yazmak zorunda kaldığımdan, bir başka Türk oyunu olan PUSU’yu almamdan, bu oyunu bitirmemden, İstanbul trafiğinden, seçim gerginliğinden ve sıralanabilecek bir çok nedenden dolayı uzun süredir günlüğe yazı yazamıyordum… Takip eden herkesin anlayışına sığınıyorum ve saygılarımı sunuyorum
July 3rd, 2007 at 03:26bu ne ciddiyetsizlik kardesim.. Allah Allah.. bi işe girdiysen hakkını ver olayın..
July 3rd, 2007 at 19:41o..züm, davetyem halen gelmedi, nese..:) yazı hakkında bişi diyemicem, ilgi alanım deil:)
Uzun süre beklediğimize değdi doğrusu. Trackback ile ilgili kaynak gösterilebilecek kalitede bir yazı olmuş. Teşekkürler
July 4th, 2007 at 22:12Rica ederim
July 5th, 2007 at 00:54gerçekten çok güzel bir yazı olmuş kaç zamandır merak ediyordum bu olayı nasıl yapıyoruz diye
ellerine sağlık.
July 6th, 2007 at 11:56Çok güzel bir yazı ve detaylı açıklamalar, eline emeğine sağlık.
July 12th, 2007 at 11:12Hocam ağzına sağlık phpden fazla anlamam.
March 7th, 2008 at 00:24Bunun wordpress tabanlı blog’a uygulanması, kurumunu nasıl yapacaz dosyaları nereye atacaz index’e hangi kodları ekliyecez, ? tşk şimdiden…
@osman
Öncelikle geç cevap verdiğimden ötürü özür dilerim. Bu sistem zaten WordPress’de dahilidir. Ama bir problem olduğunu düşünüyorsan, Ayarlar->Tartışma sekmesi altındaki ilk iki seçeneğin işaretli olduğuna emin ol. (Link verilen blogların uyarılması ve diğer bloglardan uyarı alınması gibi anlamlar içeren iki seçenek)
Aynı zamanda her yazı altında manual olarak da geri izleme gönderebileceğiniz bir form var.
April 15th, 2008 at 00:30