CodeIgniter __remap() routing more than one controller - php

I am trying to create a URL shortener using CodeIgniter 2.
I have 2 controllers: main and api.
For redirecting a short link through the router, I am using this setting in config/routes:
$route['(.*)'] = "main/$1";
along with a method in the main controller which should work. However, the controllers won't start. Please help me to solve this problem.

You controller "any" isnt called because it falls into that regex, so it's routed to main.
In order to exclude "any" from this rule you need to create a special rule for that, keeping in mind that for CI rules are cascading , so they're executed in the order they're presented
Note: Routes will run in the order
they are defined. Higher routes will
always take precedence over lower
ones.
So, you would have:
// reserved routes must come before custom routes
$route['default_controller'] = "home";
$route['404_override'] = '';
$route['any'] = //your rule here. maybe "any". ?
$route['(.*)'] = "main/$1"; // CI also provides you with `(:any)` rule, that mateches any character.
More on this here: Uri routing

Related

Setting Routing rules for different classes in codeigniter

My application URL "localhost/crdlabs/PHP" goes to "localhost/crdlabs/home/display/PHP" which is done using route.php. The rule is as follows.
$route['(:any)'] = "home/display/$1";
Now that I have another controller class called displayarticles(). The current URL for this class is "localhost/crdlabs/displayarticles/article/learning-coding". I understand that I cannot use the routing above for the new controller. How to set a routing rule for the current one to make the URL look like "localhost/crdlabs/learning-coding".
Note : learning-coding part is dynamically set which means there are several different articles that should go to the same controller.
Any help/advise please.
The current routing rule.
$route['(:any)'] = "home/display/$1";
Will routes anything appearing after localhost/crdlabs/argument to localhost/crdlabs/home/display/argument.So the route localhost/crdlabs/learning-coding will be redirected to localhost/crdlabs/home/display/learning-coding.So you can not use like this.
But I suggest you to show your articles
localhost/crdlabs/displayarticles/article/learning-coding
To
localhost/crdlabs/articles/learning-coding
using the following routing rule.
$route['articles/(:any)'] = "displayarticles/article/$1";
Will be best.

custom url in codeigniter

I have controller called 'project' with method of index
I want to pass project_id
it works with this url:
URL: http://example.com/project/index/project_id
what I am trying to do is to have url for each project
http://example.com/project_id
for example:
http://example.com/rickyboby
I tried this code
$route['(:any)'] = "project/index/$1";
It worked I could access project_id from url www.example.com/project_id but the problem is I have other controllers are not working now, for example I have welcome controller, the url: www.example.com/welcome/ is routing me to project page, how can I solve that ?
You need to whitelist all the controllers you have before the "any" rule because they go in order (so in your example, /welcome would take you to project/index/welcome). For example:
$route['welcome'] = "welcome";
$route['somethingElse'] = "someOtherUrl";
$route['(:any)'] = "project/index/$1";
You can also try to think of a clever way of doing this with regex, but I think you're better off with a whitelist.
This is a basic programming concept and probably doesn't belong here, but you can always do something like:
$controllers = array('welcome', 'otherController', 'etc');
foreach($controllers as $c) {
$route[$c] = $c; // make all URLs from the list go to their same-named controllers
}
$route['(:any)'] = "project/index/$1"; // handle the other URLs
One more thing - don't forget to prevent users from giving projects names that match existing controller names (such as welcome) because their project won't be accessible! There, yet another reason to have that controller list someplace...
Place the "welcome" routing rule before the "project" routing rule. This way the system will match welcome and won't go looking for the next rule. Alternatively, you could use (:num) instead of (:any), this way it will match only numbers (in case your project ids are numbers).

Purpose of routes.php in codeigniter

I just want to know the purpose of this on routes.php
$route['default_controller'] = "welcome";
$route['scaffolding_trigger'] = "";
Let me first take your through routing and then tell you about the meaning of those lines in routes.php.
You should start with URI Routing. In short, what you do with routes is that you map a certain URI with a controller/method/parameter statement.
Examples
See the following examples taken from the user guide:
So, something like example.com/journals can be routed to the blogs controller.
$route['journals'] = "blogs";
Another good example is when you are building a product catalogue and you need example.com/product/some_id to be routed to a controller catalog:
$route['product/(:num)'] = "catalog/product_lookup_by_id/$1";
In the example above, catalog will be the controller, product_lookup_by_id will be the method and $1 is the parameter which is picked up from the URI.
Answer to your question
You have asked:
I just want to know the purpose of this on routes.php
$route['default_controller'] = "welcome";
$route['scaffolding_trigger'] = "";
The default_controller is quite obvious. This means welcome/index will be loading whenever `example.com/index is being requested.
scaffolding_trigger was deprecated in 1.7 but you can read about it. Scaffolding was a method which you could use to seed data in your database.
$route['default_controller'] = "welcome";
This is the default controller which codeigniter would start with when you didnt specify a controller to the URL.
url:
ip/monitor/index.php
This will trigger the default controller aka welcome.php
url:
ip/monitor/index.php/controller
This will, however, trigger your given controller and not the default one
This is mostly used to asign a index page as the start page.
I'm not sure about $route['scaffolding_trigger'] = ""; as i never used it. But according to the comments it has been removed in version 2.0
Routing rules are defined in your application/config/routes.php file. In it you'll see an array called $route that permits you to specify your own routing criteria. Routes can either be specified using wildcards or Regular Expressions.
For more detail please see this link :
http://ellislab.com/codeigniter%20/user-guide/general/routing.html

Routes in Codeigniter - Automatically

I have a problem with Codeigniter routes. I would like to all registered users on my site gets its own "directory", for example: www.example.com/username1, www.example.com/username2. This "directory" should map to the controller "polica", method "ogled", parameter "username1".
If I do like this, then each controller is mapped to this route: "polica/ogled/parameter". It's not OK:
$route["(:any)"] = "polica/ogled/$1";
This works, but I have always manually entered info in routes.php:
$route["username1"] = "polica/ogled/username1";
How do I do so that this will be automated?
UPDATE:
For example, I have controller with name ads. For example, if you go to www.example.com/ads/
there will be listed ads. If you are go to www.example.com/username1 there are listed ads by user username1. There is also controller user, profile, latest,...
My Current routes.php:
$route['oglasi'] = 'oglasi';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
I solved problem with this code:
$route['oglasi/(:any)'] = 'oglasi/$1';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
Regards, Mario
The problem with your route is that by using :any you match, actually...ANY route, so you're pretty much stuck there.
I think you might have two solutions:
1)You can selectively re-route all your sites controller individually, like:
$route['aboutus'] = "aboutus";
$route['where-we-are'] = "whereweare";
//And do this for all your site's controllers
//Finally:
$route['(:any)'] = "polica/ogled/$1";
All these routes must come BEFORE the ANY, since they are read in the order they are presented, and if you place the :any at the beginning it will happily skip all the rest.
EDIT after comment:
What I mean is, if you're going to match against ANY segment, this means that you cannot use any controller at all (which is, by default, the first URI segment), since the router will always re-route you using your defined law.
In order to allow CI to execute other controllers (whatever they are, I just used some common web pages, but can be literally everything), you need to allow them by excluding them from the re-routing. And you can achieve this by placing them before your ANY rule, so that everytime CI passed through your routing rules it parses first the one you "escaped", and ONLY if they don't match anything it found on the URL, it passes on to the :ANY rule.
I know that this is a code verbosity nonetheless, but they'll surely be less than 6K as you said.
Since I don't know the actual structure of your URLs and of your web application, it's the only solution that comes to my mind. If you provide further information, such as how are shaped the regular urls of your app, then I can update my answer
/end edit
This is not much a pratical solution, because it will require a lot of code, but if you want a design like that it's the only way that comes to my mind.
Also, consider you can use regexes as the $route index, but I don't think it can work here, as your usernames are unlikely matchable in this fashion, but I just wanted to point out the possibility.
OR
2) You can change your design pattern slightly, and assign another route to usernames, something along the line of
$route['user/(:any)'] = "polica/ogled/$1";
This will generate quite pretty (and semantic) URLs nonetheless, and will avoid all the hassle of escaping the other routes.
view this:
http://www.web-and-development.com/codeigniter-minimize-url-and-remove-index-php/
which includes remove index.php/remove 1st url segment/remove 2st url sigment/routing automatically.it will very helpful for you.
I was struggling with this same problem very recently. I created something that worked for me this way:
Define a "redirect" controller with a remap method. This will allow you to gather the requests sent to the contoller with any proceeding variable string into one function. So if a request is made to http://yoursite/jeff/ or http://yoursite/jamie it won't hit those methods but instead hit http://yoursite/ remap function. (even if those methods/names don't exist and even if you have an index function, it supersedes it). In the _Remap method you could define a conditional switch which then works with the rest of your code re-directing the user any way you want.
You should then define this re-direct controller as the default one and set up your routes like so:
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
This is at first a bit of a problem because this will basically force everything to be re-directed to this controller no matter what and ultimately through this _remap switch.
But what you could do is define the rules/routes that you don't want to abide to this condition above those route statements.
i.e
$route['myroute'] = "myroute";
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
I found that this produces a nice system where I can have as many variable users as are defined where I'm able to redirect them easily based on what they stand for through one controller.
Another way would be declaring an array with your intenal controllers and redirect everything else to the user controller like this in your routes.php file from codeigniter:
$controllers=array('admin', 'user', 'blog', 'api');
if(array_search($this->uri->segment(1), $controllers)){
$route['.*'] = "polica/ogled/$1";
}

Remapping Codeigniter Controller

I've been playing with Codeigniter lately, and I came to know that you can remap a function inside a Controller so that you can have dynamic pretty URL.
I just want to know can the same be done with controllers? I mean If I call http://example.com/stack, it'll look for a controller named stack and if not found, it'll call a fixed/remapped controller where I can take care of it.
Can this be done?
Maybe this can help you:
function _remap( $method )
{
/// $method contains the second segment of your URI
switch( $method )
{
case 'about-me':
$this->about_me();
break;
case 'successful':
$this->display_successful_message();
break;
default:
$this->page_not_found();
break;
}
}
Yes, it can be done, you achieve it by using uri routing.
In your application/config/routes.php you can set your custom routes to remapping URIs.
There are already 2 provided, the default one (in case no controller is called) and the 404 error routing.
Now, if you want to add custom routes, you just add them UNDER those 2 defaults, keeping in mind that they're executed in the order they're presented.
Say, for example, you want to remap 'stack' to another controller, just use:
$routes['stack'] = 'othercontroller';
In this way, whenever you access 'stack' it will be automatically mapped to 'othercontroller', and if that doesn't exists..well, you get the same 404 error.
If you're hiding index.php from the URL with .htaccess remember to insert it into the $config['index_page'] = 'index.php';.
If what you're trying to achieve, instead, is a custom error message when a controller is not found, just override the 404 route as already suggested by #Juris Malinens, using your custom default controller to handle that situation
$route['404_override'] = 'customcontroller';
You can use .htaccess to do this or config/routes.php- Codeigniter is very flexible ;-)
If controller is not found use $route['404_override']; in config/routes.php
The application/config/routes.php file would be the appropriate place to do this. The 404_override mentioned by Juris is only available in CI 2.x just in case you have an older version (I don't know, you may be working on a legacy system, or may have to in the future).
Note, you can do more than just "remap" controllers with this. The routes accept regex patterns like htaccess rewrite rules; there are also some CI patterns which are basically just more human readable alias for regexes. Say you had an Articles controller with category, search and article functions, you might have routes that looked like:
$route["category/(:any)"] = "articles/category/$1";
$route["search/(:any)"] = "articles/search/$1";
$route["(:any)"] = "articles/article/$1';
You see how you can use routes to completely remove the controller name from you URLs? These rules would fall back to assuming the page is an article if the URL doesn't specifically say it's a category page or a search query. You could then check if you had an article for the URL and display a 404 as appropriate.

Categories