Symfony2框架实战教程——第二天:创建新页面

在此之前,我们先明确一下我们要实现什么功能,在开始开展具体的代码工作前先明确自己的目标是一个节省时间的好习惯。我们的需求如下:

  1. 用户可以使用新浪微博或者QQ帐号登录。
  2. 用户可以投稿,需要填写的内容为“标题”+“正文”
  3. 用户可以对某篇文章进行评论

在以上的基础上,我们继续具体化我们的需求:

  1. 用户的内容都将使用markdown格式
  2. 评论内容不可超过140个字
  3. 新闻内容不可超过5000个字
  4. 标题内容不可超过70个字

好,到这里我们的需求已经很明确了,虽然简单得似乎不可能会有人用的样子~

修改配置文件

此时项目里还有很多不需要的文件。比如昨天我们看到的Symfony自带的演示页面。这些文件都应该被清理。不过清理之前请等一会儿,演示页面里有 一个“configure”功能我们还可以利用一下。点击了“configure”按钮以后我们可以对数据库、以及网站的密钥进行配置。其中第二步骤是设 置网站的“密钥”,先不用管“密钥”的用途,只管点“下一步”就行。

注意:由于我们此时需要使用Mysql来作为我们的数据存储方案,所以这里我们需要安装Mysql,并且在第一步里将driver设置为PDO_Mysql。由于我们这里只介绍Symfony2,关于Mysql的安装,不太熟悉的同学可以自行查询,相关文档也是非常之多,这里就略过了。当然,如果对存储层非常熟悉的同学,你们也可以选择熟悉的驱动,Mysql并不是唯一方案。

当两个步骤都完成之后,Symfony会提示你,新的配置已经取代了旧的配置。此时就可以把此演示项目从我们的项目代码里清理掉了。

刚才的步骤,其实只是修改了app/config/parameter.yml文件而已,直接修改也是可以的。此文件里包含了一些显而易见的配置,如果你英语还过关的话,应该一看就明白。

注意:如果安装的是2.7以及以上版本Symfony,只能直接修改app/config/parameter.yml文件

清理不需要的文件和代码

首先需要清理的是app/AppKernel.php文件。在这里首先说一个Symfony世界里的“术语”:

什么是Bundle

我认为Bundle并没有明确的定义,一般来说,如果某几个功能,相互之间有关联,并且相互影响,或者都属于某一类功能,这些功能就可以捆绑在一起 成为一个Bundle。Bundle是一个目录,里面包含了此Bundle的相关代码以及配置文件。“Bundle”本来就有“一捆”的意思。比如 Symfony自带演示项目Acme,就是一个Bundle的例子。在AcmeDemoBundle里的所有代码,都是为了演示用的,所以大家可以随意删 除此Bundle而不用担心会影响现有的项目。但为了大家的入门速度以及不把大家搞晕,这里先不多说了。

现在打开app/AppKernel.php

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

// ...

class AppKernel extends Kernel

{

public function registerBundles()

{

$bundles = array(

new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),

new Symfony\Bundle\SecurityBundle\SecurityBundle(),

new Symfony\Bundle\TwigBundle\TwigBundle(),

new Symfony\Bundle\MonologBundle\MonologBundle(),

new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),

new Symfony\Bundle\AsseticBundle\AsseticBundle(),

new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),

new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),

new AppBundle\AppBundle(),

);

if (in_array($this->getEnvironment(), array(‘dev‘, ‘test‘))) {

$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();

$bundles[] = new AcmeDemo\Bundle\AcmeDemoBundle();

$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();

$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();

$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();

}

return $bundles;

}

// ...

}

仔细观察registerBundles(注册Bundles)方法,可以看到此方法有许多名为XxxBundle的 实例。所有的Bundle都需要一个类作为此Bundle的“代表”。只有Bundle的代表在此方法里被注册了,才可以使用此Bundle里的配置以及 服务。大家可以看到此方法里已经注册了许多Bundle。假如我们不使用twig作为我们的模板引擎,我们是完全可以把TwigBundle那行直接删除掉的。支持Symfony框架的第三方库,都是以Bundle的方式存在。后面我们便会举例子如何注册第三方Bundle。

之前已经透露,演示项目的Bundle名叫“AcmeDemoBundle”,我们直接把AcmeDemoBundle那一行删掉。注意AcmeDemoBundle是在if里的,意思是如果当前环境是dev或者test,才注册AcmeDemoBundle。这个判断是什么意思?大家打开web目录,可以发现有app.php以及app_dev.php两个文件,大家先不要急着看这两个文件的内容,只用知道这两个文件都是入口文件就行了。所有的请求,都会首先执行它们中的其中一个,其实看文件名大家也应该明白app_dev.php是开发的时候用的入口文件。昨天使用php app/console server:start localhost:8000命令开启web server的时候,此命令已经自动将app_dev.php作为了入口文件。当我们的项目完成上线,就应该使用Nginx、Apache等Web Server把app.php作为入口文件。

开发环境不同会导致什么不同?再来看看if里的代码:不仅AcmeDemoBundle,在这个if里的所有Bundle都是为了开发而存在的,比如DebugBundle是为了在代码里使用dump()方法打印格式化好的变量信息,WebProfilerBundle则是为了收集开发所需要的调试数据,并且有好看的页面可以显示这些数据,是我们开发的好帮手。我们看到演示页面最下面的那条工具栏,就是WebProfilerBundle里包含的,后面我们将经常使用此工具栏做开发调试分析工作。

app/AppKernel.php删除了AcmeDemoBundle那行代码之后,刷新页面,发现报错:

FileLoaderLoadException in FileLoader.php line 120: Bundle “AcmeDemoBundle” does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your AppKernel.php file? in @AcmeDemoBundle/Resources/config/routing.yml (which is being imported from “/…/app/config/routing_dev.yml”). Make sure the “AcmeDemoBundle” bundle is correctly registered and loaded in the application kernel class.

意思是说,你是否忘记在AppKernel.php文件里注册AcmeDemoBundle?因为在app/config/routing_dev.yml里还有AcmeDemoBundle的相关配置。

错误信息给我们提供了一个线索:app/config/routing_dev.yml文件里也有需要删除的代码。我们将此文件打开,将一下代码也删除掉(代码里也有注释说“以下代码应该被删除”)

1

2

3

4

# AcmeDemoBundle routes (to be removed)

_acme_demo:

resource: "@AcmeDemoBundle/Resources/config/routing.yml"

此文件是一个“YAML”格式文件,关于此文件格式这里也不多说,大家也不用有太多压力,因为YAML格式非常好懂,Symfony2的大多数配置 文件,都是使用的YAML格式。Symfony2支持多种文件格式作为配置文件,常见的还有XML文件,以及直接使用PHP来写配置文件。对于配置文件的 选择来说,XML可以使用DTD来做校验,所以一些风格严谨的第三方Bundle内部的配置文件是用的XML,但XML有写起来繁琐的问题,而编写方便正 是YAML的优点。在这里我们遵守Symfony installer帮我们做的选择:使用YAML。需要注意:YAML和XML不是一个Bundle只能用一种,他们是可以混用的,而且从性能速度来说, 没有丝毫差别,因为最终都会被编译成PHP文件。除了以上说的几种格式外,还有一种叫做“注解”的格式,后面再介绍。

routing***.yml定义了访问我们的项目的访问路径。Symfony2框架使用的“前端控制器”模式来处理HTTP访问的需求,即每一种形式的路径,都将映射到某个类的某个方法来处理。比如说当用户访问/hello/{name}路径的时候,我们可以将此路径映射到AppBundle里的HelloController(一般称为“控制器类”)的helloAction($name)(一般称为控制器方法)方法来处理。routing***.yml文件就是用来描述这种映射关系的。并且routing***.yml文件可以有包含关系,我们可以看到routing_dev.yml包含了routing.yml文件。另外,我们从文件名也可以看出,routing_dev.yml是开发环境才加载的配置。

routing_dev.yml里删除掉acme相关的路由以后,再访问首页。我们可以发现错误信息变了:

No route found for “GET /”

“route”即“路由映射规则”,出现此错误说明已经没有关于“GET /”路径相关的配置了。这说明至少从配置上,我们已经把AcmeDemoBundle删除掉了。

接下来我们再删除掉src/Acme目录,清理工作便告一段落,说是一个段落的原因是还有一个比较关键的配置文件我们没有提到,但不影响接下来的开发。以后会说。

添加页面

每次访问首页都报错,不是个好兆头,怎么着我们得有一个首页,无论有多简单。

按我们之前所说,要想首页能够被访问,我们得在routing***.yml里添加有关首页的配置。

由于首页是无论开发环境还是生产环境都需要访问的,我们就把配置写在routing.yml里好了,注意之前说过routing_dev.yml已经包含了routing.yml了。

我们打开app/config/routing.yml文件,可以看到已经有如下内容:

1

2

3

4

app:

resource: @AppBundle/Controller/

type:     annotation

这里的resource指向的不是一个文件,而是一个路径:@AppBundle我想不用多说,一定是指AppBundle所在的目录,也就是src/AppBundle。是的,resource可以不用指定某个具体的文件,目录也行,意思是:此目录内的所有配置文件都包含进来,甚至包括子目录的配置。

然后type的值为annotation,这就是之前说的“注解”格式。

我们打开@AppBundle/Controller/里随便什么文件,看看注解格式到底是个啥。

@AppBundle/Controller/目录里目前只包含一个DefaultController.php,打开此PHP文件:

1

2

3

4

5

6

7

8

9

10

11

12

// ...

class DefaultController extends Controller

{

/**

* @Route("/app/example", name="homepage")

*/

public function indexAction()

{

return $this->render(‘default/index.html.twig‘);

}

}

仔细观察,像是配置的代码,很明显是@Route("/app/example", name="homepage")那一行。原来“注解”格式,即是写在代码里的注释。使用此格式的配置有一些其他格式不可比拟的好处,比如方便重构(举个栗子:控制器名字改了,改1个文件VS改2个文件)。

既然Symfony installer帮我们生成了此文件,我们也继续沿用。我们要做的只是把路径改成首页。然后路由名改短一点,路由名是个什么,后面会说到:

1

2

3

4

5

/**

* @Route("/", name="home")

*/

public function indexAction()

这个时候我们再访问首页,会出现写着“Homepage.”的页面。

这个“Homepage.”又是从哪儿来的?看代码里面给我们提供的线索:indexAction里返回了一个$this->render(‘default/index.html.twig‘),如果英语过关,很容易看出来此方法做的事情,就是“渲染”了一个模板文件default/index.html.twig

模板文件默认目录位于app/Resources/views/,所产我们要找的文件位于app/Resources/views/default/index.html.twig,打开此文件可以看到里面有一行Homepage.,以及一些其他的代码。现在我们不用管其他的代码。

为了方便开发我们的“新闻”板块。我们先给首页加一个链接/news

我们可以直接将Homepage.替换成<a href="/news">新闻</a>。但是这样做有一个不好的地方:如果想改路径,比如改成/新闻,那么每个连接到“新闻”的href="/news"都需要改一遍。Symfony2以及Laravel或者ROR等现代框架,几乎都支持“双向路由”,即在路径和对应的控制器方法之间,再加一个路由名。此路由名可对应一个路径,又对应一个控制器方法。前端模板里不再直接写路径,而是写路由名:

1

2

<a href="{{ path(‘news_index‘) }}">新闻</a>

以后想修改路径,都只用改一下配置文件即可。

修改好以上代码,再访问首页,又会出现以下错误:

An exception has been thrown during the rendering of a template (“Unable to generate a URL for the named route “news_index” as such route does not exist.”) in default/index.html.twig at line 4.

意思是,目前还没有一个叫news的路由规则。OK我们现在来创建它:

我们把新闻相关的路径都放在AppBundle\Controller\NewsController类里:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<?php

// src/AppBundle/Controller/NewsController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

/**

* @Route("/news")

*/

class NewsController extends Controller

{

/**

* @Route("/", name="news_index")

*/

public function indexAction()

{

return $this->render(‘news/index.html.twig‘);

}

}

并且为其创建模板文件app/Resources/views/news/index.html.twig,目前就是空文件就行。

此时再刷新首页,错误消失。并且“新闻“已经可以点击。

创建文件时需要大家注意的是,一定要确认代码的文件的编码格式是UTF-8,否则会出现不可预料的字符乱码问题

时间: 2024-10-25 07:52:08

Symfony2框架实战教程——第二天:创建新页面的相关文章

Symfony2框架实战教程——第一天:创建项目

Symfony2的教程非常的详尽,但是却不太亲近新手.新手想要完全理解Symfony2文档的内容,需要对互联网开发有一定工作经验才行,否则 总是有一种看不太明白,看完了也不不知道从哪儿开始的感觉.如果你有这种感觉,希望这篇文章能让你快速上手,本篇的目的,就是为了让Symfony2新 手,甚至是PHP新手能快速开始一个具体的项目. 本篇系列重点是为了带领新手使用Symfony2框架,如果您想了解的是Symfony2组件,可阅读我翻译Symfony2项目组老大的系列教程<使用Symfony2组件创建

Symfony2框架实战教程——第五天:KnpMenuBundle创建菜单项+结合Twitter Boostrap3

做界面最好从交互比较多的页面入手,目前交互元素比较丰富的,有新闻列表页和新闻显示页. 为了开发快速,但也不会让界面太难看,我打算直接用Twitter Boostrap3了. 如果是看过我前几期文章的同学一定能猜得到,我一定又要说:“是的,像boostrap3这种常用的前端开发框架,相应的Bundle也是有的”.没错!这次我向大家推荐MopaBootstrapBundle,里面包含了使用LESS/SASS编译Boostrap CSS,支持让Symfony2框架以及常见Bundle比如我们的用过的K

Symfony2框架实战教程——第六天:模板重载与翻译

在未登录状态下点击“+发表新闻”按钮,也就是/news/new链接,会转跳到/oauth/login/链接,也就是第三方登录的链接(如果只实现了本地用户登录的同学,去的应该是另外一个界面,不过没关系,重载模板的原理都一样).目前第三方登录页面只有一个可怜巴巴的“QQ”这个链接,让我们也给它加上页头页尾. 不过,这个模板文件很明显不是我们自己添加的,是第三方Bundle里自带的,难道我们要去修改第三方Bundle的代码吗?库文件随便修改这样好吗?当然不好,好消息是Symfony2框架实际是提供了框

Symfony2框架实战教程——第三天:用KnpPaginatorBundle实现翻页

创建业务数据模型 新闻数据算是我们业务模型里必不可少的模型之一.根据我们之前对需求的分析,我们可以很容易想到,新闻模型News需要的属性: 标题属性 文本属性 接下来,我们要在AppBundle里创建它,但是这些数据还需要一个持久层来保存数据,例如之前配置的Mysql.目前流行的开发方式,无论是Java还是ROR,都会使用ORM将数据库字段和类属性关联起来. Symfony2框架本身并不包含ORM工具(严格意义上来说,Symfony2框架,即FrameworkBundle,不包含ORM,安全组

Symfony2框架实战教程——第六天#Alt:验证码

如果读者是从表世界过来的,应该知道怎么通过重载模板来改变第三方Bundle提供的模板.这里我们将重载用户登录页面作为作业留给大家,我们先来重载注册页面,不过为了提供新鲜的知识点,我们这次除了要装修注册页面以外,还要求给注册页面提供验证码. 对于我这种收集bundle的高手,自然少不了推荐验证码相关的bundle:GregwarCaptchaBundle 一如既往安装Bundle 1 2 $ composer require gregwar/captcha-bundle 一如既往注册Bundle

Symfony2框架实战教程——第四天:用HWIOAuthBundle实现第三方登录

为了方便用户能快速发布内容,我们只用要求QQ的第三方登录就行了. 如果你打算跟着我一起完成这个项目,可能会因为QQ需要验证你是否有个人域名而卡在这一章,我写了一篇不用OAuth的.但本篇文章也最好看看,大部分知识点是完全一样的. 使用HWIOAuthBundle实现第三方登录 可以想象得到,第三方登录这种常见需求,相关的库也是有的.这里我再推荐一个:HWIOAuthBundle 如同昨日,我们先将它通过Composer引入到我们项目当中: 1 2 $ composer require "hwi/

Drupal8开发教程:模块开发——创建新页面

之前我们已经通过<Drupal8开发教程:认识.info.yml文件>对模块的YAML文件有了了解,今天我们来看如何通过模块开发的方式添加一个新的页面. 在 Drupal 7 中,通过模块添加新页面非常简单,使用 hook_menu 定义路径及回调函数返回要显示的结果即可.但 Drupal 8 却要麻烦很多,虽然也是定义路径,然后关联用于显示内容的函数,但却要在两个文件中分开进行.而且 Controller 文件还有目录结构要求,这些变化都需要慢慢来适应了. 除了上文中定义的 hello_wo

android教程:Android创建新项目及开发

android教程:Android创建新项目及开发,这篇文章是比较简单的知识,比较适合才入门的同学们看,当然,大家也可以来看看我总结的,给小编一点意见,说说你们的看法! 创建一个新项目是很简单的,只要你安装了Eclipse插件,并且你的Eclipse软件版本在3.2或3.3,你就可以开始开发了. 首先, 看一下要创建Hello, World程序从高级层面上有哪些步骤: 1.通过 File -> New -> Project 菜单,建立新项目Android Project 2.填写新项目各种参数

React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块

尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息.为大家精心准备的React Native视频教程公布了,大家现能够看视频学React Native了. 前言 一直想写一下我在React Native原生模块封装方面的一些经验和心得.来分享给大家,但实在抽不开身.今天看了一下日历发现立即就春节了.所以就赶在春节之前将这篇博文写好并公布(事实上是两篇