I am currently looking into the PHP Framework Codeigniter and understand the main concepts so far until the Controllers section about _remapping. I have a understanding how _remapping overwrites the behaviour of controller methods over the URI eg from www.example.com/about_me to www.example.com/about-me. What i would like to hear is peoples opinions on what to use- _remapping method or the URI Routing method? Im only asking this as when researching these methods and someone has been troubled on remapping functions, they have been directed to use URI Routing.
So..
1) What is the main common method to use and the pro's over the other one?
2) Is it best to use URI Routing for PHP5 CI version 2 onwards?
I would be grateful to hear your opinions!
Assuming you do not want to use the index (i.e. http://www.yourdomain.com/category) action of your Categories controller, you can use routes.
$route['category/(:any)'] = 'category/view/$1';
Then you simply need a View action within your Category controller to receive the Category name, i.e. PHP.
http://www.yourdomain.com/category/PHP
function View($Tag)
{
var_dump($Tag);
}
Should you still want to access your index action within your controller, you can still access it via http://www.yourdomain.com/category/index
You should use _remap if you want to change the behaviour of default CI's routing.
For example, if you set a maintenance and want to block any specific controller from running, you can use a _remap() function loading your view, and which will NOT call any other method.
Another example is when you have multiple methods in your URI. Example:
site.com/category/PHP
site.com/category/Javascript
site.com/category/ActionScript
Your controller is category but methods are unlimited.
There you can use a _remap method as called by Colin Williams here:
http://codeigniter.com/forums/viewthread/135187/
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
To sum up, if the current CI's routing suits to your project, don't use a _remap() method.
$default_controller = "Home";
$language_alias = array('gr','fr');
$controller_exceptions = array('signup');
$route['default_controller'] = $default_controller;
$route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2';
$route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2';
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
foreach($language_alias as $language)
$route[$language] = $default_controller.'/index';
Related
i want to achieve url routing something like www.example.com/alicia
suppose alicia is not a class name or method name just something like passing data in url and with some class i want to access this and want to use it for further process.How i can use it ? Thanks in advance.
You can use Codeigniter's built-in routing, the file route.php is located in your config folder.
there you can add:
$route['alicia'] = 'welcome/index/something';
$route['alicia/:any'] = 'welcome/index/someotherthing/$1';
then in your controller, for example welcome you just create a function like:
public function index($page = null){
if($page=='something'){
// do what you need to do, for example load a view:
$this->load->view('allaboutalicia');
}
elseif ($page=='someotherthing'){
// here you can read in data from url (www.example.com/alicia/2017
$year=$this->uri->segment(2); // you need to load the helper url previously
}else{
// do some other stuff
}
}
documentation on routing and on urlhelper
edit after comment:
in case your uri segment is representing a variable, like a username, then you should use a uri scheme like www.example.com/user/alice and create your route like:
$route['user/:any'] = 'welcome/index/user';
then in your controller welcome
public function index($page=null){
if($page=='user'){
// do what you need to do with that user
$user=$this->uri->segment(2); // you need to load the helper url
}
else{
// exception
}
}
This could be tricky because you don't want to break any existing urls that already work.
If you are using Apache, you can set up a mod_rewrite rule that takes care to exclude each of your controllers that is NOT some name.
Alternatively, you could create a remap method in your base controller.
class Welcome extends CI_Controller
{
public function _remap($method)
{
echo "request for $method being handled by " . __METHOD__;
}
}
You could write logic in that method to examine the requested $method or perhaps look at $_SERVER["REQUEST_URI"] to decide what you want to do. This can be a bit tricky to sort out but is probably a good way to get started.
Another possibility, if you can think of some way to distinguish these urls from your other urls, would be to use the routing functionality of codeigniter and define a pattern matching rule in the routes.php file that points these names to some controller which handles them.
I believe that the default_controller will be a factor in this. Any controller/method situations that actually correspond to a controller::method class should be handled by that controller::method. Any that do not match will, I believe, be assigned to your default_controller:
$route['default_controller'] = 'welcome';
I don't know much about the routing concept in codeigniter, I want to pass many parameters to a single method as explained in this http://www.codeigniter.com/userguide2/general/controllers.html tutorial page.
In the url I have this
http://localhost/code_igniter/products/display/2/3/4
In my routes.php I have written
$route['products/display/(:any)'] = 'Products_controller/display';
What I thought is it will pass all the parameters (here 2/3/4) to the method 'display' automatically but I am getting 404 page not found error.
In general I want to achieve something like, if the URI is controller/method I want to route to someother_controller/its_method and pass the parameters if any to that method. How can I do it?
In CI 3.x the (:any) parameter matches only a single URI segment. So for example:
$route['method/(:any)/(:any)'] = 'controller/method/$1/$2';
will match exactly two segments and pass them appropriately. If you want to match 1 or 2 you can do this (in order):
$route['method/(:any)/(:any)'] = 'controller/method/$1/$2';
$route['method/(:any)'] = 'controller/method/$1';
You can pass multiple segments with the (.+) parameter like this:
$route['method/(.+)'] = 'controller/method/$1';
In that case the $1 will contain everything past method/. In general I think its discouraged to use this since you should know what is being passed and handle it appropriately but there are times (.+) comes in handy. For example if you don't know how many parameters are being passed this will allow you to capture all of them. Also remember, you can set default parameters in your methods like this:
public function method($param=''){}
So that if nothing is passed, you still have a valid value.
You can also pass to your index method like this:
$route['method/(:any)/(:any)'] = 'controller/method/index/$1/$2';
$route['method/(:any)'] = 'controller/method/index/$1';
Obviously these are just examples. You can also include folders and more complex routing but that should get you started.
On codeigniter 3
Make sure your controller has first letter upper case on file name and class name
application > controllers > Products_controller.php
<?php
class Products_controller extends CI_Controller {
public function index() {
}
public function display() {
}
}
On Routes
$route['products/display'] = 'products_controller/display';
$route['products/display/(:any)'] = 'products_controller/display/$1';
$route['products/display/(:any)/(:any)'] = 'products_controller/display/$1/$2';
$route['products/display/(:any)/(:any)/(:any)'] = 'products_controller/display/$1/$2/3';
Docs For Codeigniter 3 and 2
http://www.codeigniter.com/docs
Maintain your routing rules like this
$route['products/display/(:any)/(:any)/(:any)'] = 'Products_controller/display/$2/$3/$4';
Please check this link Codeigniter URI Routing
In CodeIgniter 4
Consider Product Controller with Show Method with id as Parameter
http://www.example.com
/product/1
ROUTE Definition Should be
$routes->get("product/(:any)", "Com\Atoconn\Product::show/$1");
I am new to CI and need some beginner's help from experts.
Here is what my current setup is:
/controllers/
home.php
report.php
/views/
home/index.php
home/recent.php
report/index.php
report/generate.php
the URI i am trying to produce as an outcome:
http://localhost
http://localhost/report (would load the index.php)
http://localhost/report/generate (would call the method for generate in the report controller)
http://localhost/recent/10 (would call the method for generate in the home controller passing the variable '10')
$route['default_controller'] = "home";
$route['404_override'] = '';
$route['/'] = 'home/index';
$route['recent/(:num)'] = 'home/recent/$1';
$route['report/(:any)'] = 'report/$1';
How do i avoid always modifying the routes file for each new method created in a class? so that it would follow:
$route[$controller/$method/$variable] (very use to how .net mvc routing is setup).
Any help is appreciated.
You don't need further modifications. In fact, even this line is redundant:
$route['report/(:any)'] = 'report/$1';
This one is also redundant:
$route['/'] = 'home/index';
since the default controller is set to 'home' and the default method is always index.
Look at how CI works with URLs: https://www.codeigniter.com/user_guide/general/urls.html
So, /localhost/report/generate would look for the Report controller, and load its generate method. That's how it works out-of-the-box, no routing needed.
And this route is fine:
$route['recent/(:num)'] = 'home/recent/$1';
If will take the URL /localhost/recent/123 and will load the Home, controller, recent method and will pass 123 as the first method parameter.
I'm trying to write an application that takes a parameter from the url and supplies it to the index function in the default controller. Then decides what to load depending on this parameter either a default home page or a custom page.
$route['(eventguide/:any)'] = 'eventguide';
This code works but only if I have the controller in the url like so:
example.com/eventguide/(parameter)
I don't want to include the controller name. So i'm not exactly sure how to route this.
Ideally the url would look like example.com/(parameter), is this possible?
Yes, you're almost there:
$route['(:any)'] = "eventguide/index/$1";
And in your index() method you fetch the parameter:
public function index($parameter = null){
}
$parameter will now contain anything caught by the :any shortcut, which should be equivalent to (\w)+ IIRC
Since this is a catch-all route, be careful to put any other custom route you want before it, otherwise they will never be reached.
For ex., if you have a controller "admin", your route files should be;:
$route['admin'] = "admin";
$route['(:any)'] = "eventguide/index/$1";
I have a site that has a lot of pages that lye at the root (ex. /contact, /about, /home, /faq, /privacy, /tos, etc.). My question is should these all be separate controllers or one controller with many methods (ex. contact, about, index within a main.php controller )?
UPDATE:
I just realized that methods that are within the default controller don't show in the url without the default controller (ie. main/contact wont automatically route to /contact if main is the default controller ). So you would need to go into routes and override each page.
If all of these are just pages, I would recommend putting them into a single controller. I usually end up putting static pages like this into a 'pages' controller and putting in routes for each static page to bypass the '/pages' in my URLs.
If they are share the same functionality, so they should be in the same controller.
for example, if all of them are using the same model to take content from, so, one controller can easily handle it.
Why in one controller? because you always want to reuse your code.
class someController{
function cotact(){
print $this->getContentFromModel(1);
}
function about(){
print $this->getContentFromModel(2);
}
function home(){
print $this->getContentFromModel(3);
}
private function getContentFromModel($id){
return $this->someContentModel->getContentById($id);
}
}
(instead of print, you should use load a view)
See in my example how all of the function are using the same getContentFromModel function to share the same functionality.
but this is one case only, there could be ther cases that my example can be bad for...
in application/config/routes.php
$route['contact'] = "mainController/contact";
$route['about'] = "mainController/about";
$route['home'] = "mainController/home";
$route['faq'] = "mainController/faq";
$route['privacy'] = "mainController/privacy";
and you should add all of these methods within the mainController.php
You can also save the content of the pages in your database, and them query it. For instance, you can send the url as the keyword to identify the page content
$route['contact'] = "mainController/getContent/contact";
$route['about'] = "mainController/getContent/about";
$route['home'] = "mainController/getContent/home";
$route['faq'] = "mainController/getContent/faq";
$route['privacy'] = "mainController/getContent/privacy";
in this case you only have to create one method named "getContent" in the controller "mainController" and this method will look something like this:
class mainController extends CI_Controller
{
public function getContent($param)
{
$query = $this->db->get_where('mytable', array('pageName' => $param));
// then get the result and print it in a view
}
}
Hope this works for you
The page names you listed should probably be different methods inside your main controller. When you have other functionality that is related to another specific entity, like user, you can create another controller for the user entity and have different methods to display the user, update the user, register the user. But its all really a tool for you to organize your application in a way that makes sense for your domain and your domain model.
I've written a blog post about organizing CodeIgniter controller methods that might be helpful to you. Check it out here: http://caseyflynn.com/2011/10/26/codeigniter-php-framework-how-to-organize-controllers-to-achieve-dry-principles/