Подтвердить что ты не робот

PHP PDOStatement: Fetch A Row, как первый столбец как ключ массива

Я использую 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)
         {
            $result[$row[0]][]=$row[1];  // the simplest case for 2 columns, should add more to handle more columns

         }

         return $result;

}

но я ищу существующий метод; существует ли такой метод?

4b9b3361

Ответ 1

Кредиты идут в devdRew. Проверьте другой вопрос здесь.

По-видимому, вы можете, как указано в ответе. Я тоже проверил, и он отлично работает.

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

EDIT

Для этого ответа требуется указать максимум 2 столбца: 1 ключ и 1 значение. Если вам нужно получить больше ключей из базы данных, проверьте приведенный ниже ответ и прочитайте комментарий @nullabilty. Для тех, кто ленив, вот его метод:

$q->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);

Ответ 2

$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE); 

хотя и немного взломать, но на самом деле это единственный способ сделать это, поскольку кто-то решил. FETCH_KEY_PAIR должен требовать только набор результатов из 2 столбцов.

Примечание: в первом столбце используется ключ и не возвращается в результирующем наборе в любой другой форме.

Ответ 3

Afaik, нет никакого существующего метода, который бы делал это в PHP, но есть несколько способов, которыми вы могли бы достичь того, чего хотите.

Одним из первых является то, что 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());

Надеюсь, что это поможет.

Ответ 4

Некоторые советы, вам нужно передать правильный стиль выборки в метод PDOStatement- > fetch(), чтобы вы не закончили с двойными данными (числовые и текстовые имена столбцов). Подобно $row [0] и $row ['id'], которые оба имеют одинаковое значение при использовании PDO:: FETCH_BOTH.

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

Что касается вашего вопроса, вам нужно будет получить все результаты, а затем создать массив с $row ['id'] в качестве ключа и строки результата в качестве значения - точно так же, как вы это делаете. Я построил всю библиотеку ORM вокруг PDO, и я никогда не мог найти что-либо, чтобы сделать это автоматически.

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

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

return $results;

Ответ 5

Помимо двух сценариев таблицы столбцов, на уровне 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;
}