2010-12-16 33 views
12

PHP関数を記述しようとしています。それは非常に簡単です。これは、データベースに照会するための準備済みのステートメントですが、これを動作させることはできません。私は、オブジェクト以外のオブジェクトのprepare()メンバ関数にエラーを受け取ります。ここにコードです:メンバー以外の関数prepare()を呼び出すPHPヘルプ

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

私はいつもエラーを取得します。誰かが助けてくれますか?

答えて

43

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

1.

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

グローバルキーワードを使用し、それはメンテナンスとPITAをテストしますので、これは良いアイデアではありません。その関数呼び出しをデバッグしようとしているとします。あなたは今、それが可能であるという利点を持っている$DBHパラメータ関数に

function doSomething(MySQLi $DBH) { 

ください2.

... $DBHは何が起こっているのかを把握しようとするように定義されている場所を探しに行く必要があります明示的。しかし、呼び出し元のコードがグローバル変数を追跡する必要があるので、それはまだ素晴らしいことではありません。

3.

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

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

$DBHオブジェクトがこれは完全にグローバル変数問題を回避得ることの利点を持っている「取得」する関数を作成します。しかし、複数の接続を持つことや、他の接続にコードを再利用することも難しいです。

4.これはあなたのためにすべてをカプセル化し

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

データベースへのアクセスをラップするクラスを作成します。すべてのデータベースへのアクセスは単一のクラスを経由するため、グローバル変数へのアクセスや他の何かについて心配する必要はありません。

5.事前に作成されたクラス/フレームワーク

あなたはそれを自分でやって心配する必要はありませんので、これは、最良の選択肢です。

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

フル・フレームワーク:

  • Zend Framework
  • Lithium Framework
  • Code Igniter
  • (実際にはもっとたくさんありますが、私はそれがすべて一緒に別の質問なので、それ以上をリスト気にするつもりはありません... )

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

幸運!

+1

+1良いオプションセット。 –

+0

それは私のために働かなかった:http://stackoverflow.com/questions/40080426/fatal-error-call-to-a-member-function-prepare-on-a-non-object-in-but-value – fresher

3

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

3
selectInfo($DBH); 

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

$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の静的インスタンスを返す関数を持っている:あなたは、どちらかの機能でグローバルとして$DBHを定義したいです。

+0

ありがとうございました。私はそれをグローバルにして、物事を安全に保つにはどうすればいいでしょうか?関数内の接続をラップし、関数にconnect(){new myqsli( "host"、 "test"、 "123456"、 "dbname")}のような変数を代入するかどうか$ DBH = new connect(); (接続変数は実際に別のファイルに隠されています。) – mcbeav

+0

ええ、私はある種の機能を作り、そこから接続を取得します。 – Jim

+0

@ircmaxell完了。あなたはもちろん正しいのです。すべてのメソッド呼び出しのための新しい接続を作ることは悪い考えです。 – Jim

3

これは簡単です。 $DBHは存在しませんselectInfo()機能の中にあります。グローバルスコープで定義された変数は関数内では表示されず、その逆もありません。マニュアルページのvariables scopeについてもっと読む。

どうすれば解決できますか?その変数を関数の引数として渡します。

$dbh = new MySQLi(...); 

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

接続が成功したことを確認します。

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

$ DBHが世界を作ることは健康的ではありません... ..あなたがあなたの$ DBHはクラスで保護作り、nullに設定することができますことを除いて、それを使用し...

0
class PDOconnect extends PDO{ 

保護$コン=ヌル;

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..."; 
        } 
関連する問題