find方法

find方法的使用

1、功能:获取数据表中,满足条件的单条记录。

2、源码位置:/thinkphp/library/think/db/Query.php (1954行 ~ 2041行)

/** * 查找单条记录 * @access public * @param array|string|Query|\Closure $data * @return array|false|\PDOStatement|string|Model * @throws DbException * @throws ModelNotFoundException * @throws DataNotFoundException */ public function find($data = null) { if ($data instanceof Query) { return $data->find(); } elseif ($data instanceof \Closure) { call_user_func_array($data, [ & $this]); $data = null; } // 分析查询表达式 $options = $this->parseExpress(); if (!is_null($data)) { // AR模式分析主键条件 $this->parsePkWhere($data, $options); } $options['limit'] = 1; $result = false; if (empty($options['fetch_sql']) && !empty($options['cache'])) { // 判断查询缓存 $cache = $options['cache']; if (true === $cache['key'] && !is_null($data) && !is_array($data)) { $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; } else { $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); } $result = Cache::get($key); } if (!$result) { // 生成查询SQL $sql = $this->builder()->select($options); // 获取参数绑定 $bind = $this->getBind(); if ($options['fetch_sql']) { // 获取实际执行的SQL语句 return $this->connection->getRealSql($sql, $bind); } // 执行查询 $result = $this->query($sql, $bind, $options['master'], $options['fetch_class']); if ($result instanceof \PDOStatement) { // 返回PDOStatement对象 return $result; } if (isset($cache)) { // 缓存数据 if (isset($cache['tag'])) { Cache::tag($cache['tag'])->set($key, $result, $cache['expire']); } else { Cache::set($key, $result, $cache['expire']); } } } // 数据处理 if (!empty($result[0])) { $data = $result[0]; if (!empty($this->model)) { // 返回模型对象 $model = $this->model; $data = new $model($data); $data->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); // 关联查询 if (!empty($options['relation'])) { $data->relationQuery($options['relation']); } if (!empty($options['with'])) { // 预载入 $data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : ''); } } } elseif (!empty($options['fail'])) { $this->throwNotFound($options); } else { $data = null; } return $data; }

3、参数与返回值:

  • 阅读源码发现:参数支持四种类型:
序号 参数类型 说明
1 数组 首选
2 字符串 灵活、直观,但不够规范
3 对象 用的不多,后面有实例演示
4 闭包 即匿名函数,详情见后观实例
  • 参数最终组成一条用在SQL语句中WHERE的条件表达式,;

  • 返回值:

    序号 参数类型 说明
    1 一维关联数组 与数据表某条记录对应,键名对应字段名,键值对应字段值,最常用
    2 布尔值 查询是否成功?true:成功,faluse:失败
    3 PDO对象 不常用
    4 模型 这在模型课程中,我们再详细讨论

4、适用环境:

  • 根据主键查询,确定只返回一条记录;
  • 如果返回多满足条件的记录,该方法仅返回第一条,一定要注意;

5、调用语法(以:tp5_staff表为例):

  • 通过 Db.php类中的:static _callStatic() 自动实现静态方法调用(了解即可)
  • Query对象调用:find(查询表达式)
序号 参数类型 说明
1 主键 find( '主键' );
2 数组 find( [ '条件' => 表达式 ] );
3 闭包 find( function ($query) { $query = 查询表达式 } )

6、实例:

  • 现在表中的数据如下图:
  1. 选择tp5_staff表,查询id等于1006的数据(参数为主键)
  • find('1006'):
find('1006')); } }
  1. 选择tp5_staff表,查询id等于1006的数据(参数为数组)
  • 将代码中:find( '1006' )换成 :find( [ 'id' => '1006' ] );
find(['id'=>'1006'])); } }
  1. 选择tp5_staff表,查询id等于1006的数据(参数为对象属性)
 id = 1006; //将$query->id做为条件赋给条件变量 $where $where = $query -> id; //根据对象属性设置的条件,查询数据 dump(Db::table('tp5_staff')->find($where)); } }
  1. 选择tp5_staff表,查询id等于1006的数据(参数为闭包)
where(['id'=>1006]); })); } }
  • 闭包函数:

    • 也要匿名函数,顾名思议,该函数没有名称,不能按名调用;
    • 匿名函数以变量为载体,用变量调用;
    • 闭包函数非常适合创建非常复杂的查询条件,请一定要读懂学会;
    • 如果仍觉得理解困难,请再复习一下PHP函数部分知识。
  • 运行结果:

array(7) { ["id"] => int(1006) ["name"] => string(9) "西门庆" ["sex"] => int(0) ["age"] => int(22) ["salary"] => float(19801) ["dept"] => string(9) "市场部" ["hiredate"] => string(10) "2008-12-02" }

7、局限性或注意事项:

  • find方法仅返回第一条满足条件的记录,适合预先知道只会有一条或没有记录时使用;
  • 闭包中的很多条件,可以用在find之前的链式操作中,但推荐全部放在闭包中;
  • 日常开发中,我们更多的使用模型中的get方法获取单条记录。

小作业:

find方法很重要,官方手册写得很简单,建议参照本教程,多练习几遍。