mysqli_fetch_assoc () oczekuje błędów parametru / wywołania funkcji członkowskiej bind_param (). Jak uzyskać rzeczywisty błąd mysql i go naprawić?

109

W moim środowisku lokalnym / programistycznym zapytanie MySQLi działa poprawnie. Jednak po przesłaniu go do mojego środowiska hosta internetowego pojawia się ten błąd:

Błąd krytyczny: wywołanie funkcji składowej bind_param () na obiekcie niebędącym obiektem w ...

Oto kod:

global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);

Aby sprawdzić moje zapytanie, próbowałem wykonać zapytanie przez phpMyAdmin w panelu sterowania i wynik jest OK.

siopaoman
źródło
Czy możemy zobaczyć, gdzie inicjujesz $mysqlizmienną?
Rikesh
Może się zdarzyć, że Twój użytkownik MySQL nie ma uprawnień do wykonania SELECTzapytania. Sprawdziłeś to?
Amal Murali,
Przychodzi na myśl, że nie ma dostępnego mysqli lub podałeś nieprawidłowe dane uwierzytelniające, aby połączyć się z MySQL.
Uwaga:
@YourCommonSense - w starym tytule łatwiej było znaleźć to pytanie jako zduplikowane odniesienie.
Paul Spiegel
@Paul tak, to też jest moja najgłębsza troska. Zmieniłem tytuł ze względu na wyszukiwarkę Google i ogólne rozpoznanie, ponieważ dla przeciętnego użytkownika PHP połączenie między jego kodem a różnymi środowiskami jest niejasne. Ale od tamtej pory też trudno mi go znaleźć. Skończyć mając to w zakładkach. Jeśli możesz zaproponować rozpoznawalny, ale odpowiedni tytuł, byłoby świetnie
Your Common Sense

Odpowiedzi:

122

Czasami MySQLi kod generuje błąd typu mysqli_fetch_assoc() expects parameter..., Call to a member function bind_param()...lub podobny. Lub nawet bez żadnego błędu, ale zapytanie nie działa tak samo. Oznacza to, że twoje zapytanie nie zostało wykonane.

Za każdym razem, gdy zapytanie nie powiedzie się, MySQL wyświetla komunikat o błędzie, który wyjaśnia przyczynę . Niestety, domyślnie takie błędy nie są przenoszone do PHP, a jedyne, co masz, to tajemniczy komunikat o błędzie wspomniany powyżej. Dlatego bardzo ważne jest, aby skonfigurować PHP i MySQLi, aby zgłaszały błędy MySQL. A kiedy pojawi się komunikat o błędzie, naprawienie go będzie bułką z masłem.

Jak otrzymać komunikat o błędzie w MySQLi?

Przede wszystkim zawsze miej tę linię, zanim MySQLi połączy się we wszystkich twoich środowiskach:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

Następnie wszystkie błędy MySQL zostaną przeniesione do wyjątków PHP. Z kolei nieprzechwycony wyjątek powoduje błąd krytyczny PHP. Tak więc w przypadku błędu MySQL otrzymasz typowy błąd PHP. To natychmiast uświadomi ci przyczynę błędu. A ślad stosu doprowadzi Cię do dokładnego miejsca, w którym wystąpił błąd.

Jak skonfigurować PHP w różnych środowiskach

Oto streszczenie mojego artykułu na temat
raportowania błędów PHP : Zgłaszanie błędów na serwerach deweloperskich i na żywo musi być inne. Na serwerze deweloperskim wygodnie jest wyświetlać błędy na ekranie, ale na serwerze rzeczywistym komunikaty o błędach muszą być zamiast tego rejestrowane, aby można było je później znaleźć w dzienniku błędów.

Dlatego należy ustawić odpowiednie opcje konfiguracyjne na następujące wartości:

  • Na serwerze deweloperskim

    • error_reportingnależy ustawić na E_ALLwartość;
    • log_errors powinien być ustawiony na 1 (wygodnie jest mieć dzienniki również na komputerze deweloperskim)
    • display_errors powinien być ustawiony na 1
  • Na serwerze produkcyjnym

    • error_reportingnależy ustawić na E_ALLwartość;
    • log_errors powinien być ustawiony na 1
    • display_errors powinna być ustawiona na 0

Jak właściwie tego używać?

Wystarczy usunąć kod, który sprawdza błędu ręcznie , wszystkie te or die(), if ($result)i te. Po prostu od razu napisz kod interakcji z bazą danych:

$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();

znowu bez żadnych warunków . Jeśli wystąpi błąd, będzie traktowany jak każdy inny błąd w kodzie. Na przykład na komputerze deweloperskim pojawi się po prostu na ekranie, podczas gdy na stronie na żywo zostanie zarejestrowany dla programisty, podczas gdy dla wygody użytkownika możesz użyć obsługi błędów (ale to inna historia, która jest poza tematem) MySQLi, ale możesz o tym przeczytać w artykule, do którego link znajduje się powyżej).

Co zrobić z otrzymanym komunikatem o błędzie?

Przede wszystkim musisz zlokalizować problematyczne zapytanie. Komunikat o błędzie zawiera nazwę pliku i numer wiersza dokładnego miejsca, w którym wystąpił błąd. W przypadku prostego kodu to wystarczy, ale jeśli kod korzysta z funkcji lub klas, może być konieczne śledzenie stosu śledzenia w celu zlokalizowania zapytania powodującego problem.

Po otrzymaniu komunikatu o błędzie musisz go przeczytać i zrozumieć. Wydaje się to zbyt oczywiste, jeśli nie protekcjonalne, ale uczniowie często przeoczają fakt, że komunikat o błędzie nie jest tylko sygnałem alarmowym, ale zawiera szczegółowe wyjaśnienie problemu . Wszystko, czego potrzebujesz, to przeczytać komunikat o błędzie i rozwiązać problem.

  • Powiedzmy, że jeśli mówi, że konkretna tabela nie istnieje, musisz sprawdzić pisownię, literówki, wielkość liter. Musisz także upewnić się, że twój skrypt PHP łączy się z poprawną bazą danych
  • Lub, jeśli mówi, że jest błąd w składni SQL, musisz sprawdzić swój SQL. Miejsce problemu znajduje się tuż przed częścią zapytania wymienioną w komunikacie o błędzie.

Jeśli nie rozumiesz komunikatu o błędzie, spróbuj go wygooglować. Przeglądając wyniki, trzymaj się odpowiedzi, które wyjaśniają błąd, a nie wprost podają rozwiązanie. Rozwiązanie może nie działać w twoim konkretnym przypadku, ale wyjaśnienie pomoże ci zrozumieć problem i umożliwi samodzielne rozwiązanie problemu.

Musisz także zaufać komunikatowi o błędzie. Jeśli mówi, że liczba tokenów nie jest zgodna z liczbą powiązanych zmiennych, to tak jest . To samo dotyczy nieobecnych tabel lub kolumn. Mając wybór, czy to twój własny błąd, czy komunikat o błędzie jest zły, zawsze trzymaj się tego pierwszego. Ponownie brzmi to protekcjonalnie, ale setki pytań na tej samej stronie dowodzą, że ta rada jest niezwykle przydatna.

Lista rzeczy, których nigdy nie powinieneś robić w związku z raportowaniem błędów

  • Nigdy nie używaj operatora eliminacji błędów ( @)! To sprawia, że ​​programista nie może odczytać komunikatu o błędzie, a tym samym nie może naprawić błędu
  • Nie używaj die()ani echożadnej innej funkcji do bezwarunkowego drukowania komunikatu o błędzie na ekranie. PHP może samodzielnie zgłaszać błędy i robić to we właściwy sposób w zależności od środowiska - więc po prostu zostaw to dla PHP.
  • Nie dodawaj warunku, aby ręcznie przetestować wynik zapytania (np if($result).). Przy włączonych wyjątkach błędów taki stan będzie po prostu bezużyteczny.
  • Nie używaj try..catchoperatora do powtórzenia komunikatu o błędzie. Ten operator powinien być używany do obsługi błędów, takich jak wycofywanie transakcji. Ale nigdy nie używaj go tylko do zgłaszania błędów - jak dowiedzieliśmy się powyżej, PHP może to już zrobić we właściwy sposób.

PS
Czasami nie ma błędu, ale też nie ma wyników. Oznacza to, że w bazie danych nie ma danych odpowiadających Twoim kryteriom . W takim przypadku musisz przyznać się do tego, nawet jeśli możesz przysiąc, że dane i kryteria są prawidłowe. Oni nie są. Musisz je ponownie sprawdzić. Mam artykuł, który może pomóc w tej sprawie, Jak debugować interakcje z bazą danych . Chociaż jest napisane dla PDO, ale zasada jest taka sama. Po prostu postępuj zgodnie z instrukcją krok po kroku i albo rozwiąż swój problem, albo odpowiedz na pytanie dotyczące przepełnienia stosu.

Twój zdrowy rozsądek
źródło
@AdamWinter używając @ jest zawsze błędne, aw tym konkretnym przypadku jest dziesięciokrotne. Komunikaty o błędach wysyłane do programu są tym samym, co ból ciała. Mówi ci, że coś jest nie tak, jak złamana noga. I musisz naprawić nogę, a nie tylko wziąć środek przeciwbólowy i iść dalej. TO SAMO TUTAJ. PHP mówi, że nie ma zmiennej, której się spodziewasz. Musisz więc poprawić formę lub cokolwiek innego, aby ta zmienna była dostępna. Nie wystarczy napisać kod, aby obejść błąd.
Twój zdrowy rozsądek