Gå til innhold

AJAX og PHP objekter - best måte å 'kommunisere' på?


Anbefalte innlegg

Var godt igang med AJAX(jQuery) nå, men fikk fort et slag i trynet når jeg kom på at PHP objekter/variabler bare eksisterer i det siden lastes og PHP har gjort jobben sin. Jeg har to ganske omfattende objekter som jeg jobber rundt, og disse er absolutt nødt til å eksistere når et PHP script blir kalt via AJAX. Så jeg lurte litt på hva dere foreslår er den beste måten løse dette problemet på:

 

- Objekter i _SESSION

Jeg prøvde litt med det som en løsning, men jeg droppa det når det ble for mange steder å sørge for at session ALLTID er up-to-date. Klassene har endel funksjoner som oppdaterer objektet. Jeg ble litt frustrert på åssen det blir å bruke $this->setSomeThing() med et objekt fra SESSION. Vil den oppdatere på SESSION da..?

 

- Sende objekter i POST (med $.ajax)

Vet ikke helt åssen dette vil gå an når PHP objektet forlengst er borte når brukeren 'trigger' en ajax funksjon.

 

- Opprette objekter på nytt i PHP-fila ajax kaller på

Er fult mulig å gjøre det, men det vil føre til at all dataen til objektene må hentes ned på nytt fra DB hver gang ajax PHP-scriptet blir kalt. Er egentlig den løsningen jeg sikter meg inn på nå, selv om det kan bli en resource hog...

 

- Andre bedre løsninger?

Vil gjerne høre hvordan dere gjør det, og hva som er vanlig for en slik situasjon. Jeg er ganske newb, så skal ikke se bort ifra at tankgangen min er litt unormal her :p

Lenke til kommentar
Videoannonse
Annonse
Gjest Slettet+9871234

Vet ikke helt åssen dette vil gå an når PHP objektet forlengst er borte når brukeren 'trigger' en ajax funksjon.

Naturlige spørsmål:

  1. Er du klar over at der fines ulike AJAX teknologier, hvor noen bruker frames med areal = 0, andre bruker iFrames og andre XMLHttpRequest objektet?
  2. At der finnes hybride teknologier?
  3. Om objektet er borte, kan det ikke gjenopplives med en lenke til en fil?
  4. Hva er så galt med å bruke sessions om ikke noe annet virker?

Jeg kan bare tenke høyt og har ikke tid til å programmere for deg. Poenget med AJAX er asynkrone kall til serveren i bakgrunnen.

 

Merk at med php cURL, er det enkelt å kalle andre php skripts fra egen eller en annen server (om du stoler på skriptet). Enkel informasjon om hvordan jeg bruker cURL til fjerne kall:

 

http://www.oopschool.com/phpBB3/viewtopic.php?f=9&t=261

 

Kan hende er det uten at jeg har tenkt nok på det mulig å kombinere cURL og AJAX teknologier.

Endret av Slettet+9871234
Lenke til kommentar

Hvis jeg forstår det rett, så generer du to objekter i et script. Etter at du har lastet scriptet, ønsker du å sende objektene videre? for eventuell lagring eller lignende i et annet php script?

 

Jeg ser vel et par forskjellige muligheter, som egentlig gjør det samme. Det du er ute etter er å kunne mellomlagre objektet slik at det ikke dør etter hoved-scriptet er ferdig kjørt.

 

Personlig ville jeg ha laget "rammene" for objektet(altså selve php koden) i en egen php fil. Lagret innholdet av php objektet inn i en database når hoved-scriptet er ferdig. Så lastet det inn på nytt inn i scriptet du vil kalle på ved hjelp av ajax.

 

En annen mulighet er noe av det du selv tenker på, nemlig bruk av sessions, tekstfiler eller memcache. Du kan serialisere objektet enten ved serialize() eller konvertere det til JSON ved å bruke json_encode(). Det du da ender opp med er en tekst streng du enten legge i en session , memcache, tekstfil, eller bare sende videre ved hjelp av ajax koden.

 

 

PS, frame eller Iframes er nok ikke det man definerer som Ajax-teknologi. Det blir litt som å si at man programmerer PHP... man scripter i PHP og programmerer i C++. Det har mange likhetstrekk, men det er en grunn for de forskjellige begrepene.

Lenke til kommentar

Er du klar over at der fines ulike AJAX teknologier, hvor noen bruker frames med areal = 0, andre bruker iFrames og andre XMLHttpRequest objektet?

Godt mulig. Som nevnt bruker jeg jQuery. Den har en .ajax funksjon

 

At der finnes hybride teknologier?

Sikkert.. Nevner bare at jeg bruker PHP, MySQL og jQuery sin AJAX funksjon

 

Om objektet er borte, kan det ikke gjenopplives med en lenke til en fil?

Å opprette objektet på nytt mener du? Eller lagre objektene i en fil..?? Objektet eksisterer bare idet PHP-skriptet kjører og spytter ut sida..

 

Hva er så galt med å bruke sessions om ikke noe annet virker?

Når jeg tenker på det, så er det jo en grei løsning. Hadde jeg bare hatt det som grunnlag når jeg lagde hele systemet :p Blir endel å endre. Jeg må bare sørge for at det ene objektet i SESSION blir unset når brukeren navigerer bort fra sida, fordi brukeren kan ha trykket på et annet kurs (jeg oppretter et Course objekt når brukeren gjennomgår et visuelt kurs), og da må det være et annet kurs-objekt.

Lenke til kommentar

Hvis jeg forstår det rett, så generer du to objekter i et script. Etter at du har lastet scriptet, ønsker du å sende objektene videre? for eventuell lagring eller lignende i et annet php script?

Jupp stemmer. Mellomlagring er nok det rette ordet ja.

 

Personlig ville jeg ha laget "rammene" for objektet(altså selve php koden) i en egen php fil. Lagret innholdet av php objektet inn i en database når hoved-scriptet er ferdig. Så lastet det inn på nytt inn i scriptet du vil kalle på ved hjelp av ajax.

Å lagre det i en slags tmp i databasen blir vel NESTEN det samme som å opprettet objektet på nytt (databasen er til enhver tid oppdatert samtidig som objektet), men kanskje litt mer resursvennlig. Det ene objektet er ganske stort siden den inneholder all bruker stats.

 

En annen mulighet er noe av det du selv tenker på, nemlig bruk av sessions, tekstfiler eller memcache. Du kan serialisere objektet enten ved serialize() eller konvertere det til JSON ved å bruke json_encode(). Det du da ender opp med er en tekst streng du enten legge i en session , memcache, tekstfil, eller bare sende videre ved hjelp av ajax koden.

Tror jeg bare bruker SESSION da likså godt :)

Forresten, hører noen si at man må serialize til SESSION, mens andre sier at PHP tar seg av det selv?

 

 

For å forklarer litt hva jeg prøver på:

Brukeren ser domene.com/course.php?id=42 som viser kurset brukeren ser.

Her blir cCourse-objektet og cUser-objektet opprettet som inneholder all informasjon i kurset og om brukeren sin stats.

I kurset så er det forskjellige quizes. Disse skal jeg bruke AJAX på, så brukeren får direkte feedback på om svaret var riktig eller feil. HER må cUser-objektet være tilgjengelig, så mine andre funksjoner kan legget til poeng og sjekke om brukeren har fullført kurset basert på hvor mange quizes cCourse har.

Lenke til kommentar

Det er to veier å gå når du ønsker å gjenbruke objekter på tvers av kall til server:

 

Enten må du fortelle serveren alt den trenger av variabler slik at den vet hvordan den gjenskaper objektet når brukeren trykker på en link/knapp/etc

 

Eller så må serveren lagre informasjon om brukersesjonen i en... Session! Fordelene er mange, du slipper å holde styr på alt som skal "overleve" i mellom sidene dine manuelt, du bare legger det i session og tenker ikke mer på det.

 

Førsnevnte kan i teorien sende hele phpobjektet ditt til server, men da eksponerer du også den interne serverstrukturen din.

 

Prakteksempel:

Tidligere Var start.no sin quiz bygd opp etter metode en. Da var det lett å endre svarene da alt bare var parametre: quiz.htm?svar1/svar2/svar

Dette kan du unngå ved å lagre svarene i session på fx en "eksamen" slik at flittige brukere ikke kan endre svarene sine i ettertid ( for eksempel på resultatsiden )

 

Jeg anbefaller varmt metode to hvis det er er enn bare noen parametre som skal være med over flere sider

  • Liker 1
Lenke til kommentar

Hmm, faktisk ser det ut til at du kan lagre objektet direkte inn i en session. Jeg mener at det ikke alltid har vært mulig. Men når jeg testa det nå lokalt med php v 5.3.9 , så gikk det helt glatt.

 

Jeg testa med et svært lite obj som kun inneholdt tekst variabler. Så du kan kanskje møte problemer hvis du nøster objekter i objektet, eller lagrer arrays. En annen ting du kanskje må tenke på er også minnebruken. Hvis du absolutt må gå denne veien, uten å lagre i db. Så hadde jeg kanskje brukt memcached i stede(minne er alltid raskere enn disk).

Lenke til kommentar
Gjest Slettet+9871234

PS, frame eller Iframes er nok ikke det man definerer som Ajax-teknologi. Det blir litt som å si at man programmerer PHP... man scripter i PHP og programmerer i C++. Det har mange likhetstrekk, men det er en grunn for de forskjellige begrepene.

Ikke på samme måte som med bruk av XMLHttpRequest, men det er en måte å oppdatere deler av en side på uten at hele siden oppdateres. Det er også en måte å kommunisere med serveren på i en ramme med lengde og bredde 0. Der er heller intet nytt i AJAX. AJAX er Asynchron JAvascript og Xml. Dette

 

http://www.adaptivepath.com/ideas/ajax-new-approach-web-applications

 

er den opprinnelige artiklen. Her

 

http://www.webproworld.com/webmaster-forum/threads/57061-AJAX-and-SEO.

 

er en tråd jeg startet i 2007. Selv om den dreier seg om AJAX og søkemotoroptimalisering har den informasjon som burde interessere deg. Jeg har også andre referanser om du skulle ønske det.

 

Forfattere har skrevet at Google Suggest, Gmail etc. er eksempler på hybride teknologier.

 

Jeg hadde heller sett at ordet web applikasjoner ble brukt fremfor AJAX, siden der ikke er noe fundamentalt nytt i AJAX.

 

PHP objekter kan kommunisere med hverandre ved aggregering eller ved "composition". Jeg kjenner ikke det norske ordet i OO terminologi for composition. Men det er vel ikke det du spør etter.

 

Bruk sessions om det løser problemet ditt. En session bestemmer du selv hvor lenge skal leve.

Endret av Slettet+9871234
Lenke til kommentar
Gjest Slettet+9871234

Førsnevnte kan i teorien sende hele phpobjektet ditt til server, men da eksponerer du også den interne serverstrukturen din.

Dette er kanskje utenomsnakk. Personlig har jeg et skript som henter et php script (fil) fra et annet domene med cURL, lagrer det som en fil i en mappe på et annet domene som så kan inkluderes senere i skriptet som kjøres.

 

Metoden er forklart i lenken i min første post.

 

cURL benyttes nettopp fordi det er sikrere.

Endret av Slettet+9871234
Lenke til kommentar

Jeg er ikke uenig med deg kgun. Frames brukes nok rundt omkring for å oppdatere sider på den måten du beskriver. Men mener nok at de faller utenfor begrepet Ajax og til å med begrepet kommunikasjon. Fordi man kan ikke bruke inneholde i en frame på noen pragmatisk måte etter at den har blitt mottatt. Det er bare en lettvinn måte å F5'e deler av siden, med unødvendig mye overhead.

 

Mens det å bruke ordet web applikasjon framfor Ajax blir nok også noe vagt. Det at Ajax er en del av en web applikasjon er greit nok, men det er alt for mye annet som faller innenfor det begrepet også.

 

Ajax i seg selv er nok bare et begrep som beskriver et spesifikk pattern, som du selv sier bruker JS, de forskjellige XMLHttpRequestene for å bygge et event system, uten å måtte laste inn mye html kode. Litt på samme måte som måte som man bruker begrep MVC modellen.

Lenke til kommentar

Førsnevnte kan i teorien sende hele phpobjektet ditt til server, men da eksponerer du også den interne serverstrukturen din.

Dette er kanskje utenomsnakk. Personlig henter jeg et php script (fil) fra et annet domene med cURL, lagrer det som en fil i en mappe på et annet domene som så kan inkluderes senere i skriptet og kjøres.

 

Metoden er forklart i lenken i min første post.

 

cURL benyttes nettopp fordi det er sikrere.

 

Ja nå er vi ute på off-topic føler jeg,, men jeg snakker om å sende data til server på et generelt nivå og ikke noe som helst om curl eller andre teknologier. Jeg ville nok gjort noe lignende selv og, hadde jeg ikke kodet i wicket

Lenke til kommentar
Gjest Slettet+9871234

Som andre på dette forumet vet skravler jeg visst for mye om jQuery. Intet er bedre enn om jQuery sine AJAX metoder kan brukes.

 

JSON er også en minimalistisk teknologi nevnt i denne tråden som jeg har mye sans for siden den stemmer godt over ens med objekt notasjonen i JavaScript.

 

Mange veier fører til Rom, men noen er sikrere enn andre.

Endret av Slettet+9871234
Lenke til kommentar
Gjest Slettet+9871234

En sesjon kan kapres. Sikkert ikke samme risiko på en norsk som på en internasjonal site.

 

Men som australienere og amerikanere sier.

 

Security by obscurity is not security.

Endret av Slettet+9871234
Lenke til kommentar
Gjest Slettet+9871234

Har jeg skjønt det riktig at å lagre objekter i SESSION er en sikkerhets risiko? Hvor stor risiko isåfall? Websiden jeg jobber på er riktig nok en prototype, men vil gjerne lære mer om selve sikkerheten også

 

Neida, det er hvertfall ikke noe jeg er kjent med

 

Søk på:

 

php session security holes OR risk

Lenke til kommentar

Har jeg skjønt det riktig at å lagre objekter i SESSION er en sikkerhets risiko? Hvor stor risiko isåfall? Websiden jeg jobber på er riktig nok en prototype, men vil gjerne lære mer om selve sikkerheten også

 

Neida, det er hvertfall ikke noe jeg er kjent med

 

Søk på:

 

php session security holes OR risk

 

Stakkaren prøver å lære seg grunnleggende sessionbruk i php... Jeg tror han overlever uten å vite om alt som kan misbrukes;) det var hvertfall poenget mitt

Lenke til kommentar
Gjest Slettet+9871234

Jeg fant noen gamle php kodeeksempler på henholdsvis aggreation:

 

<?php
// Include the MySQL database connection class
require_once('Database/MySQL.php');

// A class which aggregates the MySQL class
class Articles {
   var $db;
   var $result;
   // Accept an instance of the MySQL class
   function Articles(& $db) {
       // Assign the object to a local member variable
       $this->db = & $db;
       $this->readArticles();
   }
   function readArticles() {
       // Perform a query using the MySQL class
       $sql = "SELECT * FROM articles LIMIT 0,5";
       $this->result = & $this->db->query($sql);
   }
   function fetch() {
       return $this->result->fetch();
   }
}

// Create an instance of the MySQL class
$db = & new MySQL('localhost','harryf','secret','sitepoint');

// Create an instance of the Article class, passing it the MySQL object
$articles = & new Articles($db);

while ( $row = $articles->fetch() ) {
   echo ( '<pre>' );
   print_r($row);
   echo ( '</pre>' );
}
?>

 

og på composition:

 

<?php
/**
* Authentication class<br />
* Automatically authenticates users on construction<br />
* <b>Note:</b> requires the Session class be available
* @access public
* @uses Session
*/
class Auth
{
 /**
  * Instance of database connection class
  * @access protected
  * @var PDO object
  */
 protected $db;

 /**
  * Configuration array
  * @access protected
  * @var array
  */
 protected $cfg;

 /**
  * Instance of Session class
  * @access protected
  * @var Session object
  */
 protected $session;

 /**
  * Url to re-direct to in case not authenticated
  * @access protected
  * @var string
  */
 protected $redirect;

 /**
  * String to use when making hash of username and password
  * @access protected
  * @var string
  */
 protected $hashKey;

 /**
  * Auth constructor
  * Checks for valid user automatically
  * @param object database connection
  * @param string URL to redirect to on failed login
  * @param string key to use when making hash of user name and
  *               password
  * @param boolean if passwords are md5 encrypted in database
  *               (optional)
  * @return void
  * @access public
  */
 function __construct(PDO $db, $redirect, $hashKey)
 {
   $this->db       = $db;
   $this->cfg      = parse_ini_file('access_control.ini', TRUE);
   $this->redirect = $redirect;
   $this->hashKey  = $hashKey;
   $this->session  = new Session();
   $this->login();
 }

 /**
  * Checks username and password against database
  * @return void
  * @access private
  */
 private function login()
 {
   //Put the cfg vars into local vars for readability
   $var_login = $this->cfg['login_vars']['login'];
   $var_pass = $this->cfg['login_vars']['password'];
   $user_table = $this->cfg['users_table']['table'];
   $user_login = $this->cfg['users_table']['col_login'];
   $user_pass = $this->cfg['users_table']['col_password'];


   // See if we have values already stored in the session
   if ($this->session->get('login_hash'))
   {
     $this->confirmAuth();
     return;
   }

   // If this is a fresh login, check $_POST variables
   if (!isset($_POST[$var_login]) ||
       !isset($_POST[$var_pass]))
   {
     $this->redirect();
   }

   $password = md5($_POST[$var_pass]);

   try
   {
     // Query to count number of users with this combination
     $sql = "SELECT COUNT(*) AS num_users " .
         "FROM " . $user_table . " WHERE " . 
         $user_login . "=:login AND " .
         $user_pass . "=:pass";

     $stmt = $this->db->prepare($sql);
     // bind the user input
     $stmt->bindParam(':login', $_POST[$var_login]);
     $stmt->bindParam(':pass', $password);
     $stmt->execute();
     $row = $stmt->fetch(PDO::FETCH_ASSOC);
   }
   catch (PDOException $e)
   {
     // create your own error handling logic - I will redirect.
     // If the redirect page has the capability I could alter the 
     // redirect method to handle an added error message that can
     // be passed on to the page.  for simplicity - we will skip that.
     error_log('Error in '.$e->getFile().
         ' Line: '.$e->getLine().
         ' Error: '.$e->getMessage()
     );
     $this->redirect();
   }
   // If there isn't is exactly one entry, redirect
   if ($row['num_users'] != 1)
   {    
     $this->redirect();
   // Else is a valid user; set the session variables
   }
   else
   {
     $this->storeAuth($_POST[$var_login], $password);
   }
 }

 /**
  * Sets the session variables after a successful login
  * @return void
  * @access public
  */
 public function storeAuth($login, $password)
 {
   $this->session->set($this->cfg['login_vars']['login'], $login);
   // remember the $password var is a MD5 - never keep the plaintext password
   $this->session->set($this->cfg['login_vars']['password'], $password);

   // Create a session variable to use to confirm sessions
   $hashKey = md5($this->hashKey . $login . $password);
   $this->session->set($this->cfg['login_vars']['hash'], $hashKey);
 }

 /**
  * Confirms that an existing login is still valid
  * @return void
  * @access private
  */
 private function confirmAuth()
 {
   $login = $this->session->get($this->cfg['login_vars']['login']);
   $password = $this->session->get($this->cfg['login_vars']['password']);
   $hashKey = $this->session->get($this->cfg['login_vars']['hash']);
   if (md5($this->hashKey . $login . $password) != $hashKey)
   {
     $this->logout(true);
   }
 }

 /**
  * Logs the user out
  * @param boolean Parameter to pass on to Auth::redirect()
  *               (optional)
  * @return void
  * @access public
  */
 public function logout($from = false)
 {
   $this->session->del($this->cfg['login_vars']['login']);
   $this->session->del($this->cfg['login_vars']['password']);
   $this->session->del($this->cfg['login_vars']['hash']);
   // For security reasons I am choosing to destroy the session 
   // here to start a completely new one.  If however you need to keep 
   // any other data in the session other than Auth data - you 
   // may choose not to do this.
   $this->session->destroy(); 
   $this->redirect($from);  
 }

 /**
  * Redirects browser and terminates script execution
  * @param boolean adverstise URL where this user came from
  *               (optional)
  * @return void
  * @access private
  */
 private function redirect($from = true)
 {
   if ($from)
   {
     header('Location: ' . $this->redirect . '?from=' .
         $_SERVER['REQUEST_URI']);
   }
   else
   {
     header('Location: ' . $this->redirect);
   }
   exit();
 }
}
?>

 

Ved å kaste et blikk på konstruktøren, ser vi av linjen

 

$this->session  = new Session();

 

at et objekt eier et annet som er det jeg kaller "composition".

 

For fullstendighetens skyld her

 

<?php
/**
* A wrapper around PHP's session functions
* <code>
* $session = new Session();
* $session->set('message','Hello World!');
* echo ( $session->get('message'); // Displays 'Hello World!'
* </code>
* @access public
*/
class Session
{
 /**
  * Session constructor<br />
  * Starts the session with session_start()
  * <b>Note:</b> that if the session has already started,
  * session_start() does nothing
  * @access public
  */
 public function __construct()
 {
   session_start();
 }

 /**
  * Sets a session variable
  * @param string name of variable
  * @param mixed value of variable
  * @return void
  * @access public
  */
 public function set($name, $value)
 {
   $_SESSION[$name] = $value;
 }

 /**
  * Fetches a session variable
  * @param string name of variable
  * @return mixed value of session varaible
  * @access public
  */
 public function get($name)
 {
   if (isset($_SESSION[$name]))
   {
     return $_SESSION[$name];
   }
   else
   {
     return false;
   }
 }

 /**
  * unsets a session variable
  * @param string name of variable
  * @return void
  * @access public
  */
 public function del($name)
 {
   unset($_SESSION[$name]);
 }

 /**
  * Destroys the whole session
  * @return void
  * @access public
  */
 public function destroy()
 { 
   $_SESSION = array();
   session_destroy();
   session_regenerate_id();
 }
} 
?>

er session klassen.

Endret av Slettet+9871234
Lenke til kommentar
Gjest Slettet+9871234

Stakkaren prøver å lære seg grunnleggende sessionbruk i php... Jeg tror han overlever uten å vite om alt som kan misbrukes;) det var hvertfall poenget mitt

Ok, da druknet han vel etter mine siste kode eksempler :roll:

 

Det viser hvordan en session klasse kan lages og hva jeg mener med aggregering og komposisjon. :innocent:

Endret av Slettet+9871234
Lenke til kommentar

Aggregering og komposisjon ligner mye på hverandre.

 

En av de enkleste forklaringene jeg har sett er å beskrive komposisjon ved ordene "en del av". Et objekt som representerer en båtavgang kan ikke eksistere uten et båtobjekt. Båten er "en del av" avgangsobjektet-objektet. Man trenger en båt for å kunne ha en avgang. På engelsk bruker man ofte "part-of".

 

Aggregering beskrives ofte som "har en". En Person har en Adresse. En person kan også "ha en" bil. Disse tingene opphører ikke å eksistere selv om personen blir borte (i den virkelige verden). De kan fungere som frittstående objekter også uten personen.

 

Kort illustrert ved et Person-objekt:

- en person er en Student (Komposisjon)

- en person har en Jobb (Komposisjon)

- en person har en adresse (aggregering)

- en person har en bil (aggregering)

 

-------------------------------------------

 

Tilbake til temaet:

 

Sikker på at du ikke bør revurdere designet ditt en smule? I mitt hode virker det nok å ta vare på informasjon som kan identifisere brukeren og tilhørende data. Jeg ville heller lagret svar på kurs, poengsummer og lignende i en database. Det må da være enklere enn dette du gjør nå?

Endret av Sono Juventino
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...