how to get dynamic URL like mydomain.com/username using zend framework
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/controll开发者_JAVA百科er1
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.
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;
}
}
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:
- If "something" represents a user name, consider this a request to controller=user, action=viewProfile, param=something.
- 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?
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.
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
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.
精彩评论