[php] 3 Classes, 2 databases, meerdere connecties

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
In het kort een uitleg over de classes:

Class 1: maakt verbinding met een boekhoudpakket via een ODBC connectie, kan verschillende queries uitvoeren en deze classe wordt enkel gebruikt voor functionaliteit die ik nodig heb uit het boekhoud pakket. Dit is eigenlijk alleen maar lezen.

Class 2: Hierin zitten alle functionaliteiten welke gebruikt worden voor onderdeel A in de website. Deze betrekt zijn gegevens uit een MySQL database en soms ook een connectie via Class1 met het boekhoudpakket.

Class 3: Eigenlijk hetzelfde als class 2, echter nu voor functionaliteit van onderdeel B.

Het probleem is nu als volgt:
Zodra ik Class 3 gebruik (bijvoorbeeld), kan het zijn dat ik een verbinding opzet met MySQL, waarvan ik de gegevens hieruit gebruik om een functie in Class 2 aan te roepen, welke ook weer een verbinding maakt met MySQL. Echter, ik heb netjes constructors en destructors aangemaakt in alle 3 de classes, welke netjes de DB-verbinding afsluit. Echter, zodra ik in class2 'klaar ben', sluit hij de verbinding af, maar daardoor ook de verbinding met MySQL die in Class3 opgebouwd is. Een melding in de trand van
code:
1
$db is not a valid MySQL-link identifier.


Uiteraard heb ik de $db-variabele voor alle classes verschillend gemaakt, om te kijken of daar het probleem zich bevond. Dit bood geen uitkomst. $db-identifiers worden aangeroepen op de manier waarop het volgens mij hoort ($this->db, aangezien het een class-var is die binnen deze classe geldt).

Wat moet ik nu doen om de fouten eruit te krijgen.

1. Een compleet nieuw classe-model schrijven, waarin ik voor elke database een aparte class schrijf?
2. Een compleet nieuwe classe-model schrijven, waarin ik in 1 class slechts verbinding maak met 1 database?
3. iets anders, waar jullie waarschijnlijk wel iets slims op weten.

Ik vermoed dat dit niet persee een PHP denkstuk is, maar dat dit een manier van programmeren is, die bijvoorbeeld ook in C# gebruikt kan worden. Echter, ik werk nu in PHP, dus vandaar in de TopicTitel [php].

Ik ben benieuwd, want het is erg vervelend zo. Op dit moment los ik het namelijk op met een @ voor de mysql_close_db($this->db) functie.

Acties:
  • 0 Henk 'm!

  • torx
  • Registratie: Oktober 2006
  • Laatst online: 22:33
Misschien dat je wat relevante code kan posten van het daadwerkelijk verbinding maken en breken van MySql en de interactie tussen de classes?

Zo uit m'n hoofd zie ik wel mogelijke oplossingen. Bijvoorbeeld class 2 en class 3 ieder een eigen mysql-verbinding laten maken, en alleen gegevens communiceren.

Of je kan misschien een tellertje bijhouden? Optellen bij verbinding maken, aftrekken bij verbinding breken. En dan alleen daadwerkelijk verbinding maken als teller 0 is (of checken of er nog geen verbinding is), en alleen verbinding breken als teller 0 wordt.

Honda CB750 Hornet :: Yamaha Fazer FZ6 SA (2011 - 2023) | F1Pool.net


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je kunt toch een link identifier meegeven? Dan kun je toch aangeven welke connectie gesloten moet worden? Of snap ik het niet? Default sluit mysql_close gewoon de laatst geopende connectie; in jouw geval lijkt me dat class 2 dus die van class 3 'per ongeluk' sluit.

[ Voor 27% gewijzigd door RobIII op 15-10-2007 14:33 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
RobIII schreef op maandag 15 oktober 2007 @ 14:32:
Je kunt toch een link identifier meegeven? Dan kun je toch aangeven welke connectie gesloten moet worden? Of snap ik het niet?
Dat doe ik ook, maar dan is de andere verbinding uit een andere class ook gesloten, zo lijkt het.....

Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
RobIII schreef op maandag 15 oktober 2007 @ 14:32:
Je kunt toch een link identifier meegeven? Dan kun je toch aangeven welke connectie gesloten moet worden? Of snap ik het niet? Default sluit mysql_close gewoon de laatst geopende connectie; in jouw geval lijkt me dat class 2 dus die van class 3 'per ongeluk' sluit.
Het laatste is correct. Het lijkt dat Class 2, Class 3 sluit (of andersom, vice versa, etc). De link identifier wordt natuurlijk meegegeven en deze heeft per class zijn eigen naam :)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Massiefje schreef op maandag 15 oktober 2007 @ 14:34:
en deze heeft per class zijn eigen naam :)
Dat lijkt me irrelevant als het een private var is waarin je de link-id bijhoudt ;)

P.s. gebruik de edit knop (Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/tweakers/images/icons/edit.gif) i.p.v. 2x achter elkaar posten als je nog iets toe te voegen hebt aan je post ;)

[ Voor 30% gewijzigd door RobIII op 15-10-2007 14:37 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Pete
  • Registratie: November 2005
  • Laatst online: 07-09 17:51
Jouw foutcode (en workaround) duiden erop dat de waarde $this->db gewoon niet gevuld is. Daarnaast is de variable naam in de foutmelding een andere dan hetgeen je hier laat zien.

Weet je zeker dat je niet de mist ingaat met je databaselinks en dat je een niet bestaand iets probeert af te sluiten?

petersmit.eu


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
phsmit schreef op maandag 15 oktober 2007 @ 14:41:
Jouw foutcode (en workaround) duiden erop dat de waarde $this->db gewoon niet gevuld is. Daarnaast is de variable naam in de foutmelding een andere dan hetgeen je hier laat zien.

Weet je zeker dat je niet de mist ingaat met je databaselinks en dat je een niet bestaand iets probeert af te sluiten?
Wat je zegt klinkt logisch, echter, als ik in de destructor aangeef van de 2e geopende class, dat hij de connectie NIET sluit, dan gaat het in de 1e geopende class wel goed en wordt de connectie netjes gesloten :)

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Kennelijk delen class A en B dezelfde database connectie.
Waarom sluit je die dan af als je in een class klaar bent?

Sowieso is het afsluiten van dat ding een beetje overbodig, dat gebeurt automatisch als de request is afgelopen.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
Grijze Vos schreef op maandag 15 oktober 2007 @ 15:35:
Kennelijk delen class A en B dezelfde database connectie.
Waarom sluit je die dan af als je in een class klaar bent?

Sowieso is het afsluiten van dat ding een beetje overbodig, dat gebeurt automatisch als de request is afgelopen.
A & B delen zeker niet dezelfde connectie, althans, niet bewust ;)

Elke class heeft zijn eigen open_db() en close_db() functie. Elke class heeft ook zijn eigen private variabele als link-identifier, welke allemaal een eigen naam hebben.

Wat betreft je opmerking over het sluiten: waarom een databaseverbinding niet sluiten, als er een functie voor is ? Een functie bestaat toch niet voor niets, lijkt me ?

Acties:
  • 0 Henk 'm!

  • stappel_
  • Registratie: Augustus 2000
  • Laatst online: 20:41
als de servernaam, usernaam en wachtwoord hetzelfde zijn voor A en B, dan gebruikt php/mysql de eerst vrije connectie, dat doet hij ondanks dat jij een link-id opgeeft. hij gebruikt het als een connectie pool.

Ubero: #2, Euler: #1, GOT: #1, Des: #1, Zeta: #1, Eon: #3, OGR-24: #3, OGR-25: #7,
LM: #7, AP: #5, DF: #19, D2OL: #37, SOB: #50, TSC: #63, RC5: #96


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

stappel_ schreef op maandag 15 oktober 2007 @ 16:06:
als de servernaam, usernaam en wachtwoord hetzelfde zijn voor A en B, dan gebruikt php/mysql de eerst vrije connectie, dat doet hij ondanks dat jij een link-id opgeeft. hij gebruikt het als een connectie pool.
Ik denk: dat kan niet kloppen en ben even in de PHP docs gedoken, maar:
new_link

If a second call is made to mysql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned. The new_link parameter modifies this behavior and makes mysql_connect() always open a new link, even if mysql_connect() was called before with the same parameters. In SQL safe mode, this parameter is ignored.
Het is echt achterlijk om dat als default gedrag te hebben.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Confusion schreef op maandag 15 oktober 2007 @ 16:20:
Het is echt achterlijk om dat als default gedrag te hebben.
Ik denk dat het gedaan is met in het achterhoofd al de mensen die voor elke query gewoon weer die functie aanroepen met mysql_connect(), mysql_query(), etc...

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
Grijze Vos schreef op maandag 15 oktober 2007 @ 16:27:
[...]

Ik denk dat het gedaan is met in het achterhoofd al de mensen die voor elke query gewoon weer die functie aanroepen met mysql_connect(), mysql_query(), etc...
Wat zou dan de juiste manier zijn ?

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Massiefje schreef op maandag 15 oktober 2007 @ 16:29:
[...]


Wat zou dan de juiste manier zijn ?
Euhm, 1x per pagina je database initialiseren en dan elke keer alleen je query doen natuurlijk.
Ik denk dat ze die default keuze hebben gemaakt met het oog op resource besparing.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Confusion schreef op maandag 15 oktober 2007 @ 16:20:
Het is echt achterlijk om dat als default gedrag te hebben.
Zo achterlijk is dat niet aangezien php geen applicatie scope heeft. 100 concurrent users zouden dan 100 connecties naar een database maken. Dat is natuurlijk, by default, niet handig.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
Massiefje schreef op maandag 15 oktober 2007 @ 15:56:
Wat betreft je opmerking over het sluiten: waarom een databaseverbinding niet sluiten, als er een functie voor is ? Een functie bestaat toch niet voor niets, lijkt me ?
Omdat je'm nog nodig hebt.

Er bestaat ook een functie unset, ga je daarmee ook elke variabele GC'en? Doubt it. Er zijn legio goede redenen om handmatig een databaseconnectie te sluiten, maar 'omdat het kan' is er niet een van.

Waarom zou je uberhaupt met dezelfde credentials twee links naast elkaar open willen hebben? Kost je alleen maar performance en duidelijker wordt het er ook niet op.

Als je dan toch per se je connectie wilt sluiten kun je met __get() er voor zorgen dat bij je volgende DB call er automatisch een nieuwe instance komt, maar het is een volstrekt debiele manier van coden.

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

Verwijderd

ik zou er idd eerder voor kiezen om deze DB 1x te openen en dan gewoon die identifier naar beide classes door te geven. maar je kan ook gewoon de close weglaten dan krijgen ze beide de zelfde identifier en mocht je het heeeeeeel graag willen dan kan je het aan het eind van het script, wanneer je zeker bent dat beide classes opgeruimts zijn de db closen. maar aangezien php dit zelf ook doet is het erg zinloos.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Verwijderd schreef op maandag 15 oktober 2007 @ 17:43:
Zo achterlijk is dat niet aangezien php geen applicatie scope heeft. 100 concurrent users zouden dan 100 connecties naar een database maken. Dat is natuurlijk, by default, niet handig.
En nu delen die 100 concurrent users 1 connectie.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
Confusion schreef op dinsdag 16 oktober 2007 @ 10:23:
[...]

En nu delen die 100 concurrent users 1 connectie.
Ah, we zijn nog niet uitgediscussieerd. Ben benieuwd wat er hier uitkomt :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Het meest belachelijke is dat php blijkbaar een connectie pakt die nog niet vrijgegeven is.

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!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
Als ik het week, kan ik er wel 'omheen' programmeren, maar het is niet logisch nee. Ik gebruik wat ik aanmaak op het moment dat ik het nodig heb, zou ik althans denken.

Voor mijn probleem denk ik dan ook, dat ik het beste een database classe kan aanmaken en daar een en ander in vast kan leggen.

Of ik sluit gewoon de verbindingen niet af, dat is natuurlijk ook mogelijk :)

Acties:
  • 0 Henk 'm!

  • stappel_
  • Registratie: Augustus 2000
  • Laatst online: 20:41
je moet gewoon geen mysql_close() gebruiken bij een mysql_connect(), dat doet php/apache wel voor je, bij een mysql_pconnect() is het wel aan te raden. http://us3.php.net/manual...ersistent-connections.php

Ubero: #2, Euler: #1, GOT: #1, Des: #1, Zeta: #1, Eon: #3, OGR-24: #3, OGR-25: #7,
LM: #7, AP: #5, DF: #19, D2OL: #37, SOB: #50, TSC: #63, RC5: #96


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

@massiefje: Begrijp ik het nu goed wanneer ik uit je posts opmaak dat jij voor elke mysql_query commando opnieuw een mysql_connect aanroept? Dat is namelijk erg ongebruikelijk en zelfs erg inefficient. Normaal wordt maar 1x in je script een connectie gemaakt en deze wordt telkens weer door je script gebruikt.

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!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 14:12
Elke class had/heeft zijn eigen connect functie en zodra ik dus een functie uit een class nodig heb, zal hij dus een verbinding maken ja. Als ik meerdere functies uit dezelfde class nodig heb, zal ik dezelfde verbinding gebruiken. Echter, als ik via class 1 een functie uit class 2 moet hebben, zal hij in class 2 wel weer verbinding maken ja.

Ik begrijp dus nu, dat dat anders moet :)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Het is mij allemaal niet meer (zo) duidelijk, maar kennen ze in PHP dan geen connection-pooling? Zo duur is het openen van een connectie toch ook weer niet (tenzij je het heel veel doet uiteraard). En niet dat het (IMHO) aan te raden is, daar niet van...

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
Janoz schreef op dinsdag 16 oktober 2007 @ 15:51:
Het meest belachelijke is dat php blijkbaar een connectie pakt die nog niet vrijgegeven is.
Definieer vrijgegeven. Je kan -altijd- queries uitvoeren op een reeds geopende connectie en resultsets terugvragen, dus wat is het probleem? Als PHP multithreaded zou zijn was het vervelender geworden, maar dat is het niet en zal het waarschijnlijk ook niet snel worden. Ja, als je mysql_close aanroept wordt je connection (met optioneel ID) gesloten, het is ietwat vreemd dat een nieuwe connectie met dezelfde credentials standaard een reference is ernaar en dus ook gesloten wordt, maar de reden erachter is zeer waarschijnlijk zoals genoemd dat het efficienter is voor een beginner die overal dezelfde connect code copy-paste. Deze quote onderstreept dat maar weer eens:
Elke class had/heeft zijn eigen connect functie
Dat is dus nergens voor nodig. Als je je verbinding niet sluit kun je prima boveneen je script 1 keertje connecten en er vervolgens geen omkijken meer naar hebben, dat is nu juist het simpele aan PHP. Als je dan toch per se meerdere connecties naast elkaar wilt openen met dezelfde credentials kan dat ook prima, maar dan moet je de bool $new_link parameter op true zetten. Het is echter zeer af te raden voor drukke sites omdat je dan zo 10, 20 connecties per request hebt en bij een paar duizend simultane requests gaat je SQL server dan vrij hard over z'n nek, al was het alleen maar omdat je connectionpool niet oneindig groot is.

Zelf gebruik ik overigens een (global) context object met autoloader die classes voor mij aanmaakt wanneer ik ze nodig heb en een database class die bij het constructen een database connectie maakt, ergo, altijd als ik een database nodig heb is'ie er en er is er altijd maar 1 van. Connecties met verschillende databases worden afgehandelt door verschillende extensies op m'n databaseclass die weer via de context te bereiken zijn. En ja, ik laat PHP fijn zelf m'n connecties sluiten :P

Overigens, in tegenstelling tot wat Confusion beweert wordt er per PHP instance wel degelijk een aparte connectie gebruikt. Aangezien voor elke user (nouja, host) een nieuwe instance gebruikt wordt krijg je met 100 simultane requests dus wel degelijk 100 connecties naar je database (uitgaande van de PHP/Apache combo).

Om dit tegen te gaan kun je persistente connecties gebruiken die wel door blijven lopen als een request afgehandelt is. Zie ook de PHP.net site:
If persistent connections don't have any added functionality, what are they good for?

The answer here is extremely simple -- efficiency. Persistent connections are good if the overhead to create a link to your SQL server is high. Whether or not this overhead is really high depends on many factors. Like, what kind of database it is, whether or not it sits on the same computer on which your web server sits, how loaded the machine the SQL server sits on is and so forth. The bottom line is that if that connection overhead is high, persistent connections help you considerably. They cause the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the SQL server. This means that for every child that opened a persistent connection will have its own open persistent connection to the server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your SQL server, you'd have 20 different connections to the SQL server, one from each child.

[ Voor 3% gewijzigd door FragFrog op 16-10-2007 18:35 ]

[ Site ] [ twitch ] [ jijbuis ]

Pagina: 1