如何使用zend框架获取像mydomain.com/username这样的动态URL

时间:2010-09-09 05:08:46

标签: php zend-framework

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

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

6 个答案:

答案 0 :(得分:3)

这似乎相当多,有几个选择:

选项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());
}

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

如果您使用此方法,则无法使用URL帮助程序进行用户名路由,如果您开始需要添加其他自定义功能,则可能会变得有点混乱,因此请改为使用自定义路由类。

答案 1 :(得分:1)

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

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;
    }
}

答案 2 :(得分:1)

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

http:/example.com/something

表示两种类型的操作:

  1. 如果“something”代表用户名,请考虑这是对controller = user,action = viewProfile,param = something的请求。
  2. 否则,请将此视为对控制器SomethingController的标准请求
  3. 这对我来说有点奇怪。我更愿意将用户请求置于不同的url方案下,例如:

    http://example.com/user/bob

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

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

    明白我的意思?

答案 3 :(得分:1)

创建自定义路由(不是路由器;无需创建自定义路由器!)。

您的新路线应该展开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将其添加到您的路由中。

答案 4 :(得分:0)

尝试使用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

答案 5 :(得分:0)

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

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

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