number - PHP PDOStatement: Fetch A Row, como la primera columna como la clave de una matriz
php pdo get rows (5)
Estoy usando PDOStatement
para consultar la base de datos. Cada vez que obtengo una fila devuelta, quiero que se obtenga en una matriz, con la $row[0]
como clave, y los elementos subsiguientes en la fila como valores.
Puedo, por supuesto, escribir una combinación de bucles foreach
y if
condicionales para hacer el trabajo, como el siguiente:
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;
}
pero estoy buscando un método existente; ¿Existe tal método ya existe?
Además del escenario de la tabla de dos columnas, no hay nada a nivel de PDO para manejar esto, pero podría escribir un iterador reutilizable para esto, como este:
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;
}
}
El constructor toma un PDOStatement
y un modo de búsqueda opcional (columnas numéricas de forma predeterminada, pero se puede cambiar a PDO::FETCH_ASSOC
para una matriz asociativa) y le permite iterar sobre los resultados de la consulta usando un foreach
típico.
Ejemplo de uso:
$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;
}
Afaik, no hay un método existente que haga eso en PHP, pero hay un par de formas en que podría lograr lo que quiere.
Uno de los primeros fue lo que Xeoncross dijo, pero un poco modificado:
$pdostmt = $pdo->query("SELECT ... FROM your_table");
$res = array();
foreach ($pdostmt->fetchAll(PDO::FETCH_ASSOC) as $row)
{
$res[array_shift($row)] = $row;
}
De lo contrario, puede crear una clase con un método __set()
para capturar la asignación de variables:
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());
Espero eso ayude.
En algunos consejos, debe pasar el estilo de búsqueda correcto al PDOStatement->fetch() para no terminar con datos dobles (nombres de columna numéricos y de texto). Me gusta $ row [0] y $ row [''id''] que contienen el mismo valor cuando se usa PDO :: FETCH_BOTH.
$result = $dbh->query($sqlString);
while ($row = $result->fetch(PDO::FETCH_NUM)) {
...
En cuanto a su pregunta, tendrá que obtener todos los resultados y luego crear una matriz con $ row [''id''] como la clave y la fila del resultado como el valor, tal como lo está haciendo. Construí una biblioteca ORM completa alrededor de PDO y nunca pude encontrar nada para hacer esto automáticamente.
$result = $dbh->query($sqlString);
$results = array();
while ($row = $result->fetch(PDO::FETCH_NUM)) {
$results[$row[0]] = $row;
}
return $results;
Los créditos van a devdRew. Compruebe la otra pregunta aquí .
Aparentemente, puede hacerlo como se indica en la respuesta. Lo comprobé también y funciona muy bien.
$q = $db->query("SELECT `name` AS name, `value` AS value FROM `settings`;");
$r = $q->fetchAll(PDO::FETCH_KEY_PAIR);
EDITAR
Esta respuesta requiere que especifique un máximo de 2 columnas: 1 clave y 1 valor. Si necesita recuperar más claves de la base de datos, verifique la respuesta a continuación y lea el comentario de @nullabilty
. Para aquellos que son perezosos, aquí está su método:
$q->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE);
aunque sea un poco pirateado, pero en realidad es la única forma de hacerlo, ya que alguien decided FETCH_KEY_PAIR debería requerir solo un conjunto de resultados de 2 columnas.
Nota: la primera columna se usa como clave y no se devuelve en el conjunto de resultados de ninguna otra forma.