I am newbie to codeigniter.my problem is let suppose my baseurl is
www.xyz.com
Now I have function like this
class Front extends MY_Controller {
public function index()
{
$this->__front_template('index');
}
public function about()
{
$this->__front_template('about-us');
}
Now if I have to call about I call like
www.xyz.com/front/about
But I need to call like
www.xyz.com/about
How can I do that ?
You can use codeigniter URI routing
Typically there is a one-to-one relationship between a URL string and its corresponding controller class/method. The segments in a URI normally follow this pattern:
Codeigniter URL Work as
example.com/class/function/id/
So you must route for this type. in application/config/routes.php add code like
$route['about'] = 'Front/about';
it works .!
You cannot call about directly as per your architecture, because of the following reason.
In CodeIgniter we have URL divided as:
http://www.example.com/controller_name/function_name
If the function you are trying to call is index function that above can be written as: http://www.example.com/controller_name/
So, in order to call about directly you need to create a separate controller for it with the name about and you can write about code in index function. And your requirement will be fulfilled.
There are other complex ways to, but as you have mentioned you are newbie. so this will be best.
If you want a more efficient way, look at the documentation:
https://www.codeigniter.com/userguide3/general/routing.html
Related
I am a Java developer (I often used Spring MVC to develop MVC web app in Java) with a very litle knowledge of PHP and I have to work on a PHP project that use CodeIgniter 2.1.3.
So I have some doubts about how controller works in CodeIgniter.
1) In Spring MVC I have a controller class with some annoted method, each method handle a specific HTTP Request (the annotation defines the URL handled by the method) and return the name of the view that have to be shown.
Reading the official documentation of CodeIgniter it seems me that the logic of this framework is pretty different: https://www.codeigniter.com/userguide3/general/controllers.html#what-is-a-controller
So it seems to understand that in CodeIgniter is a class that handle a single URL of the application having the same name of the class name. Is it correct?
So I have this class:
class garanzieValoreFlex extends CI_Controller {
.....................................................
.....................................................
.....................................................
function __construct() {
parent::__construct();
$this->load->helper(array('form', 'url'));
$this->load->library(array('form_validation','session'));
}
public function reset() {
$this->session->unset_userdata("datiPreventivo");
$this->load->view('garanziavalore/garanzie_valore_questionario_bootstrap',array());
}
public function index() {
$this->load->model('Direct');
$flagDeroga = "true" ;
$this->session->userdata("flagDeroga");
$data = $this->session->userdata("datiPreventivo");
$this->load->model('GaranzieValoreFlexModel');
$data = $this->session->userdata("datiPreventivo");
$this->load->model('GaranzieValoreFlexModel');
$this->load->view('garanziavalore/index_bootstrap',$data);
}
public function back() {
$this->load->model('Direct');
$flagDeroga = "true" ;
$this->session->userdata("flagDeroga");
$data = $this->session->userdata("datiPreventivo");
$this->load->model('GaranzieValoreFlexModel');
//$this->load->view('garanziavalore/garanzie_valore_questionario_bootstrap',$data);
$this->load->view('garanziavalore/index_tornaIndietro_bootstrap',$data);
}
.....................................................
.....................................................
.....................................................
}
So, from what I have understand, basically this controller handle only the HTTP Request toward the URL: http://MYURL/garanzieValoreFlex.
So from what I have understand the method performed when I access to the previous URL is the index() that by this line:
$this->load->view('garanziavalore/index_bootstrap',$data);
show the garanziavalore/index_bootstrap.php page that I found into the views directory of my prohect (is it a standard that have to be into the views directory?)
Is it my reasoning correct?
If yes I am loading the view passing to id also the $data variable that I think is the model containing the data that can be shown in the page, this variable is retrieved by:
$data = $this->session->userdata("datiPreventivo");
What exactly does this line?
The last doubt is related the other back() method that I have found in the previous controller: is it a method of CodeIgniter CI_Controller class or something totally custom defined by the developer that work on this application before me?
A controller can handle more than one URL and the class garanzieValoreFlex is an example of such a class.
The URL http://MYURL/garanzieValoreFlex will call the index method.
The URLs http://MYURL/garanzieValoreFlex/back and http://MYURL/garanzieValoreFlex/reset will call the back() and reset() methods of the class respectively. These two function are custom additions to the extended class CI_Controller.
Codeigniter (CI) URLs follow the pattern example.com/class/function/argument/
The function and argument segments are optional.
When a URL uses only a class name such as example.com/class then CI will look for and call the index() method if it exists. If index() does not exist you will get 404 Page Not Found display.
Your reasoning about $this->load->view('garanziavalore/index_bootstrap',$data); is correct. It is standard to put such files in the views directory. Optionally, subdirectories of views can be used as in /views/garanziavalore/.
CI uses a file structure that associates different classes (libraries) with certain paths. Controllers, Models and View classes are stored in their respective folders. Then the loader class will know exactly where to start looking for any given "type" of class. For instance, the call to $this->load->view('garanziavalore/index_bootstrap',$data); tells the loader class to get the file index_boostrap.php from the /application/views/garanzivalore/ directory. The code $this->load->model('GaranzieValoreFlexModel'); tells the loader to use the file GaranzieValoreFlexModel.php in /application/models/.
Find documentation of the loader class here.
The line of code
$data = $this->session->userdata("datiPreventivo");
is calling the userdata method of the session class (library). Think of session data as an array. If the array was defined this way. (This is only pseudo-code for what is accomplished).
$userdata = array(); //empty array structure
The call $this->session->userdata("datiPreventivo") is in effect returning the value of $userdata["datiPreventivo"].
Your reasoning is wrong. I would really recommend you to read the official codeigniter tutorials so that you may understand how the MVC works:
Below are the links
Codeigniter 2:
http://www.codeigniter.com/userguide2/
Codeigniter 3:
http://www.codeigniter.com/user_guide/
CI controllers handles different urls. If you create a function called index in a controller, it will be loaded automatically when the controller is accessed. For your case, http://MYURL/garanzieValoreFlex should access the function.
To access any other function, you will need to http://MYURL/garanzieValoreFlex/**MyFunction**
(Read more http://www.codeigniter.com/user_guide/general/urls.html?highlight=url#codeigniter-urls) The back function is a user defined function.
For some reasons, I do not want to access from url like examples.com/controller/method. I want to force Codeigniter to use routes.php instead. I do not want to use private, protect or _method.
Please, help! I am using Codeigniter 3
In codeigniter, the methods you write in controllers are to be accessed in the url that is its mvc structure.
If you want to avoid a function in the controller to be seen in the url, simply make that function private/protected or prepend an _ in the function name.
private func_name
or
public _func_name
or
protected func_name
any of the options in your functions won't allow access to your functions in the url.
If you want you controller function to be accessed by other subclasses, you ll need to make the function public or protected as required and to avoid it to be accessed by the url simply prepend an underscore _
I found a solution in Codeigniter 4, just go to routes and set autoroute to false
$routes->setAutoRoute(false);
I'm writing a helper in CodeIgniter that I need to reuse in several controllers. The initial data loaded in the view rendered by the helper can vary depending on which controller uses the helper.
I'm trying this:
$controller = $CI->router->fetch_class();
$init = $CI->$controller->get_initial_data($id);
but getting
Call to a member function get_initial_data() on a non-object
When I view the variable contents with:
print_r($controller);
I see the name of the correct controller. Problem seems to be with $CI->$controller. Any ideas on how I can use the variable as the controller reference?
You can't access controller methods from anywhere else but from inside the controller itself. So, there is no way for the helper to call the get_initial_data method.
What you want to do is have the controller call its own get_initial_data method and pass the result as a parameter to the helper function.
For example (in your controller):
$data = $this->get_initial_data($id);
my_helper_function($data);
Try using
$CI->{$controller}->get_initial_data($id);
I am trying to learn MVC and i want to to display a store page when the url is www.example.com/store and another cart page wenn the url is www.example.com/store/cart. Both methods are inside one class:
class store extends controller {
function __construct() {
parent::__construct ();
}
function Store() { //this should display the store page
$this->view->render ( "store" );
}
function cart() { //this should display the cart page
$this->view->render ( "store", "cart.php" );
}
}
the method $this->view->render() includes the pages with the html code.
How can I decide which method to execute based on the url?
I can see you are trying to write your own MVC so I will try to explain things you should be aware of while doing this.
First thing you want to do while writing MVC is utilize Front Controller pattern.
What this means is that every HTTP Request will go through one file, index.php.
This will help you to cofigure your application in one file. You can do this by just always opening your lets say:
www.example.com/index.php/controller/method/param1/param2
or you can force users to go through index.php using .htaccess file.
For reference check other frameworks like Codeigniter and CakePHP, see how they use .htaccess files.
When you are in your front controller file, you should think about routing your HTTP Request to appropriate Controller / Method. There are really lots of ways to achive that, and its up to you to figure out the best way to do that.
Anyway you need Router class that will analyse your URL, and extract Controller / Method / Params you need from URL. Then when you know what Controller / Method you need to invoke, you need Dispatcher class that would instantiate Controller, and call Method you need. You should also think about Params you want to pass to your Method so you can use them there.
The easiest way to play around with this is to use query strings.
So lets say you have URL like this:
http://localhost/test/index.php?controller=home&method=welcome
You can easily get Controller and Method names.
Now you can do something like this:
// Get controller and method names
$controller = $_GET['controller'];
$method = $_GET['method'];
// Instantiate controller object
$app = new $controller();
// Call method on you controller object
call_user_func_array(array($app, $method));
This is like the simplest thing you can do just to play around.
Once you get hold of this, write your Router class so it can look like this:
http://localhost/test/index.php/controller/method/param1/param2
Anyway you need these classes:
Front Controller so every request goes through one file, and this is where you bootstrap you application, register class autoloading, configure everything etc...
This is not a class but a file with procedural code that boots everything up.
Router that will analyse URL and give you back Controller, Method, and Params that you want to pass to invoked Method.
Dispatcher that will instantiate Controller and call Method passing Params to your Method.
And then all control goes to user of your system, then you do your magic inside your controller / method.
While Dispatching request you can also use this:
call_user_func_array(array($app, $method), $params);
this way you are passing $params to $method, so you can use $params inside your method.
Also, check out Reflection class, this can help you to analyse if method you want to invoke exists, if not you should call HTTP 404 etc...
There is no simple answere to your question, but I hope this helps,
have fun building your system and just improve until you get it perfect :)
You need to have a separate Router class which does the routes requests to the controller. I suggest looking at/copying Symfony's Router.
I once did something like this for a home brew approach.
Use .htaccess (apache) / Web.config (iis) to redirect all requests to the following script.
// include callable controllers here
$partsA = explode("?", $_SERVER['REQUEST_URI']); // split querystring
$partsB = explode("/", $partsA[0]); // get url parts
if (count($partsB) < 2)
die("missing controller in url");
elseif (count($partsB) < 3)
die("missing action in url");
$className = $partsB[1];
$methodName = $partsB[2];
if (class_exists($className))
if (!is_subclass_of($className, "controller"))
die(htmlspecialchars("Class $className doesn't extend controller")); // prevents use of unauthorized classes
else
$controller = new $className();
else
die(htmlspecialchars("Class $className doesn't exist"));
if (!method_exists($controller, $methodName))
die(htmlspecialchars("Method $methodName doesn't exist"));
else
$controller->$methodName();
can anyone tell me how do i access model from view in codeigniter?
Load a model on the controller
$this->load->model('yourmodel');
Assign this model to a var like this
$data['model_obj'] = $this->yourmodel;
and assign this data array to your view template
Use $model_obj object on the view template for calling model methods
$model_obj->some_method()
Hope this helps ...
See the thread:
View Calling a Model
By the way why do you need to access the model from the view, you can send the model data to the view from the controller too which is the usual and better approach.
As a good note, keep your processing logic out of the view, you should use controller instead.
CodeIgniter's $this->load->model() returns absolutely nothing. Look at it: system/libraries/Loader.php.
This will output absolutely nothing:
$model = $this->load->model('table');
print_r($model);
And this next example will give you the fatal error Call to a member function some_func() on a non-object:
$model = $this->load->model('table');
$model->some_func();
It doesn't matter whether that function even exists, $model is not an object.
The thing to do is have a method in your model that returns data, then call that function and pass the results to your view file:
$this->load->model('table');
$data = $this->table->some_func();
$this->load->view('view', $data);
PS: How is the only answer you've accepted the absolute wrong thing to do?
You can use following code:
$ci = &get_instance();
$ci->load->model('your_model');
$ci->your_model->your_function();
Note: You have to call your model in your controller. Its working fine
In cases when you want to access a model function from within a shared view , you don't have to load the needed model in every controller that will call that view. you can load the model inside the view itself by using the following code :
$ci =&get_instance();
$ci->load->model(model_name);
$ci->model_name->function_name();
in older versions of codeigniter the following code used to work :
$this->load->model('model_name');
model_name::function();
but when tested on CI 3.1.9 it throw the following error
Message: Undefined property: CI_Loader::$model_name_model
Note: I use this technique in template views (sidebar, menus ...etc) which is not used everywhere in my application , if you want to access a model from anywhere in your application considre loading this model globally by adding it to the autoload array in application/config/autoload.php
Since $model is not an object, you can make a call to the model "table" using "::" scope resolution operator, which can call the function of the class itself without any object instance.
$this->load->model('table');
table::some_funct();
Note: you also need to make the function "some_funct" static inside your model "table".
Hey. You can access from view to models the same mode as you access on its controller. Remember that the view access to models that import its controller.
in the original UML I've seem for MVC architecture, view calls methods in model..
http://www.as3dp.com/wp-content/uploads/2010/02/mvc_pope_krasner.png
..but in practice with PHP apps, because there is no persistence to track state changes in objects between requests (or at least not efficiently), I find it better to keep all model method calls in controller and pass the result to view if possible.
you can add your model's name to config -> autoload model
$autoload['model'] = array('model_name');
this success for me
You can access basicly a method from view in codeingiter.
public function index()
{
$this->load->model('persons');
$data['mydata'] = $this->persons->getAllSessionData();
$this->load->view('test_page', $data);
}
in view
print_r ($mydata);
my function returned an array.