0

0

symfony表单与页面实现技巧,symfony表单技巧_PHP教程

php中文网

php中文网

发布时间:2016-07-13 10:09:02

|

874人浏览过

|

来源于php中文网

原创

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

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

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

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

登陆表单

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

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

    立即学习PHP免费学习笔记(深入)”;

    现在需要创建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'链接是否再次出现。

    问题组织

    Nanonets
    Nanonets

    基于AI的自学习OCR文档处理,自动捕获文档数据

    下载

    随着数以千计的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框架程序设计有所帮助。

    www.bkjia.comtruehttp://www.bkjia.com/PHPjc/947922.htmlTechArticlesymfony表单与页面实现技巧,symfony表单技巧 本文实例讲述了symfony表单与页面实现技巧。分享给大家供大家参考。具体如下: symfony开发很简...

    相关文章

    PHP速学教程(入门到精通)
    PHP速学教程(入门到精通)

    PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    WorkBuddy
    WorkBuddy

    腾讯云推出的AI原生桌面智能体工作台

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    TypeScript类型系统进阶与大型前端项目实践
    TypeScript类型系统进阶与大型前端项目实践

    本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

    1

    2026.03.13

    Python异步编程与Asyncio高并发应用实践
    Python异步编程与Asyncio高并发应用实践

    本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

    39

    2026.03.12

    C# ASP.NET Core微服务架构与API网关实践
    C# ASP.NET Core微服务架构与API网关实践

    本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

    140

    2026.03.11

    Go高并发任务调度与Goroutine池化实践
    Go高并发任务调度与Goroutine池化实践

    本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

    47

    2026.03.10

    Kotlin Android模块化架构与组件化开发实践
    Kotlin Android模块化架构与组件化开发实践

    本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

    90

    2026.03.09

    JavaScript浏览器渲染机制与前端性能优化实践
    JavaScript浏览器渲染机制与前端性能优化实践

    本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

    102

    2026.03.06

    Rust内存安全机制与所有权模型深度实践
    Rust内存安全机制与所有权模型深度实践

    本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

    226

    2026.03.05

    PHP高性能API设计与Laravel服务架构实践
    PHP高性能API设计与Laravel服务架构实践

    本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

    506

    2026.03.04

    AI安装教程大全
    AI安装教程大全

    2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

    170

    2026.03.04

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Symfony5【从0开始开发博客系统】
    Symfony5【从0开始开发博客系统】

    共120课时 | 10.5万人学习

    Symfony教程(入门篇+基础篇)
    Symfony教程(入门篇+基础篇)

    共18课时 | 1.3万人学习

    Symfony2中文手册
    Symfony2中文手册

    共24课时 | 25.3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号