how to get dynamic URL like mydomain.com/username

2019-01-23 09:40发布

I am developing an application using zend framework. In the application I have to provide a URL for each user like mydomain.com/[username] then public will be able to view his profile. [username] is the username of the particular user

But how can I achieve this ? I think in ZF mydomain.com/username tries to get the controller with name username, but I should show user profiles in this URL and it must goes to the right controller if something else comein like mydomain.com/controller1

6条回答
你好瞎i
2楼-- · 2019-01-23 10:01

You will need something similar to the following in your bootstrap

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;
    }
}
查看更多
Ridiculous、
3楼-- · 2019-01-23 10:02

Try using Apache .htaccess mod_rewrite.

4) Rewriting yoursite.com/user.php?username=xyz to yoursite.com/xyz

Have you checked zorpia.com.If you type hxxp://zorpia.com/roshanbh233 in browser you can see my profile over there. If you want to do the same kind of redirection i.e

hxxp://yoursite.com/xyz to hxxp://yoursite.com/user.php?username=xyz then you can add the following code to the .htaccess file.

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

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

查看更多
爷的心禁止访问
4楼-- · 2019-01-23 10:04

This seems to come up quite a bit, there are a few options:

Option 1: custom route class

I've put up a blog post with a detailed example of how to achieve this in ZF using a custom route class, see:

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

This might not be the simplest approach, but in my opinion it is the best, as it allows you to setup a username route like any other, and you can still use the standard ZF URL helpers and other routing toys.

Option 2: extending the router

Another approach is to extend the standard ZF router and then check for a username route before doing anything else. Something like:

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

You then need to tell the front controller to use your router instead of the default one, so in your bootstrap:

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

replace 'My' with your application's own namespace.

If you follow this approach you can't use the URL helper for your username routes, and things can become a bit messy if you start needing to add other custom functionality, so go with the custom route class instead.

查看更多
Summer. ? 凉城
5楼-- · 2019-01-23 10:09

Chellini's answer might work, but if you have 1000 users you are going to add 1000 rules to the router. That and the database access might add to your application's response time.

An alternative is to add a generic route which by default maps to the user action (this is defined first as routes are matched in reverse order). Then add the routes to the controllers you actually have - you are likely to have far fewer controllers than users.

If your application is modular, that reduces the number of rules you have to write even further as you just need to add one rule for a module.

查看更多
霸刀☆藐视天下
6楼-- · 2019-01-23 10:19

Seems to me that the difficulty here is that you are using the same url scheme:

http:/example.com/something

to represent two types of actions:

  1. If "something" represents a user name, consider this a request to controller=user, action=viewProfile, param=something.
  2. Otherwise, consider this to be a standard request to the controller SomethingController

This seems a bit odd to me. I'd prefer to put the user requests under a different url scheme, like:

http://example.com/user/bob

where standard routing rules can apply. Want to avoid the risk that a user registers with a name that conflicts with one of your static controllers. Of course, you could maintain a pool of "reserved" user names for your static controllers that would be unavailable for users to choose.

But if is really is the requirement that the same url format must be used for both types of requests, then I would do the following: route all requests to something like TrafficCopController with an action directTrafficAction(). The action could test - probably via db query - if the passed "something" parameter represents a real user. If so, then forward the request to controller=user, action=viewProfile. Otherwise, forward the request to controller=something, action=index.

See what I mean?

查看更多
狗以群分
7楼-- · 2019-01-23 10:19

Create a custom Route (not Router; there is no need to create a custom router!).

Your new route should extend Zend_Controller_Router_Route_Abstract, and override the match method, which takes Zend_Controller_Request_Abstract $request as the first parameter.

In your new match method, simply query your database to see if the custom page, user, etc. exists by comparing against $request->getRequestUri(), and if it does, return the relevant routing information. Example:

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

On failure (can't find the correct user, or page, etc.), then:

return false

This will scale much better than creating a route for every single user, and doesn't require you to mess around with routing too much. It will still work with the standard router, and you can add it to your routes via application.ini as expected.

查看更多
登录 后发表回答