27

PDOStatementデータベースのクエリに使用しています。$row[0]返された行を取得するたびに、 をキーとして配列にフェッチし、行の後続の要素を値として取得したいと考えています。

foreachもちろん、以下のように、ループと条件の組み合わせを記述ifしてジョブを実行することもできます。

private static function GetMySQLResult($dbname, $sqlString) {
    
    $dbh = self::ConstructPDOObject($dbname);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $result=array();
    foreach ($dbh->query($sqlString) as $row) {
        // the simplest case for 2 columns, 
        // should add more to handle more columns
        $result[$row[0]][]=$row[1];
    }
    
    return $result;   
}

しかし、私は既存の方法を探しています。そのような方法はすでに存在しますか?

なぜ質問を再開したのですか。

ここで問われているのは、明らかに PDO::FETCH_GROUP|PDO::FETCH_ASSOC の組み合わせです。PDO::FETCH_KEY_PAIR は、2 列の結果でのみ機能します。ただし、ここでの例は、すべての状況ではなく、問題のコードを単純化するためだけの 2 列の結果です。

4

5 に答える 5

36

クレジットは devdRew に送られます。ここで他の質問を確認してください

どうやら、答えに記載されているようにできます。私もチェックしましたが、うまくいきます。

$q = $db->query("SELECT `name` AS name, `value` AS value FROM `settings`;");
$r  = $q->fetchAll(PDO::FETCH_KEY_PAIR);

編集

この回答では、最大 2 つの列 (1 つのキーと 1 つの値) を指定する必要があります。データベースからさらにキーを取得する必要がある場合は、以下の回答を確認し、@nullabiltyのコメントを読んでください。怠惰な人のために、彼の方法は次のとおりです。

$q->fetchAll(PDO::FETCH_UNIQUE);
于 2012-08-19T13:44:23.293 に答える
3

ご存知のように、PHP でそれを行う既存のメソッドはありませんが、目的を達成する方法がいくつかあります。

最初の 1 つは、Xeoncross が言ったことですが、少し変更されています。

$pdostmt = $pdo->query("SELECT ... FROM your_table");

$res = array();

foreach ($pdostmt->fetchAll(PDO::FETCH_ASSOC) as $row)
{
    $res[array_shift($row)] = $row;
}

__set()それ以外の場合は、変数の割り当てをキャッチするメソッドを使用してクラスを作成できます。

class at_res
{
  public $key;
  public $values = array();
  protected $flag = true;

  public function __set($var, $value)
  {
    if ($this->flag)
    {
      $this->key = $value;
      $this->flag = false;
    }
    else
    {
      $this->values[$var] = $value;
    }
  }

  public function extract()
  {
    return array($this->key => $this->values);
  }
}


$pdo = new PDO(...);

$pdostmt = $pdo->query("SELECT ... FROM your_table");

$res = $pdostmt->fetchObject('at_res');

var_dump($res->extract());

それが役に立てば幸い。

于 2012-08-24T15:22:50.893 に答える
2

いくつかのヒントとして、正しいフェッチ スタイルをPDOStatement->fetch()メソッドに渡して、二重データ (数値とテキストの列名) にならないようにする必要があります。$row[0] と $row['id'] のように、PDO::FETCH_BOTH を使用すると、両方とも同じ値が含まれます。

$result = $dbh->query($sqlString);
while ($row = $result->fetch(PDO::FETCH_NUM)) {
...

あなたの質問に関しては、すべての結果をフェッチしてから、 $row['id'] をキーとして、結果行を値として配列を作成する必要があります-あなたがしているように。PDO を中心に ORM ライブラリ全体を構築しましたが、これを自動的に行うものを見つけることができませんでした。

$result = $dbh->query($sqlString);

$results = array();
while ($row = $result->fetch(PDO::FETCH_NUM)) {
    $results[$row[0]] = $row;
}

return $results;
于 2009-09-08T16:41:44.507 に答える
1

2 列のテーブルのシナリオ以外に、PDO レベルでこれを処理するものは何もありませんが、次のように再利用可能な反復子を作成できます。

class FirstColumnKeyIterator implements Iterator
{
    private $stmt;
    private $key;
    private $data;
    private $mode;

    public function __construct(PDOStatement $stmt, $fetch_mode = PDO::FETCH_NUM)
    {
        $this->stmt = $stmt;
        $this->mode = $fetch_mode;
        $this->fetch();
    }

    private function fetch()
    {
        if (false !== ($this->data = $this->stmt->fetch($this->mode))) {
            $this->key = current(array_splice($this->data, 0, 1));
        }
    }

    public function rewind()
    {
        // nil operation
    }

    public function key()
    {
        return $this->key;
    }

    public function current()
    {
        return $this->data;
    }

    public function next()
    {
        $this->fetch();
    }

    public function valid()
    {
        return false !== $this->data;
    }
}

コンストラクターはPDOStatement、オプションのフェッチ モード (デフォルトでは数値列ですがPDO::FETCH_ASSOC、連想配列に変更できます) を取り、通常の を使用してクエリ結果を反復処理できますforeach

使用例:

$dbh = new PDO(/* etc */);

$stmt = $dbh->query('SELECT * FROM accounts');
foreach (new FirstColumnKeyIterator($stmt, PDO::FETCH_ASSOC) as $key => $value) {
        echo $key, ' = ', print_r($value, true), PHP_EOL;
}
于 2012-08-23T14:08:40.980 に答える