[PHP] Database class & Sessions

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37
Kan er niet uit komen, ben pas net begonnen met gebruik van classes in elkaar etc.

Situatie: De sessies wil ik graag in de database hebben. Dit had ik al voor elkaar, maar wil ze nu in een class hebben zodat ik de database class ook kunnen gebruiken.

Vraag: Hoe kan ik een database class aanroepen voor andere zaken op de website én datzelfde object ook gebruiken in een class waarmee ik mijn sessies beheer (in MySQL db). Vervolgens lijkt het session_set_save_handler() ook niet helemaal goed te gaan.

Het werkt allemaal prima als het niet in een class zit, maar dan roep ik in de functies global $db aan voor de database verbinding. Dit is niet heel netjes natuurlijk en zelfs niet meer mogelijk in PHP 5.3.2 die nu op de servers draait.

Hieronder het eerste stukje, hier maak ik Db-verbinding & set session save handler

PHP:
1
2
3
4
5
6
7
8
9
10
11
// Database verbinding maken
$db = new db($config['db_host'], $config['db_user'], $config['db_password'], $config['db_database']);

ini_set('session.save_handler', 'user');

session_set_save_handler(array('session', 'open'),
                         array('session', 'close'),
                         array('session', 'read'),
                         array('session', 'write'),
                         array('session', 'destroy'),
                         array('session', 'gc'));


Hieronder de session class, helemaal gestript om het simpel te houden. Hier staat nog db::, van mijn laatste poging.

PHP:
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
class session
{
  function __construct()
  {
  }
  
  function open($path, $name) 
  {
    return true;
  }
  
  function close() 
  {
    return true;
  }
  
  function read($ses_id) 
  {
    $result = db::query("SELECT `session_data` FROM `sessions` WHERE `session_id`='".db::real_escape_string($ses_id)."'");
    if (!$result) return null;
    if (!db::num_rows($result)) return null;
  
    $row = db::fetch_assoc($result);
    return $row["session_data"];
  }
  
  function write($ses_id, $data) 
  {
    return (bool)db::query("REPLACE INTO sessions (`session_id`,`session_timestamp`,`session_data`) VALUES ('".db::real_escape_string($ses_id)."', ".time().", '".db::real_escape_string($data)."')");
  }
  
  function destroy($ses_id) 
  {
    return (bool)db::query("DELETE FROM `sessions` WHERE `session_id` = '".db::real_escape_string($ses_id)."'");
  }
  
  function gc($life) 
  {
    return (bool)db::query("DELETE FROM `sessions` WHERE `session_timestamp` < ".(time()-$life));
  }
  
  function __destruct()
  {
  }
}


Ik zou het zeer waarderen als iemand mij uit kan leggen hoe ik dit nou simpel doe :D

[ Voor 4% gewijzigd door TheNephilim op 09-04-2010 12:25 ]


Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Wat werkt er niet, welke foutmeldingen krijg je?
En wat is je vraag nou, hoe je een Class in een sessie opslaat?

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

Verwijderd

Wat gaat er precies fout dan?

[ Voor 52% gewijzigd door Verwijderd op 09-04-2010 13:16 ]


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

$db meegeven aan de constructor?

Als je je eigen session handler schrijft, kan je toch ook zelf je cookiehandling etc doen? Dan heb je heel $_SESSION niet meer nodig en heb je betere controle over wat je aan t doen bent.

Sundown Circus


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37
De vraag is; hoe kan ik in mijn Sessie class, mijn database class gebruiken. Het object meegeven in de constructor werkt niet, aangezien ik het object niet zelf maak. Dat doet die session_save_handler.

Ik krijg meerdere errors, over het algemeen over de database class, maar ik kan niet goed uitzoeken wat het probleem is, zolang de sessie class niet netjes gebruikt maakt van de database class.

Eigenlijk wil ik wel gewoon de php $_SESSION gebruiken en niet zelf weer nieuwe vars erbij maken. Heb al allerhande classes voor sessiehandeling gepakt, maar allemaal hebben ze een interne db afhandeling of zonder gebruik van classes.

Acties:
  • 0 Henk 'm!

Verwijderd

Bernardo schreef op vrijdag 09 april 2010 @ 13:23:
De vraag is; hoe kan ik in mijn Sessie class, mijn database class gebruiken. Het object meegeven in de constructor werkt niet, aangezien ik het object niet zelf maak. Dat doet die session_save_handler.

Ik krijg meerdere errors, over het algemeen over de database class, maar ik kan niet goed uitzoeken wat het probleem is, zolang de sessie class niet netjes gebruikt maakt van de database class.

Eigenlijk wil ik wel gewoon de php $_SESSION gebruiken en niet zelf weer nieuwe vars erbij maken. Heb al allerhande classes voor sessiehandeling gepakt, maar allemaal hebben ze een interne db afhandeling of zonder gebruik van classes.
Zorg dat het een extended class van db wordt?

[ Voor 4% gewijzigd door Verwijderd op 09-04-2010 13:57 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 00:12
Er zijn verschillende manieren om een dependency beschikbaar te maken binnen een klasse. De duidelijkste manier is om hem mee te geven aan de constructor. (In het geval van een session handler is dat imho wel enigszins raar, ik kan me zo een session handler voorstellen die geen database nodig heeft)
Je zou ook kunnen denken aan een registry of een access method. In zijn eenvoudigst:
PHP:
1
2
3
4
5
6
7
function getDB() {
  static $DB;
  if(is_null($DB)) {
    $DB = new DatabaseConnection($x,$y,$z);
  }
  return $DB;
}

Nu kun je overal waar je eerst global $db deed gewoon zeggen $db = getDB();

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op vrijdag 09 april 2010 @ 13:31:
[...]
Zorg dat het een extended class van db wordt?
Neen. Een session is geen database.

{signature}


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37
Oké ik heb nu eindelijk het probleem helemaal opgelost! :D

Het probleem zat hem in de __destruct van de db class, aangezien ik toch persistente connecties gebruik, kan deze (als ik het goed heb) weg.

Hier onder nog even alle code zoals het werkt voor geïntresseerden. Het is nog niet helmaal af en erg simpel, maar het werkt en daar ging het even om.

DB_class

PHP:
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
<?php
class db {

    private static $host;
    private static $username;
    private static $password;
    private static $databaseName;
    private static $link;
 
    public function db($host, $username, $password, $database) {
        self::$link = mysqli_init();
        self::$link->real_connect("p:".$host, $username, $password, $database, 3306, "tcp_ip");
    }
 
    public static function query ($sql)
    {
      $query = mysqli_query(self::$link, $sql);
      if (!$query)
      {
        printf("Error: %s\n", mysqli_error(self::$link));
      }
      
    return $query;
    }
    
    public static function fetch_assoc ($query)
    {
      return mysqli_fetch_assoc($query);
    }
    
    public static function num_rows ($query)
    {
      return mysqli_num_rows($query);
    }
    
    public static function insert_id ()
    {
      return mysqli_insert_id(self::$link);
    }
    
    public static function real_escape_string ($string)
  {
    return mysqli_real_escape_string(self::$link, $string);
  }
}
?>


---

session_class

PHP:
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
<?php
class session
{
  function __construct()
  {
  }
  
  function open($path, $name) 
  {
    return true;
  }
  
  function close() 
  {
    return true;
  }
  
  function read($ses_id) 
  {
    $result = db::query("SELECT `session_data` FROM `sessions` WHERE `session_id`='".db::real_escape_string($ses_id)."'");
    $row = db::fetch_assoc($result);
    return $row['session_data'];
  }
  
  function write($ses_id, $data) 
  {
    return db::query("REPLACE INTO `sessions` (`session_id`,`session_timestamp`,`session_data`) VALUES ('".db::real_escape_string($ses_id)."', ".time().", '".db::real_escape_string($data)."')");
  }
  
  function destroy($ses_id) 
  {
    return db::query("DELETE FROM `sessions` WHERE `session_id` = '".db::real_escape_string($ses_id)."'");
  }
  
  function gc($life) 
  {
    return db::query("DELETE FROM `sessions` WHERE `session_timestamp` < ".(time()-$life));
  }
  
  function __destruct()
  {
  }
}
?>


---

Script zelf

PHP:
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
<?php
/**
 * @author Bernardo
 * @todo null
 * @version 4-jan-2010
 */

// Main config
require("../globals.php");

// Includes
require ($config['classes_root']."mysqli.php");
require ($config['classes_root']."session.php");

// Database verbinding maken
$db = new db($config['db_host'], $config['db_user'], $config['db_password'], $config['db_database']);

ini_set('session.save_handler', 'user');

session_set_save_handler(array('session', 'open'),
                         array('session', 'close'),
                         array('session', 'read'),
                         array('session', 'write'),
                         array('session', 'destroy'),
                         array('session', 'gc'));

session_start();

print_r($_SESSION);

echo "<p />";

$_SESSION['counter']++;

echo "<p />";

print_r($_SESSION);
?>


Allen hartelijk dank voor de hulp! :D

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Tja, als je alles static maakt kun je eigenlijk ook niet echt meer spreken van een database object.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Check, in bovenstaande database class zou het woord 'static' 0x moeten voorkomen.

{signature}


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37
Janoz schreef op vrijdag 09 april 2010 @ 15:16:
Tja, als je alles static maakt kun je eigenlijk ook niet echt meer spreken van een database object.
Nee maar dat is voor een database object toch handig. Deze gebruik je overal, je hebt nu wel de controle van een object maar de vrijheid van een 'los' iets. Of is dit risicovol/etc?

---
Voutloos schreef op vrijdag 09 april 2010 @ 15:20:
Check, in bovenstaande database class zou het woord 'static' 0x moeten voorkomen.
Hoe bedoel je dat?

[ Voor 22% gewijzigd door TheNephilim op 09-04-2010 15:26 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Nog even los van het nut van een database object. Wat jij nu hebt is helemaal geen object. Een object is een instantie van iets met eigen (encapsulated) context. Wat jij nu hebt is een verzameling utility methoden die toevallig in hetzelfde bestand staan. Het heeft geen enkele meerwaarde boven gewoon de losse functies implementeren. Het meer of minder risicovol zijn is in principe niet relevant. het is gewoon geen OO.
Voutloos schreef op vrijdag 09 april 2010 @ 15:20:
Check, in bovenstaande database class zou het woord 'static' 0x moeten voorkomen.
Mwah, misschien 1x wanneer je het middels een singleton wilt implementeren. (of eigenlijk dan twee keer. Voor de methode en de variabele, maar zo bekend ben ik niet met php syntax)

Als we het dan toch over wat niet voor zou moeten komen dan zit ik eerder te denken aan uberhaupt een class die 'database' heet.

[ Voor 37% gewijzigd door Janoz op 09-04-2010 15:36 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Bee.nl
  • Registratie: November 2002
  • Niet online

Bee.nl

zoemt

Bernardo schreef op vrijdag 09 april 2010 @ 15:21:
[...]

Nee maar dat is voor een database object toch handig. Deze gebruik je overal, je hebt nu wel de controle van een object maar de vrijheid van een 'los' iets. Of is dit risicovol/etc?
Door alles static te maken verlies je juist controle. Je wilt dat een database object zijn eigen state bijhoudt. Dat gaat je niet fatsoenlijk lukken met een class die alleen static members heeft. Als je toch op deze manier wilt werken had ik nog eerder voor het singleton pattern gekozen. Of eventueel een registry.
Janoz schreef op vrijdag 09 april 2010 @ 15:34:

[..]

Als we het dan toch over wat niet voor zou moeten komen dan zit ik eerder te denken aan uberhaupt een class die 'database' heet.
Inderdaad. Maargoed, ik denk dat het al moeilijk genoeg is voor de TS. :o

[ Voor 14% gewijzigd door Bee.nl op 09-04-2010 15:42 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Ach, het is aan de ene kant wel grappig om te zien dat iedereen die begint met OO in php altijd begint met een database class. Ze beginnen dus altijd met het 'ver-OO-iseren' vanuit de technische kant. De meeste OO winst is echter te halen wanneer je begint met OO vanuit de domein kant.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • hostname
  • Registratie: April 2009
  • Laatst online: 15:38
Bernardo schreef op vrijdag 09 april 2010 @ 12:23:
...
Het werkt allemaal prima als het niet in een class zit, maar dan roep ik in de functies global $db aan voor de database verbinding. Dit is niet heel netjes natuurlijk en zelfs niet meer mogelijk in PHP 5.3.2 die nu op de servers draait.
...
Dat het niet netjes is klopt, maar dat op 5.3.2 werkt het nog gewoon hoor:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

$globalVar = 'hallo';

class test {
   public function print() {
      global $globalVar;
      echo "Global variable: " . $globalVar . "\r\n";
   }
}

$inst = new test();
$inst->print();
// output: Global variable: hallo
?>


Je session class wordt ook static aangeroepen, dus die constructor kan je weglaten (een lage constructor is uberhaupt nogal nutteloos), en het is ook wel netjes als je die functies static maakt, zoals in je database class.
$inst = new test();
$inst->method();

?>[/]
Pagina: 1