PHP ile XML verisiyle Ajax kullanmak

 XML veri tipini sunucudan ajax ile alıp kullanıcıya göstereceğiz. Bunu ASP.NET ortamında yaptıktan sonra aynı işi PHP ile yapalım.

İlk işimiz XML verisini sunucuda yaratmak daha sonra bu veriyi ajaxla sunucudan istek yapmak ve gelen sonucu yani XML verisini işleyip ekrana bastıracağız. 3 adımda bu işlemi gerçekleştirelim.

1. Adım:  İstek yapıldığı taktirde XML verisini yarat ve alıcıya yollamak.

2. Adım: Kullanıcıya ajax ile XML verisi için sunucuya istek yap.

3. Adım: XMLDocument objesindeki tüm verileri okuyup HTML tablosuyla kullanıcıya göster.

İşimiz biraz uzun. Adım adım inceleyelim.

1. Adım ( PHP ve XML veri ile Ajax kullanmak) :

PHP dilinde XML verisini yaratmanın birden fazla tekniği bulunmaktadır. Özellikle SimpleXML extenstion API'si sayesinde XML verilerini okumak ve yaratmak daha kolaydır. Aynı veriyi PHP 5. versiyonda bulunan DOMDocument sınıfı sayesinde yaratmak da mümkün. Ben yazımda DOMDocument sınıfını kullandım. Hemen kodumuza geçelim:

Yaratmacağımız XML verimiz şu şekilde olsun:
          
<?xml version="1.0" encoding= "utf-8" ?> 
 <peopledata > 
 
    <people sex="man" > 
       <name> Asım </name>  
       <surname>Hayta</surname>  
       <hobbies> 
            <hobby>watching tv </hobby>  
            <hobby>litening music</hobby> 
       </hobbies> 
    </people> 
  
    <people sex="woman"> 
        <name>Derya</name> 
        <surname>Dener</surname>  
        <hobbies> 
            <hobby>playing guitar</Hobby> 
            <hobby>reading books</Hobby> 
        </hobbies> 
    </people> 
 
  </peopledata> 
  
 
 

Yukarıdaki veriyi biraz inceleyince iki tane people etiketi almış verimiz olduğunu ve people etiketinin "sex" özelliği olduğunu da görüyoruz. Yani temelde iki tane verimiz var ve içinde başka etiketleri bulunan verileri görüyoruz. Şimdi ilk işimiz PHP'de XMLDocument objesini oluşturmak için DOMDocument sınıfını kullanmak çünkü bu sınıfın içinde XML formatında veri elde etmemize yarayan saveXML() adında bir metodu var. Bizim amacımız bu methottan yararlanmak. Tabii ilk başta verilerimizi bir bir DOMDocument objemize ekleyelim. Artık kodumuza geçelim. PHP dosyamızın ismi index.php olsun ( PHP ve XML veri ile Ajax kullanmak) :
        
      
if (isset( $_GET["xml"]))  //  sorgu katarında(query string) xml'e değer verilmiş mi? 
if ($_GET["xml"]=="true")  // xml değeri true olarak set edilmiş mi? edilmişse veriyi yarat.

{
//( PHP ve XML veri ile Ajax kullanmak) 
        //XML document objemizi yaratacak DOM objemizi yaratıyoruz
$xmlDoc = new DOMDocument('1.0',"utf-8");
 
//kök elementimizi yani peopledata elementini yaratıyoruz
$peopledataTag = $xmlDoc->appendChild( $xmlDoc->createElement("peopledata"));
           
  //peopledata elemtimizin içıne people elementini ekliyoruz
  $peopleTag = $peopledataTag->appendChild( $xmlDoc->createElement("people"));
            
  //people elemintimize attribute olarak sex anahtarını veriyoruz.
  $peopleTag->appendChild( $xmlDoc->createAttribute("sex"))->appendChild( $xmlDoc->createTextNode("man"));
    
  //people elemtimizin içine isin elemtini değeriyle birlikte ekliyoruz
  $peopleTag->appendChild( $xmlDoc->createElement("name", "Asım"));
    
  //people elemtimizin içine surname elementi  değeriyle birlikte ekliyoruz
  $peopleTag->appendChild($xmlDoc->createElement("surname", "Hayta"));
 
  //people elementinin içine Hobbies elemntini ekliyoruz. Bir insanın birden fazla hobisi olacağını düşünüyoruz.
  $hobbiesTag = $peopleTag->appendChild( $xmlDoc->createElement("hobbies"));

  //hobbies elemtine iki tane hobby elementini değeriyle birlikte veriyoruz.
  $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "watching tv"));
  $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "litening music")); 

// 1 saniye bekleme yap. Bu sunucu cevabını 1 saniye geçiktirecek.
sleep(1);

//çıktıyı düzenleyip yollamasını istiyoruz.
$xmlDoc->formatOutput = true;

header("Content-Type: text/xml; charset='utf-8'  ");
// xmlDox objesinden yani DOM objesinden yararlanarak XML document objemizi saveXML methoduyla output olarak alıcıya yolluyoruz.
echo $xmlDoc->saveXML();     
}

        
        


2. ve 3. satirda kullancıdan gelen bir istek olduğunda "xml" parametresinin set edilip edilmediğini kontrol ediyoruz, edildiyse değerinin "true" olup olmadığını da kontrol ediyoruz. Bu kontrolu her isteğe xml verisyle cevap vermeyi engellemiş oluyoruz.

6. satırda DOMDocument objesini yaratırken dikkat etmemiz gereken tek şey versiyon ve encoding parametreleri. Verimizde türkçe karakter içerdiği için "utf-8" formatı en iyi seçim olacaktır.

10. satırda verinin hiyerarşisine göre etiketleri yaratıp en dıştaki etikete ekleyerek verimizin şemasını satır satır oluşturuyoruz. İlk etiketimiz peopledata daha sonra people ve en sonda hobbies. Hangi etiket hangi etiketi içeriyorsa ona göre kodumuzu yazıyoruz. Bu haliyle çıktıyı tarayıcımızda görmeyi deneyelim:

Kodumuzda sadece ilk people etiketli verimizi yarattık. 2. verimizi de ekleyelim :
if (isset( $_GET["xml"]))
if ($_GET["xml"]=="true")

{
//( PHP ve XML veri ile Ajax kullanmak) 
//XML document objemizi yaratacak DOM objemizi yaratıyoruz
$xmlDoc = new DOMDocument('1.0',"utf-8");
 
//kök elementimizi yani peopledata elementini yaratıyoruz
$peopledataTag = $xmlDoc->appendChild( $xmlDoc->createElement("peopledata"));
           
  //peopledata elemtimizin içıne people elementini ekliyoruz
  $peopleTag = $peopledataTag->appendChild( $xmlDoc->createElement("people"));
            
  //people elemintimize attribute olarak sex anahtarını veriyoruz.
  $peopleTag->appendChild( $xmlDoc->createAttribute("sex"))->appendChild( $xmlDoc->createTextNode("man"));
    
  //people elemtimizin içine isin elemtini değeriyle birlikte ekliyoruz
  $peopleTag->appendChild( $xmlDoc->createElement("name", "Asım"));
    
  //people elemtimizin içine surname elementi  değeriyle birlikte ekliyoruz
  $peopleTag->appendChild($xmlDoc->createElement("surname", "Hayta"));
 
  //people elementinin içine Hobbies elemntini ekliyoruz. Bir insanın birden fazla hobisi olacağını düşünüyoruz.
  $hobbiesTag = $peopleTag->appendChild( $xmlDoc->createElement("hobbies"));

  //hobbies elemtine iki tane hobby elementini değeriyle birlikte veriyoruz.
  $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "watching tv"));
  $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "litening music")); 

 //2. people datamızı gırıyoruz.
  $peopleTag = $peopledataTag->appendChild( $xmlDoc->createElement("people"));
            
   $peopleTag->appendChild( $xmlDoc->createAttribute("sex"))->appendChild( $xmlDoc->createTextNode("woman"));
    
  
   $peopleTag->appendChild( $xmlDoc->createElement("name", "Derya"));

   $peopleTag->appendChild($xmlDoc->createElement("surname", "Dener"));
 
 
  $hobbiesTag = $peopleTag->appendChild( $xmlDoc->createElement("hobbies"));

   $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "playing guitar"));
   $hobbiesTag->appendChild( $xmlDoc->createElement("hobby", "reading books")); 


//response type özelliklerini veriyoruz.Bu satır kullanıcı tarafında verimizi ajaxla .responseXML metoduyla almamıza yarayacak. Bunu javascript kodumuzda daha// iyi anlayacağız.

 sleep(1);
//çıktıyı düzenleyip yollamasını istiyoruz.
$xmlDoc->formatOutput = true;

header("Content-Type: text/xml; charset='utf-8'  ");
// xmlDox objesinden yani DOM objesinden yararlanarak XML document objemizi saveXML methoduyla output olarak alıcıya yolluyoruz.
echo $xmlDoc->saveXML();

}  


sleep fonkiyonu sayesinde sunucu cevabını 1 saniye geciktiriyoruz, böylece ajaxla istek yaptığımızda cevap alırken beklediğimizde "loading" yazısını görmemize yarayacak. Daha sonra bu kısmı okuyunca anlayacaksınız.

$xmlDoc->formatOutput = true; satırı sadece xml verisinin formatını düzenliyor. Verimizde değişiklik yapmıyor.

header("Content-Type: text/xml; charset='utf-8'  "); satırı sayesinde kullanıcının internet tarayıcısına çıktının XML formatında oluğunu ve karakter kodunun "utf-8" olduğunu bildiriyoruz.

En son satırda çıktıyı kullanıcıya yolluyoruz. Şimdi çıktımızı internet tarayıcımızda tekrar görelim:

( PHP ve XML veri ile Ajax kullanmak)

 2. Adım ( PHP ve XML veri ile Ajax kullanmak) :

Aynı ASP.NET'de klasik ajax isteği yaptığımız gibi PHP sunucusu için de aynı teknikle ajax isteğimizi yapacağız. Bu kısım klasik ajaxla yapılacak.

Xml verimizi ajax ile sunucudan almak için önce biraz kullanıcı taraflı  (client side) programlamayapmamız gerekiyor. Yeni bir php sayfası yazmaya başlayım. Adı "ajax.php" olsun. Normalde  eğer sayfa PHP kodu içermiyorsa .php uzantısı olmasına gerek yok fakat ben PHP ile çalıştığımız için .php uzantısında kaydetmeyi tercih ettim. Siz bu sayfayı .html olarak da kaydedebilirsiniz. Dosyaları kaydederken "File Encoding" özelliğini "utf-8" seçmemiz yerinde olacaktır çünkü dosyamız türkçe karakterler içeriyor. 

 Ajax teknolojisini, Javascript XMLHttpRequest objesini yaratarak kullanabiliriz. O halde hemen objemezi yaratlım. Fakat XMLHttpRequest objesini yaratırken kodumuzun internet tarayıcı bağımsız olmasını istiyorsak, Firefox, Opera, Internet Explorer v.b. gibi tarayıcılara göre dizayn etmemiz gerek. Internet Explorer ActiveX objesi aracığılıyla  XMLHttpRequest objesi yaratabilirken Firefox direk XMLHttpRequest objesi yaratmamıza izin veriyor. Kodumuzu inceleyerek bunu daha iyi anlayabiliriz.
function xmlobject() 
{ var xmlHttp = null; 
    try { // Firefox, Opera 8.0+, Safari 
            xmlHttp = new XMLHttpRequest(); }
    catch (err) 
        { 
            // Internet Explorer için. Farklı versiyonlara göre deneme yanılma yöntemiyle objemizi oluşturuyoruz.
            {xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } 
            catch (err) 
            { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
         } 
    return xmlHttp;
 }
var request = xmlobject(); //fonksiyonların dışında olup her sayfa yüklendiğinde çalışan satır.
XMLHttpRequest objesini oluştururken xmlobject fonksiyonunu kullanıyoruz. Değişkenin ismini ise request olarak tanımlıyoruz. var request = xmlobject(); satırı otomatik olarak sayfa yüklendiğinde çalışıp xmlobject fonksiyonu çağrılacak ve request isimli objemiz kullanmaya hazır yaratılmış olacak.

Şimdi bu objeyi yarattıktan sonra GET metodu ile sunucuya istek yapıp gelen veriyi javacriptle alacağız. Tabii bunu yaparken tüm sayfa yenilenmeyecek. Çünkü sadece javascript ile istek sunucuya yapıyor olacağız. Kodumuz diğer parçası ( PHP ve XML veri ile Ajax kullanmak) :
    function xmlal()
          { 
                request.open("GET", "index.php?xml=true"); //xml datamızı alacğımız url adresini yazıyoruz.
                request.onreadystatechange = listener; 
                request.send(null); 
                document.getElementById("pl").innerHTML="loading"; // ekrana loading yazdır
          }      


Burada "GET" methodu ile parametremizi URL adresi üzerinden göndereceğiz. Değişkenimiz "xml" ve değeri "true" olacak. Sunucu parametrenin değerinin true olduğunu görünce kullanıcıya oluşturduğumuz XML verisini yollayacak. xmlobject() fonksiyonundan dönen XMLHttpRequest objemizi request isimli değişkene daha önce atamıştık. Bu yüzden xmlal fonksiyonundaki request objesini kullanmakta özgürüz. request objesinin onreadystatechange özelliğine yapılan isteğin sunucadan gelen uyarıya tepki olarak çalıştırılacak fonksiyon ismini atıyoruz. listener fonksiyonunda sunucudan gelen XML datamızı okuyup kullanıcıya gösterecek işi yaptıracağız.

Adım 3 ( PHP ve XML veri ile Ajax kullanmak) :

Bu adımda da ASP.NET'de yaptığımız gibi XML verisini kolay okumak için gelen XML veri etiketlerini yani başlıkların isimlerini bilmemiz gerekiyor. Direk olarak gelen veriyi etiketlerine göre ayıracağız. Verimizi her okuduğumuzda dinamik olarak yarttığımız tabloyu doldurup kullanıcıya veriyi düzenli bir şekilde göstereceğiz. Bunu daha önce  söylediğim gibi listener fonksiyonunda yapacağız. Kodumuzu inceleyelim ( PHP ve XML veri ile Ajax kullanmak) :

        function listener() {
            if (request.readyState == 4    request.status == 200) // verinin yüklendiğini kontrol et 
             {
                ic = document.getElementById("icerik"); // icerik idsine sahip elemanı al. Bu html olarak          
           	 //kullanıcıya göstereceğimiz katman olacak.
                xml = request.responseXML; //dönen veriyi al ve XMLDocument objesine cevir
                
               var name =    xml.getElementsByTagName("name");//name etiketine sahip olan tüm elemanları al
               var surname = xml.getElementsByTagName("surname"); //surname etiketine sahip olan tüm elemanları al
               var hobbies = xml.getElementsByTagName("hobbies"); //Hobbies etiketine sahip olan tüm elemanları al
               var peopleattribute;  // people attributes değerlerini almamıza yarayacak değişken
                
                var table =   document.createElement("table");
          
               for (var i=0; i < name.length; i++)
               {
  
               row= document.createElement("tr"); //satırı yarat
               cell= document.createElement("td");     // hücreyi yarat.             
               text= document.createTextNode(name[i].childNodes[0].nodeValue);
               cell.appendChild(text); //değeri hücreye ekle
               row.appendChild(cell); //hücreyi satıra ekle
               cell= document.createElement("td");           
               text= document.createTextNode(surname[i].childNodes[0].nodeValue);
               cell.appendChild(text);
               row.appendChild(cell);
               cell= document.createElement("td");
			   
			   var hobby= hobbies[i].getElementsByTagName("hobby"); //hobby etiketine sahip olan tüm elemanları al
               // hobby etiketinin hobbies etiketi içinde olduğunu biliyoruz.
               
                     for (var o=0;o < hobby.length ;o++)  //kaç tane hobby etiketi varsa hepsinin değerini oku
                     {
				        text= document.createTextNode( hobby[o].childNodes[0].nodeValue+", " ); //farklı hobileri virgülle ayırıyoruz
                    	cell.appendChild(text);	
				     }
				
			   row.appendChild(cell);
			   peopleattribute =  xml.getElementsByTagName("people")[i].attributes; //sırasıyla people etiketindeki attributes değerlerini al
               cell= document.createElement("td");
               text= document.createTextNode(peopleattribute.getNamedItem("sex").nodeValue); //sex attribute değerini oku ve hücreye ekle
               cell.appendChild(text);
               row.appendChild(cell);

               table.appendChild(row);
              
		       }// end for loop
	         document.getElementById("pl").innerHTML="";  //loading yazısını kaldır.
             ic.innerHTML=  "< table border='1'>"+table.innerHTML + " </table> " ; //tabloyı göster
             }//end if
                
          }  //end function
 


request objesinin ReadyState ve status durumlarını kontrol ederek gelen verinin tamamen yüklenip yüklenmediğini kontrol ediyoruz. Daha önce listener fonksiyonunu dinleyici olarak request objesine tanımlamıştık. Bu fonksiyon birden fazla çağrılmış olacağından ve verinin tamemen yüklenip yüklenmediğini bilmediğimizden böyle bir kontrol yapmamız gerekiyor.

 document.getElementById("icerik"); satırında tabloyu göstereceğimiz "div" elementini arıyoruz. "icerik" idsine sahip "div" elementini daha sonra html "body" içerisine ekleyeceğiz. Sonraki satırda xml = request.responseXML; satırında gelen veriyi XMLDocument objesine çeviriyoruz. request.responseXML; yazmamızın nedeni tahmin edebileceğiniz gibi sunucu cevap içeriğinin XML formatında olması. Artık getElementsByTagName metoduyla istediğimiz etiket isimleriyle arama yapabiliriz. Etiket isimlerini bildiğimiz için direk olarak "surname" ve "name" etiketlerini aratıyoruz. Daha sonra for döngüsüne sokarak dönen elemanların değerlerini alıp yarattığımız tabloyu dolduruyoruz. Tabloyu sunucu tarafında değil kullanıcı tarafında yarattığımıza dikkat edelim. Zira tam tersini de yapabilirdik.

name[i].childNodes[0].nodeValue satırında elemanın değerini okuyoruz. name isimli elemenın sadece bir tane child elemanı olduğundan ve o da içindeki değer olduğu için nodeValue metodu içindeki değeri okuyoruz. Name isimli elemanın sadece bir tane child elemanı olduğunu XML datasını inceleyerek anlayabiliriz. var name= xml.getElementsByTagName("name"); yerine var people= xml.getElementsByTagName("people"); yazabilirdik. Fakat böyle bir durumda içindeki ilk satırın ilk sütün değeri okumak için söyle bir kod yazardık: 

people[0].childNodes[0].childNodes[0].nodeValue.  Bu bize "Asım" değerini döndürürdü. Ama böyle bir kullanım IE'da çalışırken Firefox'da çalışmadı. Bu yüzeden her iki browserda çalışması için direk in içteki etiketlerin değerinlerini alıp okumak hem okunabilirlik hem de kolaylık açısından daha iyi.

Kodumuzun son kısmına yani Html Body'e gelelim:
  <body  >
 <form id="form1" runat="server">
       < div id="icerik">
        <input id="Button1" onclick="xmlal();" type="button" value="button" /> 
      </div>  
 </form>
 </body>
Basitçe anlatmak gerikirse button'a bastığımızda xmlal fonksiyonu çağrılarak XML verimizi get methodu ile istenilecek ve dönen veri ekrana basılacak. Ve tüm veri transferi XMLHttpRequest objesi sayesinde olacak.


Programımızın çalışır hali:


( PHP ve XML veri ile Ajax kullanmak)  

Button'a tıkladığımzda sonucu ekranda gösteriyor.

Programıın kodlarını hazır halde indirip üzerinde oynama yaparak daha rahat öğrenebilirsiniz.

PHP ve XML veri ile Ajax kullanmak script dosyalar  
yazan Zülküf Küçüközer tarih   11th July 2009
primary key words  Xml | Php | Ajax okunma  7162
secondary key words  Xmlhttprequest | Domdocument | Javascript
writing emrah writing 29th August 2010
Uzun süredir aradığım bir içerikti. Çok işime yaradı. Emeğine sağlık...