如何从Laravel查询构造器结果中提取自定义查询字段名列表?
从Laravel查询构造器中提取自定义查询的返回字段名
- 单表查询场景下,可以直接通过Schema构造器获取整张表的字段列表,代码如下:
DB::getSchemaBuilder()->getColumnListing('table_name');
- 上述方法仅能获取单表原生字段,无法处理联表查询、原生表达式、字段别名的复杂查询场景,例如下方的自定义查询:
DB::table('users as a') ->leftJoin('userwork AS uk','uk.WORK_ID', '=', 'a.WORK_ID') ->selectRaw("a.name ,uk.work_name as work ,concat('+',uk.work_phone) as phone") ->get();
针对这类查询,需要提取别名后的返回属性名,最终得到格式如下的字段数组:
['name','work','phone'];
实现方案
方案1:从返回结果集提取(适合有返回数据的场景)
如果查询能保证至少返回1条记录,直接读取结果首行的数组键即可拿到字段名:
$query = DB::table('users as a') ->leftJoin('userwork AS uk','uk.WORK_ID', '=', 'a.WORK_ID') ->selectRaw("a.name ,uk.work_name as work ,concat('+',uk.work_phone) as phone"); $result = $query->get(); $fields = $result->isNotEmpty() ? array_keys($result->first()->toArray()) : [];
注意:该方案依赖查询返回结果,若查询条件筛选后无匹配数据,无法获取字段列表。
方案2:解析SQL语句元数据(兼容空结果场景)
不需要依赖查询返回数据,通过PDO语句的列元数据直接读取返回字段名,兼容所有联表、原生表达式、别名场景:
$query = DB::table('users as a') ->leftJoin('userwork AS uk','uk.WORK_ID', '=', 'a.WORK_ID') ->selectRaw("a.name ,uk.work_name as work ,concat('+',uk.work_phone) as phone"); $connection = $query->getConnection(); $pdo = $connection->getPdo(); $stmt = $pdo->prepare($query->toSql()); // 绑定查询参数 foreach ($query->getBindings() as $index => $value) { $paramType = is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR; $stmt->bindValue($index + 1, $value, $paramType); } $stmt->execute(); $fields = []; for ($i = 0; $i < $stmt->columnCount(); $i++) { $meta = $stmt->getColumnMeta($i); $fields[] = $meta['name']; } $stmt->closeCursor();
执行后$fields输出结果就是目标数组['name','work','phone'],无论查询最终有没有匹配到数据都能正常获取。
内容的提问来源于stack exchange,提问作者Seyid Takele
相关产品推荐
相关产品推荐

