phalcon 之 flash组件

来源:互联网 发布:淘宝号码购买 编辑:程序博客网 时间:2024/06/07 00:43

phalcon 之 flash组件


笔者的话:之前和几个朋友一起研究了一下PHP的Phalcon框架的几个组件的用法和源代码,做了一些笔记,拿出来和大家分享一下。
笔者水平有限,如有瑕疵请大家指正,我定会知错就改。

  • flash(闪存消息)作为phalcon框架的一个组件是用来反馈一些信息,通知用户当前产生的动作状态。这个组件有两个适配器,分别是direct和session。

  • 目前主要有三种通知类型

    1. 当进行一次操作后,跳转到中间页面,在这个中间页面上输出反馈信息。不过这种古老的方法已经不是很常见了。
    2. 用户进行某次操作后,提交AJAX请求,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。用这种方式反馈通知。
    3. 用户进行某次或某些操作,将操作之后的反馈信息临时储存在session中,当需要在浏览器显示时,再从session中取出数据输出反馈信息。

      而我们接下来主要介绍的flash组件中的flashsession适配器就是以第三种方式反馈一些信息的。 既然是对session的操作,所以在使用这个适配器之前要start session。其中另一个适配器direct的原理就很简单了,得到信息后立即反馈给用户。这样的方式在很多场合都不适合使用,因此大家要根据使用环境,判断要使用哪种适配器。

  • 使用flash的利与弊

    当我们进行了一系列操作,每一步操作所要反馈的信息要在一个界面统一展示,这样的话用flash更为方便。 也就是说我们可以在一系列操作中把每一步获得的消息都储存在session中,在某一个界面将这些消息从session中全都取出来,输出给视图将其展示。
    不过要注意的是,session固然好用,但他也是一把双刃剑,如果使用了flash向session中传入了数据,可是却没有将其输出,这时存在session中的数据没有展示,也不会被清除,在下次输出session中的数据时可能造成将上一次没有输出的数据一同展示。这样会很大程度上影响用户的体验。所以当使用flash的时候一定要及时将session中的信息输出并清除。

    举例来说,当你在用户注册成功的时候想要返回一个信息“注册成功!”,可你忘记了写将信息输出的代码,只是单纯的将信息储存进了session中。之后用户登录的时候,你要回馈给用户一个信息“成功登陆!”这时如果使用了output();这个函数的话,会把储存在session中的所有信息遍历输出,用户就会看到一个“注册成功!”的反馈信息,这样就很不好了。

    我们举个例子来说明一下这种情况
    假设有一个表单要输入标题,正文。点击提交按钮后,会将这些信息发送给后端(也就是我们所写的Controller里的Action)进行处理。
    如果数据不符合规范,提交失败,则向session中存入一条消息如:“输入信息有误,请重新输入!”然后因为我们需要用户修改他输入的数据,所以回到这个输入页面,在这个页面显示这条反馈消息;如果数据符合规范,提交成功,则向session中存入一条消息如:“提交成功!”并跳转到其他页面,显示这条信息。
    如果我们没有在提交页面写显示信息的代码,也就是说当我们提交了错误的内容,返回重新输入的时候,但是却没有把session中的信息取出展示,这条信息也就不会被clear。之后我们提交了正确的内容,跳转到下一个页面,这时反馈出的消息除了“提交成功!”之外,之前的那条错误提示也会一同输出,则用户在浏览器上会看到两条矛盾的提示信息:
    “提交成功!”
    “输入信息有误,请重新输入!”

  • flash的使用方法

  • session适配器

    1.注册session适配器

    <?phpuse Phalcon\Flash\Session as FlashSession;....$di->set('flash', function () {    return new FlashSession();});

    2.下面我们以success方法为例介绍一下具体怎么使用,使用success方法,把消息存入session

    <?phpuse Phalcon\Mvc\Controller;class testController extends Controller{public function indexAction(){    $this->flash->success("hello world!");//跳转到另一个Action    return $this->response->redirect("test/show"); }    public function showAction(){}}

    3.在../app/views/test/show.phtml这个视图文件中将消息输出

    <p><?php $this->flash->output() ?></p>

    4.输出给浏览器视图的消息被格式化为html,类似这样

    <div class="successMessage">hello world!</div>

    其中的样式successMessage为默认样式。

    但是只使用默认的样式是做不出好看的消息的,下面我们来设置自定义的css样式,以下是以bootstrap框架来作为例子

    <?phpuse Phalcon\Flash\Session as FlashSession;....$di->set('flash', function () {    return new FlashSession(array(        'error'   => 'alert alert-danger',        'success' => 'alert alert-success',        'notice'  => 'alert alert-info',        'warning' => 'alert alert-warning'    ));});  

    要注意的是,这段代码是在注册服务的时候写入的,也就是说在以后的任何时候都可以只修改这一小段代码,来改变所有flash消息的css样式。

    5.如果你没有在上面的视图文件中写入output函数,那么浏览器就不会有反馈消息输出,session中的数据也不会被clear。这时你又一次向session中传入了消息,如

    <?phpuse Phalcon\Mvc\Controller;class testController extends Controller{public function indexAction(){...}public function showAction(){$this->flash->success("i love phalcon!");return $this->response->redirect("test/showother");//跳转到另一个Action}public function showotherAction(){}}

    6.这时在../app/views/test/showother.phtml文件中将消息输出

    <p><?php $this->flash->output() ?></p>

    你会发现浏览器把之前的“hello world!”与“ilove phalcon!”一起输出,这样就要求了我们在使用的时候一定要注意将session中的消息输出并clear掉。

  • direct适配器
    • 使用direct适配器,flash消息会在当前页面直接输出。他的使用方法与session类似,在此不做过多的说明。简单的介绍一下如何使用

    1.注册direct适配器

        <?php    use Phalcon\Flash\Direct as FlashDirect;    ....    $di->set('flash', function () {        return new FlashDirect();    });

    2.使用success方法,其他方法使用与之类似。

        <?php    use Phalcon\Mvc\Controller;    class PostsController extends Controller    {    public function indexAction()    {        $this->flash->success("hello world!");         }    }

好的,我们现在已经了解了flash的使用方法和使用flash时的注意事项,下面我们来探索一下flash的原理,接下来让我们走进flash的源代码

  • 首先在../phalcon/flashinterface.zep中定义了五个接口

    interface FlashInterface{Public function error (message);Public function success(message);Public function notice(message);Public function warning(message);Public function message(string type, var message);//传入的两个参数,前者为类型,后者为字符串。}

    也就是说我们的使用格式就应该类似于这样

    $this->flash->error("string");$this->flash->message("type", "string ");
    • 接下来我们打开../phalcon/flash.zep

      1. 会发现声明了四个protect变量,允许在本身和子类中访问。其中的_implicitFlush和 _automaticHtm设置了默认值为true。

      2. protected _cssClasses; //css的样式,为数组
        protected _implicitFlush = true;//布尔型,看作开关
        protected _automaticHtml = true;//布尔型,看作开关
        protected _messages;//反馈信息

    2.之后是一个构造函数,这个构造函数的作用是修改flash的css样式,因为flash是要格式化为html语言输出到浏览器的,更改css的样式就可以使输出的视图更为美观,当然你可以尽情的使用前端框架啦(如bootstrap),并且这个构造函数可以被子类继承。 当你创建一个对象的时候,构造函数优先调用此方法,先判断传入的参数cssClasses是否为数组,若是否的话。给flash的四个内置用法定义默认css样式分别为

        "error": "errorMessage",    "notice": "noticeMessage",    "success": "successMessage",    "warning": "warningMessage"

    当你想要使用自定义的css样式时,可以使用以下代码进行对应类的配置:

    <?phpuse Phalcon\Flash\Direct as FlashDirect;// 利用自定义的CSS类来注册flash服务$di->set('flash', function () {    $flash = new FlashDirect(      array(        'error'   => 'alert alert-danger',//css的样式        'success' => 'alert alert-success',        'notice'  => 'alert alert-info',        'warning' => 'alert alert-warning'    ));return $flash;});  

    3.下面我们一起看这两个函数

    public function setImplicitFlush(boolean implicitFlush);public function setAutomaticHtml(boolean automaticHtml);

    这两个函数都是要接收一个布尔型的参数,所以可以把这两个函数看作是开关,
    根据传入参数的true/false判断开关的状态,默认为开启状态。

    下面这个函数就好理解了

    public function setCssClasses(array! cssClasses); 

    这个函数要传入一个数组参数,也就是将自定义的css格式以数组的方式传入。之前的代码已经演示过了,不再细说。

    以上这三个函数只是简单的为之前声明的的变量做了一步赋值操作,这些变量会作为参数用在接下来的这个函数中。

    4.下面是这个组件中最核心的一个函数方法—— outputMessage

    public function outputMessage(string type, var message);//它要传入两个参数,与我们之前说的flash的用法相同,因为flash的用法都是基于这个函数的。  

    在这个函数中我们之前定义的几个变量发挥了作用,下面我们来看一下之前我们所说的两个“开关”的作用。

    automaticHtml——从名字来看就很明白了,自动格式化为html。
    当automaticHtml的值为true的时候,将cssClasses数组中的值作为css样式,如果你自定义了css样式,此时传入的就是你自己定义的数组。

    当automaticHtml的值为false时,传入的cssClasses的值为空。

    (ps:在这有一个变量赋值let eol = PHP_EOL;其中PHP_EOL是PHP的换行符,在不同的操作系统上被解析成不同的代码,增大了代码的可移植性,从这里也可以看出Phalcon框架对可移植性的追求。

    之后如果我们传入的message是一个数组的时候,开始判断另一个开关implicitFlush——绝对刷送(每当有输出的时候,即刻把输出发送到浏览器)

    当implicitFlush的值为false时,给content(内容)这个变量赋值为空,并返回它。此时implicitFlush为关闭状态,我们并没有立即返回值,浏览器此时没有message的输出。

    当automaticHtml的值为true时,进入循环,将message数组中的值格式化为html,并使用css样式(之前传入的cssClasses数组如果为自定义的css,此时就使用了它,否则为默认的css样式),这时如果implicitFlush的值也为true的话便直接将格式化后的message遍历输出,否则则存入content,等待输出。

    如果传入的message不是数组的话,逻辑上与以上一样,此时只要处理传入的这个值就哦ok了。

    5.clear这个方法就不多说了,简洁明了,清除数据的作用。

    public function clear() -> void{    let this->_messages = [];}

    为什么要说outputMessage这个方法是最为核心的呢?看了下面也许你也会认同这个观点。

    • ### 我们打开flash的一个适配器文件——../phalcon/flash/direct.zep

    其中的两个方法很简单实用。也很容易理解,就不过介绍,
    Direct类继承父类中的outputMessage方法,
    其中output();是将继承于父类中的_message这个数组输出,并清除数组中的数据。
    其中的message();方法就是对outputMessage函数的调用;

        public function message(string type, var message) -> string    {    return this->outputMessage(type, message);    }  

    接下来我们回到../phalcon/flash.zep中,可以看到flash的四种用法,如下

        public function success(string message) -> string    {    return this->{"message"}("success", message);    }  

这时你会发现,这四种用法全都是调用了message函数。也就是说,flash的四种内置用法和一种自定义用法本质上都是调用outputMessage这个函数,对outputMessage这个函数进行了一点修饰,这样做的好处当然是方便的开发者的使用,可以称success等函数是outputMessage函数的“函数糖”。

完毕,到此为止我们应该已经理解了flash的原理和用法了。接下来继续看它的另一个适配器。

  • 打开文件../phalcon/flash/session.zep

    这一部分主要是对session的操作,在使用这个适配器之前要start session。简单来说,这里是把message的数据放到session中,在需要的时候再从session中取出这个数据,然后输出。这个就很好理解了,当然这个也十分重要,它是这个组件的核心用法。

    值得一提的是其中的has方法,这个方法用来判断从session中取到的值是否为数组,返回值是布尔值。可以用它作为判断输出方式是否是遍历输出的先决条件。

    • ##总结

    看过了flash组件的源码之后,我们对flash组件的原理又有了更深一步的认识,简单来说,flash的direct适配器是将得到的消息立即输出。而session适配器是将得到的消息存入session会话中,之后在需要的时候从session中取出消息输出给视图。

0 0