wake-up-neo.com

Schwerwiegender Fehler: Aufruf einer Memberfunktion bind_param () auf boolean

Ich bin mit einer Funktion beschäftigt, die Einstellungen von 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 vorhandenen 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);
    }
}

Die Variable $this->db wird durch einen Konstruktor übergeben. Im Bedarfsfall ist es 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, 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 beabsichtigt funktioniert ..__ Ich setze die DB-Verbindungssachen in eine Konfigurationsdatei ein:

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

Das Seltsame ist jetzt; Die Tabelle ist vorhanden, die angeforderte Einstellung ist vorhanden, der DB ist vorhanden, aber der Fehler bleibt trotzdem bestehen. Hier ist ein Beweis dafür, dass die Datenbank korrekt ist:

IMG

51
Wesley Peeters

Das Problem liegt in:

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

Die prepare() -Methode kann false zurückgeben, und Sie sollten dies prüfen. Warum gibt es false zurück, vielleicht sind der Tabellenname oder die Spaltennamen (in SELECT oder WHERE-Klausel) nicht korrekt?

Ziehen Sie auch die Verwendung von etwas wie $this->db->conn->error_list in Betracht, um Fehler zu untersuchen, die beim Parsen der SQL aufgetreten sind. (Ich werde gelegentlich die eigentlichen SQL-Anweisungszeichenfolgen wiederholen und in phpMyAdmin einfügen, um sie ebenfalls zu testen, aber da fällt definitiv etwas aus.)

103
RobP

Jedes Mal, wenn Sie die ...

"Schwerwiegender Fehler: Aufruf einer Memberfunktion bind_param () auf Boolean"

... Es liegt wahrscheinlich daran, dass Ihre Anfrage ein Problem enthält. Die prepare() gibt möglicherweise FALSE (ein Boolean) zurück, aber diese generische Fehlernachricht lässt Sie nicht viel als Hinweis. Wie finden Sie heraus, was mit Ihrer Anfrage falsch ist? Sie fragen!

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

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

Wenn Ihre Fehlerberichterstattung in der php.ini festgelegt wurde, müssen Sie sich nicht darum kümmern. Stellen Sie einfach sicher, dass Sie Fehler fehlerfrei behandeln, und geben Sie Ihren Benutzern niemals die wahre Ursache von Problemen an. Wenn Sie der Öffentlichkeit den wahren Grund offenbaren, kann dies eine Einladung mit Goldgravur für diejenigen sein, die Ihre Sites und Server beschädigen möchten. Wenn Sie keine Fehler an den Browser senden möchten, können Sie jederzeit die Fehlerprotokolle Ihres Webservers überwachen. Protokollspeicherorte 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 tail -f /path/to/log in einem Konsolenfenster verwenden, um Fehler anzuzeigen, wenn sie in Echtzeit auftreten .... oder wenn Sie sie erstellen.

Sobald Sie sich mit der Standard-Fehlerberichterstattung auseinandergesetzt haben, erhalten Sie durch das Hinzufügen von Fehlerüberprüfungen für Ihre Datenbankverbindung und Abfragen wesentlich detailliertere Informationen zu den aufgetretenen Problemen. Sehen Sie sich dieses Beispiel an, bei dem der Spaltenname falsch ist. Zuerst den 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 generisch und für Sie bei der Lösung des Vorgangs nicht sehr hilfreich.

Mit ein paar weiteren Codezeilen erhalten Sie sehr detaillierte Informationen, mit denen Sie das Problem sofort lösen können. Überprüfen Sie die prepare()-Anweisung auf Richtigkeit. Wenn dies 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. Die Lösung des Problems ist trivial.

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

19
Jay Blanchard

prepare gibt nur dann einen booleschen Wert zurück, wenn er ausfällt, FALSE. Um den Fehler zu vermeiden, müssen Sie zunächst prüfen, ob es True ist, bevor Sie Folgendes ausführen:

$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);
}
11
meda

Selbst wenn die Abfragesyntax korrekt ist, kann prepare false zurückgeben, wenn es eine vorherige Anweisung gab, die nicht geschlossen wurde

$statement->close();

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

9
Tamas Kalman

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

Ich weiß, dass es offensichtlich klingt, aber ich bin darauf gekommen, indem ich tablename anstelle von Tablename verwende. Überprüfen Sie Ihre Abfragen, und stellen Sie sicher, dass Sie denselben Fall wie die tatsächlichen Namen der Spalten in Ihrer Tabelle verwenden.

1
4ndyG

Sie sollten immer so viel wie möglich versuchen, Ihre Anweisungen immer in einen try-catch-Block zu setzen. In Situationen wie diesen wird dies immer hilfreich sein und Sie wissen lassen, was falsch ist. Möglicherweise ist der Tabellenname oder der Spaltenname falsch. 

0
Sam Banana

Dieser spezielle Fehler hat sehr wenig mit dem tatsächlichen Fehler zu tun. Hier ist meine ähnliche Erfahrung und die Lösung ... Ich hatte eine Tabelle, die ich in meiner Anweisung mit dem Namen "| Datenbankname | .login" verwende. Ich dachte, das wäre kein Problem. Es war in der Tat das Problem. Das Einschließen in eckige Klammern löste mein Problem ("[| Datenbankname |]. [Login]"). Das Problem sind also MySQL-konservierte Wörter (andersherum;)) ... stellen Sie sicher, dass auch Ihre Spalten nicht an dieser Art von Fehler scdenario versagen ...

0
Sam Saarian

Ich habe festgestellt, dass der Fehler dadurch verursacht wurde, dass ich Tabellenfeldnamen als Variablen übergeben habe, d. H. Ich habe gesendet:

$stmt = $this->con->prepare("INSERT INTO tester ($test1, $test2) VALUES (?, ?)");

anstatt von:

$stmt = $this->con->prepare("INSERT INTO tester (test1, test2) VALUES (?, ?)");

Bitte beachten Sie die Tabellenfeldnamen in $ vor Feldnamen. Sie sollten nicht so da sein, dass $field1 sollte sein field1.

Manchmal liegt es auch an einem falsche Tabelle Name oder Spaltennamein der Vorbereitungsanweisung.

Sieh dir das an:

https://www.youtube.com/watch?v=LGHdQ1bBho8

0
Reejesh PK

Folgende zwei sind die wahrscheinlichste Ursache für dieses Problem:

  1. Schreibfehler in Spaltennamen oder Tabellennamen
  2. Die zuvor festgelegte Aussage ist nicht geschlossen. Schließen Sie es einfach, bevor Sie die vorbereitete Aussage treffen.

$stmt->close(); // <<<-----This fixed the issue for me

$stmt = $conn->prepare("Insert statement");
0
Hari Das

Manchmal kann es hilfreich sein, die Tabellenspaltennamen explizit anzugeben (insbesondere in einer Einfügeabfrage). Beispielsweise kann die Abfrage: INSERT INTO tableName(param1,param2,param3) VALUES(?,?,?) besser funktionieren als: INSERT INTO tableName VALUES(?,?,?).

0
ebite Zion