Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[MySQLi & PHP] Connectie in sessie zetten

Pagina: 1
Acties:

  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 26-11 11:58
bij elke nieuwe page-refresh moet de database connectie opnieuw aangemaakt worden. Dus ik had het idee om de connectie in een sessie te zetten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
if(!isset($_SESSION['database']))
{
    $database = new Database();
    $_SESSION['database'] = serialize($database);
}
else
{
    $database = unserialize($_SESSION['database']);
}
?>


Alleen hiermee krijg ik errors en het blijkt dat ik een MySQLi connectie niet in een session kan bewaren. Nu ben ik gaan zoeken en kwam ik uit op persistant connection maar niemand die mij een voorbeeld kon laten zien.

Heeft iemand ervaring hiermee of een voorbeeld? :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13:05

Janoz

Moderator Devschuur®

!litemod

Dat gaat niet lukken. Session 'scope' bij php betekent enkel dat de waarden die je in je sessie stopt naar de de schijf weggeschreven worden en bij het volgende request weer ingeladen wordt. Een connectie is echter geen stuk 'data', maar een resource. Een 'verbinding' kun je niet naar je schijf 'saven' en later weer inladen.

Dat is dan ook precies de reden waarom je database connecties, maar ook andere resources (zoals file handles, irc verbindingen, ftp connecties enz enz) niet in de sessie op kunt slaan.

Maar het belangrijkste is misschien nog wel dat het je helemaal niks op gaat leveren. Een verbinding opzetten is helemaal niet duur en daarnaast wordt er vaak al een vorm van pooling gebruikt. Verbindingen blijven dan al open, maar worden vervolgens onder de requests verdeeld. In die situaties is het zelfs juist veel beter wanneer je je verbindingen zo kort mogelijk gebruikt aangezien ze dan sneller aan een ander proces gegeven kunnen worden.

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


  • FragFrog
  • Registratie: September 2001
  • Laatst online: 11:39
mysql_pconnect?

Overigens hoef je niet zelf serialize aan te roepen als je een object in de sessie gooit, dat gebeurt als het goed is automatisch :)

Of je er winst uit haalt: in sommige scenario's wel (ik heb ooit eens een synthetische benchmark gedraait op mijn developmentbak, de persistente variant was iets sneller), maar doorgaans is het effect verwaarloosbaar (in mijn benchmark scheelt het slechts 1.5ms per pageview). Plus, zoals gezegd, vaak wordt er al aan connection pooling gedaan en voegt het helemaal niets toe.

//edit
Sinds 5.3 kan het trouwens ook met de mysqli extensie :)

[ Voor 62% gewijzigd door FragFrog op 07-04-2011 10:58 ]

[ Site ] [ twitch ] [ jijbuis ]


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:48

MueR

Admin Devschuur® & Discord

is niet lief

Sommige classes moeten Serializable implementen voordat je ze in sessions mag gooien ;)

Anyone who gets in between me and my morning coffee should be insecure.


  • FragFrog
  • Registratie: September 2001
  • Laatst online: 11:39
MueR schreef op woensdag 06 april 2011 @ 20:31:
Sommige classes moeten Serializable implementen voordat je ze in sessions mag gooien ;)
Geldt alleen voor bepaalde build-in classes. Dat is bij TS in elk geval niet het geval; daar is het probleem zoals Janoz al aangeeft dat je resources niet kan serializen :)
Note that many built-in PHP objects cannot be serialized. However, those with this ability either implement the Serializable interface or the magic __sleep and __wakeup methods. If an internal class does not fulfill any of those requirements, it cannot reliably be serialized.

[ Site ] [ twitch ] [ jijbuis ]


  • Cartman!
  • Registratie: April 2000
  • Niet online
Als ik me niet vergis kun je geen resources opslaan in een session.

sjees... spuit 11 :)

[ Voor 15% gewijzigd door Cartman! op 06-04-2011 21:13 ]


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Waarom wil je dit?

Freelance Unity3D developer


  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Weet je wat leuk is me leuk lijkt? Meten hoe snel een DB- connectie wordt opgezet vs hoe lang het duurt om een beetje session state te deserializen.
Heb het zelf nog niet gedaan, maar ik verwacht een winst voor de eerste, zodra je meer dan enkele objecten in je sessie hebt bewaard.

On track


Verwijderd

'het kan' is niet in alle gevallen een reden om het daadwerkelijk ook te doen. Ik vind het implementeren van een stateful database object vreemd in een stateless omgeving.

Ik denk daarnaast dat WouZz nog weleens gelijk kan hebben, dat het opzetten van een connectie sneller zal blijken dan de deserialization.

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 11:39
Verwijderd schreef op donderdag 07 april 2011 @ 13:52:
Ik vind het implementeren van een stateful database object vreemd in een stateless omgeving.
De omgeving hoeft alleen stateless te zijn voor de gebruiker (en dankzij HTML5 zelfs daar nog niet per se). Zeker in een high-performance omgeving is het logisch om een (deels) stateful backend te gebruiken zodat je niet continue dezelfde resources loopt aan te maken en destructen. Dit illustreert perfect hoe debiel dat eigenlijk is :)
Verwijderd schreef op donderdag 07 april 2011 @ 13:52:
Ik denk daarnaast dat WouZz nog weleens gelijk kan hebben, dat het opzetten van een connectie sneller zal blijken dan de deserialization.
Ik betwijfel dat eigenlijk. Je zal toch de session moeten deserializen (tenzij je verder helemaal geen sessies gebruikt, maar dat is vrij uniek) en een resource is doorgaans weinig meer dan een stream handle, qua data stelt dat weinig voor. Een string van een paar dozijn karakters inladen (met een interne functie van PHP, dus direct C code) gaat een stuk sneller dan een complete handshake met een externe service voltooien. Helemaal als je databaseserver op een andere fysieke host draait en je ook nog netwerk lag hebt om rekening mee te houden.

Maar dat is allemaal volslagen irrelevant aangezien je toch geen resources kan serializen :+ en er zoals gezegd gewoon persistent DB connecties mogelijk zijn zodat je dat ook helemaal niet zelf hoeft te doen.

[ Voor 21% gewijzigd door FragFrog op 07-04-2011 14:24 ]

[ Site ] [ twitch ] [ jijbuis ]


  • YopY
  • Registratie: September 2003
  • Laatst online: 06-11 13:47
ZeroXT schreef op woensdag 06 april 2011 @ 20:07:
bij elke nieuwe page-refresh moet de database connectie opnieuw aangemaakt worden. Dus ik had het idee om de connectie in een sessie te zetten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
if(!isset($_SESSION['database']))
{
    $database = new Database();
    $_SESSION['database'] = serialize($database);
}
else
{
    $database = unserialize($_SESSION['database']);
}
?>
Vraag me toch af wat effectief het verschil - of zelfs de verwachte winst - in vergelijking met het opzetten van een nieuwe verbinding is.

PHP:
1
2
3
<?php
$database = new Database();
?>


When in doubt: kies de eenvoudigste methode.
When in doubt: meten == weten

  • fleppuhstein
  • Registratie: Januari 2002
  • Laatst online: 21-10 21:48
Dit is natuurlijk niet logisch. Zodra je wilt gaan schalen is stap 1 het opslaan van sessies in de database, ivm clustering, en het round robin effect. Dus in je database sla je de sessie dan op die de verbinding bevat, bij een session restore heb je dan de database verbinding nodig welke opgeslagen zou zijn in de database. En uiteindelijk zit je met het Kip-Ei verhaal.

Indien het merkbare performance zou geven, welke opwegen tegen nadelen zouden grote partijen als FB etc. zoiets ook wel toepassen. Denk dat de performance makkelijk ergens anders te halen is. Probeer eens objecten te cachen of een code cacher

Verwijderd

@FragFrog .... Er zit ook wel wat in natuurlijk om ergens iets van een state bij te houden (meestal in de sessie) maar je ontkomt, bij web appllicaties/sites, nu eenmaal niet aan een bepaalde bootstrap fase... of dit nu het deserializen van je objecten is of het opniew initialiseren van de het database object. Gelukkig handelen de meeste frameworks dit soort dingen mooi voor je af zodat je hier geen omkijken naar hebt.

die XKCD kende ik al ... erg grappig en helaas een realiteit die je als developer onder ogen moet zien... maar don't shoot the developer ... shoot the protocol ;)

[ Voor 10% gewijzigd door Verwijderd op 08-04-2011 09:55 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13:05

Janoz

Moderator Devschuur®

!litemod

Een ander aspect is trouwens dat je nu probeert een database verbinding per unieke gebruiker bij te houden. De verbinding wordt pas gesloten op het moment dat de sessie verloopt. Reken maar eens uit hoeveel simultane verbindingen je nodig hebt en hoeveel die eigenlijk idle zullen zijn.

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


Verwijderd

@Janoz ... goed punt, dit zal ook wel af te vangen zijn, maar ook dit neemt weer extra overhead met zich mee waardoor je die minimale performance winst meteen kwijt bent

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13:05

Janoz

Moderator Devschuur®

!litemod

Dat wil je niet afvangen. Je wilt je pooling helemaal niet op sessie niveau doen, maar op applicatie niveau. Op applicatie niveau is duidelijk wanneer het ene request klaar is met de verbinding zodat de verbinding doorgegeven kan worden aan het eerstvolgende willekurige request dat binnenkomt.

Maar goed, dit is binnen php natuurlijk al lang niet meer relevant aangezien die niet echt een session en/of application scope heeft.

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


  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
serialize en unserialize is in dit geval ook doelloos. Dit doet de session handler zelf al.

Je kunt je "Database" - instance wel in de sessie opslaan. Hierbij gaat de connectie wel verloren. Om te zorgen dat de connectie weer up komt als je de sessie weer inlaad (ofwel als er ge unserialized wordt) dan kun je de functies __sleep en __wakeup in je classe aanmaken.

http://nl2.php.net/__sleep
Pagina: 1