Hi there, we use a wrapper class to access a mysql db with php-4.0.6 running in Apache/Linux and mysql-3.23.40.
We ran into the following problem: Assume the following test code (sorry - rather long): -----[ test code ]------ <? /* defines DB_M_SERVER and so on... */ require($DOCUMENT_ROOT . "/../../htdocs_includes/www.fhh.de/config.mysql.php"); /* the database wrapper class */ class NWN_DB { // Variablen var $reader; // DB-Verbindung aus der gelesen wird var $reader_rs; // Result-ID var $reader_nr; // Num Rows var $writer; // DB-Verbindung in die geschrieben wird var $writer_rs; // Result-ID var $writer_li; // Last ID var $writer_ar; // Affected Rows var $writer_transaction = 0; // Grade in einer Transaktion? function NWN_DB () { // Constructor global $DB_M_server, $DB_M_user, $DB_M_pass, $DB_M_dbase; global $DB_S_server, $DB_S_user, $DB_S_pass, $DB_S_dbase; unset($this->reader,$this->writer); ( $this->writer = mysql_connect($DB_M_server, $DB_M_user, $DB_M_pass) ) || die ("Konnte keine Verbindung zum Master herstellen!"); mysql_select_db($DB_M_dbase, $this->writer) || die ("Konnte Master-DB nicht auswaehlen!"); ( $this->reader = mysql_connect($DB_S_server, $DB_S_user, $DB_S_pass) ) || die ("Konnte keine Verbindung zum Reader herstellen!"); mysql_select_db($DB_S_dbase, $this->reader) || die ("Konnte Reader-DB nicht auswaehlen!"); $this->reader_rs = ""; $this->reader_nr = ""; $this->writer_rs = ""; $this->writer_li = ""; $this->writer_ar = ""; } function close () { // Verbindung kappen mysql_close($this->writer); mysql_close($this->reader); unset($this->writer); unset($this->reader); } function read ($SQL) { // Von den Slaves lesen, Anzahl der Zeilen im Result Set festhalten if ($SQL != "") { // Wenn wir grade _nicht_ in einer Transaktion sind, vom Reader lesen if ($this->writer_transaction != 1) { $this->reader_rs = mysql_query($SQL, $this->reader); if (! $this->reader_rs) return FALSE; $this->reader_nr = mysql_num_rows($this->reader_rs); return TRUE; } else { // Innerhalb einer Transaktion vom Writer lesen, nur der kann da die richtigen // Daten haben. Das Result Set wird trotzdem in $this->reader_rs gespeichert, damit // die weiteren Zugriffsfunktionen dann auch innerhalb der Transaktion funktionieren $this->reader_rs = mysql_query($SQL, $this->writer); if (! $this->reader_rs) return FALSE; $this->reader_nr = mysql_num_rows($this->reader_rs); return TRUE; } } else { $this->reader_rs = ""; $this->reader_nr = ""; return FALSE; } } function get () { // Zeile aus dem aktuellen Result Set holen return mysql_fetch_array($this->reader_rs); } } //class function bla() { $db2 = new NWN_DB; print "reader_f: " . $db2->reader."<br>"; print "writer_f: " . $db2->writer."<br>"; $sql = "SELECT * FROM bookmarks"; $db2->read($sql); echo "table bookmarks <br>"; while($tmp = $db2->get()) { echo "db2 : $tmp[0] <br>"; } $db2->close(); //if you omit this close(), $db3 will later get the same connection //as db and db2 } //lets go $db = new NWN_DB; print "reader1: " . $db->reader."<br>"; print "writer1: " . $db->writer."<br>"; $sql = "SELECT * FROM profile"; $db->read($sql); bla(); //establishes the second db connection /* $db3 will get a new ressource id if bla() closes its connection although the link is still in use by $db --> conclusion: the reference count for the db link does not work somehow probably this is related to the use of a class for the db connections */ $db3 = new NWN_DB; $db3->read("SELECT * FROM mpr_attributes"); print "reader3: " . $db3->reader."<br>"; print "writer3: " . $db3->writer."<br>"; echo "table mpr_attributes <br>"; while($tmp = $db3->get()) { echo "db3 : $tmp[0] <br>"; } $db3->close(); //this still returns the correct results //although the last $db->close() tells us //there is no more mysql connection available echo "table profile <br>"; while($tmp = $db->get()) { echo "db : $tmp[0] <br>"; } print "reader_a: " . $db->reader."<br>"; print "writer_a: " . $db->writer."<br>"; $db->close(); print "end object stuff <p><p>"; function bla2() { global $DB_M_server, $DB_M_user, $DB_M_pass, $DB_M_dbase; $conn2 = mysql_connect($DB_M_server, $DB_M_user, $DB_M_pass); mysql_select_db($DB_M_dbase,$conn2); $rs = mysql_query("SELECT * FROM mpr_attributes",$conn2); echo "resource2: $conn2 <br>"; while ($tmp = mysql_fetch_row($rs)) { print "conn2: $tmp[0] <br>"; } mysql_close($conn2); } $conn = mysql_connect($DB_M_server, $DB_M_user, $DB_M_pass); mysql_select_db($DB_M_dbase,$conn); echo "resource1: $conn <br>"; $rs1 = mysql_query("SELECT * FROM profile",$conn); bla2(); while ($tmp = mysql_fetch_row($rs1)) { print "conn1: $tmp[0] <br>"; } mysql_close($conn); //now the same procedure without a function print "<p><p>now without a function call<p><p>"; $conn3 = mysql_connect($DB_M_server, $DB_M_user, $DB_M_pass); mysql_select_db($DB_M_dbase,$conn3); $rs = mysql_query("SELECT * FROM mpr_attributes",$conn3); echo "resource3: $conn3 <br>"; while ($tmp = mysql_fetch_row($rs)) { print "conn3: $tmp[0] <br>"; } $conn4 = mysql_connect($DB_M_server, $DB_M_user, $DB_M_pass); mysql_select_db($DB_M_dbase,$conn4); echo "resource4: $conn4 <br>"; $rs1 = mysql_query("SELECT * FROM profile",$conn4); while ($tmp = mysql_fetch_row($rs1)) { print "conn1: $tmp[0] <br>"; } mysql_close($conn3); mysql_close($conn4); /* here the close calls work as expected so somehow this issue has something to do with resource handling in the context of functions / classes */ ?> ----[end of test code (finally)]---- the output is: -------------- reader1: Resource id #1 writer1: Resource id #1 reader_f: Resource id #1 writer_f: Resource id #1 table bookmarks db2 : 10 db2 : 11 db2 : 6 db2 : 2 db2 : 1 db2 : 9 db2 : 7 db2 : 8 reader3: Resource id #4 writer3: Resource id #4 table mpr_attributes db3 : 1 db3 : 2 db3 : 3 db3 : 4 table profile db : 16 db : 13 db : 11 db : 12 reader_a: Resource id #1 writer_a: Resource id #1 Warning: 1 is not a valid MySQL-Link resource in /usr/local/httpd/htdocs/www.fhh.de/test.php on line 44 Warning: 1 is not a valid MySQL-Link resource in /usr/local/httpd/htdocs/www.fhh.de/test.php on line 45 end object stuff resource1: Resource id #6 resource2: Resource id #6 conn2: 1 conn2: 2 conn2: 3 conn2: 4 conn1: 16 conn1: 13 conn1: 11 conn1: 12 Warning: 6 is not a valid MySQL-Link resource in /usr/local/httpd/htdocs/www.fhh.de/test.php on line 180 now without a function call resource3: Resource id #9 conn3: 1 conn3: 2 conn3: 3 conn3: 4 resource4: Resource id #9 conn1: 16 conn1: 13 conn1: 11 conn1: 12 --------------------- So after a mysql_close inside a function/class was executed PHP seems to assume that the db link with the used ressource id is closed. Since it isn't closed (we do read from apparently closed connections above), the final mysql_close reports "not a valid MySQL-Link resource". So somehow PHP loses information about the number of connection that are working on the same mysql link/ressource id when mysql_close is called within a function/class. There are two Bugs in the Bug database which might be related to this, but they are marked "closed": http://bugs.php.net/bug.php?id=11201 http://bugs.php.net/bug.php?id=8634 Can someone reproduce this behaviour? TIA, Matthias, Eike, Carsten -- PHP Database Mailing List (http://www.php.net/) To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]