PDOオブジェクトを取得してプロパティを設定するにはどうすればよいですか? (詳しいコード説明)

藏色散人
リリース: 2023-04-05 15:56:02
オリジナル
2800 人が閲覧しました

他のデータベース拡張機能と同様に、PDO は選択したデータから既存のクラスのインスタンスを直接作成できます。ただし、他の拡張機能とは異なり、PDO は強力かつ柔軟なオブジェクト操作のための多くの機能を提供します。

PDOオブジェクトを取得してプロパティを設定するにはどうすればよいですか? (詳しいコード説明)

#単一オブジェクトの取得

クエリ結果から単一のオブジェクトを作成するには、次の 2 つがあります。方法。

1. 使い慣れた fetch() メソッドを使用します:

class User {};
$stmt = $pdo->query('SELECT name FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
$user = $stmt->fetch();
ログイン後にコピー

2. 専用の fetchObject() メソッド:

class User {};
$user = $pdo->query('SELECT name FROM users LIMIT 1')->fetchObject('User');
ログイン後にコピー

どちらのコード スニペットでも同じ User クラス インスタンスが提供されますが、

/* object(User)#3 (1) {
  ["name"] => string(4) "John"
} */
ログイン後にコピー

後者のアプローチの方が断然すっきりしています。さらに、 fetch() メソッドが使用されているが、そのような名前でクラスが定義されていない場合は、配列がサイレントに返されますが、 fetchObject() を使用すると適切なエラーがスローされます。

オブジェクトの配列の取得

もちろん、上記で説明した両方のメソッドを使い慣れた while ステートメントとともに使用して、データベースから結果を取得することができます。ライン。

便利な

fetchAll() メソッドを使用して、オブジェクト配列内の返されたすべてのレコードを一度に取得します。

class User {};
$users = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_CLASS, 'User');
ログイン後にコピー

は、ユーザー クラス、データフィル属性を返します:

/* array(2) {
  [0]=> object(User)#3 (1) {
    ["name"] => string(4) "John"
  }
  [1]=> object(User)#4 (1) {
    ["name"]=> string(4) "Mike"
  }
} */
ログイン後にコピー

Note、このモードを PDO::FETCH_UNIQUE および PDO::FETCH_GROUP## と組み合わせることができます。 # 、一意のフィールドによってインデックス付けされた結果の配列を取得するか、一意でないフィールドを使用して結果を個別にグループ化します。 たとえば、以下のコードは、レコード ID が連続番号ではなく配列インデックスとして使用される配列を返します。

class User {};
$stmt  = $pdo->query('SELECT id, id, name, car FROM users');
$users = ->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_UNIQUE, 'User');
ログイン後にコピー

クラス属性の割り当てどのメソッドが選択されているかに関係なく、クエリによって返されるすべての列は、次に従って対応するクラス属性に割り当てられます。次のルールに従う:

1。列名と同じ名前のクラス属性がある場合、列の値は属性

2 に割り当てられます。このような属性の場合、マジックは Method __set()

3 と呼ばれます。__set() メソッドがクラスに定義されていない場合は、パブリック プロパティが作成され、列の値が割り当てられます。

たとえば、次のコード

class User
{
    public $name;
}
$user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
ログイン後にコピー

は、クラスに存在するかどうかに関係なく、すべてのプロパティが自動的に割り当てられたオブジェクトを提供します。

/* object(User)#3 (4) {
  ["id"]   => string(3) "104"
  ["name"] => string(4) "John"
  ["sex"]  => string(4) "male"
  ["car"]  => string(6) "Toyota"
} */
ログイン後にコピー

これからわか​​るように、 、属性が自動的に作成されないようにするには、マジック メソッド __set() を使用して属性をフィルターで除外します。最も単純なフィルタリング手法は、空の __set() メソッドです。これを使用すると、既存のプロパティのみが設定されます:

class User
{
    private $name;
    public function __set($name, $value) {}
}
$user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
/*
array(1) {
  [0]=> object(User)#3 (1) {
    ["name":"User":private]=> string(4) "John"
  }
} */
ログイン後にコピー

上記のように、PDO はプライベート プロパティに値を割り当てることもできます。

コンストラクター パラメーターをオブジェクトに渡すもちろん、新しく作成されたオブジェクトの場合は、コンストラクター パラメーターを提供する必要がある場合があります。この目的のために、

fetchObject()

メソッドと fetchAll() メソッドには、コンストラクター パラメーターを配列の形式で渡すために使用できる専用のパラメーターがあります。 クラス User があるとします。このクラスには、変数を指定することでコンストラクターに設定できる car 属性があります。

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}
ログイン後にコピー

レコードを取得するときは、次の配列を含むコンストラクターを追加する必要があります。パラメータ:

$users = $pdo->query('SELECT name FROM users LIMIT 1')
             ->fetchAll(PDO::FETCH_CLASS, 'User', ['Caterpillar']);

$user = $pdo->query('SELECT name FROM users LIMIT 1')
            ->fetchObject('User',['Caterpillar']);
ログイン後にコピー
/* object(User)#3 (2) {
    ["name"] => string(4) "John"
    ["car"]  => string(11) "Caterpillar"
} */
ログイン後にコピー

ご覧のとおり、デフォルトでは PDO はコンストラクターを呼び出す前にクラス プロパティを割り当てるため、データベース内の値は上書きされます。これは問題になる可能性がありますが、修正するのは簡単です。

#コンストラクターを呼び出した後のクラス プロパティの設定

mysql_fetch_object()

注意:mysql_fetch_object を使用してクラスを指定する場合、コンストラクターが実行される前にプロパティが設定されます。これは通常は問題ありませんが、プロパティが

__set()

マジック メソッドを介して設定されている場合は、コンストラクター ロジックを最初に実行する必要があります。そうしないと、重大な問題が発生する可能性があります。 残念ながら、mysql は mysqli 拡張機能ですが、PDO を使用します。それでは、コンストラクターの実行後に PDO にプロパティを割り当てるように指示する方法はありますか。この目的のために、PDO::FETCH_PROPS_LATE 定数を使用する必要があります。

fetchAll() の使用は非常に簡単です。

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}
$stmt  = $pdo->query('SELECT name, car FROM users LIMIT 1');
$users = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);
ログイン後にコピー

単一行をフェッチするときは、setFetchMode() と fetchObject() を同時に呼び出す必要があり、少し不便かもしれません。 。

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}
$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User');
$user = $stmt->fetchObject('User', ['Caterpillar']);
/*
object(User)#3 (2) {
  ["car"]  => string(6) "Toyota"
  ["name"] => string(4) "John"
} */
ログイン後にコピー

上記のコードは、クラス名を 2 回記述する必要があるため効率的ではありません。

代わりに、 fetch():

$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);
$user = $stmt->fetch();
ログイン後にコピー

を使用することもできます。ただし、上で述べたように、クラスがたまたま未定義の場合、エラー メッセージの処理には役立ちません。

データベースからクラス名を取得します さらに興味深いフラグもあります。これは、PDO に次の値からクラスを取得するように指示します。最初の列名。このフラグを使用すると、setFetchMode() と fetch() の使用を回避できます。

$data = $pdo->query("SELECT 'User', name FROM users")
            ->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
/*
object(User)#3 (1) {
  ["name"]=> string(4) "John"
} */
ログイン後にコピー

さらに、このモードは、異なるクラスのオブジェクトを同じクエリから作成できる場合に便利です

class Male {};
class Female {};
$stmt = $pdo->query('SELECT sex, name FROM users');
$users = $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
/*
array(6) {
  [0]=> object(Male)#3 (1) {
    ["name"]=> string(4) "John"
  }
  [1]=> object(Male)#4 (1) {
    ["name"]=> string(4) "Mike"
  }
  [2]=> object(Female)#5 (1) {
    ["name"]=> string(4) "Mary"
  }
  [3]=> object(Female)#6 (1) {
    ["name"]=> string(5) "Kathy"
  }
}*/
ログイン後にコピー

ただし、 , このパターンを使用する場合、クラス コンストラクターでパラメーターを渡すことは不可能のようです。

#既存のオブジェクトを更新

#

除了创建新对象,PDO还可以更新现有对象。只使用setFetchMode(),它将现有变量作为参数。显然,使用fetchAll()是无用的。

class User
{
    public $name;
    public $state;

    public function __construct()
    {
        $this->name = NULL;
    }
}
$user = new User;
$user->state = "up'n'running";
var_dump($user);

$stmt = $pdo->query('SELECT name FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_INTO, $user);
$data = $stmt->fetch();
var_dump($data, $user);
/*
object(Foo)#2 (2) {
  ["name"]  => NULL
  ["state"] => string(12) "up'n'running"
}
object(Foo)#2 (2) {
  ["name"]  => string(4) "John"
  ["state"] => string(12) "up'n'running"
}
object(Foo)#2 (2) {
  ["name"]  => string(4) "John"
  ["state"] => string(12) "up'n'running"
} */
ログイン後にコピー

如上,fetch()调用返回的是相同的对象,这在我看来是多余的。还要注意,与PDO::FETCH_CLASS不同,这种模式不分配私有属性。

以上がPDOオブジェクトを取得してプロパティを設定するにはどうすればよいですか? (詳しいコード説明)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート