Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Utrata połączenia z bazą danych po deklaracji dwóch instancji połączenia (nadpisanie zawartości zmiennej obiektu)
Forum PHP.pl > Forum > PHP > Object-oriented programming
Athlan
Witam. Od kilku dni zajmuje się bardzo dziwnym przypadkiem utraty połączenia z bazą danych. Dokładniej: destruktor jednej instancji przerywa połączenie z bazą danych przy tworzeniu kolejnej.

Ok, przykład najprostrzego połączenia z bazy danych, testuję tutaj źródło połączenia (resource)

  1. <?php
  2.  
  3. /**
  4.  * Debug function
  5.  */
  6.  
  7. function debug_connection($rResource, $sText)
  8. {
  9. echo '<p>' . $sText . '<br />';
  10. var_dump($rResource);
  11. echo'<br />is resource: ';
  12. var_dump(is_resource($rResource));
  13. echo'</p>';
  14. }
  15.  
  16. /**
  17.  * Ok, let's go...
  18.  */
  19.  
  20.  
  21. $rConnection = null;
  22.  
  23. echo debug_connection($rConnection, 'debug handler instance:');
  24.  
  25. $rConnection = mysql_connect('localhost', 'root', '');
  26.  mysql_select_db('safnet', $rConnection);
  27.  
  28. echo debug_connection($rConnection, 'debug handler after connection:');
  29.  
  30.  mysql_close($rConnection);
  31.  
  32. echo debug_connection($rConnection, 'debug handler after disconnection:');
  33.  
  34. /**
  35.  * ... that's all.
  36.  */
  37.  
  38. ?>


Test wyszedł smile.gif źródło połączenia jest zaraz po połączeniu i przed rozłączeniem.

Ok, przyjmijmy, że połączenie jest ustanawiane przez klasę. Przykład:

  1. <?php
  2.  
  3. abstract class MySQL_ConnectResource
  4. {
  5. protected $_rConnection = null;
  6. }
  7.  
  8. final class MySQL_test1 extends MySQL_ConnectResource
  9. {
  10. private $_sIdentyficator = null;
  11.  
  12. public function __construct($sIdentyficator)
  13. {
  14. $this->_sIdentyficator = $sIdentyficator;
  15.  
  16. echo'<p style="color: dodgerblue"> >> connectiong for <b>'.$this->_sIdentyficator.'</b></p>';
  17.  
  18. $this->_rConnection = mysql_connect('localhost', 'root', '');
  19. mysql_select_db('safnet', $this->_rConnection);
  20. }
  21.  
  22. public function __destruct()
  23. {
  24. echo'<p style="color: blue"> << disconnectiong for <b>'.$this->_sIdentyficator.'</b></p>';
  25.  
  26. if(is_resource($this->_rConnection))
  27. mysql_close($this->_rConnection);
  28. else
  29. echo'<p style="color: red"> Error thrown: try to close missing connection at <b>'.$this->_sIdentyficator.'</b>!</p>';
  30. }
  31. }
  32.  
  33.  
  34. /**
  35.  * EXAMPLES
  36.  */
  37.  
  38.  
  39. $oDb = new MySQL_test1('1 instance');
  40. unset($oDb); // prawidlowe zamkniecie #1
  41. $oDb = new MySQL_test1('2 instance'); // prawidlowe zamkniecie #2, komplikacje #3
  42. $oDb = new MySQL_test1('3 instance'); // ... komplikacje
  43. $oDb = new MySQL_test1('4 instance'); // prawidlowe zamkniecie #4, komplikacje #5
  44. $oDb = new MySQL_test1('5 instance'); // ... komplikacje
  45. unset($oDb);
  46.  
  47. ?>


Jak widzimy w linii testu: ciągle niszczymy poprzednią instancję połączenia nadpisując drugą, przez co połowa połączeń nie zamyka się smile.gif

A co jak chcę przy pierwszym nadpisaniu wysłać zapytanie metodą (nieistniejącą w mojej powyższej klasie) Execute(), która sprawdza czy połączenie jest is_resource()? Wówczas nie wykona sie, tylko wywali mi wyjątek (załóżmy że wywalam wyjątek).

Moje pytanie brzmi: Co zrobić, aby przy nadpisaniu zawartości zmiennej (w tym przypadku obiektu) połączenie spokojnie się zamknęło?

P.S. To nie jest mój problem, ale zawsze mnie ciekawił - dobry temat do dyskusji i szerokie pole popisu speców od php. Może wspólnie wyciągniemy jakieś wnioski.

Pozdrawiam, Athlan smile.gif
Turgon
Nie rozumiem za bardzo o co ci chodzi?
Athlan
-.-"

Prościej wytłumaczyć się nie dało, przykłady napisałem tongue.gif

Chodzi o to, że po nadpisaniu instancji tej samej klasy w zmiennej co drugie połączenie źle się zamyka. Bug?

Przy okazji Wesołych Świąt.

Athlan smile.gif
Turgon
Cytat
>> connectiong for 1 instance

>> connectiong for 2 instance

<< disconnectiong for 1 instance

>> connectiong for 3 instance

<< disconnectiong for 2 instance

Error thrown: try to close missing connection at 2 instance with resource id Resource id #2!

>> connectiong for 4 instance

<< disconnectiong for 3 instance

>> connectiong for 5 instance

<< disconnectiong for 4 instance

Error thrown: try to close missing connection at 4 instance with resource id Resource id #3!

<< disconnectiong for 5 instance


Tutaj nawala, albo funkcja is_resource albo jest sporo namieszane z czasami życia.

Ale jak zmienie minimalnie kod :
  1. <?php
  2.  
  3. abstract class MySQL_ConnectResource
  4. {
  5. protected $_rConnection = null;
  6. }
  7.  
  8. final class MySQL_test1 extends MySQL_ConnectResource
  9. {
  10. private $_sIdentyficator = null;
  11.  
  12. public function __construct($sIdentyficator)
  13. {
  14. $this->_sIdentyficator = $sIdentyficator;
  15.  
  16. echo'<p style="color: dodgerblue"> >> connectiong for <b>'.$this->_sIdentyficator.'</b></p>';
  17.  
  18. $this->_rConnection = mysql_connect('localhost', 'root', '');
  19. mysql_select_db('turgon', $this->_rConnection);
  20. }
  21.  
  22. public function _destruct()
  23. {
  24. echo'<p style="color: blue"> << disconnectiong for <b>'.$this->_sIdentyficator.'</b></p>';
  25.  
  26. if(is_resource($this->_rConnection))
  27. mysql_close($this->_rConnection);
  28. else
  29. echo'<p style="color: red"> Error thrown: try to close missing connection at <b>'.$this->_sIdentyficator.'</b> with resource id '.$this->_rConnection.'!</p>';
  30. }
  31. }
  32.  
  33.  
  34. /**
  35.  * EXAMPLES
  36.  */
  37.  
  38.  
  39. $oDb = new MySQL_test1('1 instance');// prawidlowe zamkniecie #1
  40. $oDb->_destruct();
  41. $oDb = new MySQL_test1('2 instance'); // prawidlowe zamkniecie #2, komplikacje #3
  42. $oDb->_destruct();
  43. $oDb = new MySQL_test1('3 instance'); // ... komplikacje
  44. $oDb->_destruct();
  45. $oDb = new MySQL_test1('4 instance'); // prawidlowe zamkniecie #4, komplikacje #5
  46. $oDb->_destruct();
  47. $oDb = new MySQL_test1('5 instance'); // ... komplikacje
  48. $oDb->_destruct();
  49. ?>


Otrzymuje :
Cytat
>> connectiong for 1 instance

<< disconnectiong for 1 instance

>> connectiong for 2 instance

<< disconnectiong for 2 instance

>> connectiong for 3 instance

<< disconnectiong for 3 instance

>> connectiong for 4 instance

<< disconnectiong for 4 instance

>> connectiong for 5 instance

<< disconnectiong for 5 instance
Athlan
Turgon: właśnie chodzi o to, aby połączenie zaykało się samo.

Zastanawiam się, czy warto woggóle zamykac połączenie z bazą danych. Teoretycznie zamyka się (bezpiecznie) samo. Jego nadpisanie wartością NULL również bezpiecznie je zamyka. Ciekawe po co jest funckja mysql_close(), czyżby nadpisywała połącznie wartością NULL?

Szeroki temat do dyskusji, ale Vengenace na gg, on nie zamyka połączenie i jest dobrze smile.gif
Turgon
W sumie przyznam się, że zamykam połączenie tylko i wyłącznie kiedy sytuacja tego wymaga.
Chodzi mi po głowie kilka refleksji. Odświeżaj stronę kilka razy i za każdym razem otwieraj nowe połączenie i sprawdź jakie mają Id... Hmm... Zaraz napiszę skrypta testowego.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.