原文发表于:Phalcon模型入门教程Phalcon提供了四种操作Mysql数据库的方式:模型、PHQL、数据库抽象层和原生SQL。无论哪种方式,都需要先在DI中注册db服务才能正常使用:DIregisterdbservice//文件路径:app/core/services.php$di->setShared('db',function()use($config){$dbconfig=$config->database->db;$dbconfig=$dbconfig->toArray();if(!is_array($dbconfig)||count($dbconfig)==0){thrownew\Exception("数据库配置错误");}$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['字符集']));返回$connection;});数据库连接信息配置如下://文件路径:app/config/system.phpreturnarray(//数据库表配置'database'=>array(//数据库连接信息'db'=>array('host'=>'127.0.0.1','端口'=>3306,'用户名'=>'admin','密码'=>'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){thrownew\Exception("数据库配置错误");}$eventsManager=new\Phalcon\Events\Manager();//分析底层sql性能并记录日志$profiler=newPhalcon\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);返回$connection;});通过代码我们可以看到,日志中不仅记录了底层SQL,还记录了SQL绑定的参数(PDO预处理)和SQL执行时间日志演示如下:SELECT`users`.`uid`AS`uid`,`users`.`mobile`AS`mobile`FROM`users`WHERE`users`.`uid`=:uidLIMIT:APL0{"uid":1,"APL0":1}0.034402132034302大括号({})是SQL预处理时绑定的参数,最后的浮点数是SQL执行时间(秒)。创建模型模型类的命名必须符合驼峰命名法,必须继承自Phalcon\Mvc\Model类://文件路径:app/frontend/models/ArticlesModel.phpclassArticlesextends\Marser\App\Frontend\Models\BaseModel{//\Marser\App\Frontend\Models\BaseModel继承自\Phalcon\Mvc\Model类。//这里是再封装一个基础模型类,方便后续通用方法封装//...}数据库表映射默认Articles模型类对应的数据表名是articles;如果是ArticlesTags模型类,对应的数据库表名是articles_tags,即类名对应表名。如果要映射到其他数据库表,可以使用setSource()方法设置://文件路径:app/frontend/models/ArticlesModel.phpclassArticlesextends\Marser\App\Frontend\Models\BaseModel{publicfunctioninitialize(){$this->setSource("articles_tags");}}在项目开发中,建议一个数据表对应一个模型类。即使是关联表,也强烈建议创建其对应的模型类,因为Phalcon中提供的表连接操作都是基于模型类的(后续教程会分享)。设置表前缀在设计数据库表时,有时会在表名前加一个前缀,比如test_articles。我们仍然可以通过setSource()映射数据表://文件路径:app/frontend/models/ArticlesModel.phpclassArticlesextends\Marser\App\Frontend\Models\BaseModel{publicfunctioninitialize(){$this->setSource(“测试文章”);}}假设我们的项目中有100张数据表,也就是说有100个模型类。此时我们必须在每个模型类中调用setSource()来映射完整的表名。如果哪天我们要修改这100张表的前缀,那我们就得修改这100个模型类,不仅费时费力,还很麻烦。我们尝试把这个过程提取出来进行封装://文件路径:app/frontend/models/ArticlesModel.phpclassArticlesModelextends\Marser\App\Frontend\Models\BaseModel{/***表名*/constTABLE_NAME='articles';publicfunctioninitialize(){parent::initialize();//映射数据表(添加表前缀)$this->set_table_source(self::TABLE_NAME);}}BaseModel模型基类中的set_table_source()方法定义如下://文件路径:app/frontend/models/BaseModel.phpclassBaseModelextends\Phalcon\Mvc\Model{publicfunctioninitialize(){}/***映射数据表(添加表前缀)*@paramstring$tableName*@paramnull$prefix*/protectedfunctionset_table_source($tableName,$prefix=null){//默认从配置中读取表前缀配置empty($prefix)&&$prefix=$this->getDI()->get('config')->database->prefix;//拼接成完整的表名后,通过setSource()映射数据表$this->setSource($prefix.$tableName);}}我们在每个模型类中定义一个类常量,用于存放不带前缀的表名,然后使用set_table_source()成员方法对表前缀进行拼接映射。眼尖的读者应该看到上面数据库连接信息配置中prefix的表前缀配置。还是以上面为例,此时我们不需要修改100个模型类的代码,只需要修改配置文件中的前缀配置即可。以上代码已经托管在github上:https://github.com/KevinJay/m...最后欢迎大家加入QQ群交流讨论:广州PHP高端交流群:158587573Phalcon玩家群:150237524
