【问题标题】:how to get dynamic URL like mydomain.com/username using zend framework如何使用 zend 框架获取像 mydomain.com/username 这样的动态 URL
【发布时间】:2011-04-10 02:10:15
【问题描述】:

我正在使用 zend 框架开发应用程序。在应用程序中,我必须为每个用户提供一个 URL,例如 mydomain.com/[username],然后 public 将能够查看他的个人资料。 [username] 是特定用户的用户名

但我怎样才能做到这一点?我认为在 ZF mydomain.com/username 中尝试获取名称为 username 的控制器,但我应该在此 URL 中显示用户配置文件,并且如果其他类似 mydomain.com 的内容进入,它必须转到正确的控制器/控制器1

【问题讨论】:

  • +1 因为这是我对 ZF(以及其他 fw 也是)的最大问题。使用自定义引擎可以轻松生成,但我从来没有在 ZF 中找到关于这个东西的好的描述。

标签: php zend-framework


【解决方案1】:

尝试使用 Apache .htaccess mod_rewrite。

4) 将 yoursite.com/user.php?username=xyz 重写为 yoursite.com/xyz

你检查过 zorpia.com。如果你在浏览器中输入 hxxp://zorpia.com/roshanbh233,你可以在那里看到我的个人资料。如果你想做同样的重定向,即

hxxp://yoursite.com/xyz 到 hxxp://yoursite.com/user.php?username=xyz 然后您可以将以下代码添加到 .htaccess 文件中。

RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ user.php?username=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ user.php?username=$1

来源:http://roshanbh.com.np/2008/03/url-rewriting-examples-htaccess.html

【讨论】:

  • 不确定它是否与 ZF 兼容,但是,如果您的服务器正在运行 Apache...您应该能够将 .htaccess 文件添加到根目录,然后让 Apache 发挥作用...跨度>
【解决方案2】:

您的引导程序中将需要类似于以下内容的内容

public function _initRouter()
{
     $router = Zend_Controller_Front::getinstance()->getRouter();
     $users = array() // get the usernames from DB or wherever you have them

      // Adds some routes
     foreach($users as $user)
     {
        $router->addRoute($user['name'], new Zend_Controller_Router_Route($user['name'].'/:controller/:action/*', array(
          'module' => 'users', // module name
          'controller' => 'index', // controller name
          'action' => 'profile', // action name
          'username' => $user['name']))); // user name
      }
      return $router;
    }
}

【讨论】:

    【解决方案3】:

    Chellini 的答案可能有效,但如果您有 1000 个用户,您将向路由器添加 1000 条规则。这和数据库访问可能会增加应用程序的响应时间。

    另一种方法是添加一个默认映射到用户操作的通用路由(这是首先定义的,因为路由以相反的顺序匹配)。然后将路由添加到您实际拥有的控制器 - 您的控制器可能比用户少得多。

    如果您的应用程序是模块化的,那么您必须进一步编写的规则数量会减少,因为您只需为模块添加一条规则。

    【讨论】:

      【解决方案4】:

      这个好像出现了不少,有几个选择:

      选项 1:自定义路由类

      我已经发布了一篇博文,其中详细介绍了如何在 ZF 中使用自定义路由类实现此目的,请参阅:

      http://tfountain.co.uk/blog/2010/9/9/vanity-urls-zend-framework

      这可能不是最简单的方法,但在我看来这是最好的方法,因为它允许您像其他任何方法一样设置用户名路由,并且您仍然可以使用标准的 ZF URL 帮助程序和其他路由工具。

      选项 2:扩展路由器

      另一种方法是扩展标准 ZF 路由器,然后在执行其他任何操作之前检查用户名路由。比如:

      class My_Router extends Zend_Controller_Router_Rewrite
      {
          public function route(Zend_Controller_Request_Abstract $request)
          {
              $pathBits = explode('/', $request->getPathInfo());
              if (!empty($pathBits[0])) {
                  // check whether $pathBits[0] is a username here
                  // with a database lookup, if yes, set params and return
              }
      
              // fallback on the standard ZF router
              return parent::route($request);
          }
      }
      

      然后您需要告诉前端控制器使用您的路由器而不是默认路由器,因此在您的引导程序中:

      protected function _initRoutes()
      {
          Zend_Controller_Front::getInstance()->setRouter(new My_Router());
      }
      

      将“My”替换为您的应用程序自己的命名空间。

      如果您采用这种方法,您将无法为您的用户名路由使用 URL 帮助程序,并且如果您开始需要添加其他自定义功能,事情可能会变得有些混乱,因此请改用自定义路由类。

      【讨论】:

      • 您不必扩展路由器 - 您可以简单地创建自定义路由。发布了一个解释如何的答案。
      • 自定义路线正是我所建议的。请参阅我链接的博客文章。显示扩展路由器的代码示例只是一个替代选项,自定义路由更好(这就是为什么写了一整篇关于它的博客文章)。
      【解决方案5】:

      在我看来,这里的困难在于您使用的是相同的 url 方案:

      http:/example.com/something

      表示两种类型的动作:

      1. 如果“something”代表用户名,则认为这是对 controller=user、action=viewProfile、param=something 的请求。
      2. 否则,将其视为对控制器 SomethingController 的标准请求

      这对我来说似乎有点奇怪。我更愿意将用户请求放在不同的 url 方案下,例如:

      http://example.com/user/bob

      标准路由规则可以应用的地方。希望避免用户注册的名称与您的静态控制器之一冲突的风险。当然,您可以为静态控制器维护一个“保留”用户名池,用户无法选择。

      但是,如果确实要求两种类型的请求必须使用相同的 url 格式,那么我会执行以下操作:将所有请求路由到类似 TrafficCopController 的内容,并使用操作 directTrafficAction()。该操作可以测试 - 可能通过 db 查询 - 如果传递的“某物”参数代表真实用户。如果是,则将请求转发到controller=user, action=viewProfile。否则,将请求转发到controller=something, action=index

      明白我的意思吗?

      【讨论】:

        【解决方案6】:

        创建自定义Route(不是Router;不需要创建自定义Router!)。

        您的新路由应扩展Zend_Controller_Router_Route_Abstract,并覆盖match 方法,该方法将Zend_Controller_Request_Abstract $request 作为第一个参数。

        在您的新匹配方法中,只需通过与$request->getRequestUri() 比较来查询您的数据库以查看自定义页面、用户等是否存在,如果存在,则返回相关路由信息。示例:

        return array(
            'module'     => 'default',
            'controller' => 'users',
            'action'     => 'view',
            'user'       => $user
        );
        

        如果失败(找不到正确的用户或页面等),则:

        return false
        

        这将比为每个用户创建路由更好地扩展很多,并且不需要您过多地弄乱路由。它仍然适用于标准路由器,您可以按预期通过 application.ini 将其添加到您的路由中。

        【讨论】:

          猜你喜欢
          • 2016-03-11
          • 2011-07-08
          • 2015-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-21
          • 2014-08-31
          相关资源
          最近更新 更多