在我们的业务代码中操作MySQL查询结果集时,通常使用PDO查询出结果之后都是FETCH_ASSOC关联数组列表,当我们foreach操作结果集时,phpstorm无法代码提示。而且很多情况,这个PDO查询接口都是其他同事封装的方法,直接调用时字段名没提示相当不方便,就不得不去复制mysql的列名到ide中,这个效率低不说,而且很麻烦。由此作者给出一个解决方案
<?php
//以下只是代码示例,无法直接运行
/**
*
* @property int user_id //类成员名必须和mysql的column一致
* @property string nickname
*/
class UserModel {
//类中无需定义任何成员,因为定义了也无法起到作用
//但是可以在注释中添加 @property 标记MySQL表中的column名
//只有添加了 @property标记的colunmn ,代码提示才能显示该列名
//PDO在获取记录之后,将其转换为类对象时,触发该魔术方法赋值,
//此处只是example, 在产品环境中一般需要自己处理。
public function __set($k, $v){
switch($k){
case "user_id":
$this->$k=$v;
break;
case "nickname":
$this->$k = "prefix{$v}";
break;
}
}
}
$pdo = new PDO(...);
$stmt = $pdo->prepare("select * from `user`");
$stmt->execute();
//关键方法
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, UserModel::class);
//常规写法:
$data = $stmt->fetchAll();
foreach($data as $item){
$item->此处代码提示出不来,字段名要手打或者从mysql中复制column名
}
//带代码提示的写法:
/** @var UserModel[] $data */
$data = $stmt->fetchAll();
foreach($data as $item){
$item->代码提示出来了
user_id
nickname
}
//在实际项目中,类属性成员一般都用小驼峰方式命名,用小写下划线风格不统一
function convertCamel($name) {
return lcfirst(str_replace('_','', ucwords($name,"_")));
}
上述方法:
/** @var UserModel[] $data */
$data = $stmt->fetchAll();
在真正的业务代码中往往使用方法封装起来的,所以实现代码提示的关键在于@return注释,示例如下:
<?php
class UserService {
/**
* @return UserModel[]
*/
public funciton getList(){
your code ...
}
/**
* @return UserModel
*/
public function getSingle(){
your code ...
}
}
对于一些老项目,往往mysql字段名又臭又长,而且很难记忆,基本都需要复制的。用这个方法优化一下,会发现代码写起来顺手很多。
总结:核心方法: PDO::setFetchMode,ide注释中加上自定义类型