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 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 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 smile.gif w takim wypadku dobrym zwyczajem jest każdorazowa likwidacja utworzonego obiektu połączenia z bazą danych zaraz po jego zakończeniu smile.gif