Bei einer Funktion, die Einstellungen aus einer DB erhält, ist der Fehler aufgetreten [duplicate]

Lesezeit: 8 Minuten

Benutzer-Avatar
Sushihirn

Ich bin mit einer Funktion beschäftigt, die Einstellungen aus einer Datenbank erhält, und plötzlich bin ich auf diesen Fehler gestoßen:

Fatal error: Call to a member function bind_param() on boolean in C:\xampp2\htdocs\application\classes\class.functions.php on line 16

Normalerweise würde das bedeuten, dass ich Sachen aus nicht existierenden Tabellen und Sachen auswähle. Aber in diesem Fall bin ich nicht…

Hier ist die getSetting Funktion:

public function getSetting($setting)
{
    $query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
    $query->bind_param('s', $setting);
    $query->execute();
    $query->bind_result($value, $param);
    $query->store_result();
    if ($query->num_rows() > 0)
    {
        while ($query->fetch()) 
        {
            return $value;
            if ($param === '1')
            {
                $this->tpl->createParameter($setting, $value);
            }
        }
    }
    else
    {
        __('invalid.setting.request', $setting);
    }
}

Das $this->db Variable wird durch einen Konstruktor übergeben. Bei Bedarf hier:

public function __construct($db, $data, $tpl)
{
    $this->db = $db;
    $this->tpl = $tpl;
    $this->data = $data;
    $this->data->setData('global', 'theme', $this->getSetting('theme'));
}

Da ich eine Datenbank verwende, ist meine Datenbankverbindung:

class Database
{
    private $data;

    public function __construct($data)
    {
    $this->data = $data;
    $this->conn = new MySQLi(
      $this->data->getData('database', 'hostname'), 
      $this->data->getData('database', 'username'), 
      $this->data->getData('database', 'password'), 
      $this->data->getData('database', 'database')
    );
    if ($this->conn->errno)
    {
        __('failed.db.connection', $this->conn->errno);
    }
    date_default_timezone_set('Europe/Amsterdam');
}

Ich habe die Verbindung bereits getestet, 100% positiv, dass sie wie vorgesehen funktioniert. Ich stelle die DB-Verbindungsdinge in einer Konfigurationsdatei ein:

'database' => array(
    'hostname' => '127.0.0.1',
    'username' => 'root',
    'password' => ******,
    'database' => 'wscript'
)

Das Seltsame ist jetzt; die Tabelle existiert, die angeforderte Einstellung existiert, die DB existiert, aber dieser Fehler wird trotzdem nicht verschwinden. Hier ist ein Beweis dafür, dass die DB korrekt ist:

IMG

  • Beantwortet das deine Frage? mysqli_fetch_assoc() erwartet Parameter/Aufruf einer Member-Funktion bind_param() Fehler. Wie bekomme ich den eigentlichen MySQL-Fehler und behebe ihn?

    – Dharman

    1. März 2020 um 10:07 Uhr

Benutzer-Avatar
RobP

Das Problem liegt in:

$query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
$query->bind_param('s', $setting);

Das prepare() Methode kann zurückkehren false und das solltest du prüfen. Warum es zurückkehrt falsevielleicht der Tabellenname oder die Spaltennamen (in SELECT oder WHERE Klausel) sind nicht richtig?

Erwägen Sie auch die Verwendung von etwas wie $this->db->conn->error_list um Fehler zu untersuchen, die beim Analysieren der SQL aufgetreten sind. (Ich gebe gelegentlich die eigentlichen SQL-Anweisungszeichenfolgen aus und füge sie zum Testen auch in phpMyAdmin ein, aber da ist definitiv etwas fehlgeschlagen.)

  • Warum schlagen Sie vor anzurufen? $query->error_listwenn die Methode „prepare“ false zurückgibt (und somit $query falsch wäre?), wenn ein Fehler auftritt?

    – Adam

    11. Mai 2016 um 13:01 Uhr

  • @Adam du hast Recht. Berufung $query->error_list macht Sinn, wenn der bind_param oder eine Ausführung fehlschlägt, aber wenn $query falsch ist, dann sollte man anrufen error oder error_list auf der mysql Objekt, dh $this->db->conn->error_list.

    – RobP

    13. Dezember 2016 um 14:53 Uhr


  • Als ich dieses Problem hatte, entfernte ich „(“ aus der SQL-Abfrage. Vorher war „SELECT (user_id, price) FROM operations WHERE user_id = 1. Die korrekte Version ist „SELECT user_id, price FROM … Als ich „()“ entfernte“ Ich bin diesen Fehler losgeworden.

    – Mateusz H.

    15. August 2019 um 14:55 Uhr


  • Der Fehler ist ziemlich irreführend. Im Gegensatz zu anderen Sprachen wird die eigentliche Ursache nicht angegeben. Wenn der Fehler durch die erste Zeile „prepare“ verursacht wird, zeigt der ausgelöste Fehler an, dass „bind_param“ der Grund ist. Qudo!!

    – Sriram Nadiminti

    6. Mai 2021 um 4:08 Uhr

Jedes Mal, wenn Sie die…

“Schwerwiegender Fehler: Aufruf einer Member-Funktion bind_param() auf boolesch”

…es liegt wahrscheinlich daran, dass es ein Problem mit Ihrer Abfrage gibt. Das prepare() könnte zurückkehren FALSE (ein boolescher Wert), aber diese generische Fehlermeldung gibt Ihnen nicht viele Hinweise. Wie finden Sie heraus, was an Ihrer Anfrage falsch ist? Du fragen!

Stellen Sie zunächst sicher, dass die Fehlerberichterstattung aktiviert und sichtbar ist: Fügen Sie diese beiden Zeilen direkt nach dem Öffnen oben in Ihre Datei(en) ein <?php Schild:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Wenn Ihre Fehlerberichterstattung in der php.ini eingestellt wurde, müssen Sie sich darüber keine Gedanken machen. Stellen Sie einfach sicher, dass Sie Fehler ordnungsgemäß behandeln und Ihren Benutzern niemals die wahre Ursache von Problemen offenbaren. Das Aufdecken der wahren Ursache für die Öffentlichkeit kann eine goldgravierte Einladung für diejenigen sein, die Ihren Websites und Servern Schaden zufügen möchten. Wenn Sie keine Fehler an den Browser senden möchten, können Sie jederzeit die Fehlerprotokolle Ihres Webservers überwachen. Die Speicherorte der Protokolle variieren von Server zu Server, z. B. befindet sich das Fehlerprotokoll unter Ubuntu normalerweise unter /var/log/apache2/error.log. Wenn Sie Fehlerprotokolle in einer Linux-Umgebung untersuchen, können Sie verwenden tail -f /path/to/log in einem Konsolenfenster, um Fehler zu sehen, wenn sie in Echtzeit auftreten … oder wenn Sie sie machen.

Sobald Sie sich mit der Standardfehlerberichterstattung vertraut gemacht haben, erhalten Sie durch Hinzufügen von Fehlerprüfungen für Ihre Datenbankverbindung und Abfragen viel mehr Details zu den auftretenden Problemen. Sehen Sie sich dieses Beispiel an, in dem der Spaltenname falsch ist. Zuerst der Code, der die generische schwerwiegende Fehlermeldung zurückgibt:

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();

Der Fehler ist allgemein und für Sie bei der Lösung des Problems nicht sehr hilfreich.

Mit ein paar weiteren Codezeilen erhalten Sie sehr detaillierte Informationen, mit denen Sie das Problem lösen können sofort. Überprüf den prepare() Aussage auf Wahrhaftigkeit und wenn sie gut ist, können Sie mit dem Binden und Ausführen fortfahren.

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    // any additional code you need would go here.
} else {
    $error = $mysqli->errno . ' ' . $mysqli->error;
    echo $error; // 1054 Unknown column 'foo' in 'field list'
}

Wenn etwas nicht stimmt, können Sie eine Fehlermeldung ausspucken, die Sie direkt zum Problem führt. In diesem Fall gibt es keine foo Spalte in der Tabelle, ist die Lösung des Problems trivial.

Wenn Sie möchten, können Sie diese Überprüfung in eine Funktion oder Klasse einbeziehen und sie erweitern, indem Sie die Fehler wie zuvor erwähnt elegant behandeln.

  • Sehr gute Antwort, hauptsächlich für Ratschläge zur Fehlerberichterstattung. Das Programmieren mit deaktivierter Fehlerberichterstattung ist wie Schachspielen mit geschlossenen Augen. Die Leute wissen auch nicht, wie man einen Debugger benutzt (oder dass es ihn überhaupt gibt).

    – David Ferenczy Rogožan

    27. November 2015 um 17:04 Uhr

  • Vielen Dank für diese großartige Arbeit, das ist sehr hilfreich @Jay Blanchard

    – Kerim Yagmurcu

    17. März 2019 um 11:45 Uhr

  • Aber der Fehler war Fatal Error und starb und stoppte das Programm, also kann das Ausschalten der Anzeige von Fehlern keine gute Lösung sein.

    – Nabi KAZ

    19. Juni 2019 um 19:12 Uhr

  • Prüfen Sie auch die Rechte Ihres Benutzers für Ihre Datenbank. Wenn Sie sagen, dass Ihr Benutzer keine Aktualisierungen vornehmen kann, erhalten Sie diesen Fehler, aber die obige (wirklich hervorragende Antwort) erfasst dies möglicherweise nicht.

    – Shaedo

    3. August 2019 um 14:17 Uhr

Auch wenn die Abfragesyntax korrekt ist, vorbereiten könnte false zurückgeben, wenn es eine vorherige Anweisung gab und diese nicht geschlossen wurde. Schließen Sie Ihre vorherige Anweisung immer mit ab

$statement->close();

Wenn die Syntax korrekt ist, wird die folgende Abfrage auch gut ausgeführt.

prepare einen booleschen Wert nur zurückgeben, wenn er daher fehlschlägt FALSEum den Fehler zu vermeiden, müssen Sie überprüfen, ob dies der Fall ist True zuerst vor der Ausführung:

$sql="SELECT value, param FROM ws_settings WHERE name = ?";
if($query = $this->db->conn->prepare($sql)){
    $query->bind_param('s', $setting);
    $query->execute();
    //rest of code here
}else{
   //error !! don't go further
   var_dump($this->db->error);
}

Benutzer-Avatar
Reejesh PK

Manchmal liegt es auch an a falscher Tisch Namen bzw Spaltenname in der Prepare-Anweisung.

Sehen diese.

  • Das war mein Problem, falscher Tabellenname! Ich wünschte, ich hätte diesen Kommentar schon früher hier unten gesehen!

    – Reid Svntn

    9. November 2020 um 19:55 Uhr

Benutzer-Avatar
Cody Grey

Eine andere Situation, die dieses Problem verursachen kann, ist eine falsche Umwandlung in Ihren Abfragen.

Ich weiß, es mag offensichtlich klingen, aber ich bin darauf gestoßen, indem ich verwendet habe tablename anstatt Tablename. Überprüfen Sie Ihre Abfragen und stellen Sie sicher, dass Sie dieselbe Groß-/Kleinschreibung verwenden wie die tatsächlichen Namen der Spalten in Ihrer Tabelle.

  • Das war mein Problem, falscher Tabellenname! Ich wünschte, ich hätte diesen Kommentar schon früher hier unten gesehen!

    – Reid Svntn

    9. November 2020 um 19:55 Uhr

Benutzer-Avatar
Sam Banane

Sie sollten immer so viel wie möglich versuchen, Ihre Anweisungen immer in einen Try-Catch-Block zu packen … das wird in Situationen wie dieser immer helfen und Sie wissen lassen, was falsch ist. Möglicherweise ist der Tabellen- oder Spaltenname falsch.

1012230cookie-checkBei einer Funktion, die Einstellungen aus einer DB erhält, ist der Fehler aufgetreten [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy