Sokszor előfordul, hogy olyan nagy mennyiségű információt kell feldolgoznunk PHP-val ami már nem fér bele az olykor nagyon szűkös futási időkeretbe. Ekkor praktikus szétbontani a feladatott több részfeladatra és ezeket a részfeladatokat egymás után végrehajtani. A célom az volt, hogy készítsek egy icipici kis AJAX-os példarendszert a probléma megoldására. Lássuk mi kell ehhez.

Először is szükségünk lesz egy jófajta JavaScript keretrendszerre, hogy ne kelljen feltalálnunk a meleg vizet. Én a JQuery-t választottam, mivel azt jól ismerem és használom már régóta. Lesz két fájlunk. Az egyik ami mutatja, hogy éppen hol tartunk és tartalmazza a kliens oldali programrészeket. A másik lesz a tulajdonképpeni PHP, ami a feldolgozást végzi.

Nézzük az első fájlt, melyet nevezzünk index.html-nek



  
  
  Kötegelt feldolgozó
    
  
    /* itt lesz az AJAX-os JavaScript kódunk */
  
  
  #slider { margin: 30px; border: 1px solid black; }
  #slider div { height: 20px; background-color: blue; width: 0px; }
  #messages p { margin: 0; padding: 0; border-bottom: 1px dotted black; }
  
  
  
   <div id="slider">
     <div>
     </div>     
   </div>
   <div id="slider_info">
   </div>
   <div id="messages">
   </div>
  

Mint látható három div elem van. Az első mutatja meg nekünk grafikusan, hogy éppen hol tartunk. Maga a div egy egyszerű kis téglalap ami rendelkezik egy szép elegáns fekete kerettel. Ebben van egy kék hátterű másik div, mely a csíkot fogja húzni. Kezdeti mérete nulla, hisz még nem tartunk sehol sem. A második, slider_info azonosítójú div fogja tartalmazni azt a szöveges információt, hogy éppen hol tartunk és mennyi van még hátra. A harmadik div elembe pedig a PHP-től jövő üzeneteket foguk megjeleníteni. Itt láthatjuk, hogy mi az amit sikerült és mi az amit nem sikerült megtennie a scriptünknek. Nézzük a JavaScriptet!

  $.getJSON("send.php?id=0", feldolg);
  function feldolg(json){
    $('#slider_info').html(json.szam + ' / ' + json.ossz);
    hossz = $('#slider').width();
    $('#slider div').width(hossz * json.szam / json.ossz);
    $('#messages').append(''+ json.message +'');
    if(json.szam &lt; json.ossz){
     $.getJSON("send.php?id="+ json.szam, feldolg);
    }else{
    $('#slider div').css('background-color','green');     
    }
  }

Természetesen a működéshez szükségünk lesz még a JQuery függvény könyvtárra is. Nézzük a kódot részletesen.

    $('#slider_info').html(json.szam + ' / ' + json.ossz);

Itt annyit csinálunk, hogy beírjuk az információs div-be, hogy éppen hol tartunk és mennyi az összes feldolgozandó rekord. Felhívnám a figyelmet itt és most, hogy ez egy olyan mintakód, mely pusztán a működés bemutatására szolgál. Nincs benne semmifajta hibakezelés. Nem vizsgáljuk, hogy sikerült-e a lekérés, jött-e egyáltalán adat és ha jött az megfelelő-e.

    hossz = $('#slider').width();
    $('#slider div').width(hossz * json.szam / json.ossz);

Beállítjuk a kék sáv szélességét. A számítás egyszerű. A befoglaló div hosszát annyi részre osztjuk ahány feldolgozandó rekordunk lesz, majd ezt a számot megszorozzuk azzal a számmal, mely jelzi mennyi adatot dogloztunk már fel. A műveletek fordított sorrendje egy rég elfeledett a gépi kódú programozást idéző egész számos aritmetika nyomait idézi.

    $('#messages').append(''+ json.message +'');

Kiíratjuk a kapott üzenetet. A friss üzeneteket mindig a többi végére szúrjuk be.

    if(json.szam &lt; json.ossz){
     $.getJSON("send.php?id="+ json.szam, feldolg);
    }else{
    $('#slider div').css('background-color','green');     
    }

Amennyiben nem végeztünk, újra elindítjuk ezt a szép asszinkron folyamatot. Ha már minden elemet feldolgoztunk, akkor szép zöldre állítjuk a csíkot, hogy tudjuk a feldolgozás befejeződött.

Végezetül nézzük a PHP fájlt.

&lt;?
  include('dbconnect.php');
  $limit = 10;
  $sql = "SELECT * FROM tabla ...";
  $csql = "SELECT COUNT(*) as db FROM tabla ...";
  $db= mysql_fetch_assoc(mysql_query($csql));
  $ossz = $db['db'];
  $res = mysql_query($sql. ' LIMIT '. (int)$_GET['id'] .','. (int)$limit);
  $id = (int) $_GET['id'] + $limit;
  if ($id &gt; $ossz) {$id = $ossz;}
  $message = '';
  while($row = mysql_fetch_assoc($res)){
    // itt csináljuk azt amit csinálunk
    // az eredményt beletesszük a $message változóba
  }
  print "{ szam : $szam, ossz : $ossz, message : '$message'}";

Az első természetesen az, hogy betöltjük az adatbázis kapcsolódásához szükséges részeket, ezt itt nem részletezem. A $limit változóba beállítjuk, hogy egy akció során egyszerre hány rekordot szeretnénk feldolgozni.

&lt;?
  include('dbconnect.php');
  $limit = 10;

Ezután lekérdezzük, hogy hány rekordunk lesz összesen.

  $sql = "SELECT * FROM tabla ...";
  $csql = "SELECT COUNT(*) as db FROM tabla ...";
  $db= mysql_fetch_assoc(mysql_query($csql));
  $ossz = $db['db'];

Természetesen az itt látható sql lekérdezés nem egy teljes értékű használható kód, csak egy minta. Az esetek nagy részében elégséges, hogy a rekordok lekérdezésére szolgáló query-ben ($sql) kicseréljük a SELECT és FROM közötti részt a következő kódra: " COUNT(*) as db “. Ne felejtsük el azonban, hogy egy “bonyolultabb” lekérdezésben, ahol pl. GROUP direktívát használunk, vagy egy másik al-lekérdezés eredményét ez nem lesz elég. Ott le kell ülnünk és átgondolnunk, hogy mely lekérdezés fogja a megfelelő eredményt adni. Miután ez megvan lekérdezzük az egyetlen egy rekordot és a kapott eredmény egyetlen egy oszlopát beletöltjük az $ossz változóba. Ezek után jöhet a megfelelő szelet amit feldolgozunk.

  $res = mysql_query($sql. ' LIMIT '. (int)$_GET['id'] .','. (int)$limit);

Látszik, hogy csak egyszerűen hozzárakjuk a LIMIT záradékot a megfelelő paraméterezéssel. A kezdő rekord számát ($_GET[‘id’]) az AJAX-os alkalmazástól kapjuk, ezért ezt típus kényszerítjük, ezzel elkerülve az esetleges felhasználótól érkező trükkös hibákat. A $limit paraméter ugyan a saját kódunkból érkezik, de biztos ami ziher arra is rárakjuk a típuskényszerítést. Erre azért van szükség, mert lehetséges, hogy egy óvatlan pillanatban egy ügyes kis függvénybe helyezzük el ezt a kódot és akkor már nem a mi kódunkból, hanem a felhasználót érkezik majd ez a paraméter is. Mindenképpen érdemes azonban megszokni azt, hogy bármely SQL lekérdezés összerakásánál a változókat vagy escape-eljük, vagy típus kényszerítjük. Ez nem véd meg minket minden esetben az SQL-injection támadások ellen, de az alap hibákat ki tudjuk ezzel küszöbölni. Ezek után kiderítjük a következő adag kezdő rekordszámát.

  $id = (int) $_GET['id'] + $limit;
  if ($id &gt; $ossz) {$id = $ossz;}

Amennyiben a lépésszám ($limit) nem osztója az összes elem számának ($ossz) akkor természtesen az utolsó etapban a következő adag kezdő rekordszáma nagyobb lesz mint az összes elem száma. Ebben az esetben beállítjuk az $id-t az utolsó rekord utánra, így jelezzük a JavaScript függvényünknek, hogy véget ért a feldolgozás. Most következzen kódunk legkidolgozatlanabb része.

  $message = '';
  while($row = mysql_fetch_assoc($res)){
    // itt csináljuk azt amit csinálunk
    // az eredményt beletesszük a $message változóba
  }

Végigmegyünk az eredmény halmazon és feldolgozzuk. Itt küldhetünk E-mail-t, konvertálhatunk fájlokat, végrehajthatunk bonyolult lekérdezéseket stb. A végén pedig kiírjuk a válaszunkat.

  print "{ szam : $szam, ossz : $ossz, message : '$message'}";

Természetesen ez sem egy tökéletes kód. A legfontosabb, hogy a $message változó nem tartalmazhat soremelést, csak ‘\n’ karakterpárost. Figyelj ezt úgy tudod PHP-ben szöveges változóba beletenni, hogy dupla visszaperjelet használsz! A kódból talán kiderül az is, hogy aposztrófot (') sem túl egészséges használni, azt is csak escape-elve tegyük bele az üzeneteinkben.

Remélem hasznos volt ez a kis szösszenet, egészségetekre.