在之前的博客中,我们实现并完善了Model类的findOne方法,下面我们来实现其中的其他方法。

先来看findAll方法,这个方法和findOne很相似。

    public static function findOne($condition = null)
{
$sql = 'select * from ' . static::tableName();
$params = []; // 判空
if (!empty($condition)) {
$sql .= ' where ';
$params = array_values($condition);
$keys = [];
foreach ($condition as $key => $value) {
array_push($keys, "$key = ?");
}
$sql .= implode(' and ', $keys);
} $stmt = static::getDb()->prepare($sql);
$rs = $stmt->execute($params);
$models = []; if ($rs) {
// 直接获取出所有符合条件的
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if (!empty($row)) {
$model = new static();
foreach ($row as $rowKey => $rowValue) {
$model->$rowKey = $rowValue;
}
array_push($models, $model);
}
}
} return null;
}

你会发现有findOne和findAll方法很相似,明显可以将公共的部分抽出来,然后我们就多了如下两个方法:

    /**
* Build a sql where part
* @param mixed $condition a set of column values
* @return string
*/
public static function buildWhere($condition, $params = null)
{
if (is_null($params)) {
$params = [];
} $where = '';
if (!empty($condition)) {
$where .= ' where ';
$keys = [];
foreach ($condition as $key => $value) {
array_push($keys, "$key = ?");
array_push($params, $value);
}
$where .= implode(' and ', $keys);
}
return [$where, $params];
} /**
* Convert array to model
* @param mixed $row the row data from database
*/
public static function arr2Model($row)
{
$model = new static();
foreach ($row as $rowKey => $rowValue) {
$model->$rowKey = $rowValue;
}
return $model;
}

分别是构建sql中where部分的方法和将查找到的Array转换成Model的方法。大家会奇怪第一个方法中为什么需要params参数和返回值,其实这个为了之后的updateAll方法的使用。其实这个地方跟适合使用引用传值。

这样我们的findOne和findAll就便成了如下内容:

    /**
* Returns a single model instance by a primary key or an array of column values.
*
* ```php
* // find the first customer whose age is 30 and whose status is 1
* $customer = Customer::findOne(['age' => 30, 'status' => 1]);
* ```
*
* @param mixed $condition a set of column values
* @return static|null Model instance matching the condition, or null if nothing matches.
*/
public static function findOne($condition = null)
{
list($where, $params) = static::buildWhere($condition);
$sql = 'select * from ' . static::tableName() . $where; $stmt = static::getDb()->prepare($sql);
$rs = $stmt->execute($params); if ($rs) {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($row)) {
return static::arr2Model($row);
}
} return null;
} /**
* Returns a list of models that match the specified primary key value(s) or a set of column values.
*
* ```php
* // find customers whose age is 30 and whose status is 1
* $customers = Customer::findAll(['age' => 30, 'status' => 1]);
* ```
*
* @param mixed $condition a set of column values
* @return array an array of Model instance, or an empty array if nothing matches.
*/
public static function findAll($condition = null)
{
list($where, $params) = static::buildWhere($condition);
$sql = 'select * from ' . static::tableName() . $where; $stmt = static::getDb()->prepare($sql);
$rs = $stmt->execute($params);
$models = []; if ($rs) {
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if (!empty($row)) {
$model = static::arr2Model($row);
array_push($models, $model);
}
}
} return $models;
}

剩下的updateAll/deleteAll/insert/update和delete方法就不一一详细说明了,直接给出代码。其基本思想都是一致的,都是按照规则拼接SQL语句。

    /**
* Updates models using the provided attribute values and conditions.
* For example, to change the status to be 2 for all customers whose status is 1:
*
* ~~~
* Customer::updateAll(['status' => 1], ['status' => '2']);
* ~~~
*
* @param array $attributes attribute values (name-value pairs) to be saved for the model.
* @param array $condition the condition that matches the models that should get updated.
* An empty condition will match all models.
* @return integer the number of rows updated
*/
public static function updateAll($condition, $attributes)
{
$sql = 'update ' . static::tableName();
$params = []; if (!empty($attributes)) {
$sql .= ' set ';
$params = array_values($attributes);
$keys = [];
foreach ($attributes as $key => $value) {
array_push($keys, "$key = ?");
}
$sql .= implode(' , ', $keys);
} list($where, $params) = static::buildWhere($condition, $params);
$sql .= $where; $stmt = static::getDb()->prepare($sql);
$execResult = $stmt->execute($params);
if ($execResult) {
// 获取更新的行数
$execResult = $stmt->rowCount();
}
return $execResult;
} /**
* Deletes models using the provided conditions.
* WARNING: If you do not specify any condition, this method will delete ALL rows in the table.
*
* For example, to delete all customers whose status is 3:
*
* ~~~
* Customer::deleteAll([status = 3]);
* ~~~
*
* @param array $condition the condition that matches the models that should get deleted.
* An empty condition will match all models.
* @return integer the number of rows deleted
*/
public static function deleteAll($condition)
{
list($where, $params) = static::buildWhere($condition);
$sql = 'delete from ' . static::tableName() . $where; $stmt = static::getDb()->prepare($sql);
$execResult = $stmt->execute($params);
if ($execResult) {
// 获取删除的行数
$execResult = $stmt->rowCount();
}
return $execResult;
} /**
* Inserts the model into the database using the attribute values of this record.
*
* Usage example:
*
* ```php
* $customer = new Customer;
* $customer->name = $name;
* $customer->email = $email;
* $customer->insert();
* ```
*
* @return boolean whether the model is inserted successfully.
*/
public function insert()
{
$sql = 'insert into ' . static::tableName();
$params = [];
$keys = [];
foreach ($this as $key => $value) {
array_push($keys, $key);
array_push($params, $value);
}
// 构建由?组成的数组,其个数与参数相等数相同
$holders = array_fill(0, count($keys), '?');
$sql .= ' (' . implode(' , ', $keys) . ') values ( ' . implode(' , ', $holders) . ')'; $stmt = static::getDb()->prepare($sql);
$execResult = $stmt->execute($params);
// 将一些自增值赋回Model中
$primaryKeys = static::primaryKey();
foreach ($primaryKeys as $name) {
// Get the primary key
$lastId = static::getDb()->lastInsertId($name);
$this->$name = (int) $lastId;
}
return $execResult;
} /**
* Saves the changes to this model into the database.
*
* Usage example:
*
* ```php
* $customer = Customer::findOne(['id' => $id]);
* $customer->name = $name;
* $customer->email = $email;
* $customer->update();
* ```
*
* @return integer|boolean the number of rows affected.
* Note that it is possible that the number of rows affected is 0, even though the
* update execution is successful.
*/
public function update()
{
$primaryKeys = static::primaryKey();
$condition = [];
foreach ($primaryKeys as $name) {
$condition[$name] = isset($this->$name) ? $this->$name : null;
} $attributes = [];
foreach ($this as $key => $value) {
if (!in_array($key, $primaryKeys, true)) {
$attributes[$key] = $value;
}
} return static::updateAll($condition, $attributes) !== false;
} /**
* Deletes the model from the database.
*
* @return integer|boolean the number of rows deleted.
* Note that it is possible that the number of rows deleted is 0, even though the deletion execution is successful.
*/
public function delete()
{
$primaryKeys = static::primaryKey();
$condition = [];
foreach ($primaryKeys as $name) {
$condition[$name] = isset($this->$name) ? $this->$name : null;
} return static::deleteAll($condition) !== false;
}

这样基本的Model就算是暂时完成了,虽然可能还有很多问题和局限,但暂时先这样了,我们之后有机会会一步一步的去完善。

好了,今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。

code:https://github.com/CraryPrimitiveMan/simple-framework/tree/0.7

blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework

构建自己的PHP框架--实现Model类(3)的更多相关文章

  1. 构建自己的PHP框架--实现Model类(1)

    在之前的博客中,我们定义了ORM的接口,以及决定了使用PDO去实现.最后我们提到会有一个Model类实现ModelInterface接口. 现在我们来实现这个接口,如下: <?php names ...

  2. 构建自己的PHP框架--实现Model类(2)

    在上一篇博客中我们简单实现了findOne方法,但我们可以看到,还是有一些问题的,下面我们来修正一下这些问题. 首先是返回的数据中,数字被转换成了字符串.我们需要的是数字啊... PDO中有属性可以支 ...

  3. tp框架之Model类与命名空间

    1.获取系统常量信息 public function shuchu() { var_dump(get_defined_constants()); } 2.跨控制器或跨模块调用 function dia ...

  4. 为测试框架model类自动生成xml结果集

    问题:有大量类似于theProductId这样名字的字符串需要转换成the_product_id这种数据库column名的形式. 思路:见到(见)大写字母(缝)就插入(插)一个“_”字符(针)进去,最 ...

  5. J2EE进阶(七)利用SSH框架根据数据表建立model类

    J2EE进阶(七)利用SSH框架根据数据表建立model类 前言 在利用SSH框架进行项目开发时,若将数据库已经建好,并且数据表之间的依赖关系已经确定,可以利用Hibernate的反转功能进行mode ...

  6. laravel5.1框架model类查询实现

    laravel框架model类查询实现: User::where(['uid'=8])->get(); User类继承自Model类:Illuminate\Database\Eloquent\M ...

  7. yii框架之gii创建数据表相应的model类

    一.首先是在数据库中建立project须要的表: 二.然后,配置相应文件: 在project文件夹下yiiProject\protected\config\main.php.在50行定义了db应用组件 ...

  8. 如何构建Android MVVM 应用框架

    概述 说到Android MVVM,相信大家都会想到Google 2015年推出的DataBinding框架.然而两者的概念是不一样的,不能混为一谈.MVVM是一种架构模式,而DataBinding是 ...

  9. 构建自己的PHP框架--创建组件的机制

    在之前的博客中,我们完成了基本的Model类,但是大家应该还记得,我们创建数据库的pdo实例时,是hard好的配置,并且直接hard在Model类中. 代码如下: public static func ...

随机推荐

  1. HTML5新特性——HTML 5 Canvas vs. SVG

    Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的. SVG SVG 是一种使用 XML 描述 2D 图形的语言. SVG 基于 XML,这意味着 SVG DOM 中的每个 ...

  2. Probe在性能测试中的使用方式简介

    简介: Lambda Probe(以前称为Tomcat Probe)是一款实时监控和管理的Apache Tomcat实例的基本工具. Lambda Probe 是基于 Web + AJAX 的强大的免 ...

  3. HDU--洗衣服

    洗衣服 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  4. jQuery中事件与动画的总结

       1.加载DOM     1.1.window事件 window.onload=function(){}.... 时机:其他资源都加载完毕后,再执行   $(function(){}) ……:只是 ...

  5. ViewPager自动轮播

    Android使用ViewPager实现左右循环滑动及轮播效果   ViewPager是一个常用的android组件,不过通常我们使用ViewPager的时候不能实现左右无限循环滑动,在滑到边界的时候 ...

  6. react-native 环境搭建以及项目创建打包

    参考:http://www.lcode.org/%E5%8F%B2%E4%B8%8A%E6%9C%80%E8%AF%A6%E7%BB%86windows%E7%89%88%E6%9C%AC%E6%90 ...

  7. LINUX 下grep命令查找

    当出现查找文件出现匹配到二进制文件时,大概是因为文件同时含有文本文件与二进制文件,需要加上 grep -a,就可以解决问题.

  8. ABP理论学习之验证DTO

    返回总目录 本篇目录 验证介绍 使用数据注解 自定义验证 标准化 验证介绍 首先应该验证应用的输入.用户或者其它应用都可以向该应用发送输入.在一个web应用中,验证通常要实现两次:在客户端和服务器端. ...

  9. ReactJS入门(二)—— 组件的生命周期

    如果你熟悉avalon,使用过 data-include-rendered 和 data-include-loaded 等回调方法,那么你会很好地理解React组件的各个生命周期. 说白了其实就是Re ...

  10. 移动Web触控事件总结

    移动web风风火火几多年,让我这个在Pc端漂流的前端er不免心生仰慕,的确入行几多年,也该是时候进军移动web了.移动web中踩到的第一个坑就是事件问题,所以在吸取众大神的经验后,特作总结以示后来者. ...