请问一下哪个苹果屏下指纹专利IC芯片没有专利困扰?

博客访问: 765612
博文数量: 238
博客积分: 10681
博客等级: 上将
技术积分: 2449
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 系统运维
我们的第一个Symfory工程现在我们试验一下Symfony。我们要在一个小时内构建一个全功能的网络程序。一个书店销售程序?可以!一个Weblog!这是一个好主意。让我们开始吧。安装Symfony并且初始化工程为了方便,我们将会使用Symfony沙盒。这是一个空的Symfony工程,在其中已经包含了所有所需要的库,并且完成了基本的配置。比起其他类型的安装,沙盒的最大优点就是我们可以立刻试验Symfony。下载sf_sandbox.tgz,并且将其解压到我们的网络目录的根目录下。我们可以查看其中的readme文件,从而得以更为详细的信息。生成的文件结构如下所示:www/& sf_sandbox/&&& apps/&&&&& frontend/&&& batch/&&& cache/&&& config/&&& data/&&&&& sql/&&& doc/&&& lib/&&&&& model/&&& log/&&& plugins/&&& test/&&& web/&&&&& css/&&&&& images/&&&&& js/从这里我们可以看出sf_sandbox工程包含一个前端程序。我们可以通过请求下面的URL来测试沙盒:http://localhost/sf_sandbox/web/index.php/我们应会看到一个祝贺页面。我们也可以将symfony安装一个定制的目录中,并且使用一个虚拟主机或是一个Alias设置我们的网络服务器。初始化数据模型所以Weblog应可以处理文章发布,并且我们可以进行评论。在sf_sandbox/config下创建一个schema.yml文件,并且将下面的数据模型粘贴到其中:propel:& weblog_post:&&& _attributes: { phpName: Post }&&& id:&&& title:&&&&&& varchar(255)&&& excerpt:&&&& longvarchar&&& body:&&&&&&& longvarchar&&& created_at:& weblog_comment:&&& _attributes: { phpName: Comment }&&& id:&&& post_id:&&& author:&&&&& varchar(255)&&& email:&&&&&& varchar(255)&&& body:&&&&&&& longvarchar&&& created_at:这个配置文件使用YAML语法。这是一个非常简单的语言,可以通过缩进来描述类XML的树结构。而且,他具有比XML更快的读写速度。唯一的问题就是缩进是具有意义的,而且不允许使用Tab,所以记住要使用空格来进行缩进。我们将会在配置一章中了解更多的YAML以及symfony配置的内容。这个概要描述了weblog所需要的两个表的结构。Post与Comment是要创建的相关类的名字。保存这个文件,打开一个命令行,进行sf_sandbox目录,并且执行下面的命令:$ php symfony propel-build-model注意:要保证我们在调用symfony命令时在我们工程的根目录下。在sf_sandbox/lib/model/目录下创建了一些类。这些是对象相关映射的类,这允许我们在面向对象的代码中而不使用单一的SQL查询来访问相关的数据库。为了这个目的,Symfony使用Propel库。我们将这些对象称之为模型(model)。现在我们执行下面的命令:$ php symfony propel-build-sql这会在sf_sandbox/data/sql/目录下创建一个lib.model.schema.sql文件。这个SQL查询可以用来使用相同的表结构来初始化一个数据库。我们可以使用命令行或是Web界面在MySQL中创建一个数据库。幸运的是symfony沙盒的配置使用一个简单的SQLite文件来进行工作,所以不需要数据库的初始化工作。默认情况下,sf_sandbox工程会使用sf_sandbox/data/目录中的sandbox.db进行工作。要构建基于SQL文件的表结构,可以输入下面的命令:$ php symfony propel-insert-sql注意:如果此时有警告并不用担心。insert-sql命令在添加我们的lib.model.schema.sql数据表之前会移除已存在的数据表,而在此时并没有需要移除的数据表。(注:此时如果我们需要连接的是MySQL数据的话,我们做如下的一些修改:1 修改config/databases.yml,其param:下的参数部分分别为:phptype:指明我们要使用的数据库类型hostspec:指明我们所要用的数据库所在的域名database:指明我们要使用的数据库的名字username:指明我们连接数据库所用的用户名password:指明我们连接数据库所用的密码2 修改config/propel.ini,所需要修改的部分如下:propel.database:指明我们需要使用的数据库类型propel.database.createUrl:我们需要使用的数据库所在的主机地址,其格式为mysql://username:password@domain/,其各部分分别为用户名,密码以及域名propel.database.url:我们需要使用的数据库的地址,其格式为:mysql://username:password@domain/database,其各部分分别为用户名,密码,密码以及数据库的名字)创建程序框架一个Blog的基本特征是可以创建,获取,更新以及删除发表及评论。因为我们是初次接触Symfony,所以我们不会从头开始创建Symfony代码,而是让Symfony创建一个我们可以使用并且在需要时可以修改的程序框架。Symfony可以解释数据模型来自动创建CRUD接口。$ php symfony propel-generate-crud frontend post Post$ php symfony propel-generate-crud frontend comment Comment$ php symfony clear-cacheOn *nix systems, you will have to change some rights:$ chmod 777 data$ chmod 777 data/sandbox.db现在我们就拥有了两个可以用来处理Post与Comment类的模型(post,comment)。一个模型(module)通常代表一个页面或是具有相似目的的一组页面。我们的新模型位于sf_sandbox/apps/frontedn/modules/目录下,而他们可以通过下面的URL来进行访问:http://localhost/sf_sandbox/web/frontend_dev.php/posthttp://localhost/sf_sandbox/web/frontend_dev.php/comment此时我们可以进行一些简单的测试。修改布局为了在两个新模型之间进行切换,weblog需要一些全局的浏览设置。编辑全局模板sf_sandbox/apps/frontend/templates/layout.php,修改body内容如下:&div id="container" style="width:600margin:0border:1padding:10px"&&& &&div id="navigator" style="display:float:right"&&& &&& &&ul&&& &&& &&& &&li&&?php echo link_to('List of posts','post/list') ?&&/li&&& &&& &&& &&li&&?php echo link_to('List of comments','comment/list') ?&&& &&& &&/ul&&& &&/div&&& &&div id="title"&&& &&& &&h1&&?php echo link_to('My First symfony project','@homepage') ?&&/h1&&& &&/div&&& &&div id="content" style="clear:right"&&& &&& &&?php echo $sf_data-&getRaw('sf_content') ?&&& &&/div&&/div&当我们编辑这个工程时,我们可以改变我们页面的标题。编辑程序(sf_sandbox/apps/frontend/config/view.yml)的视图配置文件,定位到显示title关键字的行,将其改为:metas:& title:&&&&&&& The best weblog ever& robots:&&&&&& index, follow& description:& symfony project& keywords:&&&& symfony, project& language:&&&& en主页面本身需要改变。他使用默认模块的默认模板,这个默认模块保存在框架中,但是却并不在我们的程序目录中。要覆盖他,我们需要创建一个自己的main模块:$ php symfony init-module frontend main默认情况下,index动作会显示一个默认的欢迎页面。要移除他,我们可以编辑sf_sandbox/apps/frontend/modules/main/actions/actions.class.php文件,并且移除executeIndex()方法的内容:public function executeIndex(){}编辑sf_sandbox/apps/frontend/modules/main/templates/indexSuccess.php文件来显示我们的欢迎页面:&h1&Welcome to my swell weblog&/h1&&p&You are the &?php echo rand() ?&th visitor today.&/p&现在我们需要告诉Symfony当请求主页时需要执行哪个action。为了这个目的,我们可以编辑sf_sandbox/apps/frontend/config/routing.yml文件,并且改变homepage规则:homepage:& url:&& /& param: { module: main, action: index }我们可以通过再一次请求主页来查看结果:http://localhost/sf_sandbox/web/frontend_dev.php/从action向template传递数据这样的速度很快,不是吗?现在我们要将评论模块与一个文章发布想混合,从而可以在一个发布的文章下面显示评论。首先,我们要使得发布的评论为发布显示模板可用。在Symfony中这种逻辑类型是保存在actions中。编辑动作文件sf_sandbox/apps/frontend/modules/post/actions/actions.class.php,更改executeShow()方法,并且添加下面的最后四行:public function executeShow(){&& $this-&post = PostPeer::retrieveByPk($this-&getRequestParameter('id'));&& $this-&forward404Unless($this-&post);&&& &&& $c = new Criteria();&& $c-&add(CommentPeer::POST_ID, $this-&getRequestParameter('id'));&& $c-&addAscendingOrderByColumn(CommentPeer::CREATED_AT);&& $this-&comments = CommentPeer::doSelect($c);}Criteria与-Peer类是Propel类型关系映射的一部分。基本来说,这四行将会处理一个到Comment表的SQL查询,从而得到与当前发布相关的评论(通过URL参数id来指定)。动作中的$this-&comments行将可以访问相应的模板中的一个$comments变量。现在修改发布显示模板sf_sandbox/apps/frontend/modules/post/templates/showSuccess.php,并且在最后添加下面的代码行:...&?php use_helper('Text', 'Date') ?&&&hr /&&?php if ($comments) : ?&& &p&&?php echo count($comments) ?& comment&?php if (count($comments) & 1) : ?&s&? ?& to this post.&/p&&& &?php foreach ($comments as $comment): ?&&&&& &p&&em&posted by &?php echo $comment-&getAuthor() ?& on &?php echo format_date($comment-&getCreatedAt()) ?&&/em&&/p&&&&& &div class="comment" style="margin-bottom:10"&&&&&&&& &?php echo simple_format_text($comment-&getBody()) ?&&&&& &/div&&& &? ?&&? ?&这个页面使用了Symfony提供的新的PHP函数(format_date(),simple_format_text()),并且调用'helpers',因为他们会为我们完成一些需要更多时间和代码的任务。为我们的第一个发布添加一条评论,然后检测我们的第一个发布,我们可以点击列表中前面的标号,或是直接点击列表链接本身:http://localhost/sf_sandbox/web/frontend_dev.php/post/show?id=1添加与另一个表相关的记录当添加一条评论时,我们可以选择相应的发布id。这并不是用户友好的。让我们来改变这种行为,从而可以保证用户在添加一条评论之后可以返回到他正在查看的发布上。首先,在modules/post/templates/showSuccess.php模板底部添加下面一行:&?php echo link_to('Add a comment', 'comment/create?post_id='.$post-&getId()) ?&link_to() helper会创建一个指向评论模板中创建动作的一个超链接,所以我们可以直接由发布详细页面中添加一个评论。接下来,打开modules/comment/templates/editSuccess.php并且替换下面的代码行:&tr&& &th&Post:&/th&&&& &td&&?php echo object_select_tag($comment, 'getPostId', array (&&&&& 'related_class' =& 'Post',)) ?&&/td&&/tr&为&?php if ($sf_params-&has('post_id')): ?&& &?php echo input_hidden_tag('post_id',$sf_params-&get('post_id')) ?& & &?php else: ?&&& &tr&&&& &th&Post*:&/th&&&& &td&&?php echo object_select_tag($comment, 'getPostId', array('related_class' =& 'Post')) ?&&/td&&& &/tr&&? ?&comment/create页面中的表单指向一个comment/update动作,当提交成功时会重新定向到comment/show(这是生成的CRUD的默认动作)。对于weblog而言,在对于一个文章发布添加了一个评论之后,则会显示评论的详细内容。更好的解决是与评论同时显示发布文章的内容。所以打开modules/comment/actions/actions.class.php,并且找到executeUpdate()方法。注意动作中并没有定义created_at域:Symfony会知道当创建一个记录时一个名为created_at的域会设置为系统时间。动作的最后重定向必须进行修改来指向正确的动作。所以将其改为:public function executeUpdate (){& if (!$this-&getRequestParameter('id', 0))& {&& $comment = new Comment();& }&& else& {&&&&& $comment = CommentPeer::retrieveByPk($this-&getRequestParameter('id'));&&&&& $this-&forward404Unless($comment);&& }&&& &&& &&& &&& $comment-&setId($this-&getRequestParameter('id'));&& $comment-&setPostId($this-&getRequestParameter('post_id'));&& $comment-&setAuthor($this-&getRequestParameter('author'));&& $comment-&setEmail($this-&getRequestParameter('email'));&& $comment-&setBody($this-&getRequestParameter('body'));&&& &&& &&& &&& &&& && $comment-&save();&&& &&& &&&&&& && return $this-&redirect('post/show?id='.$comment-&getPostId());}现在用户可以为文章发布添加一个评论,并且在评论之后返回文章页面。我们希望一个weblog吗?现在我们已经有了一个weblog。表单验证访问者可以发布评论,但是如果他们所提交的表单没有任何内容时会怎么样呢?我们就会得到一个脏数据库。为了避免这样的情况,在sf_sandbox/apps/frontend/modules/comment/validate/目录下创建一个名为update.yml的文件,并且写入下面的内容:methods:& post:&&&&&&&&&& [author, email, body]& get:&&&&&&&&&&& [author, email, body]fillin:& enabled:&&&&&& onnames:& author:&&& required:&&&& Yes&&& required_msg: The name field cannot be left blank& email:&&& required:&&&& No&&& validators:&& emailValidator& body:&&& required:&&&& Yes&&& required_msg: The text field cannot be left blankemailValidator:&&& class:&&&&&&&&& sfEmailValidator&&& param:&&&&& email_error:& The email address is not valid.注意,我们不应拷贝每一行开头的额外四个空格,因为这样YAML会解析抢购。这个文件的第一行必须为methods的m。fillin动作会保证在验证失败的情况下会使用用户以前输入的数据来填充表单。名字声明部分为每一个表单的输入域设置验证规则。在默认情况下,当检测到一个错误时控制器会将用户重定向到一个updateError.php模板。更好的方法是重新显示带有错误信息的表单。为了达到这样的目的,在modules/comment/actions/actions.class.php文件中添加一个handleErrorUpdate方法:public function handleErrorUpdate(){& $this-&forward('comment', 'create');}现在就要完成了,再一次打开modules/comment/templates/editSuccess.php模板,并且在顶部添加下面的代码行:&?php if ($sf_request-&hasErrors()): ?&& & &div id="errors" style="padding:10"&&&&&& Please correct the following errors and resubmit:&&& &ul&&&&&& &?php foreach ($sf_request-&getErrors() as $error): ?&&&&&&&& &li&&?php echo $error ?&&/li&&&&&& &? ?&&&& &/ul&& &/div&&? ?&现在我们就有一个健壮的表单了。改变URL形式我们是否注意到了URL的形式?我们可以使得URL对于用户和搜索引擎更为的友好。对于文章发布而言,我们要使用post标题作为URL。问题在于post标题可能包含特殊的字符,例如空格。如果我们只是进行转义,那么URL则会显示为丑陋的%20之类的内容,所以我们应扩展这个模块来添加一个新的方法,从而得到一个干净的,简洁的标题。要达到这样的目的,编辑sf_sandbox/lib/model/目录下的Post.php,并且添加下面的方法:public function getStrippedTitle(){& $result = strtolower($this-&getTitle());&& & // strip all non word chars& $result = preg_replace('/\W/', ' ', $result);&&&&&&& & // replace all white space sections with a dash& $result = preg_replace('/\ +/', '-', $result);&&& &&&& & // trim dashes& $result = preg_replace('/\-$/', '', $result);& $result = preg_replace('/^\-/', '', $result);&& & return $}现在我们可以为这个post模块创建一个permalink动作。在modules/post/actions/actions.class.php添加下面的方法:public function executePermalink(){&$posts = PostPeer::doSelect(new Criteria());&$title = $this-&getRequestParameter('title');&foreach ($posts as $post)&{&&& if ($post-&getStrippedTitle() == $title)&&& {&&&&&&&& }& }& $this-&forward404Unless($post);&&& &&& &&& &&&&&& & $this-&getRequest()-&setParameter('id', $post-&getId());&&& &&& &&& & & $this-&forward('post', 'show');}post列表可以调用permalink动作。在modules/post/templates/listSuccess.php,删除id表头及相应的单元,并且将Ttitle的形式&td&&?php echo $post-&getTitle() ?&&/td&改为下面的形式:&td&&?php echo link_to($post-&getTitle(), 'post/permalink?title='.$post-&getStrippedTitle()) ?&&/td&还剩下另外一步:编辑位于sf_sandbox/apps/frontend/config/目录下的routing.yml文件,并且在顶部添加下面的规则:下面我们可以浏览我们的程序并且查看URL的形式。前端清理当然,如果这是一个weblog,那么每一个人都可以发表。而这不是我们所希望的样子,对吧?好吧,让我们对于我们的模板进行一些小的清理。在模板modules/post/templates/showSuccess.php中,通过移除下面的行来清除edit链接:&?php echo link_to('edit', 'post/edit?id='.$post-&getId()) ?&对于modules/post/templates/listSuccess.php模板也执行同样的操作:&?php echo link_to('create', 'post/create') ?&我们同时也需要从modules/post/actions/actions.class.php文件中移除下面的方法:* executeCreate* executeEdit* executeUpdate* executeDelete好了,现在读者再也不可以发表了。生成后端对于我们来说要发表文章,我们可以通过在命令行输入下面的命令来生成一个后端程序:$ php symfony init-app backend$ php symfony propel-init-admin backend post Post$ php symfony propel-init-admin backend comment Comment此时,我们使用admin生成器。也基本的CURD生成器相比,他提供了更多的特性与自定义。正如我们在前端程序所做的,编辑layout(apps/backend/templates/layout.php)来添加全局浏览:&div id="navigation"&& &ul style="list-style:"&&&& &li&&?php echo link_to('Manage posts', 'post/list') ?&&/li&&&& &li&&?php echo link_to('Manage comments', 'comment/list') ?&&/li&& &/ul&&/div&&div id="content"&&& &?php echo $sf_data-&getRaw('sf_content') ?&&/div&在开发环境下,我们可以通过调用下面的URL来访问我们的后台程序:http://localhost/sf_sandbox/web/backend_dev.php/post生成的admin的最大优点就是我们可以通过编辑一个配置文件很容易的来进行定制。将backend/modules/post/config/generator.yml改为:generator:& class:&&&&&&&&&&&&& sfPropelAdminGenerator&&& param:&&& model_class:&&&&& Post&&& theme:&&&&&&&&&&& default&&& fields:&&&&& title:&&&&&&&&& { name: Title }&&&&& excerpt:&&&&&&& { name: Exerpt }&&&&& body:&&&&&&&&&& { name: Body }&&&&& nb_comments:&&& { name: Comments }&&&&& created_at:&&&& { name: Creation date }&&& list:&&&&& title:&&&&&&&&& Post list&&&&& layout:&&&&&&&& tabular&&&&& display:&&&&&&& [=title, excerpt, nb_comments, created_at]&&&&& object_actions:&&&&&&& _edit:&&&&&&& ~&&&&&&& _delete:&&&&& ~&&&&& max_per_page:&& 5&&&&& filters:&&&&&&& [title, created_at]&&& edit:&&&&& title:&&&&&&&&& Post detail&&&&& fields:&&&&&&& title:&&&&&&& { type: input_tag, params: size=53 }&&&&&&& excerpt:&&&&& { type: textarea_tag, params: size=50x2 }&&&&&&& body:&&&&&&&& { type: textarea_tag, params: size=50x10 }&&&&&&& created_at:&& { type: input_date_tag, params: rich=on }注意在已存在的Post表的列中,admin将会查找nb_comments。但是此时并没有相关的方法,但是很容易在sf_sandbox/lib/model/Post.php中添加:public function getNbComments(){& return count($this-&getComments());}现在我们可以刷新页面来查看改变。限制后台访问后台可以为任何人访问。我们需要添加访问限制。在apps/backend/modules/post/config/目录下添加一个security.yml文件,其内容为:all:& is_secure: on对于comment模块也要重复同样的操作。现在我们不可以访问这些模块,除非我们已经进行登陆。但是登陆现在并不存在。好吧,我们可以很容易的添加一个。首先,创建一个安全模块框架:$ php symfony init-module backend security这个新的模块将用来处理登陆表单与请求。编辑apps/backend/modules/security/templates/indexSuccess.php来创建登陆表单:&h2&Authentication&/h2&&&?php if ($sf_request-&hasErrors()): ?&&& Identification failed - please try again&? ?&&&& &?php echo form_tag('security/login') ?&& &label for="login"&login:&/label&& &?php echo input_tag('login', $sf_params-&get('login')) ?&&&& && &label for="password"&password:&/label&& &?php echo input_password_tag('password') ?&&&& &&&&& & &?php echo submit_tag('submit', 'class=default') ?&&/form&在安全模块中添加为表单所调用的登陆动作(apps/backend/modules/security/actions.class.php):public function executeLogin(){&if ($this-&getRequestParameter('login') == 'admin' && $this-&getRequestParameter('password') == 'password')&{&& $this-&getUser()-&setAuthenticated(true);&&& &&& return $this-&redirect('main/index');&}&else&{&& $this-&getRequest()-&setError('login', 'incorrect entry');&&& &&& &&&&&&& && return $this-&forward('security', 'index');&}}作为主模块,在index动作中移除默认代码:public function executeIndex(){}最后一件事情就是要将安全模块作为默认模块来处理登陆动作。为了完成这样的任务,打开apps/backend/config/setting.yml配置文件,并且添加下面的代码行:all:& .actions:&&&& login_module:&&&&&&&&&& security&&&& login_action:&&&&&&&&&& index这样当我们试着访问文章发布管理时,我们必须输入登陆名与密码。结论好了,现在我们学习的时间已经到了。我们完成了我们的练习。现在我们可以在生产环境下使用这些程序。frontend:&& http://localhost/sf_sandbox/web/index.php/backend:&&& http://localhost/sf_sandbox/web/backend.php/此时,如果我们遇到错误,也许是因为我们在cacahe中放了一些动作后改变了模块造成的(在开发环境下,cacahe并没有激活)。要清除cacahe,我们可以简单的输入下面的命令:$ php symfony cc&
阅读(2267) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。深入理解symfony原理
深入理解symfony原理
发布时间: 11:05:33
编辑:www.fx114.net
本篇文章主要介绍了"深入理解symfony原理",主要涉及到深入理解symfony原理方面的内容,对于深入理解symfony原理感兴趣的同学可以参考一下。
深入理解symfony原理关键词: 深入理解symfony原理
深入理解symfony原理用symfony开发的程序乍看起来有吓人。它包含很多目录和脚本,有PHP类,HTML甚至两者的混合,程序里面有些类很难找到定义的地方,目录深达6层。不过一旦你了解了这些背后的原因,你会突然发现这其实是很自然的,symfony程序的结构就应该是这样。MVC模式 The MVC PatternSymfony基于MVC架构这个经典的Web设计模式,MVC架构包含三层:模型(model)代表程序操作的信息--业务逻辑。视图(view)将模型用网页的形式展现出来从而与用户进行交互。控制器(controller)通过调用合适的模型或者视图来回应用户的动作。图 2-1 解释了MVC模式MVC架构把业务逻辑(模型)与展示(试图)分开,从而大大提高了可维护性。例如,如果你的程序需要能同时在标准web浏览器与手持设备上面运行,你只需要一个新的视图(view),而不改变原来的控制器(controller)与模型(model)。控制器(controller)把请求(request)的协议(HTTP,命令行模式,邮件等)与模型和视图分开来。模型抽象化逻辑与数据,从而独立于视图与动作(action),例如,程序使用的数据库类型。图 2-1 - MVC模式screen.width*0.7) {this.resized= this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}
}" onclick="function anonymous()
if(!this.resized) {} else {window.open('/images/book/F0201.png');}
}" alt="" src="/images/book/F0201.png" onload="function anonymous()
if(this.width>screen.width*0.7) {this.resized= this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}
}" border="0" />symfony核心类 Symfony Core Classes在本书里你会经常碰到symfony的MVC核心的几个类:sfController 控制器类。它解析请求并交给动作处理。sfRequest 保存所有的请求元素(参数,cookie,请求的头 等)。sfResponse 包含回应的头和内容。它的内容最终会转化为HTML传给用户。context singleton (由sfContext::getInstance()取得) 保存所有核心对象还有当前的配置的引用,它可以从任何地方访问到。在第6章你会了解到更多这些对象的信息。如你所见,所有的symfon类都有一个sf前缀,很多symfony模版中的核心变量也是这样。这样可以避免与你的类名与变量名重复,并使框架核心类更像是一家人,更好辨认。NOTE symfony的编码规范中,开头字母大写的驼峰字(UpperCamelCase)是变量名与类名的标准。只有两个例外:核心symfony类以小写的sf开头,模版里面的变量使用小写下划线的方式。代码组织 Code Organization现在你了解了symfony应用程序的不同组成部分,你可能会想知道它们是怎么组织的。symfon按照项目组织代码,项目文件放在标准的树结构里。项目结构: 应用程序,模块与动作 Project Structure: Applications, Modules, and Actions一个symfony项目由一个域名下的服务与操作组成,它们共享同样的对象模型。在一个项目里,操作逻辑上组成应用程序。同一个项目里面的不同应用程序相互独立。大多数情况,一个项目会包含两个应用程序:一个是前台,一个后台,它们共享同一个数据库。不过一个项目也可以包含很多小网站,每一个站点是一个不同的应用程序。注意应用程序间的链接必须用绝对形式。每个应用程序由一个或更多模块组成。模块就是功能相近的一个页面或者一组页面。例如,模块 home ,articles, help, shoppingCart, account 等。模块包含动作,也就是说一个模块可以包含多个动作。例如,shoppingCart模块也许会有add,show与update`等动作。一般来说,动作的名字是动词。动作就好像一般的web应用程序的页面一样,尽管两个动作可能显示同样的页面(例如,在给文章留言后还会把文章显示出来)。TIP 如果你认为这么做对于一个刚开始的项目来说层次太多了,你可以很方便的把所有的动作集中到一个模块里,这样文件结构就简单了。当应用程序越来越复杂,你就需要把这些动作分开放到不同的模块。本书第1章提到,通过重写代码来改善结构与可读性(同样保留功能)被称为重构,当你应用RAD原则的时候经常需要这么做。图 2-3 是一个blog项目的代码组织结构图,按照项目/应用程序/模块/动作来划分。 但注意项目的实际文件结构可能会与图里面的不一样。图 2-3 - 代码组织结构例子screen.width*0.7) {this.resized= this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}
}" onclick="function anonymous()
if(!this.resized) {} else {window.open('/images/book/F0203.png');}
}" alt="" src="/images/book/F0203.png" onload="function anonymous()
if(this.width>screen.width*0.7) {this.resized= this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}
}" border="0" />目录结构所有的web项目都有这些内容:一个数据库,例如MySQL或者PostgreSQL静态文件(HTML, 图片, JavaScript文件,样式表等)网站管理员与用户上传的文件PHP类与函数库外部库(第三方脚本)批处理文件 (用于命令行或者cron的脚本)日志文件 (应用程序或者服务器的留下的脚印)配置文件symfony用一种合理的目录结构组织所有这些内容,这种树形结与symfony的架构(MVC模式与应用程序/项目/模块分组)想符合。这个目录结构是在项目,应用程序,模块初始化的时候自动生成的。当然,为了满足客户的需求你可以完全自定义这个结构。根目录结构这些是一个symfony项目根目录下的文件:apps/ frontend/ backend/batch/cache/config/data/ sql/doc/lib/ model/log/plugins/test/ unit/ functional/web/ css/ images/ js/ uploads/表 2-1 介绍这些目录的内容表 2-1 - 根目录目录 描述apps/ 包含此项目内所有应用程序(一般情况, frontend 与 backend 分别代表前台与后台).batch/ 包含命令行下运行的PHP脚本或者定期执行的脚本cache/ 包含了配置文件的缓存,如果你开了动作和模版,还有这两个部分的缓存。缓存机制(详见第12章)把这些信息存在文件里面加快响应web请求的速度。每个应用程序都会有一个子目录,包含了预处理的PHP与HTML文件。config/ 存放项目的配置信息。data/ 这里是你可以存放项目的数据文件,例如数据库schema,包含了建立数据表的SQL文件,或者一个SQLite数据库文件。doc/ 存放项目文档,包括你自己的文档和PHPdoc生成的文档。lib/ 主要用来存放外部类或者库。这里的内容整个项目都能访问到。'model/`子目录存放项目的对象模型(详见第8章)。log/ 存放symfony生成的应用程序的日志文件。也可以放web服务器的日志文件,数据库日志文件,或者项目的任何地方的日志文件。symfony自动为项目的每一个应用程序的每一个环境生成一个日志文件(l日志文件详见第16章).plugins/ 存放安装在项目里的插件(插件详见第17章)。test/ 包含PHP写的与symfony测试框架兼容的单元与功能测试(详见第15章)。 项目初始化的时候,symfony会自动建立一些基本的测试。web/ web服务器的根目录。所有从因特网能够直接访问的文件都在这个目录里。应用程序目录结构 Application Tree Structure所有应用程序的目录结构都是一样的:apps/ [应用程序名]/ config/ i18n/ lib/ modules/ templates/ layout.php error.php error.txt表 2-2 介绍应用程序的子目录表 2-2 - 应用程序的子目录目录 描述config/ 包含一些YAML格式的配置文件。大部分应用程序的配置信息都在这里,symfony框架自己的默认配置除外。 注意需要的话默认值可以修改。详见第5章。i18n/ 包含应用程序的国际化文件--大部分的界面翻译文件(详见第13章)。如果你用数据库存放翻译信息可以忽略这个目录。lib/ 包含应用程序用到的类与库。modules/ 存放应用程序的所有功能模块。templates/ 包含应用程序的全局模版--所有模块公用的模版。默认情况,这个目录会有一个layout.php文件,这是模块模版默认主布局。NOTE 新应用程序的i18n/, lib/, 与 modules/ 目录是空的。一个应用程序的类的方法或属性不能被同一个项目的其他应用程序访问到。另外,同一项目的两个应用程序之间的超链接必须用绝对形式。开始把项目分成不同的应用程序的时候,这个这个限制就存在了。模块目录结构 Module Tree Structure每个应用程序包括一个或更多的模块。在modules每个模块都有它自己的子目录,这个目录的名字是模块初始化的时候确定的。这是一个典型的模块目录结构:apps/ [应用程序名]/ modules/ [模块名]/ actions/ actions.class.php config/ lib/ templates/ indexSuccess.php validate/表 2-3 介绍模块子目录表 2-3 - 模块子目录目录 描述actions/ 一般只有一个文件actions.class.php,这个文件里面包含了模块的所有动作。模块的不同动作也可以分开写在不同的文件里。config/ 可以存放与模块的配置信息。lib/ 存放模块的类与库。templates/ 存放模块里所有动作的模版。模块初始化的时候,会建立一个默认模版indexSuccess.php。validate/ 用户存放表单验证配置信息(详见第10章)。NOTE 新模块的config/, lib/, 与validate/ 目录是空的web目录结构web目录的限制很少,这里存放的是互联网可以访问得到的文件。模版的默认行为还有helper里包含了几个基本的命名规则。下面是一个web目录的结构的例子:web/ css/ images/ js/ uploads/表 2-4 介绍web目录的内容表 2-4 - 典型的web目录的子目录目录 描述css/ 存放.css结尾的样式表文件images/ 存放.jpg,.png与.gif扩展名的图片文件。js/ 存放.js扩展名的JavaScript文件uploads/ 只能存放用户上传的文件。虽然这个目录通常会存放图片我们还是把这个目录与图片目录分开,这样同步开发服务器与正式服务器的时候不会影响上传的文件。NOTE 虽然强烈建议维持默认的目录结构,你还是可以作出修改,例如一个项目要运行在不同的目录结构与命名规则的服务器上。参数 holder Parameter Holders很多symfony类都包含一个参数holder。参数holder用简便的方式封装了getter与setter方法。例如,sfResponse类包含了一个可以通过执行getParameterHolder()方法获得的参数holder。每一个参数holder都用同样的方式存取数据,如例2-15所示。例 2-15 - 使用 sfResponse 参数holder[php]$response-echo $response-=大部分类通过使用参数holder的proxy方法来减少get/set操作的代码量。这是sfResponse对象的例子,例2-16可以达到例2-15同样效果。Listing 2-16 - Using the sfResponse Parameter Holder Proxy Methods[php]$response-echo $response-=参数holder的getter方法可以有第二个参数作为默认值。这样在取值失败的时候比较简洁。见例2-17。例 2-17 - 使用参数holder的get方法的默认值[php]// 'foobar' 参数没有定义, 所以getter返回空值echo $response-=// 利用条件判断给一个默认值if ($response-{ echo $response-}else{ echo 'default';}=// 但是使用第二个默认值参数快的多echo $response-=参数holder还支持命名空间。如果你给setter或者getter指定第三个参数,这个参数代表命名空间,那么这个参数就只会在这个命名空间里定义或者取值。见例2-18例 2-18 - sfResponse 参数 Holder 的命名空间[php]$response-$response-echo $response-=echo $response-=当然,你可以给你自己的类增加参数holder来获得这些好处。例2-19告诉我们如何定一个有参数holder的类。例 2-19 - 给类增加参数holder[php]class MyClass{ protected $parameter_holder = public function initialize ($parameters = array()) { $this- $this- } public function getParameterHoder() { return $this- }}常量 Constantssymfony里的常量少得出奇。这是因为PHP的一大缺点:常量定义后就不能改变了。所以symfony使用自己的配置对象,称作sfConfig,用来取代常量。它提供了在任何地方存取参数的静态方法。例2-20演示了sfConfig类的方法。例 2-20 - 使用 sfConfig 类方法取代常量[php]// PHP常量define('SF_FOO', 'bar');echo SF_FOO;// symfony 使用sfConfig对象sfConfig::set('sf_foo', 'bar');echo sfConfig::get('sf_foo');sfConfig方法支持默认值,并且sfConfig::set()方法可以多次调用来设置同一个参数的值。第5章详细讨论了sfConfig方法。类自动载入 Class Autoloading一般来说,当你在PHP中要用一个类来创建一个对象的时候,你需要首先包含这个类的定义。[php]include 'classes/MyClass.php';$myObject = new MyClass();但是大的项目包含了很深的目录结构,包含所有这些文件还有路径很浪费时间。由于有__autoload()函数(或者spl_autoload_register()函数),symfony使得我们不需要写包含语句,你可以直接这么写:[php]$myObject = new MyClass();symfony会在项目的lib目录里的所有php文件里寻找MyClass的定义。如果找到,就自动包含它。所以你可以把所有的类放在lib目录,你再也不必包含他们。所以symfony项目通常没有include或者require语句。NOTE 为了提高效率,第一次symfony自动在一个目录列表(在配置文件里面定义)里寻找。然后symfony把这些目录里的所有类和文件的关联存放在一个PHP数组里。这样,以后的自动载入就不需要扫描整个目录了。所以你每次在项目里面增加一个类都需要通过symfony clear-cache命令清空symfony缓存。总结使用MVC框架迫使你按照框架的规定把代码分开。显示的代码归到视图里,数据处理的代码归到模型,请求处理逻辑归到控制器。这对MVC模式的应用程序很有用,也是一个约束。symfony是一个PHP5写的MVC框架。它的结构充分发挥了MVC模式的好处,但也非常容易使用。这要感谢他的全面性与可配置性。现在你已经了解了symfony背后的原理,差不多该是开发你的第一个应用程序的时候了。但是在这之前,你需要在你的开发服务器上安装一套symfony并跑起来。
【作者: Liberal】【访问统计:】【日 星期二 14:38】【注册】【打印】
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:

我要回帖

更多关于 苹果拿下指纹专利 的文章

 

随机推荐