12 Stimmen

Aufruf einer Memberfunktion prepare() auf einem Nicht-Objekt PHP-Hilfe

Ich versuche, eine PHP-Funktion zu schreiben. Sie ist sehr einfach. Es ist nur eine vorbereitete Anweisung, die die Datenbank abfragt, aber ich kann das nicht zum Laufen bringen. Ich erhalte immer wieder die Fehlermeldung Call to a member function prepare() on a non-object. hier ist der Code:

$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset){
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
    $stmt->bind_param("ii", $limit, $offset);
    $stmt->execute();
    }
selectInfo();

Jedes Mal, wenn ich die Funktion aufrufe, erhalte ich diesen Fehler. Kann jemand bitte helfen?

44voto

ircmaxell Punkte 159431

Das ist ein Scoping-Fehler. Sie machen $DBH eine globale Variable. Wenn Sie also die Funktion eingeben, ist die globale Variable nicht verfügbar. Sie haben 5 echte Optionen.

1. Verwenden Sie das globale Schlüsselwort

function doSomething() {
    global $DBH;
    //...

Das ist keine gute Idee, da es die Wartung und das Testen zu einer PITA macht. Stellen Sie sich vor, Sie versuchen, diesen Funktionsaufruf zu debuggen. Sie müssen jetzt herausfinden, wo $DBH ist definiert, um herauszufinden, was hier vor sich geht...

2. Machen Sie $DBH ein Parameter für die Funktion

function doSomething(MySQLi $DBH) {

Sie hat den Vorteil, dass sie eindeutig ist. Aber es ist immer noch nicht toll, da der aufrufende Code dann die globale Variable im Auge behalten muss.

3. Erstellen Sie eine Funktion zum "Holen" der $DBH Objekt

function getDBH() {
    static $DBH = null;
    if (is_null($DBH)) {
        $DBH = new mysqli(...);
    }
    return $DBH;
}

function doSomething() {
    $DBH = getDBH();
}

Dies hat den Vorteil, dass das Problem der globalen Variablen vollständig umgangen wird. Aber es ist auch schwer, mehrere Verbindungen zu haben oder einen Teil des Codes für andere Verbindungen wiederzuverwenden.

4. Erstellen Sie eine Klasse für den Datenbankzugriff

class Database {
    public function __construct($host, $user, $pass) {
        $this->DBH = new MySQli($host, $user, $pass);
    }
    public function doSOmething() {
        $this->DBH->foo();
    }
}

Damit ist alles für Sie auf den Punkt gebracht. Der gesamte Datenbankzugriff erfolgt über eine einzige Klasse, so dass Sie sich nicht um den Zugriff auf globale Variablen oder andere Dinge kümmern müssen.

5. Verwendung einer vorgefertigten Klasse/eines vorgefertigten Rahmens

Dies ist die beste Option, da Sie sich nicht selbst darum kümmern müssen.

Datenbankzugriffsklassen:

Vollständige Rahmenwerke:

Die Auswahl ist wirklich endlos. Finden Sie etwas, das Sie mögen, und bleiben Sie dabei. Es wird Ihr Leben wirklich einfacher machen...

6voto

Jim Punkte 22031

$DBH nicht in den Geltungsbereich fällt. Sie wollen entweder definieren $DBH als global in der Funktion:

$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset){
    global $DBH;
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
    $stmt->bind_param("ii", $limit, $offset);
    $stmt->execute();
}

oder, wie ircmaxell in seiner ausgezeichneten Antwort sagte, eine Funktion, die eine statische Instanz von $DBH .

3voto

Versuchen Sie hinzuzufügen global $DBH; in der Funktion, oder fügen Sie sie zu den Parametern der Funktion hinzu.

3voto

Sandeepan Nath Punkte 9441
selectInfo($DBH);

function selectInfo($DBH,$limit, $offset){
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
    $stmt->bind_param("ii", $limit, $offset);
    $stmt->execute();
    }

3voto

Crozin Punkte 42878

Das ist einfach. $DBH existiert nicht innerhalb selectInfo() Funktion. Variablen, die im globalen Bereich definiert sind, sind in der Funktion nicht sichtbar und umgekehrt. Lesen Sie mehr über Umfang der Variablen auf den Handbuchseiten.

Wie kann man das Problem lösen? Übergeben Sie die Variable als Argument der Funktion:

$dbh = new MySQLi(...);

function selectInfo(MySQLi $dbh, $limit, $offset) {
    $stmt = $dbh->prepare(...);
    ...
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X