博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Phalcon入门教程之模型
阅读量:7044 次
发布时间:2019-06-28

本文共 5292 字,大约阅读时间需要 17 分钟。

原文发表于:

Phalcon 提供了四种方式操作Mysql数据库:模型、PHQL、数据库抽象层以及原生SQL。不论何种方式,首先都需要在DI中注册 db 服务才能正常使用:

DI注册db服务

//  文件路径:app/core/services.php$di -> setShared('db', function () use($config) {    $dbconfig = $config -> database -> db;    $dbconfig = $dbconfig -> toArray();    if (!is_array($dbconfig) || count($dbconfig)==0) {        throw new \Exception("the database config is error");    }    $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array(        "host" => $dbconfig['host'], "port" => $dbconfig['port'],        "username" => $dbconfig['username'],        "password" => $dbconfig['password'],        "dbname" => $dbconfig['dbname'],        "charset" => $dbconfig['charset'])    );    return $connection;});

数据库连接信息配置如下:

// 文件路径:app/config/system.phpreturn array(    //数据库表配置    'database' => array(        //数据库连接信息        'db' => array(            'host' => '127.0.0.1',            'port' => 3306,            'username' => 'admin',            'password' => 'admin',            'dbname' => 'test',            'charset' => 'utf8',        ),        //表前缀        'prefix' => 'test_',    ),);

记录底层SQL语句

在我们开发过程中,有时候需要通过SQL语句来分析定位问题。那么,我们需要将ORM生成的底层SQL记录到日志中。修改DI中注册的 db 服务如下:

//文件路径:app/core/services.php$di -> setShared('db', function () use($config) {    $dbconfig = $config -> database -> db;    $dbconfig = $dbconfig -> toArray();    if (!is_array($dbconfig) || count($dbconfig)==0) {        throw new \Exception("the database config is error");    }    $eventsManager = new \Phalcon\Events\Manager();    // 分析底层sql性能,并记录日志    $profiler = new Phalcon\Db\Profiler();    $eventsManager -> attach('db', function ($event, $connection) use ($profiler) {        if($event -> getType() == 'beforeQuery'){            //在sql发送到数据库前启动分析            $profiler -> startProfile($connection -> getSQLStatement());        }        if($event -> getType() == 'afterQuery'){            //在sql执行完毕后停止分析            $profiler -> stopProfile();            //获取分析结果            $profile = $profiler -> getLastProfile();            $sql = $profile->getSQLStatement();            $params = $connection->getSqlVariables();            (is_array($params) && count($params)) && $params = json_encode($params);            $executeTime = $profile->getTotalElapsedSeconds();            //日志记录            $currentDay = date('Ymd');            $logger = new \Phalcon\Logger\Adapter\File(ROOT_PATH . "/app/cache/logs/{$currentDay}.log");            $logger -> debug("{$sql} {$params} {$executeTime}");        }    });    $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array(        "host" => $dbconfig['host'], "port" => $dbconfig['port'],        "username" => $dbconfig['username'],        "password" => $dbconfig['password'],        "dbname" => $dbconfig['dbname'],        "charset" => $dbconfig['charset'])    );    /* 注册监听事件 */    $connection->setEventsManager($eventsManager);    return $connection;});

通过代码可以看到,不仅是底层SQL,还将SQL绑定的参数(PDO预处理)和SQL执行时间也记录到日志中了。日志记录demo如下:

SELECT `users`.`uid` AS `uid`, `users`.`mobile` AS `mobile` FROM `users` WHERE `users`.`uid` = :uid LIMIT :APL0 {"uid":1,"APL0":1} 0.034402132034302

花括号({})中的就是SQL预处理时绑定的参数,最后的浮点数就是SQL执行时间(单位为秒)。

创建模型

模型类的命名必须符合驼峰命名法,而且须继承自 Phalcon\Mvc\Model 类:

// 文件路径:app/frontend/models/ArticlesModel.phpclass Articles extends \Marser\App\Frontend\Models\BaseModel {    // \Marser\App\Frontend\Models\BaseModel继承自 \Phalcon\Mvc\Model 类。    // 此处是再次封装一个基础模型类,  以方便后续的通用方法封装    //...}

数据库表映射

默认情况下,Articles 模型类对应的数据表名是 articles ;若是 ArticlesTags 模型类,则对应的数据库表名是 articles_tags , 即类名对应着表名。如果想映射到其他数据库表,可以使用 setSource() 方法设置:

// 文件路径:app/frontend/models/ArticlesModel.phpclass Articles extends \Marser\App\Frontend\Models\BaseModel {  public function initialize()    {        $this->setSource("articles_tags");    }}

在项目开发中,建议一个数据表对应着一个模型类。即使是关联表,也强烈建议创建其对应的模型类,因为 Phalcon 中提供的连表操作,都是基于模型类的(后续的教程会分享)。

设置表前缀

在进行数据库表设计的时候,有时会在表名前加上一段前缀,如 test_articles 。我们依然可以通过 setSource() 映射数据表:

// 文件路径:app/frontend/models/ArticlesModel.phpclass Articles extends \Marser\App\Frontend\Models\BaseModel {  public function initialize()    {        $this->setSource("test_articles");    }}

假设,我们的项目中有100张数据表,那么就意味着有100个模型类。此时我们在每个模型类中都必须调用 setSource() 来映射完整的表名。如果某天我们需要修改这100张表的前缀,那么将要修改这100个模型类,不仅耗时耗力还麻烦。我们尝试着将此处理过程提取出来进行封装:

// 文件路径: app/frontend/models/ArticlesModel.phpclass ArticlesModel extends \Marser\App\Frontend\Models\BaseModel {    /**     * 表名     */    const TABLE_NAME = 'articles';    public function initialize(){        parent::initialize();        //映射数据表(补上表前缀)        $this->set_table_source(self::TABLE_NAME);    }}

BaseModel 模型基类中的 set_table_source() 方法定义如下:

// 文件路径: app/frontend/models/BaseModel.phpclass BaseModel extends \Phalcon\Mvc\Model {    public function initialize(){    }    /**     * 映射数据表(补上表前缀)     * @param string $tableName     * @param null $prefix     */    protected function set_table_source($tableName, $prefix = null){        //默认从配置中读取表前缀配置        empty($prefix) && $prefix = $this->getDI()->get('config')->database->prefix;        //拼接成完整表名之后,再通过setSource()映射数据表        $this->setSource($prefix . $tableName);    }}

我们在每个模型类中定义一个 类常量 来存储无前缀的表名,再通过 set_table_source() 成员方法来拼接表前缀并映射。眼尖的读者,应该在上面的数据库连接信息配置中有看到 prefix 的表前缀配置。

还是以上面为例,此时我们就不需要修改100个模型类的代码,而只需修改配置文件中的 prefix 配置即可。

以上代码已托管在github:

最后,欢迎大家加入QQ群交流讨论:

  • 广州PHP高端交流群:158587573
  • Phalcon玩家群:150237524

转载地址:http://zseal.baihongyu.com/

你可能感兴趣的文章
文档对象模型DOM
查看>>
2019北京国际康复及个人健康博览会将在中国国际展览中心举办
查看>>
JVM——类加载机制(一)
查看>>
超清晰的 DNS 原理入门指南 (资源)
查看>>
大神笔记
查看>>
spring cloud构建java b2b2c 电子商务云商平台
查看>>
阿里在使用一种更灵活的软件集成发布模式
查看>>
阿里顶级Java架构师,教你这样手写Spring!
查看>>
android课程表控件、悬浮窗、Todo应用、MVP框架、Kotlin完整项目源码
查看>>
比特币现金的未来取决于采用而非投资
查看>>
Kafka从入门到进阶
查看>>
传统IDC部署网站(二)
查看>>
刨根问底-struts和ognl密切分析
查看>>
Mybatis 源码学习
查看>>
树莓派拍照工具raspistill
查看>>
URL加随机数的作用
查看>>
CLOB字段在java中操作
查看>>
磁盘清理
查看>>
javascript 判断数据类型 判空
查看>>
matplotlib 中文字体问题
查看>>