How can I handle dynamic URIs where all segments are arbitrary? - mod-rewrite

How can push a URI like this in CodeIgniter (1.7.1 currently):
example.com/seg1/seg2/seg3/seg4/
or
example.com/seg1/seg2/
etc. through a single class method in a controller whose name does not appear in the URI? In a regular PHP scenario I would use mod_rewrite something like this:
RewriteRule ^([^/]+)/$ myfile.php?one=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/$ myfile.php?one=$1&two=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ myfile.php?one=$1&two=$2&three=$3 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ myfile.php?one=$1&two=$2&three=$3&four=$4 [L]
(I sanitize and validate the segments extensively in PHP, returning 404 if invalid)
But in Codeigniter I can't figure out how to do this without hard coding at least the first segment, but then using custom routes it still wants to treat the subsequent segments as method calls.
I'm a newbie to CI, but have so far managed to port over the entire existing site with the exception of this part of it. I don't see how all the parts come together on this problem, so any suggestion is welcome.
Clarification: I read through documentation on URI library, routing etc before starting my project, and they were helpful for various things, but this specific problem is not addressed by any of them. I'm not seeing how all segments of the URI can essentially be funneled through a controller that is not named in the URI and where all segments are arbitrary. The routing examples assume you know the value of the first segment. I already know how to remove "index.php" as well as access segments.

Have you looked up URI routing in the user guide and the wiki? They should tell you almost anything about routing, rewriting and accessing the different URI segments.
http://codeigniter.com/user_guide/general/routing.html
http://codeigniter.com/user_guide/libraries/uri.html
http://codeigniter.com/wiki/mod_rewrite/
[Edit:]
Here's the long description:
There is no way to not "hard-code" the first segment, and you can still "hard-code" the second segment.
What you want to accomplish can be nearly done by editing the routes in system/application/config/routes.php:
$route['(:any)'] = 'your_default_controller/index/$1';
$route['default_controller'] = "your_default_controller";
So, the first segment of your URI will be the method of the controller. You can access all segments of your (initial) URI by
$this->uri->segment(n)
You would then use the method index to call the desired function for each request.
On a side note: Why do you want to use an MVC framework for that, as you do not use much of the benefits of MVC?

Related

Set a custom url for Codeigniter Controller

Please can any one suggest how to shorten the url
http://localhost:8080/MyWebApp/index.php/Cpanel_control/
to
http://localhost:8080/MyWebApp/Cpanel
in Codeigniter using routes.
I tried it in this way
$route['Cpanel'] = "MyWebApp/index/Cpanel_control";
But did not work
To remove index.php from your url in CI, you need .htaccess file.
Check this out https://gist.github.com/philipptempel/4226750
I'm assuming Cpanel_control is a valid controller.
For the routing, you can have this in your routes settings
$route['Cpanel'] = "Cpanel_control";
To avoid any other issues, make sure base_url in config file is set thus
$config['base_url'] = "http://localhost:8080/MyWebApp";
New Approach
Routing:
In some instances, however, you may want to remap this relationship so
that a different class/method can be called instead of the one
corresponding to the URL.
A short excerpt from the CI doc shows that you can't use routing here. Instead you should go for a mod_rewrite rule (.htaccess)
RewriteEngine On
RewriteRule ^index/Cpanel_control/(.*) Cpanel/$1 [R]
Old approach
According to the corresponding documentation, the paths are both not absolute. Furthermore, you need to set the "from"-URI as the array key and the "to" URI as the string. If you want to route index/Cpanel_control to Cpanel, you need to swap the URIs of you example.
So this would be correct:
$route['index/Cpanel_control'] = "Cpanel";

CodeIgniter router for joomla sef urls?

I wish to create a front-end for joomla using CodeIgniter. I prefer to make my own front-end that reads joomla database and I had my own "framework" to accomplish this, this is because I feel that joomla front-end is too heavy for high traffic websites, because it needs to accommodate for so many user needs, at the end you would really only use a small percentage of what joomla has to offer, yet a lot of unneeded core modules load and when you have a website with 300k visits per day, every bit of resource counts. And I like joomla because of its back-end and database structure.
Anyway, I'm looking to standardize a framework for joomla front-end using CodeIgniter instead of my own messy php code, the main issue for me is the ci router. In joomla I set sef url like these:
websitex.com/
websitex.com/category.html
websitex.com/category/subcat/123-alias.html
I'm looking for a router override that would allow me to process those urls. Basically, if any of the params has a number, then its for sure an article. If it doesn't, and its not index.php then its for sure a category or subcategory (if it exists).
And if I write this:
websitex.com/123 [OR]
websitex.com/category/123-alias.html
It would display the article with id 123. At least that's how it works in joomla and its what I'm trying to achieve here.
If anyone could point me in the right direction that would be great. Thanks in advance.
ADDED:
OK #ImranQamer comment left me thinking. What if I try to do it with conventional CI router? So I tried, and came up with this:
$route['default_controller'] = "controller/index";
$route['index'] = "controller/index";
$route[':num'] = "controller/article";
$route['(:any)/:num'] = "controller/article";
$route['(:any)'] = "controller/section";
I think it may work. I've run some tests and so far so good.
First and second line, if nothing is specified OR index.suffix (index.html) is the URI, then it goes to my controller index method.
Third line, if URI is a number (eg: /123.html) then it routes to controller/article.
Fourth line needs more testing, but apparently it will grab any URI that ends with a number (or number + suffix) and route it to controller/article. Still needs another rule to let article's title alias to be put in the URI (eg: /category/123-hello.html)
And last line, will treat the URI as one of the categories/section of the joomla site. In this controller though, I'm going to need to check if submitted URI corresponds to an existing section, in which case it gets displayed, otherwise, redirected to 404.
I'm gonna test this out for a while, but looks good so far.

mod_rewrite not working as expected

i have an issue regarding mod_rewrite ... the url rewrite sems to work fine ... only thing is that the url in the address bar remains the same as it was before rewrite
for example: i want to rewrite www.site.com/page.php?page=merchandise to www.site.com/merchandise. now when i write the url i go to the right page (www.site.com/page.php?page=merchandise) but the address in the address bar remains ( www.site.com/page.php?page=merchandise) where it should be (www.site.com/merchandise) ... it works fine on the local environmnt...but problems occurs in live environment ...
I'm currently using simple RewriteRule.
The rewrite rule is as followed:
RewriteRule ^merchandise$ http://www.mysite.com/page.php?page=merchandise [NC]
Its pretty simple and should work. But it does not hide the actual address in the address bar. That's my problem.Otherwise it is going to right page.
Any help is appreciated.
You are describing the way mod_rewrite has been made for, and you are surprised that is works this way. This is funny :)
And it seems you're mixing things.
mod_rewrite is here to hide complex URLs and to make them simpler (generally speaking).
You are wrong when you say
"www.site.com/page.php?page=merchandise" to www.site.com/merchandise"
The real thing is probably the opposite:
you want the Net surfer to type "http://www.site.com/merchandise"
you want your server to change "http://www.site.com/merchandise" to "http://www.site.com/page.php?page=merchandise"
what you didn't get is that 99.9999% of the time webmasters don't want the client to see the real page is "http://www.site.com/page.php?page=merchandise"
...
And that's what does mod_rewrite: it looks at incoming URLs, and modify them internally. So the webdevelopper (= you) can transform the URLs using RewriteRule's and make whatever you want but it's always into the server. The only exception is when you want to explicitely redirect the client to another URLs, then you can use the "[F]" directive which means "Forward".
Hope this helps

mod_rewrite take part of url and add it to the end of a second url

I am attempting to make it where faculty or students at my library that have a pmid number for PubMed, and want to share the link with others could do it by just remembering our url, and adding the pmid to the end of our url, with the identifier p.
This is where mod_rewrite comes in it would drop off the url: site.com/p/112233444 but keep 112233444 and then add it to the end of linkresolver.com/112233444
The rule that I have come up with is:
RewriteRule ^/p/(.*)$ linkresolver.com=$1
First, is this possible I control the library domain, but I am not in control of the second url that I am attempting to add the PMID to.
Second, this is my first attempt at mod_rewrite so if I am way let me know I have looked at Apache's documentation. I know it is really powerful complex tool, so my rewrite rule just seems off.
Any help would be greatl
Does this work?
RewriteRule ^p/(.*)$ http://linkresolver.com/$1 [R]

Mod_rewrite and MySql

I have a url eg. www.example.com/user.php?user_id=9 , where the user_id field maps to one of the pk in the user table . I don't want the url to be like this , instead i want to have a url like www.example.com/user/Aditya-Shukla.i am using apache 2 and I understand that mod-rewrite module has sets of rewriting rules which can be used to create url alias.
My question is
I have all href in the form www.example.com/user.php?user_id=9. So to change the url I suppose i have to change all the href's to the www.example.com/user/Aditya-Shukla and for rewriting the rule do a query to get a record?
Is there a better solution .
No, mod_rewrite does not have sets of rewriting rules. It rather provides directives to build rules based on regular expression patterns that can be combined with additional conditions.
In your case you would build a rule that takes any requested URL path that starts with /user/ and has another path segment following and rewrites it internally to your user.php, like:
RewriteEngine on
RewriteRule ^/user/([^/]+)$ /user.php?name=$1
The first directive RewriteEngine on is just to enable mod_rewrite. And the second directive RewriteRule … is the rule as described above: ^/user/([^/]+)$ is the pattern that matches any URL path that starts with /user/ (i.e. ^/user/) and that is followed by one path segment (i.e. ([^/]+)$). That request is then rewritten internally to /user.php while the matched path segment behind the /user/ is used as a parameter value for the name parameter ($1 is a reference to the matched value of the first group denoted with (…)).
So this will rewrite a request of /user/Aditya-Shukla internally to /user.php?name=Aditya-Shukla. You can then use that user name and look it up in your table.
You can either add a RewriteRule that will rewrite user/Aditya-Shukla to user.php?user_name=Aditya-Shukla and handle the rest in your code.
RewriteEngine On
RewriteRule ^user/(.*)$ user.php?user_name=$1
Or using a RewriteMap directive to lookup usernames, which will allow to rewrite user/Aditya-Shukla directly to user.php?user_id=9
I presume that within your own site you will always create the canonical form of the URL, i.e.:
/user/Aditya-Shukla
...and you are just having to deal with outside links that are not in canonical form, i.e. "old links" like:
www.example.com/user.php?user_id=9
mod_rewrite may not be suitable for remapping in this situation. I am presuming you may have very many users, and that number may grow. mod_rewrite does have a RewriteMap directive and yes there are ways to generate your map dynamically, but I don't think that would be a good design (to dynamically create a map of userId-to-userName dynamically every time your rewrite rule matches...)
Instead you should simply write your user.php code to lookup the correct userName, assemble the canonical form of URL you want, and send a redirect back to the client. Something like:
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.example.com/user/Aditya-Shukla" );
You should probably also use a 301 redirect (instead of 302) to indicate this is a "permanent" URL change, which will help search bots index your site correctly if it encounters an "old style" URL out there.
-broc

Resources