Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Fatal error: Exception thrown without a stack frame in Unknown on line 0
Forum PHP.pl > Forum > PHP > Object-oriented programming
Jarod
Mam taki kod (niedokończony ale odczytuje dane z bazy i zapisuje).
  1. <?php
  2.  
  3. require_once('Core/Cube/Session/SessionHandler.interface.php');
  4. require_once('Core/Cube/Session/SessionException.class.php');
  5. require_once('Core/Cube/Database/' . Config::$DbType . '/' . Config::$DbType . '.class.php');
  6.  
  7. class CubeSession implements SessionHandler
  8. {
  9. private $sSessionValues = null;
  10. private $sAddressIp = null;
  11. private $oConnection = null;
  12. private $sLogin = null;
  13.  
  14. public function __construct($oRegistry, $sConnectionName)
  15. {
  16. $this->oConnection = $oRegistry->get($sConnectionName);
  17.  
  18. session_set_save_handler(array(&$this, 'open'), array(&$this, 'close'), array(&$this, 'read'), array(&$this, 'write'), array(&$this, 'destroy'), array(&$this, 'gc'));
  19.  
  20. $this->sAddressIp = $_SERVER['REMOTE_ADDR'];
  21. if (isset($_SESSION['Login'])) $this->sLogin = $_SESSION['Login'];
  22. }
  23.  
  24. public function open($sSessionSavePath, $sSessionName)
  25. {
  26. return true;
  27. }
  28.  
  29. public function close()
  30. {
  31. $this->gc(Config::$SessionMaxLifeTime);
  32. return true;
  33. }
  34.  
  35. public function read($sSessionId)
  36. {
  37. $this->oConnection->query('SELECT sessions_values FROM sessions WHERE sessions_identifier = '' . $sSessionId . ''');
  38. $this->sSessionValues = $this->oConnection->fetchOne();
  39.  
  40. return $this->sSessionValues;
  41. }
  42.  
  43.  
  44. public function write($sSessionId, $aSessionValues)
  45. {
  46. $aInsert = array('sessions_identifier'=>session_id(), 'sessions_time_start'=>'21:15',
  47. 'sessions_last_time' => '21:16', 'sessions_values'=>'serialize','login'=>'dupa', 'address_ip'=>$this->sAddressIp );
  48. @$this->oConnection->insert('sessions', $aInsert);
  49.  
  50.  
  51. echo '<br/>Metoda write() została wywołana<br/>';
  52. }
  53.  
  54. public function destroy($sSessionId){}
  55.  
  56. public function gc($iSessionLifeTime)
  57. {
  58. echo 'Zniszczone';
  59. }
  60.  
  61. }
  62.  
  63.  
  64. ?>


Błąd, który podałem w temacie pojawia się gdy tabela sessions wygląda tak:
  1. CREATE TABLE sessions
  2. (
  3. sessions_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  4. sessions_identifier VARCHAR(32) NOT NULL,
  5. sessions_time_start TIME NOT NULL,
  6. sessions_last_time TIME NOT NULL,
  7. sessions_values TEXT NOT NULL,
  8. login VARCHAR(20),
  9. address_ip VARCHAR(15),
  10. UNIQUE(sessions_identifier)
  11. ) ENGINE = InnoDB DEFAULT CHARSET=utf8;


Jeśli usunę UNIQUE(sessions_identifier) z tabeli to błąd się nie pojawia. Można to obejść sprawdzając czy wpis o podanym numerze sesji istnieje. Jeśli nie to wykonujemy insert a jeśli istnieje to update.
Problem w tym, że zawsze sprawdzałem to poprzez mysql_affected_rows(). Niestety w tym wypadku to nic nie daje i błąd się pojawia. Mógłbym wykonywać selecta i sprawdzać czy został zwrócony wynik (jeśli tak to wpis już istnieje) ale chciałbym uniknąć zbędnego zapytania do bazy..

Macie jakiś pomysł?
mike
Mam trzy pytania pomocnicze?
  • Obiektem jakiej klasy jest $this->oConnection;
  • Co dokładnie robi $this->oConnection->insert(), bo zakładam że to właśnie tu jest źródło problemów;
  • Co się dzieje jeśli usuniesz @ przez wywołaniem tego inserta
Jarod
Cytat(mike_mech @ 12.02.2007, 08:38:15 ) *
Mam trzy pytania pomocnicze?
  • Obiektem jakiej klasy jest $this->oConnection;

W $this->oConnection zapisana jest instancja klasy Mysql (domyślasz się co umożliwia)

Cytat(mike_mech @ 12.02.2007, 08:38:15 ) *
  • Co dokładnie robi $this->oConnection->insert(), bo zakładam że to właśnie tu jest źródło problemów;

  1. <?php
  2. /**
  3.  * Metoda wykonująca przekazane zapytanie SQL, zapisująca identyfikator wyniku
  4.  * zapytania do prywatnej właściwości $rQuery i dopisująca do tablicy $aQuerySta
    ck
  5.  * treść zapytania. Jeśli zapytanie nie powiedzie się, zwracany jest odpowiedni
  6.  * komunikat wyjątku.
  7.  * 
  8.  * @param string $sQuery Zapytanie SQL
  9.  */
  10. public function query($sQuery)
  11. {
  12. if (isset($this->rQuery)) unset($this->rQuery);
  13.  
  14. if (!$this->rQuery = @ mysql_query($sQuery, $this->rDatabaseHandle))
  15. throw new MysqlException('Nieudane zapytanie: ' . $sQuery);
  16.  
  17. array_push($this->aQueryStack, $sQuery);
  18. }
  19.  
  20.  
  21. /**
  22.  * Metoda pobiera dwa parametry: nazwę tabeli oraz tablicę z atrybutami tabeli
  23.  * i ich wartościami, które zostaną dodane do bazy. Po odpowiednim przetworzeniu
  24.  * parametrów konstruowane jest zapytanie, a następnie wykonywana jest metoda
  25.  * query() z tym zapytaniem.
  26.  * 
  27.  * @param string $sTableName Nazwa tabeli w bazie danych
  28.  * @param array $aInsert Atrybuty tabeli z przypisanymi wartościami
  29.  */
  30. public function insert($sTableName, array $aInsert)
  31. {
  32. $aInsert = $this->_quoteArray($aInsert);
  33.  
  34. $sSqlFields = '`' . implode('`, `', array_keys($aInsert)) . '`';
  35. $sSqlValues = implode(', ', array_values($aInsert));
  36.  
  37. $sQuery = 'INSERT INTO ' . $sTableName . ' (' . $sSqlFields . ') VALUES (' . $sSqlValues . ')';
  38.  
  39. $this->query($sQuery);
  40. }
  41. ?>



Cytat(mike_mech @ 12.02.2007, 08:38:15 ) *
  • Co się dzieje jeśli usuniesz @ przez wywołaniem tego inserta

Dokładnie ten sam błąd. @ nic w tym przypadku nie wnosi.
mike
Cytat(J4r0d @ 12.02.2007, 23:03:22 ) *
Dokładnie ten sam błąd. @ nic w tym przypadku nie wnosi.

Hmm, tak. Ale nadal masz @ przed jedną z kluczowych instrukcji. Bardziej mi chodziło o to żebyś zdjął je zewsząd, to może pomóc w uzyskaniu tekstu błędu, który powie coś więcej.

Zdejmij @ z przed mysql_query() w linii 14.
Jarod
Cytat(mike_mech @ 13.02.2007, 15:25:23 ) *
Hmm, tak. Ale nadal masz @ przed jedną z kluczowych instrukcji. Bardziej mi chodziło o to żebyś zdjął je zewsząd, to może pomóc w uzyskaniu tekstu błędu, który powie coś więcej.

Zdejmij @ z przed mysql_query() w linii 14.

Wszędzie pousuwałem @. Błąd ten sam. Nie wiem co jest grane..

Cytat(J4r0d @ 13.02.2007, 20:49:16 ) *
Wszędzie pousuwałem @. Błąd ten sam. Nie wiem co jest grane..


EDIT: Na szybko napisałem:
  1. <?php
  2. class Mysql
  3. {
  4. public function __construct()
  5. {
  6. $link = mysql_connect('localhost', 'root', 'maestro')
  7.  or die('Nie można się połączyć: ' . mysql_error());
  8.  
  9.  mysql_select_db('cube') or die('Nie można się połączyć: ' . mysql_error());
  10.  
  11.  mysql_query('INSERT INTO sessions VALUES (null, '1', '22:00', '22:05', 'serialize', 'dupa', '127.0.0.1')') or die('Błąd zapytania'.mysql_error());
  12.  
  13. }
  14. }
  15.  
  16. $oM = new Mysql();
  17. ?>


I dostaję błąd:
Kod
Błąd zapytania Duplicate entry '1' for key 2
Czyli tak jak powinno być :/
mike
Hmm, zagadkowa sprawa.
Mam kolejne pytanko pomocnicze, które może pozwoli znaleźć przyczynę błędu.
Czy problem wywala przy każdym zapytaniu INSERT czy tylko przy tych, które naruszają klucz unikalności?
Podejrzewam, że odpowiedź jest jasna, że tylko podczas wstawiana takich samych danych, ale wolę się upewnić.

Nie mniej jednak mam pomysł. Wstaw sam wyrzucanie wyjątku w miejscu gdzie faktycznie problem może wystąpić. Ciekawe czy nadal będzie fatal czy Twój wyjątek.

  1. <?php
  2.  
  3. // ...
  4.  
  5. public function insert($sTableName, array $aInsert)
  6. {
  7. $aInsert = $this->_quoteArray($aInsert);
  8.  
  9. $sSqlFields = '`' . implode('`, `', array_keys($aInsert)) . '`';
  10. $sSqlValues = implode(', ', array_values($aInsert));
  11.  
  12. $sQuery = 'INSERT INTO ' . $sTableName . ' (' . $sSqlFields . ') VALUES (' . $sSqlValues . ')';
  13.  
  14. $this->query($sQuery);
  15.  
  16. if(mysql_errno() != 0) {
  17. throw new Exception(mysql_error(), mysql_errno());
  18. }
  19.  
  20. }
  21.  
  22. // ...
  23.  
  24. ?>
Jarod
Cytat(mike_mech @ 13.02.2007, 21:06:13 ) *
Hmm, zagadkowa sprawa.
Mam kolejne pytanko pomocnicze, które może pozwoli znaleźć przyczynę błędu.
Czy problem wywala przy każdym zapytaniu INSERT czy tylko przy tych, które naruszają klucz unikalności?
Podejrzewam, że odpowiedź jest jasna, że tylko podczas wstawiana takich samych danych, ale wolę się upewnić.

Pisałem, że tylko gdy jest naruszany klucz integralności..


Cytat(mike_mech @ 13.02.2007, 21:06:13 ) *
Nie mniej jednak mam pomysł. Wstaw sam wyrzucanie wyjątku w miejscu gdzie faktycznie problem może wystąpić. Ciekawe czy nadal będzie fatal czy Twój wyjątek.

Nadal fatal..

EDIT. Przetestowałem dokładniej. Sterownik do bazy mysql jest poprawny. Problem występuje tylko przy insercie wydawanym w klassie CubeSession. W innych miejscach poprawnie wywala informacje o duplikacji..


EDIT2. Problem rozwiązany. Trzeba było dodać obsługę wyjątków w CubeSession:
  1. <?php
  2. public function write($sSessionId, $aSessionValues)
  3. {
  4. $aInsert = array('sessions_identifier'=>session_id(), 'sessions_time_start'=>'21:15',
  5. 'sessions_last_time' => '21:16', 'sessions_values'=>'serialize','login'=>'dupa', 'address_ip'=>$this->sAddressIp );
  6. // $this->oConnection->insert('sessions', $aInsert);
  7.  
  8. try
  9. {
  10. $this->oConnection->query('INSERT INTO sessions VALUES (null, '1', '22:00', '22:05', 'serialize', 'dupa', '127.0.0.1')');
  11. }
  12. catch (Exception $e)
  13. {
  14. echo $e;
  15. }
  16. ?>

Nie rozumiem tylko dlaczego bez obsługi wyjątków wywala się tak.. Ktoś to potrafi wytłumaczyć?
kicaj
Mam identyczny przypadek i identyczny blad... rozwiazalem go podobnie, jednak to wyglada mi na amatorke:p

Wiem ze jest to blad w PHP, jednak znalezione rozwiazania z __destruct() i/lub __sleep() nie pomagaly, jesli ktos juz wie cos na ten temat wiecej, zapraszam:)
Turgon
Czy ludzie naprawdę nie domyślacie się dlaczego ? Skoro używacie session_set_save_handler(), to większość funkcji jest wywoływana po za skryptem i jak nie ma ramki try{}, to skrypt głupieje, bo jest po za...
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.