帮助你开始使用 phalcon 的简易指南。

简介

Phalcon 2将于2015年4月17日发布,这个版本大约85%的代码是基于 Zephir 语言重写的。Zephir是开源的,使用类似PHP语法的语言,生成C语言代码,并编译成PHP扩展。这提高了PHP扩展的开发效率,并降低了框架的后期维护成本。

phalcon-devtools

安装 https://github.com/phalcon/phalcon-devtools 之后可以帮助自动生成目录结构和代码。同时把ide目录下的相应版本加入IDE的External libraries之后,可以帮助IDE自动完成代码。

nginx配置

配置nginx的时候,建议用$_SERVER[‘REQUEST_URI’]方式,这样可以防止自动加入$_GET[‘_url’]的隐规则,在参数签名时,如果你忘记这个隐规则会导至签名验证失败。

参考配置:

server {

listen 80;

server_name www.example.com;

index index.html index.htm index.php;

root $root_path/example/public;

location / {

try_files $uri $uri/ /index.php$is_args$args;

}

location ~ \.php$ {

try_files $uri =404;

fastcgi_split_path_info ^(.+\.php)(/.+)$;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include fastcgi_params;

}

}

这样设置后,代码也要参考URI Sources调整

$router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI);

代码结构

phalcon框架对代码结构并没有约定,你可以按自己的实际需要自行组织代码结构,这里有一个供参考的例子:https://github.com/phalcon/mvc。

实际项目中,代码分层至少要分三层,controller/view -> services -> models

services和models为了重用,可以参考composer的组织方式,放到vendor。

使用PSR-4规范的namespace自动加载。

处理404

404要处理3个场景

没有匹配route

dispatch时没找到controller文件

dispatch时没找到action方法

当没有匹配route时,会使用用默认的namespace,默认的module,默认的controller,默认的action,默认的params。此时你或许会困惑为何一个请求会显示默认首页。

// Not Found Paths

$router->notFound([

'controller' => 'errors',

'action' => 'route404'

]);

$di->setShared('dispatcher', function () {

$eventsManager = new EventsManager();

$eventsManager->attach("dispatch:beforeException", function ($event, $dispatcher, $exception) {

if ($exception instanceof DispatcherException) {

switch ($exception->getCode()) {

case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:

case Dispatcher::EXCEPTION_ACTION_NOT_FOUND:

$dispatcher->forward([

'controller' => 'errors',

'action' => 'show404',

'params' => array('message' => $exception->getMessage())

]);

return false;

}

}

$dispatcher->forward([

'controller' => 'errors',

'action' => 'show500'

]);

return false;

});

$dispatcher = new MvcDispatcher();

$dispatcher->setDefaultNamespace('\namespace\Controllers');

$dispatcher->setEventsManager($eventsManager);

return $dispatcher;

});

以代码由于还拦截了其它异常,且没有throw $exception,会中断异常调用链,可以考虑把异常$exception->getMessage(), $exception->getFile(),$exception->getLine(),$exception->getCode()信息传给view,判断是开发模式就显示,生产模式就不显示。

使用原生 SQL

原则上是不允许使用原生的SQL的,某些场景一定要用的情况下,建议把所有的sql放到config内,在service层读取使用。

第一种方式

$sql = "SELECT id, name FROM robots ORDER BY name";

$connection = \Phalcon\DI::getDefault()->get('db');

$result = $connection->query($sql);

$result->setFetchMode(Db::FETCH_ASSOC);

echo $connection->getSQLStatement(); // sql

$data = $result->fetchAll();

print_r($data);

第二种方式

// A raw SQL statement

$sql = "SELECT * FROM robots WHERE id > 0";

$robot = new Robots();

$result = $robot->getReadConnection()->query($sql);

$result->setFetchMode(Db::FETCH_ASSOC);

$data = $result->fetchAll();

print_r($data);

echo $robot->getReadConnection()->getSQLStatement();

使用PHQL

简单粗暴的理解是把models下的namespaceclass对应成数据库的表,类属性对应表字段。

理解事件驱动

数据库分库,读写分离,负载均衡

用命名空间区分不同的数据库实例,对应代码结构上是不同的目录区分,在同一目录下基类负责初始化连接。连接来自初始化时注入的多个db服务

隐规则:

initialize()在每个请求期间只会调用一次

为每个 new 创建的实例执行初始化任务使用onConstruct()

namespace Company\Models\Notification;

/**

* Class BaseModel

*

* beforeSave()和afterFetch()成对使用,用于读写数据时自动转化数据。

* 例如自动执行serialize unSerialize

*

* save()发生时事件调用顺序是

* initialize,

* onConstruct,

* beforeValidation,

* beforeValidationOnCreate,

* afterValidationOnCreate,

* afterValidation,

* beforeSave,

* beforeCreate,

* afterCreate,

* afterSave,

*

* @package Company\Models\Notification

*/

class BaseModel extends \Phalcon\Mvc\Model

{

/**

* - initialize()在每个请求期间只会调用一次

* - 子类必需调用父类方法

* - 为每个 new 创建的实例执行初始化任务使用onConstruct()

*/

public function initialize()

{

$this->setConnectionService('db_notification');

//$this->setConnectionService('node1');

//$this->setConnectionService('node2');

//

//真实场景可能使用mysqlnd_ms扩展或者haproxy

//仅演示读负载均衡一种思路

//$dbSlave = ['node1', 'node2', 'node3'];

//$key = array_rand($dbSlave);

//$db = $dbSlave[$key];

//$this->setReadConnectionService($db);

//

//

//$this->setReadConnectionService('dbRead');

//$this->setWriteConnectionService('dbWrite');

}

}

表前缀与分表

model中提供的getSource()方法,合理运用即可。

class BaseModel extends \Phalcon\Mvc\Model {

public function getSource()

{

return 'v1'.str_tolower(get_class($this));

}

}

class User extends BaseModel {

...

}

class Robots extends Phalcon\Mvc\Model

{

public function getSource()

{

return "robots_" . date("Ym");

}

}

cookie

2.0.9之前的版本先set('key'),然后再正常的set('key','value')。也就是set两次绕过bug。

2.0.x分支已经修复这个bug,查看github源码

下面的单元测试可以重现这个bug。如果使用2.0.9之前的版本,建议采用两次set

public function testCookies()

{

// di factory

$di = new \Phalcon\Di\FactoryDefault();

$di->setShared('crypt', function () {

$crypt = new \Phalcon\Crypt();

// don't use PADDING_DEFAULT, Affect the cookie result

$crypt->setPadding(\Phalcon\Crypt::PADDING_ZERO);

$crypt->setKey('secret_key@123456789'); // Use your own key!

return $crypt;

});

// http cookies

$di->setShared('cookies', function () {

$cookies = new \Phalcon\Http\Response\Cookies();

$cookies->useEncryption(false);

return $cookies;

});

/** @var \Phalcon\Http\Response\CookiesInterface $cookies */

$cookies = \Phalcon\DI::getDefault()->get('cookies');

$_COOKIE['key'] = '1234567890';

$_COOKIE['key2'] = '0987654321';

//$cookies->set('key'); // ver <= 2.0.9 uncomment will test passed

//$cookies->set('key2'); // ver <= 2.0.9 uncomment will test passed

$this->assertEquals('1234567890', $cookies->get('key')->getValue());

$cookies->set('key', 'value', time() + 3600, '/', false, 'kinhom.com', true);

$cookies->set('key2', 'value2', time() + 3600, '/', false, 'kinhom.com', true);

$this->assertInstanceOf('\Phalcon\Http\Cookie', $cookies->get('key'));

/*

* phalcon ver <= 2.0.9

* Failed asserting that two strings are equal.

* Expected :'value'

* Actual :'1234567890'

*/

$this->assertEquals('value', $cookies->get('key')->getValue());

$this->assertEquals('value2', $cookies->get('key2')->getValue());

}

view 渲染顺序是

volt模板文件内 {{ content() }} 是联接各个模板的桥梁,完整的顺序是setMainView() -> setTemplateAfter() -> setLayout() -> setTemplateBefore -> pick()

即Main Layout -> Layout -> Action View

controller中若echo字符串,Action view内要写上{{ content() }}才会输出。

参考范例

背景知识

无论你是否使用phalcon框架,做为PHP开发者,有些背景知识是必需要了解的。

phalcon index.php,phalcon简易指南相关推荐

  1. phalcon index.php,Phalcon环境搭建与项目开发

    简介 Phalcon 是开源.全功能栈.使用 C 扩展编写.针对高性能优化的 PHP 5 框架. 开发者不需要学习和使用 C 语言的功能, 因为所有的功能都以 PHP 类的方式暴露出来,可以直接使用. ...

  2. git 简易指南+常用命令

    git 简易指南                      git 常用命令   ----------------------------------------------------------- ...

  3. 如何启动 WordPress 博客 – 简易指南 – 创建博客(2021)

    您想以正确的方式创建 WordPress 博客吗?我们知道,特别是当您不是技术极客时,创建博客可能是一个复杂的想法.在帮助许多用户创建博客后,我们决定创建最全面的指南,介绍如何在没有任何技术知识的情况 ...

  4. git - 简易指南

    http://www.bootcss.com/p/git-guide/ 转载于:https://www.cnblogs.com/passer1991/p/3279333.html

  5. 如何取消linux响铃_linux初学者入门:VIM编辑简易指南(常用操作)

    在linux低下最常用的文本编辑器为vim,如何进入编辑模式 i,I,a,A (i,在光标当前位置插入,a在当前位置追加),o,O在一个新的一行输入新字符,r,R为取代原来的字符以上输入都在一般模式当 ...

  6. 快速制作U盘WIN PE启动盘简易指南

    什么是WIN PE呢?WIN PE是一个精简过的WIN XP操作系统,具有图形界面的特点很适合做系统崩溃后的救急平台,是一个功能强大的维护工具,在没有光驱的情况下还可以用来硬盘安装WIN 98/WIN ...

  7. git reset --hard_Git紧急自救简易指南(二)——版本的游历

    这一篇重点说说 Git版本的游历,想要在不同版本之间操作,这个就要涉及到git一个非常重要的部分--日志管理 查看历史记录 git log 此命令用来查看版本的历史记录 比如说我这里添加了5条记录 由 ...

  8. php myflow,WordPress安装使用Flowplayer简易指南

    本文是简单易懂的现代魔法系列文章的第二弹~ 一.Flowplayer简介FlowPlayer 是一个用Flash开发的在Web上的视频播放器,可以很容易将它集成在任何的网页上.支持HTTP以及流媒体传 ...

  9. linux 更改ssh端口_如何在Linux中更改SSH端口-简易指南

    linux 更改ssh端口 The default port on SSH is 22. But for security reasons, it's a good idea to change SS ...

  10. 在虚拟机上安装Kali Linux的简易指南

    Let's learn to install Kali Linux on a Virtual machine today. If you want to venture into the field ...

最新文章

  1. PX4如何开启本地在环仿真?如何将仿真地点定位为本地位置?你进来就对了!
  2. 话里话外:浅淡对流程管理的认识及流程管理对企业价值
  3. Android handler Thread 修改UI Demo
  4. 【SpringBoot】SpringBoot、ThemeLeaf 官方文档地址
  5. poj 3321 Apple Tree 树状数组
  6. JDBC系列 之 JDBC层次结构和基本构成
  7. JAVA图书馆管理系统各个项目链接
  8. 蜂巢输入法android,讯飞输入法“蜂巢II”输入模型 内核提速便捷实用
  9. python实现堆栈 后进先出 LIFO
  10. Hungry for your love 真爱无限
  11. python调用加签名的接口_python接入开放平台:签名验签、加密解密、授权认证的测试方法...
  12. c语言圆周率小数点后500万位,圆周率小数点后500位数字是多少
  13. 在物联网领域,英特尔除了高速计算的芯片,还提供了什么技术?
  14. 超有爱的并查集 6666
  15. YOLO-先验框/anchor(锚点)
  16. 重新启动oracle 服务,在linux重新启动下如何设置oracle服务自动开启
  17. 最新版FusionCharts2D面积图
  18. php 清除js,php,js清除cookie
  19. GRAIL Efficient Time Series Representation Learning论文阅读笔记(一)
  20. 医院建网站需要多少钱?

热门文章

  1. pcf8591c语言编程,学51单片机-基于PCF8591的AD采样和DA输出
  2. 数据仓库、数据湖、数据平台和数据中台的概念和区别
  3. SFDC 日常经验积累
  4. jdk官网下载与安装
  5. Android 创建淡入淡出动画的详解
  6. linux堆栈有什么作用,嵌入式世界里,堆栈的作用和意义
  7. java中 字符串的补位
  8. Minecraft 1.18.1、1.18.2模组开发 19.拼图结构建筑(JigSaw Structure)
  9. 十六、DPM模型-颗粒流动
  10. 编码,隐匿在计算机软硬件背后的语言读书笔记(1)