komegome_
@komegome_

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

SQL 連想配列に関して

下記のような形で連想配列を変数に格納しようと考えたのですが、エラーが出てしまいます。

$username = $stmt[0]["username"];
$mail = $stmt[0]["mail"];

これは、そもそも下記のように連想配列を変数に格納することができないのでしょうか。それともルールとしては存在するが、他のコードが間違っているためエラーが出てしまうのでしょうか。

また下記のように連想配列を変数に格納できない場合は、理由も併せてご教示いただけると大変助かります。

例)

<?php
header("X-FRAME-OPTIONS: DENY");

define("HOST", "localhost");
define("DB_NAME", "task02");
define("USER", "root");
define("PASS", "root"); // mampの場合はパスワードをrootに変更します
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET 'utf8'"); // 文字化け対策;

$pdo = new PDO("mysql:host=" . HOST . ";dbname=" . DB_NAME, USER, PASS, $options);

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$id = intval($_GET["id"]);

try {
  $sql = "select id, username, mail from users where id = :id";
  $stmt = $pdo->prepare($sql);
  $stmt->bindValue(":id", $id, PDO::PARAM_INT);

  $stmt->execute();
} catch (Exception $e) {

  echo $e->getMessage();
}

//エラーが出てしまうのはこちらになります
$username = $stmt[0]["username"];
$mail = $stmt[0]["mail"];

?>

1

1Answer

エラーメッセージなど、エラーの詳細を記載しましょう。
コードだけで判断するのは難しいので、実行環境やその時の状況など、なるべく細かく説明しましょう。

今回はわかったのでこのまま回答します。

下記のように連想配列を変数に格納することができないのでしょうか

できません。

まず変数$stmtの中身は連想配列ではありません。PDOStatementクラスのオブジェクトです。(DB接続に成功している場合)
prepareメソッドの戻り値を確認してください。

連想配列だと思われているのは、おそらくこのようにforeachでループできるからではないでしょうか?

foreach ($stmt as $key => $row) {
    var_dump($row);
}

このようなことが可能なのはPDOStatementが「foreachで扱えるような仕組み」を提供しているからです。(連想配列そのものではありません)
そして、配列のようにindexでアクセスするような仕組みは提供されていないので、そういった扱いはできないです。

PDOStatementIteratorAggregateインターフェイス(8.0以前はTraversable)を実装しています。これは簡単に言うと「foreachで扱えるようにする」という約束です。

PHP8.0以降
class PDOStatement implements IteratorAggregate {
}

配列として扱いたいのであれば、いったんfetchAllメソッドなどで結果を取得しましょう。

$results = $stmt->fetchAll();
$name = $results[0]['name'];

2Like

Your answer might help someone💌