【问题标题】:Fetching Zend Framework URL parameters获取 Zend Framework URL 参数
【发布时间】:2012-11-03 15:04:00
【问题描述】:

我正在构建我的第一个 Zend Framework 应用程序,我想找出从 URL 获取用户参数的最佳方法。

我有一些控制器具有indexaddeditdelete 操作方法。 index 操作可以采用page 参数,editdelete 操作可以采用id 参数。

Examples
    http://example.com/somecontroller/index/page/1
    http://example.com/someController/edit/id/1
    http://example.com/otherController/delete/id/1

到目前为止,我在操作方法中获取这些参数是这样的:

class somecontroller extends Zend_Controller_Action
{
    public function indexAction()
    {
        $page = $this->getRequest->getParam('page');
    }
}

但是,一位同事告诉我使用 Zend_Controller_Router_Rewrite 的更优雅的解决方案如下:

$router = Zend_Controller_Front::getInstance()->getRouter();

$route = new Zend_Controller_Router_Route(
                        'somecontroller/index/:page',
                        array(
                            'controller' => 'somecontroller',
                            'action'    => 'index'
                        ),
                        array(
                            'page' => '\d+'
                        )
);

$router->addRoute($route);

这意味着我需要为每个控制器添加至少三个路由:

  • 一个用于带有 :page 参数的“索引”操作
  • 一个用于带有 :id 参数的“编辑”操作
  • 一个用于带有 :id 参数的“删除”操作

请参阅下面的代码作为示例。这些只是一个控制器的 3 个基本动作方法的路由,想象一下有 10 个或更多控制器......我无法想象这是最好的解决方案。我看到的唯一好处是参数键已命名,因此可以从 URL 中省略(somecontroller/index/page/1 变为 somecontroller/index/1

// Route for somecontroller::indexAction()
$route = new Zend_Controller_Router_Route(
                        'somecontroller/index/:page',
                        array(
                            'controller' => 'somecontroller',
                            'action'     => 'index'
                        ),
                        array(
                            'page' => '\d+'
                        )
);

$router->addRoute($route);

// Route for somecontroller::editAction()
$route = new Zend_Controller_Router_Route(
                        'somecontroller/edit/:id',
                        array(
                            'controller' => 'somecontroller',
                            'action'     => 'edit'
                        ),
                        array(
                            'id' => '\d+'
                        )

$router->addRoute($route);

// Route for somecontroller::deleteAction()
$route = new Zend_Controller_Router_Route(
                        'somecontroller/delete/:id',
                        array(
                            'controller' => 'somecontroller',
                            'action'     => 'delete'
                        ),
                        array(
                            'id' => '\d+'
                        )

$router->addRoute($route);

【问题讨论】:

    标签: zend-framework zend-route


    【解决方案1】:

    我倾向于这样看:

    1. 确定处理要求。

      每个“动作”需要什么?一个编辑操作和一个删除操作可能需要一个 :id 参数。添加操作和列表操作可能不会。这些控制器/动作然后使用参数并进行处理。

      注意:您可以编写这些控制器/操作,而无需参考将访问者带到那里的 url。这些动作只是期望它们的参数将被传递给它们。

    2. 决定(!)你想要什么网址。

      一般来说,我发现 url 的 (/:module/):controller/:action 部分基本上可以正常工作(除了像 /about 这样的顶级相对静态页面,我经常将操作放在 IndexController(或 StaticController)上,并且讨厌在 url 中包含 /index 前缀。

      因此,要处理帖子,您可能需要以下网址:

      • /post - 列出所有帖子,可能带有一些分页
      • /post/:id - 显示特定帖子
      • /post/:id/edit - 编辑特定帖子
      • /post/:id/delete - 删除特定帖子
      • /post/add - 添加帖子

      或者,您可能想要:

      • /post/list - 列出所有帖子,可能带有一些分页
      • /post/display/:id - 显示特定帖子
      • /post/edit/:id - 编辑特定帖子
      • /post/delete/:id - 删除特定帖子
      • /post/add - 添加帖子

      或任何其他 url 方案。关键是,您决定要公开的网址。

    3. 创建路线...

      ...将这些 url 映射到控制器/操作。 [并确保无论何时渲染它们,都使用带有路由名称的url() view-helper,这样路由更改不需要更改您的操作或视图中的下游代码。

    您最终会以这种方式编写更多路线吗?是的,我发现我做到了。但是,对我来说,好处是我可以决定我的网址。我不拘泥于 Zend 的默认设置。

    但是,与大多数事情一样,YMMV。

    【讨论】:

    • 我发现您的第一个 url 结构有问题。您说“/post 网址列出了所有帖子,可能带有一些分页”。这意味着我们需要像这样传递一个页面参数:/post/:page。另一方面,/post url 也需要一种获取单个记录的方法,例如:/post/:id。我们如何知道用户指定了页面 ID 还是记录 ID?
    • 我倾向于通过查询字符串传递分页参数,不一定作为路由路径的一部分。
    【解决方案2】:

    这完全取决于您的具体要求。如果您只是想传递一个或两个参数,第一种方法将是最简单的。为每个动作定义路线是不切实际的。您想要定义路线的一些场景是:

    1. 长 url - 如果特定操作的参数列表很长,您可能需要定义一个路由,以便可以在请求中省略键,从而缩短 url。
    2. 花哨的 url - 如果您想偏离 Zend 框架的常规控制器/操作 url 模式,并为您的应用程序定义不同的 url 模式(例如,以“.html”结尾)
    3. Slugs / SEO 友好的 URL

    以博客为例,您可能希望为博客文章 url 定义路由,以便 url 对 SEO 友好。同时,您可能希望保留编辑/删除/发表评论等 url 以保持 ZF 默认并使用 $this->getRequest->getParam() 访问该上下文中的请求参数。

    总而言之,一个优雅的解决方案是路由和默认 url 模式的组合。

    【讨论】:

      【解决方案3】:

      在之前的回答中@janenz00 提到“长网址”是使用路由的原因之一:

      长 url - 如果特定操作的参数列表很长,您可能需要定义一个路由,以便可以省略请求中的键,从而缩短 url。

      假设我们有一个带有index 操作的employee 控制器,该操作显示了一个员工表,其中包含每个员工的一些附加数据(例如年龄、部门...)。 index 操作可以采用以下参数:

      • page 参数(必需)
      • 一个sortby 参数(可选),它采用一个列名进行排序(例如年龄)
      • dept 参数(可选)采用部门名称并仅显示在该部门工作的员工

      我们添加以下路线。请注意,在使用此路由时,如果不先指定sortby 参数,我们将无法指定dept 参数。

      $route = new Zend_Controller_Router_Route(
                          'employee/index/:page/:sortby/:dept',
                          array(
                              'controller' => 'employee',
                              'action'    => 'index')
      );
      

      如果我们在操作方法中获取这些参数,我们可以避免这个问题(因为参数键是在 url 中指定的):

      http://example.com/employee/index/page/1/dept/staff
      

      我可能以错误的方式看待它(或者可能看不到路由的全部潜力),但对我而言,使用路由的唯一两个原因是:

      • 如果您的网址不符合传统的/module/controller/action 模式
      • 如果您想让您的网址对 SEO 更友好

      如果您使用路由的唯一原因是使用命名参数,那么我认为最好在您的操作方法中获取这些参数,原因有两个:

      • 将路由数量保持在最低限度将减少路由器花费的时间和资源
      • 在 url 中传入参数键允许我们使用带有可选参数的更复杂的 url。

      非常欢迎您对这个主题提出任何想法或建议!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-06
        • 2017-03-07
        • 2011-02-04
        相关资源
        最近更新 更多