web-dev-qa-db-ja.com

非オブジェクトでのメンバー関数prepare()の呼び出しPHPヘルプ

PHP関数を書き込もうとしています。これは非常に単純です。データベースにクエリを実行するプリペアドステートメントですが、これを機能させることができません。次のエラーを受け取り続けます。非オブジェクトのメンバー関数prepare()。コードは次のとおりです。

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

関数を呼び出すたびに、そのエラーが発生します。誰か助けてもらえますか?

12
mcbeav

これはスコープエラーです。 $DBHをグローバル変数にしています。したがって、関数を入力すると、グローバル変数は使用できなくなります。 5つのリアルオプションがあります。

1。グローバルキーワードを使用する

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

これは、PITAの保守とテストを行うため、お勧めできません。その関数呼び出しをデバッグしようとしていると想像してみてください。何が起こっているのかを理解するために、$DBHがどこで定義されているかを調べる必要があります...

2。 $DBHを関数のパラメーターにします

function doSomething(MySQLi $DBH) {

明示的であるという利点があります。ただし、呼び出し元のコードはグローバル変数を追跡する必要があるため、それでも問題はありません。

3。 $DBHオブジェクトを「取得」する関数を作成します

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

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

これには、グローバル変数の問題を完全に回避できるという利点があります。ただし、複数の接続を確立したり、コードを他の接続に再利用したりすることも困難です。

4。データベースアクセスをラップするクラスを作成します

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

これにより、すべてがカプセル化されます。すべてのデータベースアクセスは単一のクラスを経由するため、グローバル変数アクセスなどについて心配する必要はありません。

5。事前に構築されたクラス/フレームワークを使用する

自分で行うことを心配する必要がないため、これが最良のオプションです。

データベースアクセスクラス:

完全なフレームワーク:

本当に、選択肢は無限大です。あなたが好きなものを見つけて、それに固執してください。それは本当にあなたの人生を楽にするでしょう...

幸運を!

43
ircmaxell

$DBHはスコープ内にありません。関数で$DBHをグローバルとして定義する必要があります。

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

または、ircmaxellが彼の優れた回答で指摘したように、$DBHの静的インスタンスを返す関数があります。

7
Jim

関数にglobal $DBH;を追加するか、関数のパラメーターに追加してみてください。

selectInfo($DBH);

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

それは簡単です。 _$DBH_はselectInfo()関数内に存在しません。グローバルスコープで定義された変数は関数内に表示されません。その逆も同様です。 変数スコープ の詳細については、マニュアルページを参照してください。

それを解決する方法は?その変数を関数の引数として渡します。

_$dbh = new MySQLi(...);

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

接続が成功していることを確認してください。

$DBH = @new mysqli("Host", "test", "123456", "dbname");

if ($DBH->connect_errno) {
    die('Connect Error: ' . $DBH->connect_errno);
}

または

$DBH = @mysqli_connect("Host", "test", "123456", "dbname");

if (!$DBH ) {
    die('Connect Error: ' . mysqli_connect_errno());
}
3
madkris24

$ DBHをグローバルにすることは健全ではありません... $ DBHをクラスで保護し、nullに設定して使用できることを除いて。

0
Nami Hamiroo
class PDOconnect extends PDO{

保護された$ con = null;

    public function __construct(){
              try {      

                     $this->con= new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); //our new PDO Object

                      $this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );                       
                      $this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );                     
                      $this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
                      echo "hi.. you are connected succcessfully...";
                  }
0
Nami Hamiroo