摘要:原文发表于入门教程之模型提供了四种方式操作数据库模型数据库抽象层以及原生。创建模型模型类的命名必须符合驼峰命名法,而且须继承自类文件路径继承自类。
原文发表于:Phalcon入门教程之模型
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 PhalconDbAdapterPdoMysql(array( "host" => $dbconfig["host"], "port" => $dbconfig["port"], "username" => $dbconfig["username"], "password" => $dbconfig["password"], "dbname" => $dbconfig["dbname"], "charset" => $dbconfig["charset"]) ); return $connection; });
数据库连接信息配置如下:
// 文件路径:app/config/system.php return 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 PhalconEventsManager(); // 分析底层sql性能,并记录日志 $profiler = new PhalconDbProfiler(); $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 PhalconLoggerAdapterFile(ROOT_PATH . "/app/cache/logs/{$currentDay}.log"); $logger -> debug("{$sql} {$params} {$executeTime}"); } }); $connection = new PhalconDbAdapterPdoMysql(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执行时间(单位为秒)。
创建模型模型类的命名必须符合驼峰命名法,而且须继承自 PhalconMvcModel 类:
// 文件路径:app/frontend/models/ArticlesModel.php class Articles extends MarserAppFrontendModelsBaseModel { // MarserAppFrontendModelsBaseModel继承自 PhalconMvcModel 类。 // 此处是再次封装一个基础模型类, 以方便后续的通用方法封装 //... }数据库表映射
默认情况下,Articles 模型类对应的数据表名是 articles ;若是 ArticlesTags 模型类,则对应的数据库表名是 articles_tags , 即类名对应着表名。如果想映射到其他数据库表,可以使用 setSource() 方法设置:
// 文件路径:app/frontend/models/ArticlesModel.php class Articles extends MarserAppFrontendModelsBaseModel { public function initialize() { $this->setSource("articles_tags"); } }
在项目开发中,建议一个数据表对应着一个模型类。即使是关联表,也强烈建议创建其对应的模型类,因为 Phalcon 中提供的连表操作,都是基于模型类的(后续的教程会分享)。
设置表前缀在进行数据库表设计的时候,有时会在表名前加上一段前缀,如 test_articles 。我们依然可以通过 setSource() 映射数据表:
// 文件路径:app/frontend/models/ArticlesModel.php class Articles extends MarserAppFrontendModelsBaseModel { public function initialize() { $this->setSource("test_articles"); } }
假设,我们的项目中有100张数据表,那么就意味着有100个模型类。此时我们在每个模型类中都必须调用 setSource() 来映射完整的表名。如果某天我们需要修改这100张表的前缀,那么将要修改这100个模型类,不仅耗时耗力还麻烦。我们尝试着将此处理过程提取出来进行封装:
// 文件路径: app/frontend/models/ArticlesModel.php class ArticlesModel extends MarserAppFrontendModelsBaseModel { /** * 表名 */ const TABLE_NAME = "articles"; public function initialize(){ parent::initialize(); //映射数据表(补上表前缀) $this->set_table_source(self::TABLE_NAME); } }
在 BaseModel 模型基类中的 set_table_source() 方法定义如下:
// 文件路径: app/frontend/models/BaseModel.php class BaseModel extends PhalconMvcModel { 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:https://github.com/KevinJay/m...
最后,欢迎大家加入QQ群交流讨论:
广州PHP高端交流群:158587573
Phalcon玩家群:150237524
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/23021.html
摘要:原文发表于入门教程之目录结构很多初学的朋友,对于以框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。只需要通过注册这些目录结构,即可正常使用。 原文发表于:Phalcon入门教程之目录结构 很多初学Phalcon的朋友,对于以Phalcon框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。比如多模块的项目中,如何共用libs类库和models目录中模型类的情况,就有很...
摘要:异步队列消费者开发只提供了模式下运行控制器方法,并未提供主进程多子进程的进程模型,并未提供多线程处理。多线程异步队列服务只需写好控制器方法,然后在配置文件中配置下路由命名空间进程线程数量,就可在模式中启动多进程多线程模型的异步队列处理程序。 最近业余时间一直在开发ExpressPHP的第二个版本 MixPHP,今天下班想起之前一个面试官的问题:你为什么还要再造一个轮子呢?仔细回想,第一...
摘要:使用模型模型表示应用程序信息数据以及这些数据的处理规则,主要用于管理与对应数据表的交互规则。应用中,是所有模型的基类。创建模型模型需继承类,以大驼峰格式命名。方法在请求期间只调用一次,目的是为该模型的所有实例执行初始化操作。 使用模型(Working with Models) 模型表示应用程序信息(数据)以及这些数据的处理规则,主要用于管理与对应数据表的交互规则。大多数情况下,数据库中...
摘要:本文描述了框架中数据库操作方法,主要讨论框架的组件中的操作方法。属性方法在框架中支持属性的扩展查询,在上例中,可以把条件语句改为同时省略查询条件结果不变。 本文描述了PHP-Phalcon框架中数据库操作方法,主要讨论Phalcon框架的Model组件中的操作方法。更详细的Model介绍请参考:官方文档 1. 连接数据库 在Phalcon框架中,通过在DI中注入db参数来实现数据库的...
摘要:若在云服务器上安装失败或者卡住,可参考此博文云服务器编译安装失败 Phalcon安装 # 下载安装包 wget https://github.com/phalcon/cphalcon/archive/v3.0.1.tar.gz # 重命名 mv v3.0.1.tar.gz cphalcon-3.0.1.tar.gz #解压 tar -zxvf...
阅读 3468·2021-09-02 09:53
阅读 1790·2021-08-26 14:13
阅读 2749·2019-08-30 15:44
阅读 1313·2019-08-30 14:03
阅读 1961·2019-08-26 13:42
阅读 3013·2019-08-26 12:21
阅读 1301·2019-08-26 11:54
阅读 1899·2019-08-26 10:46