资讯专栏INFORMATION COLUMN

phalcon简易指南

whataa / 2324人阅读

摘要:帮助你开始使用的简易指南。第一种方式参考第二种方式参考使用参考简单粗暴的理解是把下的对应成数据库的表,类属性对应表字段。

帮助你开始使用 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,配置route

// Not Found Paths
$router->notFound([
    "controller" => "errors",
    "action" => "route404"
]);

参考handling not found exceptions在注入dispatcher服务时初始化代码如下

$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("
amespaceControllers");
    $dispatcher->setEventsManager($eventsManager);
    return $dispatcher;
});

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

使用原生 SQL

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

第一种方式

参考Finding Rows

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

$connection = PhalconDI::getDefault()->get("db");

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

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

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

$data = $result->fetchAll();

print_r($data);
第二种方式

参考Using Raw SQL

// 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

参考Phalcon Query Language (PHQL)

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

理解了PHQL之后就可以读下Working with Models

理解事件驱动

model类的事件调用顺序如下:参考官方文档http://docs.phalconphp.com/en/latest/reference/models.html#events-and-events-manager

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

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

隐规则:

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

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

namespace CompanyModelsNotification;

/**
 * Class BaseModel
 *
 * beforeSave()和afterFetch()成对使用,用于读写数据时自动转化数据。
 * 例如自动执行serialize unSerialize
 *
 * save()发生时事件调用顺序是
 * initialize,
 * onConstruct,
 * beforeValidation,
 * beforeValidationOnCreate,
 * afterValidationOnCreate,
 * afterValidation,
 * beforeSave,
 * beforeCreate,
 * afterCreate,
 * afterSave,
 *
 * @package CompanyModelsNotification
 */
class BaseModel extends PhalconMvcModel
{

    /**
     * - 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 PhalconMvcModel {
    public function getSource()
    {
        return "v1".str_tolower(get_class($this));
    }
}

class User extends BaseModel {
...
}


class Robots extends PhalconMvcModel
{
    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 PhalconDiFactoryDefault();
    $di->setShared("crypt", function () {
        $crypt = new PhalconCrypt();
        // don"t use PADDING_DEFAULT, Affect the cookie result
        $crypt->setPadding(PhalconCrypt::PADDING_ZERO);
        $crypt->setKey("secret_key@123456789"); // Use your own key!

        return $crypt;
    });
    // http cookies
    $di->setShared("cookies", function () {
        $cookies = new PhalconHttpResponseCookies();
        $cookies->useEncryption(false);

        return $cookies;
    });

    /** @var PhalconHttpResponseCookiesInterface  $cookies */
    $cookies = PhalconDI::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("PhalconHttpCookie", $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() }}才会输出。

参考范例

https://github.com/phalcon/invo

https://github.com/phalcon/forum

背景知识

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

从 PHP 5.2.x 移植到 PHP 5.3.x

从 PHP 5.3.X 迁移到 PHP 5.4.X

从 PHP 5.4.x 迁移到 PHP 5.5.x

从PHP 5.5.x 移植到 PHP 5.6.x

PHP标准库 (SPL)


PHPUnit

xdebug,xhprof

composer,中文

PHP Framework Interop Group

phpDocumentor,apigen

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31916.html

相关文章

  • PHP7 安装Phalcon框架

    摘要:是什么是开源全功能栈使用扩展编写针对高性能优化的框架。也是松耦合的,可以根据项目的需要任意使用其他对象。安装支持版本的不支持普通方式的编译安装,只能通过安装。因此安装之前,请先安装。 Phalcon 是什么? Phalcon 是开源、全功能栈、使用 C 扩展编写、针对高性能优化的 PHP 5 框架。 开发者不需要学习和使用 C 语言的功能, 因为所有的功能都以 PHP 类的方式暴露出来...

    kidsamong 评论0 收藏0
  • phalcon使用经验杂谈

    摘要:初次认识是在刚学的时候最近终于有机会用上了故此说说使用上的一些感受个人是很喜欢这套框架的方式使用依赖注入让代码组织很灵活耦合也很低但是也许是框架东西太多了遇到几个坑上一年以上的也还没解决不过有一定开发经验的话还是可以自己修复的被这几个坑浪费 初次认识phalcon是在刚学php的时候,最近终于有机会用上了.故此说说使用上的一些感受 个人是很喜欢phalcon这套框架的方式,使用...

    UsherChen 评论0 收藏0
  • Phalcon入门教程之目录结构

    摘要:原文发表于入门教程之目录结构很多初学的朋友,对于以框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。只需要通过注册这些目录结构,即可正常使用。 原文发表于:Phalcon入门教程之目录结构 很多初学Phalcon的朋友,对于以Phalcon框架为基础构建的项目,应该如何组织目录结构有点摸不着头脑。比如多模块的项目中,如何共用libs类库和models目录中模型类的情况,就有很...

    reclay 评论0 收藏0
  • PhpStorm下提示Phalcon框架语法

    摘要:下载源码源码地址下载下载源码地址下载修改文件,指定生成语法文件到目前为止,会在目录下生成对应版本的目录在中导入最后重启 1、下载Phalcon源码 git clone https://github.com/phalcon/cphalcon.git 源码地址:下载 2、下载phalcon-devtools git clone https://github.com/phalcon/phal...

    luckyw 评论0 收藏0
  • PHP-Phalcon框架中的数据库操作

    摘要:本文描述了框架中数据库操作方法,主要讨论框架的组件中的操作方法。属性方法在框架中支持属性的扩展查询,在上例中,可以把条件语句改为同时省略查询条件结果不变。 本文描述了PHP-Phalcon框架中数据库操作方法,主要讨论Phalcon框架的Model组件中的操作方法。更详细的Model介绍请参考:官方文档 1. 连接数据库 在Phalcon框架中,通过在DI中注入db参数来实现数据库的...

    xiaotianyi 评论0 收藏0

发表评论

0条评论

whataa

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<