您的位置:首页 > 其它

phalcon 之 flash组件

2016-03-31 17:21 465 查看

phalcon 之 flash组件

笔者的话:之前和几个朋友一起研究了一下PHP的Phalcon框架的几个组件的用法和源代码,做了一些笔记,拿出来和大家分享一下。

笔者水平有限,如有瑕疵请大家指正,我定会知错就改。

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

目前主要有三种通知类型

当进行一次操作后,跳转到中间页面,在这个中间页面上输出反馈信息。不过这种古老的方法已经不是很常见了。

用户进行某次操作后,提交AJAX请求,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。用这种方式反馈通知。

用户进行某次或某些操作,将操作之后的反馈信息临时储存在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适配器

<?php

use Phalcon\Flash\Session as FlashSession;
....

$di->set('flash', function () {
return new FlashSession();
});


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

<?php

use 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框架来作为例子

<?php

use 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中传入了消息,如

<?php

use 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

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

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样式时,可以使用以下代码进行对应类的配置:

<?php

use 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中取出消息输出给视图。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: