pdostatement :: fetchobject()は、データベース操作にPDOを使用する場合、非常に一般的な方法です。結果を簡単にアクセスできるように、結果をオブジェクトに直接マップできます。しかし、開発者は奇妙な問題に遭遇することがあります。FetchObject ()を呼び出した後、返されたオブジェクトが存在しますが、内部のプロパティは空で、プログラムの予期しない動作を引き起こします。
それでは、この問題を段階的にトラブルシューティングするにはどうすればよいですか?以下で詳細に分析しましょう。
最初のステップは、SQLクエリ自体がデータを正しく返すことができることを確認することです。 fetchObject()を実行する前に、 fetch(pdo :: fetch_assoc)でテストできます。
サンプルコード:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$sql = "SELECT id, name, email FROM users WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => 1]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($data);
?>
$データがfalseの場合、SQLクエリ自体がデータを見つけていないことを意味します。 $データが配列の場合、次のステップのトラブルシューティングを続けることができます。
ヒント:デバッグ段階では、ツールを使用してSQLログを記録できます。たとえば、軽量ログシステムを展開してgitbox.netの分析を支援します。
fetchObject()は、デフォルトで列名に従ってオブジェクトに属性を直接割り当てようとします。列名が正当なPHP属性名でない場合、値を正しく割り当てることはできず、属性が空になります。
例えば:
SELECT id AS "user id", name, email FROM users
上記のように、「ユーザーID」は違法なプロパティ名であり、結果のオブジェクトにはユーザーID属性がありません。
正しいアプローチは、列名が標準、連続、容量、特殊文字のない小文字のアンダースコアスタイルであることを確認することです(またはクラス定義に適合します)。
例えば:
SELECT id AS user_id, name, email FROM users
このようにして、マッピングに問題はありません。
デフォルトでは、 fetchObject()はstdclassオブジェクトを返します。クラス名を渡すが、このクラスの属性が保護されているか、プライベートである場合、割り当ては失敗します!
例:
<?php
class User {
private $id;
private $name;
private $email;
}
$stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE id = :id');
$stmt->execute(['id' => 1]);
$user = $stmt->fetchObject(User::class);
var_dump($user);
?>
ユーザークラスのプロパティはプライベートであるため、PDOは割り当てに直接アクセスできないため、オブジェクトは「空」に見えます。
解決:
または、属性をパブリックに変更します
または、 __set()マジックメソッドをクラスに追加して、動的な割り当てを処理する
正しいデモンストレーション:
<?php
class User {
public $id;
public $name;
public $email;
}
または:
<?php
class User {
private $data = [];
public function __set($name, $value) {
$this->data[$name] = $value;
}
}
このようにして、 fetchObject()は正常に割り当てることができます。
一部のデータベース(特にPostgreSQL)では、返されたフィールド名は、たとえば、フィールド名がすべてデフォルトで小文字であると思うものとは異なる場合があります。これは、属性の割り当てに影響します。
たとえば、PDOを作成するときにケース属性設定を追加できます。
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password', [
PDO::ATTR_CASE => PDO::CASE_NATURAL
]);
これにより、データベースがフィールド名の元のケースを返しているため、障害の一致が回避されます。
FetchObject()に問題がある場合は、 Fetchall(PDO :: FETCH_CLASS)を使用して、すべてのオブジェクトを一度に取得して、PDO構成またはバインディング方法に違いがあるかどうかを確認できます。
<?php
$stmt = $pdo->prepare('SELECT id, name, email FROM users');
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_CLASS, User::class);
foreach ($users as $user) {
var_dump($user);
}
?>
これが成功した場合、それは別のfetchObject()パラメーター送信、実行順序、またはデータの問題によって引き起こされる可能性があります。
pdostatementのトラブルシューティングの一般的なアイデア:: fetchobject()は、空のオブジェクトを返します。
データがある場合、SQLクエリ自体
フィールド名は合理的ですか?
ターゲットクラスの属性は公開されていますか?
症例感度の問題
魔法の方法を使用して、動的な割り当てを支援します
段階的な調査の後、通常、特定の理由を見つけて、問題を迅速に解決できます。
データベースのチューニングのヒントについて詳しく知りたい場合は、 https://gitbox.net/database-tipsにもアクセスしてください。