Я использую 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; }
но я ищу существующий метод; существует ли такой метод уже существует?
Кредиты идут в 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_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE);
хотя и немного взломать, но на самом деле единственный способ сделать это, так как кто-то решил, что FETCH_KEY_PAIR должен требовать только набор результатов из 2 столбцов.
Примечание: в первом столбце используется ключ и не возвращается в результирующем наборе в любой другой форме.
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());
Надеюсь, поможет.
В некоторых советах вам нужно передать правильный стиль выборки методу 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;
Помимо сценария таблицы с двумя столбцами, на уровне 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
для ассоциативного массива) и позволяет выполнять 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; }