Phalcon是一个C语言写的高性能PHP框架,相比PHP写的框架,它作为PHP的扩展在进程开启时便加载了,节省了每一次请求时的类库加载、MVC框架分派的开销。前面提到的使用Zephir来开发PHP扩展也是这个项目贡献的。
在CentOS 上安装Phalcon,因为之前安装过zephire了,所以直接下载cphalcon来编译安装就可以了,可以参照这里安装所需其他lib
git clone --depth=1 git://github.com/phalcon/cphalcon.git cd cphalcon/build/ sudo ./install sudo vim /etc/php.d/phalcon.ini
创建phalcon.ini增加以下内容
[phalcon] extension=phalcon.so
这里单独把phalcon.ini单独配置,是因为Phalcon扩展加载要在PDO扩展之后,而我的PDO也是单独配置的。如果不是的话会提示这个错误:
$ php -m | grep phalcon PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/phalcon.so' - /usr/lib64/php/modules/phalcon.so: undefined symbol: php_pdo_get_dbh_ce in Unknown on line 0
与Zend Framwork类似,Phalcon也提供开发工具用于快速生成项目骨架
git clone https://github.com/phalcon/phalcon-devtools.git cd phalcon-devtools ./phalcon.sh sudo ln -s ~/phalcon-devtools/phalcon.php /usr/bin/phalcon sudo chmod ugo+x /usr/bin/phalcon phalcon commands
注意,这个开发工具也是需要依赖Phalcon扩展的,否则会提示
$ phalcon command
PHP Fatal error: Class 'Phalcon\Script' not found in /home/vagrant/phalcon-devtools/phalcon.php on line 40
PHP Stack trace:
PHP 1. {main}() /home/vagrant/phalcon-devtools/phalcon.php:0
生成一个测试项目store
phalcon scaffold store
按照官方的Nginx说明配置
server {
listen 8005;
server_name store.localhost;
index index.php index.html index.htm;
set $root_path '/usr/share/nginx/html/tutorial/store/public';
root $root_path;
try_files $uri $uri/ @rewrite;
location @rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location ~ \.php {
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index /index.php;
include fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
root $root_path;
}
location ~ /\.ht {
deny all;
}
}
访问一下192.168.33.14:8005,提示:Access denied。。。查看Nginx错误日志
[root@vagrant nginx]# tail -n 20 error.log 2015/07/28 03:41:42 [error] 7343#0: *1 FastCGI sent in stderr: "Access to the script '/usr/share/nginx/html/tutorial/store/public' has been denied (see security.limit_extensions)" while reading response header from upstream, client: 192.168.33.1, server: store.localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/tmp/php5-fpm.sock:", host: "192.168.33.14:8005"
一开始还以为是PHP-FPM配置security.limit_extensions引起的,后来发现这个这个参数默认就是注释掉的,没限制。 最后在这里找到答案:原来是之前安装Nginx时配置了:cgi.fix_pathinfo=0,将它改回1(默认值)就可以了。当这个参数为1时,会把 PATH_TRANSLATED 转换为 SCRIPT_FILENAME。当然把这个参数去掉也是可以的
;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
重启Nginx
sudo service nginx restart
与其他PHP框架一样,Phalcon 支持MVC应用开发,提供了诸多组件如,数据库,缓存,队列等。
Phalcon\DI 作为全局的服务管理,用于服务注册,比如数据库,缓存,文件等。将这些资源统一起来管理,以便其他地方可以调用,各个需要的地方不再需要是new 一个对象,解除耦合关系。
Phalcon\Events\Manager作为全局的事件管理,用于事件注册,触发,以便自定义消息通知,如数据库查询事件,初始化事件。
Phalcon还有一个比较有特色的地方支持注释解析: Phalcon\Annotations 。官方教程举例如何使用注释做输出缓存。首先在Dispatcher服务中注册一个监听dispactch事件的缓存插件
<?php
$di['dispatcher'] = function () {
$eventsManager = new \Phalcon\Events\Manager();
// 添加插件到dispatch事件中
$eventsManager->attach('dispatch', new CacheEnablerPlugin());
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
};
然后实现监听的缓存插件
<?php
/**
* 为视图启动缓存,如果被执行的action带有@Cache 注释单元。
*
*/
class CacheEnablerPlugin extends \Phalcon\Mvc\User\Plugin
{
/**
* 这个事件在dispatcher中的每个路由被执行前执行
*
*/
public function beforeExecuteRoute($event, $dispatcher)
{
// 解析目前访问的控制的方法的注释
$annotations = $this->annotations->getMethod(
$dispatcher->getActiveController(),
$dispatcher->getActiveMethod()
);
// 检查是否方法中带有注释名称‘Cache’的注释单元
if ($annotations->has('Cache')) {
// 这个方法带有‘Cache’注释单元
$annotation = $annotations->get('Cache');
// 获取注释单元的‘lifetime’参数
$lifetime = $annotation->getNamedParameter('lifetime');
$options = array('lifetime' => $lifetime);
// 检查注释单元中是否有用户定义的‘key’参数
if ($annotation->hasNamedParameter('key')) {
$options['key'] = $annotation->getNamedParameter('key');
}
// 为当前dispatcher访问的方法开启cache
$this->view->cache($options);
}
}
}
现在就可以使用注释来进行缓存了
<?php
class NewsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
/**
* This is a comment
*
* @Cache(lifetime=86400)
*/
public function showAllAction()
{
$this->view->article = Articles::find();
}
/**
* This is a comment
*
* @Cache(key="my-key", lifetime=86400)
*/
public function showAction($slug)
{
$this->view->article = Articles::findFirstByTitle($slug);
}
}
为Action增加了缓存,但对Action的代码改动为0(无侵入)并且非常简洁。数据模型里面也可以使用注释来对字段进行处理
<?php
use Phalcon\Mvc\Model;
class Robots extends Model
{
/**
* @Primary
* @Identity
* @Column(type="integer", nullable=false)
*/
public $id;
/**
* @Column(type="string", length=70, nullable=false)
*/
public $name;
/**
* @Column(type="string", length=32, nullable=false)
*/
public $type;
/**
* @Column(type="integer", nullable=false)
*/
public $year;
}
路由解析也可以使用RouterAnnotations反射来实现
?php
/**
* @RoutePrefix("/api/products")
*/
class ProductsController
{
/**
* @Get("/")
*/
public function indexAction()
{
}
/**
* @Get("/edit/{id:[0-9]+}", name="edit-robot")
*/
public function editAction($id)
{
}
/**
* @Route("/save", methods={"POST", "PUT"}, name="save-robot")
*/
public function saveAction()
{
}
/**
* @Route("/delete/{id:[0-9]+}", methods="DELETE",
* conversors={id="MyConversors::checkId"})
*/
public function deleteAction($id)
{
}
public function infoAction($id)
{
}
}
是不是跟Java annotation有点像?之前介绍的PHPUnit,Zend Framework,还有Symfony 2 和 Doctrine 2已经在PHP层面上支持,使用ReflectionClass便可实现。
Phalcon也支持创建命令行应用,可以将PHP应用打包成Phar,直接运行,也可以结合命令行颜色进行输出。
参考链接:
Nginx 安装说明(Nginx Installation Notes)
Can’t upgrade to Phalcon 1.3.0
Nginx/PHP-FPM “Access denied.” error
Access denied (403) for PHP files with Nginx + PHP-FPM
Phalcon 开发工具(Phalcon Developer Tools)
IDE autocomplete for PhalconPHP
Annotations in PHP: They Exist
PHP Annotations Are a Horrible Idea
PHP CLI Colors – PHP Class Command Line Colors (bash)



