Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [php][mysql] Odwołanie do składowej rzekomo nieistniejącego obiektu, Fatal error: Call to a member function query() on a non-object in...
Geston
post
Post #1





Grupa: Zarejestrowani
Postów: 60
Pomógł: 9
Dołączył: 29.11.2010
Skąd: T

Ostrzeżenie: (0%)
-----


Witam, z tego co widziałem/czytałem, problem jest dość popularny. Mimo tego przeglądnięcie dziesiątek tematów nie pomogło mi go rozwiązać :/

Zacznę może od kodu i jego opisu.

W napisanej przeze mnie klasie User pod lupę trafiają dwie jej funkcje, publiczna "set" i prywatna "is_exists", reszta nie ma związku z problemem:

  1. <?php #class_User.php
  2.  
  3. class User {
  4.  
  5. public $error;
  6.  
  7. private $login;
  8. private $email;
  9. private $password;
  10. private $firstname;
  11. private $lastname;
  12. private $street;
  13. private $city;
  14. private $postal;
  15.  
  16. public function set($name, $var) {
  17. // funkcja ustawiająca wartości zmiennych
  18.  
  19. User::validate($name, $var);
  20.  
  21. // dla loginu i maila
  22. if ($name == 'login' || $name == 'email') {
  23. User::is_exists($name, $var);
  24. }
  25.  
  26. if ($this->error == '') {
  27. $this->$name = $var;
  28. }
  29. }
  30.  
  31. private function is_exists($name, $var) {
  32. // funkcja sprawdzająca dostępność loginu/maila
  33.  
  34. // utworzenie połączenia z bazą danych
  35. require_once('../db_connect.php');
  36.  
  37. $query = sprintf("SELECT %s FROM adresses WHERE %s = '%s'", $name, $name, $var);
  38.  
  39. echo $query;
  40.  
  41. $result = $dbc->query($query);
  42.  
  43. // zakończenie połączenia z bazą
  44. $dbc->close();
  45.  
  46. if ($result->num_rows) {
  47. $result->close();
  48. $this->error .= "Podany $name już istnieje!\n";
  49.  
  50. return true;
  51. }
  52. }
  53. }


Funkcja set wywoływana jest w pliku który korzysta z utworzonego obiektu klasy User i przekazuje do obiektu za pomocą funkcji set wartości pobrane z formularza. Kod poniżej:

  1. if (isset($_POST['submitted'])) {
  2. // obsługa formularza
  3.  
  4. // dołączenie pliku z definicją klasy user
  5. require_once('../classes/class_User.php');
  6.  
  7. // usunięcie zbędnych znaków z danych wejściowych
  8. $trimmed = array_map('trim', $_POST);
  9.  
  10. // tworzenie nowego obiektu klasy user
  11. $user = new User();
  12.  
  13. // ustawianie wartości zmiennych klasy user
  14. $user->set(login, $trimmed['login']);
  15. $user->set(firstname, $trimmed['firstname']);
  16. $user->set(lastname, $trimmed['lastname']);
  17. $user->set(email, $trimmed['email']);
  18. ($trimmed['password1'] == $trimmed['password2']) ? $user->set(password, $trimmed['password1']) : $user->error .= "Podane hasła różnią się!\n";
  19. $user->set(street, $trimmed['street']);
  20. $user->set(city, $trimmed['city']);
  21. $user->set(postal, $trimmed['postal']);
  22. $user->set(birthday, $trimmed['birthday']);
  23.  
  24. // wyświetlenie błędu w przypadku nieudanej próby ustawienia zmiennej klasy user,
  25. // brak błędu = wywołanie funkcji register klasy user dodającej użytkownika do bazy i wysyłającej email aktywacyjny
  26. if (!$user->error == '') echo "\n" . '<p class="error">' . "\n" . str_replace("\n", "<br />\n", $user->error) . "</p>\n";
  27. else $user->register();
  28. }


Jak widać do kontroli błędów podczas walidacji danych służy mi publiczna zmienna error, dzięki niej wiem że nie mam błędu na etapie walidacji który występuje przed felernym sprawdzeniem czy w bazie danych istnieje już podany wcześniej login lub email. Również jak widać wyświetlam sobie utworzone zapytanie przed wykonaniem go, jest ono w 100% poprawne.

W funkcji "is_exists" poprzez dołączenie pliku odpowiedzialnego za utworzenie obiektu przez który łączę się z bazą tworzę właśnie taki obiekt. Błąd połączenia nie jest zwracany a więc teoretycznie też powinienem mieć pewność że obiekt ten zostaje utworzony. Również jak widać obiekt jest tworzony wewnątrz funkcji - a więc lokalnie, dzięki czemu nie muszę się do niego odwoływać globalnie itd, a bezpośrednio za pomocą zmiennej $dbc.

Poniżej kod odpowiedzialny za połączenie z bazą danych:

  1. <?php #db_connect.php
  2.  
  3. // połączenie z bazą danych
  4.  
  5. // stałe dostępu do bazy
  6. DEFINE ('DB_USER', 'root');
  7. DEFINE ('DB_PASSWORD', '');
  8. DEFINE ('DB_HOST', 'localhost');
  9. DEFINE ('DB_NAME', 'library');
  10.  
  11. // nawiązanie połączenia
  12. $dbc = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
  13.  
  14. if (mysqli_connect_errno()) {
  15. echo "Connection failed: " . mysqli_connect_error() . "\n";
  16. exit();
  17. }
  18.  
  19. ?>


Proszę o pomoc, nie pierwszy raz działam w podobny sposób i zawsze radziłem sobie z tym problemem, teraz jednak nie mam zielonego pojęcia skąd on się bierze (IMG:style_emoticons/default/sad.gif)

Fatal error: Call to a member function query() on a non-object in...

Rozumiem że wywołując składową klasy mysqli - query() - wywala mi błąd bo obiekt nie istnieje...

Przepraszam za zamieszanie, wątek do zamknięcia. Problem najczęściej leży nie tam gdzie go szukamy (IMG:style_emoticons/default/smile.gif) Może podając na czym polegał przyczynię się do pomocy innym którzy kiedyś trafią na ten temat.

Otóż funkcja is_exists zostaje wywołana w jednym skrypcie dwukrotnie, co za tym idzie require_once() nie dołącza drugi raz pliku odpowiedzialnego za połączenie z bazą. Zamiana na require() rozwiązuje problem (IMG:style_emoticons/default/smile.gif) w takim wypadku dobrym zwyczajem jest każdorazowa likwidacja utworzonego obiektu połączenia z bazą danych zaraz po jego zakończeniu (IMG:style_emoticons/default/smile.gif)

Ten post edytował Geston 29.11.2010, 15:43:44
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 01:26