Today, I talked to my colleagues about whether to disable the database connection for the Destructor in the DB class, it seems that the database connection is closed before the DB object is destroyed. today, I am discussing with my colleagues whether The Destructor in the DB class should close the database connection, it seems that it is normal to close the database connection before the DB object is destroyed:
1234567891011121314151617 |
ClassDB {public $ conn; publicfunction _ construct () {$ this-> conn = mysql_connect ('localhost', 'root', ''); mysql_select_db ('test ', $ this-> conn);} publicfunctionquery ($ SQL) {returnmysql_query ($ SQL, $ this-> conn);} publicfunction _ destruct () {echo "destruct: close "; Mysql_close ($ this-> conn );}} |
Run:
Print destruct normally: close.
Let's take a look at the following session redirection to DB:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
Conn = mysql_connect ('localhost', 'root', ''); mysql_select_db ('test', $ this-> conn);} publicfunctionquery ($ SQL) {returnmysql_query ($ SQL, $ this-> conn);} publicfunction _ destruct () {echo "destruct: close "; Mysql_close ($ this-> conn) ;}} classSessionHandler {publicstatic $ db; functionopen () {} functionclose () {} functionread () {} functionwrite ($ id, $ data) {echo "session: write "; $ SQL =" replace into session VALUES ('$ ID',' $ data') "; self: $ db-> query ($ SQL);} functiondestroy () {} functiongc () {}} SessionHandler: $ db = newDB; session_set_save_handler (array ('sessionhandler', 'open'), array ('sessionhandler', 'close '), array ('sessionhandler', 'read'), array ('sessionhandler', 'write'), array ('sessionhandler', 'deststroy'), array ('sessionhandler ', 'gc '); session_start (); $ _ SESSION ['user'] = 'Deep Space ';?> |
This time, the analysis structure is normal, but the session write error occurs. the analysis structure is executed before the session write:
1234 |
Destruct: closesession: write Warning: mysql_query (): 2 is not a valid MySQL-Link resource on line 12 |
Er, let's see it. PHP executes the destructor after the script is executed, and then processes the session.
Let me modify SessionHandler a bit:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
Conn = mysql_connect ('localhost', 'root', ''); mysql_select_db ('test', $ this-> conn);} publicfunctionquery ($ SQL) {returnmysql_query ($ SQL, $ this-> conn);} publicfunction _ destruct () {echo "destruct: close "; Mysql_close ($ this-> conn) ;}} classSessionHandler {functionopen () {} functionclose () {} functionread () {} functionwrite ($ id, $ data) {global $ db; echo "session: write "; $ SQL =" replace into session VALUES ('$ ID',' $ data') "; $ db-> query ($ SQL);} functiondestroy () {} functiongc () {}}$ db = newDB (); session_set_save_handler (array ('sessionhandler', 'open'), array ('sessionhandler', 'close '), array ('sessionhandler', 'read'), array ('sessionhandler', 'write'), array ('sessionhandler', 'deststroy'), array ('sessionhandler ', 'gc '); session_start (); $ _ SESSION ['user'] = 'extension';?> |
The output is as follows:
1234 |
Destruct: closesession: write Fatal error: Call to a member function query () on a non-object on line 35 |
I was surprised when this error was reported. according to the prompt, we can identify that the $ db variable of 35 rows is not an object. later, we thought it should be like this, because the _ destruct method has been executed, in fact, the object has been destroyed before write, so it is not surprising that the $ db variable cannot be found. I tested some strings and array variables and found that these variables were not destroyed during write execution. I made the following changes:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
Conn = mysql_connect ('localhost', 'root', ''); mysql_select_db ('test', $ this-> conn);} publicfunctionquery ($ SQL) {returnmysql_query ($ SQL, $ this-> conn);} publicfunction _ destruct () {echo "destruct: close "; Mysql_close ($ this-> conn) ;}} classSessionHandler {functionopen () {} functionclose () {} functionread () {} functionwrite ($ id, $ data) {global $ db; echo "session: write "; $ SQL =" replace into session VALUES ('$ ID',' $ data') "; $ db ['session ']-> query ($ SQL );} functiondestroy () {}functiongc () {}} $ db ['session'] = newDB (); session_set_save_handler (array ('sessionhandler', 'open '), array ('sessionhandler', 'close'), array ('sessionhandler', 'read'), array ('sessionhandler', 'write'), array ('sessionhandler ', 'deststroy'), array ('sessionhandler', 'gc '); session_start (); $ _ SESSION ['user'] = 'Deep ary';?> |
Output:
1234 |
Destruct: closesession: write Warning: mysql_query (): 2 is not a valid MySQL-Link resource on line 12 |
Haha, this $ db is not destroyed because it is an array variable. later I analyzed it with my colleagues and thought it may be because these variables are stored differently from the object and the destruction order is different. However, _ destruct is still executed before the write operation. Basically, it can be judged that the session is executed only after a very long time. To solve this problem, you can only remove the DB _ destruct method.
I didn't go into the PHP internal processing and recycling methods of variables, but this problem was revealed only when the session handling method was redirected. it was an interesting issue, I am trying to share my findings with you, so that you will not waste much time debugging when encountering this problem.
I hope you can give some advice.