Fatale fout: aanroep van een lidfunctie bind_param() op boolean [duplicaat]

Ik ben bezig met een functie die instellingen uit een database haalt, en plotseling kwam ik deze fout tegen:

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

Normaal gesproken zou dit betekenen dat ik dingen selecteer uit niet-bestaande tabellen en zo. Maar in dit geval ben ik niet…

Hier is de functie getSetting:

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);
    }
}

De variabele $this->dbwordt doorgegeven via een constructor. In geval van nood, hier is het:

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

Ook, aangezien ik gebruik maak van een database, is mijn databaseverbinding:

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');
}

Ik heb de verbinding al getest, 100% zeker dat deze werkt zoals bedoeld.
Ik stel de DB-verbindingsdingen in een configuratiebestand in:

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

Nu is het rare; de tabel bestaat, de gevraagde instelling bestaat, de DB bestaat, maar toch gaat die fout niet weg. Hier is enig bewijs dat de DB correct is:

IMG


Antwoord 1, autoriteit 100%

Het probleem ligt in:

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

De prepare()methode kan FALSEretourneren en u moet dat controleren. Wat betreft de reden waarom het FALSEretourneert, zijn de tabelnaam of kolomnamen (in SELECTof WHEREclausule) misschien niet correct?

Overweeg ook het gebruik van iets als $this->db->conn->error_listom fouten te onderzoeken die zijn opgetreden bij het parseren van de SQL. (Ik zal af en toe de daadwerkelijke SQL-statementstrings herhalen en in phpMyAdmin plakken om ook te testen, maar er is zeker iets dat daar niet werkt.)


Antwoord 2, autoriteit 25%

Elke keer dat u de…

“Fatale fout: aanroep van een lidfunctie bind_param() op boolean”

…het is waarschijnlijk omdat er een probleem is met uw vraag. De prepare()retourneert mogelijk FALSE(een Boolean), maar dit algemene foutbericht laat je niet veel achter op het gebied van aanwijzingen. Hoe kom je erachter wat er mis is met je vraag? Je vraagt!

Zorg er allereerst voor dat foutrapportage is ingeschakeld en zichtbaar is: voeg deze twee regels toe aan de bovenkant van uw bestand(en) direct na uw openingstag <?php:

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

Als uw foutrapportage is ingesteld in php.ini, hoeft u zich hier geen zorgen over te maken. Zorg ervoor dat u correct omgaat met fouten en vertel uw gebruikers nooit de ware oorzaak van problemen. Het onthullen van de ware oorzaak aan het publiek kan een in goud gegraveerde uitnodiging zijn voor degenen die uw sites en servers willen schaden. Als u geen fouten naar de browser wilt sturen, kunt u altijd de foutenlogboeken van uw webserver controleren. Loglocaties variëren van server tot server, bijvoorbeeld op Ubuntu bevindt het foutenlogboek zich meestal op /var/log/apache2/error.log. Als je foutenlogboeken in een Linux-omgeving bekijkt, kun je tail -f /path/to/login een consolevenster gebruiken om fouten te zien zoals ze in realtime optreden….of als jij maakt ze.

Als je eenmaal klaar bent met standaard foutrapportage, kun je door het toevoegen van foutcontrole op je databaseverbinding en query’s veel meer details krijgen over de problemen die zich voordoen. Bekijk dit voorbeeld waar de kolomnaam onjuist is. Ten eerste de code die de algemene fatale foutmelding retourneert:

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

De fout is algemeen en niet erg nuttig voor u om op te lossen wat er aan de hand is.

Met nog een paar regels code kun je zeer gedetailleerde informatie krijgen die je kunt gebruiken om het probleem onmiddellijkop te lossen. Controleer de prepare()-instructie op waarheidsgetrouwheid en als deze goed is, kunt u doorgaan met binden en uitvoeren.

$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'
}

Als er iets mis is, kun je een foutmelding uitspugen die je direct naar het probleem brengt. In dit geval is er geen fookolom in de tabel, het oplossen van het probleem is triviaal.

Als je ervoor kiest, kun je deze controle opnemen in een functie of klasse en uitbreiden door de fouten netjes af te handelen zoals eerder vermeld.


Antwoord 3, autoriteit 12%

Zelfs als de query-syntaxis correct is, kan preparefalse retourneren als er een eerdere instructie was en deze niet was gesloten.
Sluit uw vorige verklaring altijd af met

$statement->close();

Als de syntaxis correct is, zal de volgende query ook goed werken.


Antwoord 4, autoriteit 7%

prepareretourneer alleen een boolean wanneer deze mislukt, daarom FALSE, om de fout te voorkomen moet je eerst controleren of deze Trueis voordat je het uitvoert :

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

Antwoord 5, autoriteit 2%

Soms komt het ook door een verkeerde tabelnaam of kolomnaamin de voorbereidingsverklaring.

Zie dit.


Antwoord 6

Een andere situatie die dit probleem kan veroorzaken, is het onjuist casten van uw zoekopdrachten.

Ik weet dat het misschien voor de hand liggend klinkt, maar ik ben dit tegengekomen door tablenamete gebruiken in plaats van tablename. Controleer uw zoekopdrachten en zorg ervoor dat u hetzelfde hoofdlettergebruik gebruikt als de werkelijke namen van de kolommen in uw tabel.


Antwoord 7

Je moet altijd zoveel mogelijk proberen om je uitspraken altijd in een try-catch-blok te plaatsen … het zal altijd helpen in dit soort situaties en je laten weten wat er mis is. Misschien is de tabelnaam of kolomnaam verkeerd.


Antwoord 8

De volgende twee zijn de meest waarschijnlijke oorzaak van dit probleem:

  1. Spelfout in kolomnamen of tabelnaam
  2. Eerder opgestelde verklaring is niet gesloten. Sluit het gewoon voordat u de voorbereide verklaring aflegt.

$stmt->close(); // <<<-----This fixed the issue for me
$stmt = $conn->prepare("Insert statement");

Antwoord 9

Ik merkte dat de fout werd veroorzaakt doordat ik tabelveldnamen als variabelen doorgaf, d.w.z. ik stuurde:

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

in plaats van:

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

Let op dat de tabelveldnamen $voor de veldnamen bevatten. Ze zouden er niet moeten zijn zodat $field1field1zou moeten zijn.


Antwoord 10

Soms kan het helpen om expliciet uw tabelkolomnamen te vermelden (vooral in een invoegquery). Bijvoorbeeld de vraag:

INSERT INTO tableName(param1, param2, param3) VALUES(?, ?, ?)

kan beter werken in tegenstelling tot:

INSERT INTO tableName VALUES(?, ?, ?)

Antwoord 11

Deze specifieke fout heeft weinig te maken met de werkelijke fout. Hier is mijn soortgelijke ervaring en de oplossing…

Ik had een tabel die ik in mijn instructie gebruik met de samengestelde naam |database-name|.login. Ik dacht dat dit geen probleem zou zijn. Het was inderdaad het probleem. Door het tussen vierkante haken te plaatsen, werd mijn probleem opgelost ([|database-name|].[login]). Het probleem is dus dat MySQL-bewaarde woorden (anders om)… zorg ervoor dat ook uw kolommen niet falen in dit type foutscenario…


Antwoord 12

In mijn ervaring was de bind_paramin orde, maar ik had de databasenaam vergist, dus ik veranderde alleen de databasenaam in de verbindingsparameter en het werkte perfect.

Ik had het hoofdpad gedefinieerd om de hoofdmap aan te geven, het pad om de map op te nemen en de basis-URL voor de home-url van de website. Dit wordt gebruikt om ze te bellen waar ze maar nodig zijn.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

one + eight =

Other episodes