搜索
首页php教程php手册symfony表单与页面实现技巧,symfony表单技巧

symfony表单与页面实现技巧,symfony表单技巧

本文实例讲述了symfony表单与页面实现技巧。分享给大家供大家参考。具体如下:

symfony开发很简洁,但是功能的数量仍然很缺乏。现在是时候进行一些askeet站点与用户之间的交互了。而HTML交互的根本--除了起链接--就是表单了。

这里我们的目标是允许用户登陆,并在主页的问题列表中进行翻阅。这对于开发而言是很快的,并且可以让我们回忆起前面的内容。

登陆表单

在测试数据中存在用户,但是程序却没有办法来进行验证。下面我们要在程序的每一个页面添加一个登陆表单。打开全局的布局文件askeet/apps/frontend/templates/layout.php,并且在到about的连接之前添加下面的代码行:

复制代码 代码如下:

  • 当前的布局将这些链接放在web调试工具栏之后。要看到这些链接,点击'Sf'图标折叠起调试工具栏就可以看到了。

    现在需要创建user模块。而question模块是在第二天生成的,这一次我们只是叫symfony来创建模块框架,而我们将会自己来编写这些代码。

    复制代码 代码如下:

    $ symfony init-module frontend user

    这个框架包含一个默认的index动作与一个indexSuccess.php模板。删除他们,因为我们并不需要他们。

    创建user/login动作

    复制代码 代码如下:

    在user/actions/action.class.php文件中,添加下面的登陆动作:

    public function executeLogin()
    {
      $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
     
      return sfView::SUCCESS;
    }

    这个动作将referer保存在请求属性中。然后这个属性可为模块所用存放在一个隐藏区域中,从而这个表单的目的动作可以在成功登陆后重定向到原始的referer。

    语句return sfView::SUCCESS将动作执行结果传递到loginSuccess.php模块。这条语句是在一个不包含返回语句的动作中实现的,这也就是一个动作的默认模块被称之为actionnameSuccess.php的原因。

    在动作上开始更多的工作之前,我们先来看一下模块。

    创建loginSuccess.php模块

    web上的许多人机交互使用表单,而Symfony通过提供一个form帮助器集合来组织表单的创建与管理。

    在askeet/apps/frontend/modules/user/templates/目录下,创建下面的loginSuccess.php模块:

    复制代码 代码如下:


     
     


     
     

       
        get('nickname')) ?>
     

     
     

       
       
     

     
     

     
      getAttribute('referer')) ?>
     
     

    这个模块是我们第一次使用表单帮助器。这些Symfony函数可以帮助我们自动化编写表单标签。form_tag()打开一从此标签,使用POST作为默认的动作,并且指向作为参数传递的动作。input_tag()帮助器产生一个标签,并且依据所传递的第一个参数自动添加一个id属性;而默认值则是由第二个参数得到。我们可以在Symfony一书的相关章节查找到更多的关于表单帮助器与他们所产生的HTML代码的内容。

    这里的实质是当表单提交时则会调用这个动作。所以我们返回来看一下这个动作。

    处理表单提交

    用下面的代码来替换我们刚才所编写的登陆动作:

    复制代码 代码如下:

    public function executeLogin()
    {
      if ($this->getRequest()->getMethod() != sfRequest::POST)
      {
        // display the form
        $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
      }
      else
      {
        // handle the form submission
        $nickname = $this->getRequestParameter('nickname');
     
        $c = new Criteria();
        $c->add(UserPeer::NICKNAME, $nickname);
        $user = UserPeer::doSelectOne($c);
     
        // nickname exists?
        if ($user)
        {
          // password is OK?
          if (true)
          {
            $this->getUser()->setAuthenticated(true);
            $this->getUser()->addCredential('subscriber');
     
            $this->getUser()->setAttribute('subscriber_id', $user->getId(), 'subscriber');
            $this->getUser()->setAttribute('nickname', $user->getNickname(), 'subscriber');
     
            // redirect to last page
            return $this->redirect($this->getRequestParameter('referer', '@homepage'));
          }
        }
      }
    }

    登陆动作可以同时用来显示登陆表单并且进行处理。相应的,他必须知道所调用的环境。如果这个动作并没有在POST模式下调用(因为是由一个链接来请求的):而这正是我们在前面所讨论的情况。如果是在POST模式下请求的,那么则会由表单调用这个动作并进行相应的处理。

    这个动作会由请求参数得到nickname域的值,并且查询User表来查看在数据库是否存在此用户。

    将来一个密码控制将会为用户分配凭证。但是现在,这个动作所做的只是在一个会话属性中存储用户的id与nickname属性。最后,这个动作重定向到表单中隐藏中的原始referer域,这是作为一个请求参数传递的。如果这个域是空的,则会使用默认值。

    这里我们需要注意这个例子中两种类型的属性集合之间的区别:request attributes($this->getRequest()->setAttribute())是为模板所保存的,而且只要答案发送到referer则会被忘记。session attributes($this->getUser()->setAttribute())是在整个用户会话生命期被保存的,而且在将来其他的动作也可以访问他们。如果我们希望了解更多的关于属性的内容,我们可以查看Symfony一书的参数保存器一节。

    分配权限

    用户可以登陆进askeet网站是一件好事,但是用户并不仅是因为好玩而登陆。发表一个新问题,对某一个问题表示兴趣,评价一个评论都需要登陆。而其他的动作将会向非登陆用户开放。

    要将一个用户设置为经过验证的,我们需要调用sfUser对象的->setAuthenticated()方法。这个对象同时提供了一个证书机制(->addCredential()),来通过配置限制访问。Symfony一书的用户证书一节对此进行了详细的解释。

    这就是下面两行的目的:

    复制代码 代码如下:

    $this->getContext()->getUser()->setAuthenticated(true);
    $this->getContext()->getUser()->addCredential('subscriber');

    当nickname被识别后,不仅用户数据被存放在会话属性中,而且这个用户也会被分配网站限制部分的访问权限。在明天我们将会看到如何限制验证用户的程序访问。

    添加user/logout动作

    关于->setAttribute()方法还有最后一个窍门:最后一个参数(上面例子中的subscriber)定义了属性存放的名字空间。一个名字空间不仅允许一个在另一个名字空间存在的名字指定给一个属性,而且可以使用一个命令快速移除所有这些属性:

    复制代码 代码如下:

    public function executeLogout()
    {
      $this->getUser()->setAuthenticated(false);
      $this->getUser()->clearCredentials();
     
      $this->getUser()->getAttributeHolder()->removeNamespace('subscriber');
     
      $this->redirect('@homepage');
    }

    使用名字空间可以省去我们一个一个移除这些属性的麻烦:这只是一行语句。

    更新布局

    当前这个布局即使用户已经登陆仍然显示一个'login'链接。让我们来修正这一点。在askeet/apps/frontend/templates/layout.php文件中,修改我们在今天的指南开始时所修改的代码:

    复制代码 代码如下:

    isAuthenticated()): ?>
     


  •  
  • getAttribute('nickname', '', 'subscriber').' profile', 'user/profile') ?>


  •  

  • 现在是时候进行测试了,我们可以显示程序的任何一页,点击'login'链接,输入一个可用的昵称('anonymous'为例)并且进行验证。如果窗口顶部的'login'变为'sign out',则我们所做的一切都是正确的。最后,试着注销来查看'login'链接是否再次出现。

    问题组织

    随着数以千计的Symfony爱好者访问askeet网站,在主页上显示的问题就会逐渐变多。为了避免变慢的请求速度,问题列的随意翻阅就成为必须解决的问题。

    Symfony为这一目的提供了一个对象:sfPropelPager。他会封装到数据的请求,从而只会查询当前页面所显示的记录。例如,如果一个页面初始化时每页只显示10个问题,则到数据的请求只会限制为10个结果,并且会设置偏移来在页面中进行匹配。

    修改question/list动作

    在前面的练习中,我们看到了问题模块的显示动作:

    复制代码 代码如下:

    public function executeList ()
    {
      $this->questions = QuestionPeer::doSelect(new Criteria());
    }

    我们将会修改这个动作来向模板传递一个sfPropelPager而不是传递一个数组。同时,我们会依据感兴趣的数量来对问题进行排序:

    复制代码 代码如下:

    public function executeList ()
    {
      $pager = new sfPropelPager('Question', 2);
      $c = new Criteria();
      $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS);
      $pager->setCriteria($c);
      $pager->setPage($this->getRequestParameter('page', 1));
      $pager->setPeerMethod('doSelectJoinUser');
      $pager->init();
     
      $this->question_pager = $pager;
    }

    sfPropelPager对象的初始化指明了他包含哪个对象类,以及在一个页面中可以放置的对象的最大数目(在这个例子中为2)。->setPage()方法使用一个请求参数来设置当前页面。例如,如果这个页面参数的值为2,sfPropelPager将会返回3到5的结果。页面请求参数的值变为1,则页面默认会返回1到2的结果。我们可以在Symfony一书的页面章节中了解到关于sfPropelPager对象及其方法的更多信息。

    使用一个默认参数

    将常量放在我们所使用的配置文件中是一个好主意。例如,每页的结果(在这个例子为2)可以由一个在我们自定义的程序配置中的参数来代替。用下面的代码来改变上面的sfPropelPager行:

    复制代码 代码如下:

    ..
      $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));

    这里的pager关键字是作为名字空间使用的,这也就是为什么在参数名字中出现的原因。我们可以在Symfony一书的配置一节中查看到更多的关于自定义配置与命名自定义参数规则的更多的内容。

    修改listSuccess.php模板

    在listSuccess.php模板中,将下面的代码行:

    复制代码 代码如下:

    替换为

    复制代码 代码如下:

    getResults() as $question): ?>

    从而页面显示存储在页面中的结果列表。

    添加页面浏览

    在这个模板中还需要做另外一件事:页面浏览。现在,模板所做的只是显示前两个问题,但是我们应添加到下一个页面的功能,以及回到前一个页面的功能。要完成添加这些功能,我们需要在模板后面添加下面的代码:

    复制代码 代码如下:


    haveToPaginate()): ?>
     
      getPreviousPage()) ?>
     
      getLinks() as $page): ?>
        getPage(), $page, 'question/list?page='.$page) ?>
        getCurrentMaxLink()) ? '-' : '' ?>
     
     
      ', 'question/list?page='.$question_pager->getNextPage()) ?>
      getLastPage()) ?>

    这段代码利用了sfPropelPager对象的各种方法,以及->haveToPaginate(),这个函数只有在请求的结果数目超过了页面尺寸时才会返回真;而->getPreviousPage(),->getNextPage(),->getLastPage()都具有明显示的意义;->getLinks()函数提供了一个页面号的数组;而->getCurrentMaxLink()函数返回最后的页面号。

    这个例子同时显示了一个Symfony链接帮助器:link_to_unless()会在作为第一个参数的测试为假的情况下输出一个常规link_to(),否则会输出一个非链接的文本,并使用简单的包装。

    我们测试这个页面了吗?我们应进行测试。直到我们用我们自己的眼睛来验证,这个修改才算结束。要进行测试,打开在第三天所创建的测试数据文件,并且为要显示的页面浏览添加一些问题。重新运行导入数据批处理文件,然后再一次请求主页。

    为子页添加路由规则

    默认情况下,页面规则如下:

    http://askeet/frontend_dev.php/question/list/page/XX

    现在我们利用路由规则使用这些页面更易于理解:

    http://askeet/frontend_dev.php/index/XX

    打开apps/frontend/config/routing.yml文件并且在顶部添加下面内容:

    复制代码 代码如下:

    popular_questions:
      url:   /index/:page
      param: { module: question, action: list }

    并且为登陆页面添加另外的路由规则:

    复制代码 代码如下:

    login:
      url:   /login
      param: { module: user, action: login }

    重构

    模型

    question/list动作执行与模型相关的代码,这也就是我们为什么要将这些代码移动到模块中的原因。用下面的代码来代替question/list动作:

    复制代码 代码如下:

    public function executeList ()
    {
      $this->question_pager = QuestionPeer::getHomepagePager($this->getRequestParameter('page', 1));
    }

    并且在lib/model中的QuestionPeer.php类中添加下面的方法:

    复制代码 代码如下:

    public static function getHomepagePager($page)
    {
      $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));
      $c = new Criteria();
      $c->addDescendingOrderByColumn(self::INTERESTED_USERS);
      $pager->setCriteria($c);
      $pager->setPage($page);
      $pager->setPeerMethod('doSelectJoinUser');
      $pager->init();
     
      return $pager;
    }

    同样的想法也适用于我们昨天编写的question/show动作:Propel对象由其剥离的标题取回问题的用法应属于这个模块。所以用下面的代码来变更question/show动作代码:

    复制代码 代码如下:

    public function executeShow()
    {
      $this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title'));
     
      $this->forward404Unless($this->question);
    }

    在QuestionPeer.php文件中添加下面的代码:

    复制代码 代码如下:

    public static function getQuestionFromTitle($title)
    {
      $c = new Criteria();
      $c->add(QuestionPeer::STRIPPED_TITLE, $title);
     
      return self::doSelectOne($c);
    }

    模板

    在question/templates/listSuccess.php中显示的问题列表在将来的某些地方还会用到。所以我们将显示问题列表的模板代码放在一个_list.php片段中,并且用下面的简单代码来代替listSuccess.php的内容:

    复制代码 代码如下:

    popular question

    $question_pager)) ?>

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

  • 声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    PHP中如何使用Symfony框架PHP中如何使用Symfony框架Jun 27, 2023 am 11:16 AM

    Symfony是一种基于PHP语言的高性能、可重复使用的web应用程序框架。它用于构建高质量的web应用程序和服务,并提供多种功能和工具来简化开发过程。Symfony的目标是使Web开发变得更加可用、可重复使用和高效,并且是一个开源框架,它遵循最佳的软件工程实践。对于PHP开发者来说,Symfony框架是一个非常好的选择,因为它提供了丰富而强大的灵活性,可以

    使用PHP框架Symfony开发一个高效的CRM系统使用PHP框架Symfony开发一个高效的CRM系统Jun 27, 2023 pm 04:17 PM

    随着信息技术的快速发展,企业管理系统越来越普及。其中,客户关系管理系统(CRM)是一种非常流行的企业管理系统。当今企业面临的最大挑战之一是如何有效地管理客户关系。开发一个高效的CRM系统就成了一个发展企业的核心任务。本文将介绍如何使用PHP框架Symfony,结合其丰富的功能和文档资料,来开发一款高效的CRM系统。一、了解Symfony框架Symfony是一

    什么是Symfony框架的优势?什么是Symfony框架的优势?Jun 03, 2023 am 09:21 AM

    Symfony框架是一款流行的PHP框架,它的优势很多,本文将对于Symfony框架的优势进行探讨。高度的灵活性Symfony框架非常灵活,可以满足各种各样的需求。通过使用它的不同组件,你可以使用你自己的代码来构建自己的块,而无需使用强制性的体系结构。这使得Symfony框架成为开发出高度复杂的应用程序的理想选择。强大的安全性Symfony框架是一个非常安全

    使用Symfony框架实现用户权限管理的步骤使用Symfony框架实现用户权限管理的步骤Jul 29, 2023 pm 11:33 PM

    使用Symfony框架实现用户权限管理的步骤Symfony框架是一个功能强大的PHP开发框架,使用它可以快速开发出高质量的Web应用程序。在开发Web应用程序时,用户权限管理是一个不可忽视的重要部分。本文将介绍使用Symfony框架实现用户权限管理的步骤,并附带代码示例。第一步:安装Symfony框架首先,我们需要在本地环境中安装Symfony框架。可以通过

    Symfony vs Phalcon:哪个框架更适合开发大规模社交媒体应用?Symfony vs Phalcon:哪个框架更适合开发大规模社交媒体应用?Jun 18, 2023 pm 10:09 PM

    随着社交媒体应用的不断增长,越来越多的开发人员开始关注哪个框架最适合用来构建这样的应用。Symfony和Phalcon是两个非常受欢迎的PHP框架,它们都有着成熟的社区和强大的开发工具。但是如果你需要开发大规模的社交媒体应用程序,那么哪个框架更适合呢?Symfony是一个成熟的PHP框架,它提供了丰富的功能和工具,可以帮助你快速构建大型应用程序。Symfon

    Symfony vs Yii2:哪个框架更适合开发大型Web应用?Symfony vs Yii2:哪个框架更适合开发大型Web应用?Jun 19, 2023 am 10:57 AM

    随着Web应用需求的不断增长,开发者们在选择开发框架方面也越来越有选择的余地。Symfony和Yii2是两个备受欢迎的PHP框架,它们都具有强大的功能和性能,但在面对需要开发大型Web应用时,哪个框架更适合呢?接下来我们将对Symphony和Yii2进行比较分析,以帮助你更好地进行选择。基本概述Symphony是一个由PHP编写的开源Web应用框架,它是建立

    PHP实现框架:Symfony入门教程PHP实现框架:Symfony入门教程Jun 18, 2023 pm 01:18 PM

    Symfony是一种基于PHP语言开发的Web开发框架,它提供了一系列工具和组件,可以帮助开发者快速开发高质量的web应用程序。Symfony框架在Web应用程序当中被广泛使用,它允许开发者构建具备高度可扩展性和灵活性的应用程序。在本文中,我们将向您介绍Symfony框架,并提供一些有关如何使用Symfony框架构建Web应用程序的简单指导。安装Symfon

    Symfony框架中间件:提供错误处理和异常管理功能Symfony框架中间件:提供错误处理和异常管理功能Jul 28, 2023 pm 01:45 PM

    Symfony框架中间件:提供错误处理和异常管理功能当我们在开发应用程序时,经常会遇到错误和异常的情况。为了优化用户体验和提供更好的开发者工具,Symfony框架提供了强大的错误处理和异常管理功能。在本文中,我们将介绍Symfony框架中间件的使用和示例代码。Symfony框架中的错误处理和异常管理功能主要通过中间件来实现。中间件是一个特殊的功能组件,用于在

    See all articles

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    3 周前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    3 周前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您听不到任何人,如何修复音频
    3 周前By尊渡假赌尊渡假赌尊渡假赌

    热工具

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    功能强大的PHP集成开发环境

    EditPlus 中文破解版

    EditPlus 中文破解版

    体积小,语法高亮,不支持代码提示功能

    螳螂BT

    螳螂BT

    Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

    SublimeText3 Linux新版

    SublimeText3 Linux新版

    SublimeText3 Linux最新版

    mPDF

    mPDF

    mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),