たとえば、簡単なデータセットを使用してみましょう
_+---------+------+------+------------+
| name | age | sex | position |
+---------+------+------+------------+
| Antony | 34 | M | programmer |
| Sally | 30 | F | manager |
| Matthew | 28 | M | designer |
+---------+------+------+------------+
_
取得しようとしているのは、このように配列構成された配列です
_Array
(
[Antony] => Array
(
[age] => 34
[sex] => M
[position] => programmer
)
[Sally] => Array
(
[age] => 30
[sex] => F
[position] => manager
)
[Matthew] => Array
(
[age] => 28
[sex] => M
[position] => designer
)
)
_
おおよその概算として使用できます
_$pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
_
しかし結果として、不要なネストレベルがあります。
_Array
(
[Antony] => Array
(
[0] => Array
(
[age] => 34
[sex] => M
[position] => programmer
)
)
[Sally] => Array
(
[0] => Array
(
[age] => 30
[sex] => F
[position] => manager
)
)
[Matthew] => Array
(
[0] => Array
(
[age] => 28
[sex] => M
[position] => designer
)
)
)
_
コールバック関数を使用して、この不要なネストレベルを取り除こうとしました
_$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC|PDO::FETCH_FUNC, 'current');
_
しかし、いくつかの理由でそれは渡されません
_Array
(
[0] => Array
(
[age] => 34
[sex] => M
[position] => programmer
)
)
_
しかし、スカラーの束_34, 'M', 'programmer'
_をコールバック関数:(
コールバックなどの関数を使用してそれを見ることができます
_function what_do_you_pass_me() {
$numargs = func_num_args();
$arg_list = func_get_args();
for ($i = 0; $i < $numargs; $i++) {
echo "Argument $i is: " . $arg_list[$i] . "\n";
};
echo "\n\n";
};
_
結果をフェッチした後、array_map('current', $result)
を使用せずに_PDO::FETCH_*
_モードを使用して目的の結果セットを取得する方法はありますか?
それはかなり古いトピックですが、私は非常に簡単な解決策を見つけました:
->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE)
最初の列はキーとして設定され、残りは値として設定されます。
配列をウォークスルーしたり、array_mapを使用したりする必要はありません。
不要なネスト配列レベルを減らすには:
$res = $pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
$res = array_map('reset', $res);
鍵連想配列
PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC
受け入れられた回答は、本質的に貨物カルトコードであり、偶然にのみ機能しますが、それ自体では意味がありません。
PDO::FETCH_GROUP
およびPDO::FETCH_UNIQUE
は相互に排他的なフェッチモードであり、一緒に使用することはできません。そのうちの1つだけが機能します。それらを組み合わせると、後者が引き継ぎ、\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE
は実際にはPDO::FETCH_UNIQUE
。
それ以外に、質問はそれ自体で曖昧であり、OPは配列に一意のフィールドによってindexedを付けることを望んでいますが、彼はそれをgrouping回答にも論争を巻き起こしました。
だからそれをまっすぐにするために:
toindex一意の値を持つ配列(一意の場合、結果の配列に従業員の名前でインデックスを付ける場合)、フェッチモードは PDO :: FETCH_UNIQUE :
$pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_UNIQUE);
groupの結果(たとえば、部署ごとに従業員をグループ化する場合)の場合、フェッチモードは PDO ::である必要があります。 FETCH_GROUP :
$pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_GROUP);
どちらの場合も、最初のレベルの配列インデックスとして使用されるフィールドは、SELECTフィールドリストの最初にリストする必要があります。
PDO::FETCH_ASSOC
。優先結果フォーマットのフェッチモードをコンストラクターで一度に設定できる場合、明示的にリストすることも意味がありません。
この回答は古くなっています。代わりに this other answer を参照してください。
fetchAll
の一部としてこれを行う方法はないようです。
あなたの最善の策は、PDOを拡張するクラスを作成し、それにユーティリティメソッドを追加することです。
public function queryKeyedAssoc($query, $params, $key) {
$sth = $this->prepare($query);
$sth->execute($params);
$res = array();
while($row = $sth->fetch(PDO::FETCH_ASSOC))
$res[ $row[$key] ] = $row;
return $res;
}
代わりにステートメントクラスを拡張することで、Charlesのソリューションを少し良くすることができます。
class MyPdo extends PDO {
function __construct($Host, $database_name, $username, $password, $options=array()) {
$options = self::merge(array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_STATEMENT_CLASS => array('PdoPlusStatement', array()),
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
), $options);
$dsn = "mysql:Host=$Host;dbname=$database_name;charset=utf8";
parent::__construct($dsn, $username, $password, $options);
}
}
class PdoPlusStatement extends PDOStatement {
protected function __construct() {}
/**
* @param array|mixed $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed, or one or more non-array arguments to be matched with sequential parameter markers.
* @throws PDOException
* @return PdoPlusStatement
*/
public function execute($input_parameters=null) {
$args = func_get_args();
$argc = func_num_args();
if($argc===0) {
parent::execute();
} else {
if($argc===1 && is_array($args[0])) {
$args = $args[0];
}
parent::execute($args);
}
return $this;
}
/**
* Returns an array containing all of the remaining rows in the result set
* @return array An associative array using the first column as the key, and the remainder as associative values
*/
public function fetchKeyAssoc() {
return array_map('reset', $this->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC));
}
}
使用法:
$users = $pcs->query("SELECT name, user_id, discipline_id FROM wx_user")->fetchKeyAssoc();
なぜ誰も次の解決策を投稿していない理由はわかりませんが、それは私にとっては完璧に機能します:
PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC
したがって、ステートメントを次のように変更します。
$pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
まさにあなたが望むものでなければなりません。