Symfony页面的基本创建实例详解


Posted in PHP onJanuary 26, 2015

本文实例分析了Symfony页面的基本创建方法。分享给大家供大家参考。具体如下:

这里我们将会学习如何创建一个模块,这是组织页面的结构化元素。同时我们也会学习如何创创建一个分为一个动作也一个模板的页面,之所以分为动作与模板,是因为MVC模式。链接与表彰是基本的页面交互,我们将会学习如何在模板中插入这些元素并且在动作中进行处理。

创建一个模块框架

Symfony将页面组织为模块。在创建一个页面之前,我们需要创建一个模块,并且初始化为一个Symfony可以识别的文件结构的空壳。

Symfony命令行自动化处理模块的创建。我们只需要调用init-module任务,并且使用程序名以及模块名作为参数。在创建了一个myapp程序之后,要向这个程序中添加一个mymodule模块,我们可以输入下面的命令:

> cd ~/myproject

> symfony init-module myapp mymodule
>> dir+      ~/myproject/apps/myapp/modules/mymodule

>> dir+      ~/myproject/apps/myapp/modules/mymodule/actions

>> file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php

>> dir+      ~/myproject/apps/myapp/modules/mymodule/config

>> dir+      ~/myproject/apps/myapp/modules/mymodule/lib

>> dir+      ~/myproject/apps/myapp/modules/mymodule/templates

>> file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

>> dir+      ~/myproject/apps/myapp/modules/mymodule/validate

>> file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php

>> tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php

>> tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php

>> tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

与actions/,config/,lib/,templates/,validate/目录相分离,这个命令只创建三个文件。位于test/目录中的一个为单元测试。actions.class.php指向默认的模块欢迎页面。templates/indexSuccess.php文件为空。

在actions/actions.class.php文件中默认生成的动作:

<?php

 class mymoduleActions extends sfActions

 {

   public function executeIndex()

     {

         $this->forward('default', 'module');

     }

   }

?>

对于每一个新的模块,Symfony会创建一个默认的index动作。他是由一个名为executeIndex的动作方法以及一个名为indexSuccess.php的模板文件组成。我们可以通过下面的URL来浏览相应的页面:
http://localhost/myapp_dev.php/mymodule/index
这里我们并不会使用默认的index动作,所以我们可以从actions.class.php文件中移除executeIndex()方法,并且从templates/目录中删除indexSuccess.php文件。

除了命令行,Symfony还提供了其他的方法来初始化一个模块。其中一个方法就是手动来创建目录与文件。在许多情况下,一个模块的动作与模板就意味着操作一个给定数据表的数据。因为创建,获取,更新,以及从一个数据表中删除数据记录的必须代码通常都是相同的,Symfony提供了一个名为框架的机制来我们生成这些代码。我们后续会继续介绍。

添加一个页面

在Symfony中,页面后面的逻辑存储在动作中,而表面则是在模板中。没有逻辑的页面仍然需要一个空的动作。

添加一个动作

"Hello,world!"页面则会通过一个myAction的动作进行访问。要创建这个动作,只需要在mymoduleActions类中添加一个executeMyAction方法,如下所示:

<?php

 class mymoduleActions extends sfActions

 {

   public function executeMyAction()

     {

     }

 }

动作方法的名字总是execute'Xxx'()的形式,其中名字的第二部分是动作的名字,并且第一个字母大写。

现在我们可以请求下面的URL:
http://localhost/myapp_dev.php/mymodule/myAction

Symfony将会抱怨丢失了myActionSuccess.php模板。这是正常的。在Symfony中,一个页面通常是由一个动和与一个模板组成的。

URL是响应的一部分

Symfony包含一个路由系统允许我们在实际的动作名与需要调用的URL格式之间有一个完整的分隔。这允许自定义URL的自定义格式,就如同他是响应的一部分。我们不再为文件的结构或是请求的参数据限制,一个动作的URL看起来就我们所希望的解析。例如,到一个名为article模块的索引动作调用通常如下面的样子:
http://localhost/myapp_dev.php/article/index?id=123

这个URL由一个数据获取一篇指定的文章。但是URL可以通过在routingyml配置文件中作一些小的改动而以一种完全不同的方式进行编写:
http://localhost/articles/europe/france/finance.html

这样的URL不仅对于搜索引擎友好的,他对于用户来说也是十分重要的,这样用户就可以将地址栏作为一个伪码命令来自定义查询,例如下面的例子:
http://localhost/articles/tagged/finance+france+euro

Symfony知道如何为用户解析并生成URL。路由系统会自动从一个简洁URL中脱去所请求的参数,并使其为动作可用。他同时也会格式化响应中所包含的超链接,从而使其看起来更为简洁。我们将会在第九章了解这个特性的更多内容。

总之,这就意味着我们命名程序的动作的方式不应受到调用他们的URL的样子的影响,而是受程序中动作的函数控制。一个动作的名了解释了动作实际所做的内容,而且通常为不定式格式中的一个动词(例如show,list,edit)。动作的名字可以做到对于终端用户完全不可见,从而不必担心使用显式的动作名。我们可以有效的利用代码注释来解释我们的函数功能,从而使代码更读。

添加一个模板

动作需要一个模板来进行封装。一个模板就是位于一个模块的templates/目录的一个文件,通常是以动作和动作的词尾来进行命名的。默认的动作词尾为"success",所以为myAction动作所创建的模板文件应命名为myActionSuccess.php。

模板只包含表现代码,所以在其中要包含尽可有少的PHP代码。实际上,一个显示"Hello,world!"的页面只有一行的代码的模板。

<p>Hello, world!</p>

如果我们需要在模板中运行一些PHP代码,我们应避免使用下面所列的通常的PHP语法。相反,应使用另一种PHP语法来编写我们的模板,从而使得代码对于非PHP程序来说更易于理解。不仅最终代码是正确的,而且有助于我们在动作中保持复杂的PHP代码,因为只有控制语句有对应代码。

通常的PHP语法如下:

<p>Hello, world!</p>

<?php

 

 if ($test)

 {

   echo "<p>".time()."</p>";

 }

    

?>

替代的PHP语法如下:

<p>Hello, world!</p>

<?php if ($test): ?>

<p><?php echo time(); ?></p>

<?php endif; ?>

 
由动作向模板传递信息

动作的工作是要完成所有复杂的计算,数据读取以及测试,并且设置要输出或是测试的模板变量。Symfony使得动作类的属性在全局名字空间中为模板可用。下面显示如何由动作向模板传递信息。

在动作中设置动作属性从而使其为模板可用:

<?php

 

 class mymoduleActions extends sfActions

 {

   public function executeMyAction()

     {

         $today = getdate();

     $this->hour = $today['hours'];

     }

 }

模板直接访问动作属性:

<p>Hello, world!</p>

<?php if ($hour >= 18): ?>

<p>Or should I say good evening? It's already <?php echo $hour ?>.</p>

<?php endif; ?>

模板已经可以访问一些数据,而不需要在动作中设置任何变量。每一个模板通常可以调用$sf_context,$sf_request,$sf_params,$sf_user对象的方法。他们包含与当前内容,请求,请求参数以及会话相关的数据。我们很快就会学到他们的用法。

使用表单向用户收集信息

表单是向用户收集信息的一个好方法。使用HTML编写表单以及表单元素有时是相当麻烦的,尤其是当我们希望适用于XTHML时更是如此。我们可以用通常的方式在Symfony模板中包含表单元素,如下面所示,但是Symfony提供了帮助器从而使得这个任务更为简单。

模板可以包含通常的HTML代码:

<p>Hello, world!</p>

<?php if ($hour >= 18): ?>

<p>Or should I say good evening? It's already <?php echo $hour ?>.</p>

<?php endif; ?> 

<form method="post" target="/myapp_dev.php/mymodule/anotherAction">

  <label for="name">What is your name?</label>

  <input type="text" name="name" id="name" value="" />

  <input type="submit" value="Ok" />

</form>

一个帮助器是用在模板中的由Symfony定义的PHP函数。他输出HTML代码,并且比我们自己编写实际的HTML代码要快速得多。使用Symfony帮助器,我们用下面的代码得到的输出结果与上面通常的HTML代码相同:

<p>Hello, world!</p>

<?php if ($hour >= 18): ?>

<p>Or should I say good evening? It's already <?php echo $hour ?>.</p>

<?php endif; ?>

<?php echo form_tag('mymodule/anotherAction') ?>

  <?php echo label_for('name', 'What is your name?') ?>

  <?php echo input_tag('name') ?>

  <?php echo submit_tag('Ok') ?>

</form>

如果在上面的代码中,我们认为使用帮助器的版本并不会比编写HTML代码快,那么我们可以考虑一下下面的情况:

<?php

     $card_list = array(

       'VISA' => 'Visa',

       'MAST' => 'MasterCard',

       'AMEX' => 'American Express',

       'DISC' => 'Discover');

     echo select_tag('cc_type', options_for_select($card_list, 'AMEX'));

?>

这会得到下面的HTML输出结果:

<select name="cc_type" id="cc_type">

  <option value="VISA">Visa</option>

  <option value="MAST">MasterCard</option>

  <option value="AMEX" selected="selected">American Express</option>

  <option value="DISC">Discover</option>

</select>

在模板中使用的帮助器的好处就在于加快了编码的速度,代码的清晰与简洁。而代价就是我们需要花费时进行学习。所以我们可以在模板中不使用Symfony帮助器,并且以我们通常的方式来编写代码,但是这会是一个巨大的损失。

注意,短开放标记的用法(<?=,等同于<?php echo)并不推荐在专业的web程序中使用,因为我们的web服务器也许会理解多个脚本语言,从而会使其变得迷惑。另外,短开放标记并不会与默认的PHP配置进行工作,而且需要修改服务来激活。最后,当我们必须处理XML与验证时,他会出错,因为<?在XML中有着特殊的意义。

表单处理有专门的一章进行讨论,因为Symfony提供了许多工具,绝大数的帮助器,来使其简单。我们将会在第10章了解到关于帮助器更多的内容。

链接到另一个动作

我们现在已经知道在动作名字与需要调用的URL之间有一个分离。所以我们使用下面的方式来创建到另一个动作的链接时,他只会工作在默认的路由系统中。如果我们以后决定改变URL的样子,那么我们就需要查看所有的模板来改变超链接。

超链接,通常的方法:

<a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">

  I never say my name

</a>

要避免这样的麻烦,我们应总是使用link_to()帮助器来我们的程序动作创建超链接。下面的例子演示了超链接帮助器的用法。

link_to()帮助器:

<p>Hello, world!</p>

<?php if ($hour >= 18): ?>

<p>Or should I say good evening? It's already <?php echo $hour ?>.</p>

<?php endif; ?>

<?php echo form_tag('mymodule/anotherAction') ?>

  <?php echo label_for('name', 'What is your name?') ?>

  <?php echo input_tag('name') ?>

  <?php echo submit_tag('Ok') ?>

  <?php echo link_to('I never say my name','mymodule/anotherAction?name=anonymous') ?>

</form>

生成的HTML与前面的相同,所不同的就在于当我们改变我们的路由规则时,所有的模板都会正确工作,并且重新格式化URL。

link_to()帮助器,就像其他的帮助器,会接受特定选项的额外参数和额外的标签属性。下面的例子显示了一个可选参数以及生成的HTML。选项参数或者是一个相关的数组或者是由空格分隔的显示key=value的简单字符串。

大多数帮助器接收一个可选参数:

// Option argument as an associative array

<?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',

  array(

      'class'    => 'special_link',

          'confirm'  => 'Are you sure?',

          'absolute' => true

)) ?>

    

// Option argument as a string

<?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',

  'class=special_link confirm=Are you sure? absolute=true') ?>

          

// Both calls output the same

=> <a class="special_link" onclick="return confirm('Are you sure?');"

    href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous">

    I never say my name</a>

任何时候我们使用一个Symfony帮助器来输出一个HTML标记时,我们可以在可选参数中插入额外的标记属性。我们可以使用HTML 4.0的方式来编写这样的属性,而Symfony将会以更简洁的格式进行输出。这也就是为什么帮助器会比HTML更容易编写的原因。

因为他需要一个额外的分析与转换,字符串语法比数组语法要慢一些。

与表单帮助器相类似,链接帮助器有更多的数量和选项。

由请求得到信息

无论用户通过表单发送信息(通常以POST请求的方式)还是通过URL(GET请求),我们可以通过带有sfActions对象的getRequestParameter()方法的动作来获取数据。下面的例子显示如何在anotherAction中得到name参数的值。

在动作中由请求参数得到数据:

<?php

 

class mymoduleActions extends sfActions

{

  ...

 

  public function executeAnotherAction()

  {

    $this->name = $this->getRequestParameter('name');

  }

}

如果数据的处理是简单的,我们甚至并不需要使用动作来得到请求参数。模板可以访问一个名为$sf_params的对象,他提供了get()方法来得到请求参数,就如同动作中的getRequestParameter()方法。

如果executeAnotherAction()方法是空的,下面的例子显示了anotherActionSuccess.php模板文件如何得到同样的name参数。

在模板中直接由请求参数得到数据:

<p>Hello, <?php echo $sf_params->get('name') ?>!</p>

那么为什么不使用$_POST,$_GET或是$_REQUEST变量呢?因为我们的URL将会不同的方式进行格式化(http://localhost/articles/europe/france/finance.html),这样通常的PHP变量就会再起作用,并且只有路由系统可以得到请求参数。而我们希望添加输入过滤来阻止恶意代码注入,而这只有当我们将所有的请求参数保存在一个简洁的参数装配器中才可能。

$sf_params对象比仅提供一个与数组等同的方法要强大得多。例如,如果我们只是希望检测一个请求参数是否存在,我们可以简单的使用$sf_params->has()方法,而不使用get()测试实际的值。

在模板中测试请求参数的存在:

<?php if ($sf_params->has('name')): ?>

  <p>Hello, <?php echo $sf_params->get('name') ?>!</p>

<?php else: ?>

  <p>Hello, John Doe!</p>

<?php endif; ?>

我们已经猜到了,这可以在单一的代码行中编写。与Symfony中大多数的获取方法一样,动作中的getRequestParameter()方法与模板中的$sf_params->get()(实际上调用同一个对象的相同主法)方法接受第二个参数:如果没有提供请求参数则使用默认值:

<p>Hello, <?php echo $sf_params->get('name', 'John Doe') ?>!</p>

总结

在Symfony中,页面是由一个动作(actions/actions.class.php文件中以execute为前缀的一个方法)和一个模板(templates/目录下的一个文件,通常以Success.php结尾)组成的。他们通地在程序中的函数组织在一个模块中。编写模板是由帮助器来完成的,而帮助器则是由Symfony提供的返回HTML代码的函数。而我们需要将URL看作响应的一部分,而URL在需要可以格式化,所以我们应避免在动作命名中使用到URL的直接引用或者是请求参数检索。

一旦我们知道了这些基本原则,我们就可以使用Symfony来编写一个完整的Web程序了。但是我们的路还有很长,因为我们在程序开发过程需要处理的每一个任务由一些Symfony特性来完成的。

希望本文所述对大家的symfony框架程序设计有所帮助。

PHP 相关文章推荐
PHP怎样调用MSSQL的存储过程
Oct 09 PHP
php合并数组中相同元素的方法
Nov 13 PHP
php jsonp单引号转义
Nov 23 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
Jul 14 PHP
PHP页面输出搜索后跳转下一页的处理方法
Sep 30 PHP
PHP实现多图上传(结合uploadify插件)思路分析
Nov 30 PHP
thinkPHP模板中函数的使用方法示例
Nov 30 PHP
PHP实现查询手机归属地的方法详解
Apr 28 PHP
Yii2配置Nginx伪静态的方法
May 05 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
May 19 PHP
Laravel框架中Blade模板的用法示例
Aug 30 PHP
PHP有序表查找之二分查找(折半查找)算法示例
Feb 09 PHP
PHP中使用imagick生成PSD文件缩略图教程
Jan 26 #PHP
PHP中使用imagick实现把PDF转成图片
Jan 26 #PHP
PHP中使用Imagick操作PSD文件实例
Jan 26 #PHP
PHP实现将浏览历史页面网址保存到cookie的方法
Jan 26 #PHP
php ImageMagick windows下安装教程
Jan 26 #PHP
php的GD库imagettftext函数解决中文乱码问题
Jan 24 #PHP
php绘图之生成饼状图的方法
Jan 24 #PHP
You might like
[原创]效率较高的php下读取文本文件的代码
2008/07/02 PHP
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
php实现socket推送技术的示例
2017/12/20 PHP
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
JS弹出窗口代码大全(详细整理)
2012/12/21 Javascript
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
在js文件中如何获取basePath处理js路径问题
2013/07/10 Javascript
VS2008中使用JavaScript调用WebServices
2014/12/18 Javascript
JavaScript中的console.group()函数详细介绍
2014/12/29 Javascript
JS实现转动随机数抽奖特效代码
2020/04/16 Javascript
JS+CSS实现自动切换的网页滑动门菜单效果代码
2015/09/14 Javascript
jquery判断当前浏览器的实现代码
2015/11/07 Javascript
Angular中的interceptors拦截器
2017/06/25 Javascript
react-native中ListView组件点击跳转的方法示例
2017/09/30 Javascript
Vue2.5学习笔记之如何在项目中使用和配置Vue
2018/09/26 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
2019/01/23 Javascript
layui树形菜单动态遍历的例子
2019/09/23 Javascript
Jquery 动态添加元素并添加点击事件实现过程解析
2019/10/12 jQuery
[01:14:34]DOTA2上海特级锦标赛C组资格赛#2 LGD VS Newbee第一局
2016/02/28 DOTA
python编程开发之textwrap文本样式处理技巧
2015/11/13 Python
python使用matplotlib绘图时图例显示问题的解决
2017/04/27 Python
深入浅出学习python装饰器
2017/09/29 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
通过pykafka接收Kafka消息队列的方法
2018/12/27 Python
Python爬虫实现验证码登录代码实例
2019/05/10 Python
Python unittest单元测试框架实现参数化
2020/04/29 Python
PyQt5中QSpinBox计数器的实现
2021/01/18 Python
分享一个H5原生form表单的checkbox特效代码
2018/02/26 HTML / CSS
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
Spartoo英国:欧洲最大的网上鞋店
2016/09/13 全球购物
AVON雅芳官网:世界上最大的美容化妆品公司之一
2016/11/02 全球购物
小学语文课后反思精选
2014/04/25 职场文书
2016暑期校本培训心得体会
2016/01/08 职场文书
Python机器学习三大件之一numpy
2021/05/10 Python