Skip to content
Caution: You are browsing the legacy symfony 1.x part of this website.

第一天: 开始项目

Language
ORM

简介

symfony 框架作为开源项目经过三年多发展,已经成为最流行的PHP框架之一了,这得归功于 她出众的性能和丰富的文档,而这个伟大的传统很早就开始了。

2005年12月,symfony发布了第一个官方版本时,我们发布了"Askeet 系列教程", 由24个子教程组成,从12月1日持续到圣诞节,持续不断每天发布。

事实证明该教程是非常好的向新手推广 symfony 框架的工具。许多开发者因为 askeet 而掌握了 symfony 框架, 而很多公司到现在还在使用askeet作为主要的培训资料。

现在,当在我们庆祝 symfony1.2 版本发布的时,askeet系列教程也日显过时。是时候发布一个新的教程了。

现在,请加入2008年的 Jobeet 事件日历教程!

挑战

没错,我们要再做一遍。每天,包括周末,我们会发布一个新的教程。每个教程持续大约一个小时左右, 是学习使用 symfony 做从头到尾做一个真实的web项目的好机会。

24个一小时等于一天,这正是我们估计的一个开发者要掌握 symfony 基础知识所需要的时间。 每天,我们都会向程序中加入新的功能,借开发过程向你展示 symfony 的新功能 以及 symfony web 开发过程中的最佳实践。

对于 Askeet 来说,这21天可称作“一天修成 Symfony 骨灰级专家”。我们没有预先安排, 而是由社区决定 askeet 的功能。这非常成功,社区决定我们的程序中需要搜索引擎。当 然,我们做到了。事实证明,第21天的教程是 askeet 系列教程中最受欢迎的。

对Jobeet来说,我们要在第21天以“设计者日”来庆祝冬天的到来。在第四天的教程后,你将 获得设计 Jobeet 公开站点需要的所有HTML和CSS信息。因此,如果你有设计师拍档或者 你公司有设计部门,你不妨向我们提交设计稿。在第21天,我们会组织一次投票,由社区 来选择默认绑定到 Jobeet 的发布包里的设计稿,而您将获得署名权及其相关的一系列荣誉。

这个教程与众不同

还记得在 PHP4 早期的时候,真是一段美好的时光啊!, PHP作为最高专注于WEB的语言,学起来非常容易。

但是随着 web 技术飞速发展,web 开发者需要掌握最新的最佳实践和工具。获取这些知识的最佳途径 当然是阅读博客、教程。我们也读了不少,PHP、Python、Java、Ruby或者Perl等各种语言编写的都有, 林林总总,但很多作者给出的示例代码片段却比较失败。

你可能会读到这样子的句子:

“在实际编程中,不要忘了添加验证代码并做适当的错误处理。”

或者

“安全问题留下来请读者当做练习。”

或者

“当然,你应事先编写测试用例的。”

什么?这些都是很严肃的事情。在任何一份代码中,这都差不多是最重要。作为读者, 你被丢下不管了。如果不解决这些实际问题,例子显得苍白无力。他们不能给你一个很好的启蒙。 这太不好了。为啥?安全、验证、错误处理和测试用例等都严重关乎代码的正确性的。

在这个教程中,我们会编写测试用例、错误处理、验证代码以确保我们开发的程序是安全可靠的, 你不会再感到失落了。因为,synfony 关心代码, 但更关心最佳实践和怎样开发专业的企业级应用。 我们能够提供这些丰富的功能,全都要归功于 symfony 为我们提供了必须的工具因而不需编写太多 代码就可完成任务。

在 symfony 的国度里,验证、错误处理、安全和测试用例是一等公民,不须我们花太多时间去解释。 这也是为什么在实际的项目开发中我们需要使用框架的原因。

本教程中的所有代码,你都可以用到实际开发的项目中去。我们鼓励你摘抄代码片段甚至整个拿去使用。

关于项目

我们计划的项目用“又一个博客引擎”来概括。但是我们需要使用 symfony 来创建一个有用的项目。 目标就是展示我们只需付出小小的努力就可以用 symfony 来开发出具有专业水准的带样式的程序,

项目的其他细节将作为秘密在后续的教程中一一揭晓,今天我们已经说了不少了。至少,你已经 知道我们的项目名称了:Jobeet

那,今天做什么呢?

用24个小时来开发一个 symfony 项目时间是非常充沛的,但我们今天不写PHP代码。虽然我们 不编写任何代码,但我们就可以开启一个新的项目,仅仅这一点就能耐让你开始了解使用 symfony 这样的框架所带来的好处了。

今天的目标是搭建开发环境并能在浏览器中访问项目页面,包括了安装 symfony 、创建项目和 配置 web 服务器等步骤。

预备知识

首先,你得有一个已经配置好的 web 开发环境,包括 web 服务器(如 Apache)、数据 库(MysQL、PostgreSQL或者SQLite)以及5.2.4以上版本的PHP。

因为我们会更多的使用命令行,你最好是使用Unix风格的操作系统。当然,如果你使用Windows系统, 也没关系,只是会在 cmd 命令提示符下多敲不少的命令而已。

note

在 Windows 环境下配置 Unix 命令行也是很容易的。 如果你在 Windows 希望使用诸如tar, gzip, 和 grep 等工具 你可以安装 Cygwin. 官方的文档或许不够用,你可以在 这里找到一篇很好的安装教程。. 喜欢专研的同志不妨去试试微软自己的Windows Services for Unix

由于本教程主要关注 symfony 框架本身,我们还希望你已经具有扎实的 PHP5 相关知识和面向对象编程的背景。

安装 Symfony

首先,创建一个目录来保存 Jobeet 项目相关的文档:

$ mkdir -p /home/sfprojects/jobeet
$ cd /home/sfprojects/jobeet

在Windows下:

c:\> mkdir c:\development\sfprojects\jobeet
c:\> cd c:\development\sfprojects\jobeet

note

建议Windows用户避免在诸如Documents and Settings 目录 和 My Documents 等带有空格的路径下使用symfony和搭建项目

创建存放 symfony 框架文件的目录。

$ mkdir -p lib/vendor

要安装symfony,从 symfony 官方网站下载安装包。 因为本教程是为 symfony1.2 编写的,请下载此版本下的最新子版本。

在“源码下载”栏目下,你将找到.tgz或者.zip格式的安装包,下载并保存到刚创建的lib/vendor目录里解压开来:

$ cd lib/vendor
$ tar zxpf symfony-1.2-latest.tgz
$ mv symfony-1.2.0 symfony

在 Windows 下可直接用文件浏览器解压 zip 文件。将目录重命名为symfony后,系统 应存在c:\development\sfprojects\jobeet\lib\vendor\symfony这个目录。

运行 symfony 命令行,显示symfony版本号,以确认 symfony 已经正确的安装(注意是大写的V)。

$ cd ../..
$ php lib/vendor/symfony/data/bin/symfony -V

在windows下:

c:\> cd ..\..
c:\> php lib\vendor\symfony\data\bin\symfony -V

如果想知道这个命令行工具可以干些啥,直接运行symfony将列出所有支持的选项和任务。

$ php lib/vendor/symfony/data/bin/symfony

在windows下:

c:\> php lib\vendor\symfony\data\bin\symfony

symfony 命令行是开发者的好朋友。它提供了大量的工具来提高你日常工作的效率, 比如清除缓存、生成代码等等。

建立项目

在symfony中,使用相同的数据模型的 应用程序(applications) 组成 项目(projects)。以 Jobeet 项目为例,我们会有两个不同的应用程序:前台和后台。

创建项目

jobeet目录下运行 symfony 任务generate:project生成symfony项目:

$ php lib/vendor/symfony/data/bin/symfony generate:project jobeet

在windows下:

c:\> php lib\vendor\symfony\data\bin\symfony generate:project jobeet

generate:project任务生成了 symfony 项目默认的文件和目录结构:

目录 说明
apps/ 存放项目的所有应用程序
cache/ 框架的缓存文件
config/ 项目配置文件
lib/ 项目使用到的类和库
log/ 项目日志文件
plugins/ 安装的插件
test/ 单元测试和功能测试文件
web/ 网站根目录(见下文)

note

为啥symfony生成了这么多文件?使用全栈式框架的主要好处是标准化你的开发。 得益于symfny的默认文件目录结构,任何具有 symfony 知识的开发者都可以接手任何 symfony 项目。大约几分钟后,他就能够深入到代码中修正bug、增加新的功能。

generate:project 任务还创建了一个symfony 快捷方式在 Jobeet 项目的根目录 来减少你运行任务时需要键入的命令代码。

因此,从现在起,你可以只输入symfony来调用symfony命令了。

生成应用程序

现在,我们运行generate:app 命令生成前台应用程序。

$ php symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret frontend

tip

因为symfony文件是可执行的,Unix用户在后面遇到的所有的 'php symfony'都可以用 './symfony' 替代。

Windows下的用户可以拷贝 'symfony.bat' 文件到项目根目录,使用'symfony'替代 'php symfony':

c:\> copy lib\vendor\symfony\data\bin\symfony.bat .

再一次的,generate:app 任务帮我们在apps/frontend目录下创建了应用程序的默认文件目录结构

目录 说明
config/ 应用程序配置文档
lib/ 应用程序需要的类和库
modules/ 应用程序的代码 (MVC)
templates/ 全局的模板文件

tip

除非特别说明,所有的symfony命令都请在项目的根目录下运行。

当我们运行 generate:app 任务时,我们还传入了两个和安全相关的选项:

  • --escaping-strategy: 激活输出转义来避免XSS攻击
  • --csrf-secret: 激活session密码来避免CSRF攻击。

通过传递这两个可选选项给任务,我们已经让即将开发的应用程序直接针对目前网络上流 传甚广的两大安全隐患免疫。symfony 会自动替我们处理安全问题,很棒吧。

note

如果你还不知道XSSCSRF的话,花点时间了解更多的关于这些安全隐患吧。

symfony 路径

你可以通过运行如下命令来获得symfony版本:

$ php symfony -V

-V选项还会在结果中显示symfony的安装路径,这可以在config/ProjectConfiguration.class.php中找到:

// config/ProjectConfiguration.class.php
require_once '/Users/fabien/work/symfony/dev/1.2/lib/autoload/sfCoreAutoload.class.php';

为方便移植项目,修改到 symfony 的绝对路径为相对路径:

// config/ProjectConfiguration.class.php
require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';

这样,把 Jobeet 项目移动到本机或其他及其的任意目录都可以正常运行。

环境

web/目录下的两个PHP文件index.phpfrontend_dev.php 被称作前端控制器: 向应用程序发送的所有请求都通过他们来转达。但我们只有一个应用程序,为啥要有两个前端控制器呢?

两个文件都指向同一个应用程序但适用于不同的环境。除非直接在生产服务器上开发应用程序,你至少需要如下几个环境:

  • 开发环境: web 开发者可用他来添加新的夹具、修订bug ...
  • 测试环境: 此环境用于自动测试应用程序.
  • 阶段环境: 用于客户 测试应用程序和报告Bug和缺失的功能。
  • 生产环境: 这才和最终用户打交道。

什么使环境如此不同?在开发环境中,应用程序需要记录一次请求的所有细节来方便开发, 异常信息必须在浏览器中显示出来,但是必须关闭缓存系统以便所有的代码改动都能马上生效。 因此,开发环境必须针对开发者优化。

An exception in the dev environment

作为生产环境下,应用程序应显示自定义的错误信息,二不是原始的异常信息。当然,缓存必须开启。因此,生产环境必须针对性能和用户体验优化。

An exception in the prod environment

Symfony 环境是一套特殊的配置,内置的有三个devtestprod

你打开前端控制器文件,你能比较出他们唯一的不同就是环境设置:

// web/index.php
<?php
 
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
 
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

note

要定义一个新的symfony环境,我们只需简单的创建一个前端控制器。后面我们会讨论如何修改一个环境下的配置。

蹩脚的 Web 服务器配置

如果在前面小节中你将 Jobeet 项目的创建到了 web 服务器的根目录,你已经能够通过浏览器访问到这个项目了。

当然了,因为不需要任何配置,这很方便,但是当你试着访问config/databases.yml时,就会发现偷懒所带来的严重后果。

永远不要在生产服务器上像这样配置并请阅读下一小节以正确的配置你的web服务器。

安全的 Web 服务器配置

好的方式是只将需要通过浏览器访问的如样式表、javascripts和图片等放到根目录。 而且,作为默认设置,我们推荐将这些文件保存在 symfony 项目的web子目录。

在这个目录下保存着web组件和两个前端控制器文件。前端控制器是唯一需要放在web服务器 根目录下的PHP文件。其他PHP文件都将隐藏在浏览器的眼皮底下,考虑到安全因素,这是一个很好的注意。

web服务器配置

是时候修改 Apache 配置让全世界人民都可以访问你的网站了。

现在请修改 apache 配置文件以方便所有人都能访问我们的新项目。找到并打开 httpd.conf 配置文件,在文末加入如下配置:

# 请确保下面这行在配置文件只出现一次
NameVirtualHost 127.0.0.1:8080

# 这是针对 Jobeet 项目的配置
Listen 127.0.0.1:8080

<VirtualHost 127.0.0.1:8080>
  DocumentRoot "/home/sfprojects/jobeet/web"
  DirectoryIndex index.php
  <Directory "/home/sfprojects/jobeet/web">
    AllowOverride All
    Allow from All
  </Directory>

  Alias /sf /usr/local/symfony/data/web/sf
  <Directory "/usr/local/symfony/data/web/sf">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

note

别名/sf让你能够访问到显示 symfony 默认页和调试工具栏时需要的图片和javascripts文件。 Windows 下, 你需要像下面这样替换 Alias 行:

Alias /sf "c:\development\symfony\data\web\sf"

/home/sfprojects/jobeet/web 应替换为:

c:\development\sfprojects\jobeet\web

这样配置会让 apache 在机器的8080端口监听,因此可以使用如下URL访问Jobeet:

http://localhost:8080/

你可以将8080替换为大于1024的任何端口,因为这不需要服务器管理权限。

sidebar

为 Jobeet 配置独立域名

如果你是服务器的管理员,最好是设置虚拟主机而不要每新增一个项目就新增一个端口。也就是以 选择合适的域名并加入ServerName指令来代替选择端口并加入Listen指令的方式。

# This is the configuration for Jobeet
<VirtualHost 127.0.0.1:80>
  ServerName jobeet.localhost
  <!-- same configuration as before -->
</VirtualHost>

域名jobeet.localhost 必须在本地声明并解析。如果你是LInux操作系统, 可以编辑 /etc/hosts文件. 如果是 Windows XP, 文件则在C:\WINDOWS\system32\drivers\etc\ 目录下. 加入如下行:

127.0.0.1         jobeet.localhost

测试新的配置

重启apache, 根据上一小节的 apache 配置,打开浏览器访问http://localhost:8080/index.php/, 或者 http://jobeet.localhost/index.php/, 确保你现在能够访问新的应用程序。

Congratulations

note

如果你安装了apache的mod_rewrite模块,可以删除URL中的 /index.php/ 部分。

你还可以试着访问开发环境下的应用程序。键入如下URL:

键入如下URL:

http://jobeet.localhost/frontend_dev.php/

web调试工具栏应该能显示在右上角,包括小图标,这表明我们前面的sf/ 别名已配置成功。

web debug toolbar

note

在 Windows 下的IIS服务器运行 symfony 时配置稍有不同。请[到这里查找相关教程]学习怎样配置

Subversion

开发期间采用源代码版本控制是非常好主意。使用源码控制我们可以:

  • 信心满满的工作
  • 如果改动破坏了啥我们可以恢复到旧版本
  • 允许超过1个人来有效的工作在项目下
  • 允许访问应用程序的每一个正确运行的版本。

我们将在本节讲解怎样使用Subversion配合 symfony 项目开发。 如果你使用的是其他的源码版本控制器,从我们介绍的Subversion转过去也是很容易的。

我们假定你已经有一台可以访问 Subversion 服务器了。

tip

如果你还没有 subversion 服务器,你可以到 Google Code免费申请,或者在Google键入 "免费 subversion 版本仓库"等关键词查找更多可用的服务器。

首先,我们为jobeet项目创建一个新的仓库

$ svnadmin create http://svn.example.com/jobeet
$ svn mkdir -m "created default directory structure" http://svn.example.com/jobeet/trunk http://svn.example.com/jobeet/tags http://svn.example.com/jobeet/branches

然后,清空cache/log/目录下的内容,我们不需要将他们纳入版本控制。

$ cd /home/sfprojects/jobeet
$ rm -rf cache/*
$ rm -rf log/*

现在,确保cache和logs目录拥有写入权限以便 web 服务器向其中写入内容:

$ chmod 777 cache
$ chmod 777 log

下一步,做第一次导入:

$ svn import -m "made the initial import" . http://svn.example.com/jobeet/trunk

因为我们永远不需要提交cache//log目录下的内容,你可以设定忽略名单:

$ svn propedit svn:ignore cache

为SVN配置的默认文本编辑器将自动打开。我们需要 Subversion 让忽略此目录下的所有内容:

*

存盘退出。做好了。

针对log/目录重复如上操作:

$ svn propedit svn:ignore log

并键入:

*

最后,将这些改动提交到仓库:

$ svn import -m "added cache/ and log/ content in the ignore list"

tip

Windows用户可以使用TortoiseSVN这个很棒的客户端来管理 Subversion 仓库。

Note 我们会逐日公开 Jobeet SVN 代码仓库.

因此,就算是整个仓库还没有公开 (http://svn.jobeet.org/)今天的代码也已经提交并打上了标签。

你可以取出今天的代码,release_day_01:

  $ svn co http://svn.jobeet.org/tags/release_day_01/ jobeet/

明天见

好了,今天的时间差不多了。虽然我们还没有开始讲到 symfony ,但我们已经搭建了可靠的 开发环境,还提到了web开发的最佳实践,做好开始编码的准备了。

明天,我们将透露这个应用程序会做些什么并开始深入symfony。期间如果你想知道关于Jobeet 的最新消息, 别忘了订阅symfony 的博客种子

别忘了,明天我们继续哦!

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.