public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
This is what i read from official site. As i understand _remap method is getting called before all actions. But this instruction $this->$method(); means that calling $method will call _remap again and it is being something like cycle. Isn't it?
No, _remap is called by the framework, during the init, but when you call some method directly, you only execute the function content...
Hope it's helpful!
Some explanation found here:
Important: If your controller contains a function named _remap(), it will always get called regardless of what your URI contains. It overrides the normal behavior in which the URI determines which function is called, allowing you to define your own function routing rules.
Related
Hi I have a class which includes two methods.
One of which is to initialize session , another one is for redirect the web page
I ve written the class such that it can be called repeatedly.
$obj->setSession(key,value)->redirect(url);
In this mode , the session is firstly initialized and then it redirects to the next page.
But if it's written like this
$obj->redirect(url)->setSession(key,value);
It just redirects to the defined location qnd the session is not initialized anymore ..
It s cuz when the resirect method is called, the page changes promptly and it causes the second method not to be called ..
Is there any way to be able to call methods repeatedly without the need of considering their order ?
When I usually face that issue, I add a method in the $obj object called render() or done() or something to that effect that checks all the flags I might have defined previously. One of those flags might be a header flag, which is what a redirect method usually does header(Location: $yourDestUrl).
So you end up with something like:
$obj->redirect(url)->setSession(key,value)->render();
When you call a method such as redirect or setSession, put those actions in a "stack" as a property of you class.
Then, when all your methods are called, call a method called exec (for example) that will execute all the actions in the "stack".
Here is a base class based on this idea using magic methods:
class Stack {
private $_stack = array();
public function __call($method, $args) {
// Adding method to stack
$this->_stack[$method] = $args;
return $this;
}
public function __isset($name) {
// Checks if method is in stack
return isset($this->_stack[$name];
}
public function exec() {
// setSession is executed first
if (isset($this->setSession))
call_user_func_array('setSessionMethod', $this->_stack['setSession']);
// redirect is executed second
if (isset($this->redirect))
call_user_func_array('redirectMethod', $this->_stack['redirect']);
}
}
To use this class, you would do:
$stack = new Stack;
$stack->redirect('arg')
->setSession('arg1', 'arg2')
->exec();
I'm trying to create my own little PHP-Framework just for fun and to learn.
But now I stuck with the View.
class Index extends Controller {
function __construct() {
parent::__construct();
$this->view->msg = 'This message is sended over the view.';
$this->view->content = 'This is the INDEX-Content.';
$this->view->render('index/index');
}
public function something() {
// do something
// and render it
$this->view->content = 'This is the content from something.'
}
So what I can do is to misuse the __destruct and render here my output. But I guess that is against the purpose of this method.
When I compare my intention with e.g. Zend Framework or Laravel they use e.g. an after() method to render a view.
But I do not understand which method can do this. The constructor is the first, the destructor the last and everything between it has to be called to work.
Are there any "magic" methods for this?
You should handle your HTTP I/O
This is how you can output
This is how a request is executed
This is how the action is triggerd
Sniff through the repo as much as you can, Kohana is a simple yet powerfull framework. (you can learn a thing or two)
You can do something like this in your main Controller class :
public function __call($method,$arguments) {
if(method_exists($this, $method)) {
call_user_func_array(array($this,$method),$arguments); //this is where the function is called
$this->render();
}
}
You can eliminate in hear constructors, destruct and other functions that you do not want to automatically render.
You can also have a variable in your main Controller class, autoRender set default to false and just set it to true when you want to produce a predefined output.
Also in the _call function, you can use the $method variable to have a predefined name for your view. Like for example lets say you would have a folder in your framework called Views and in there you would have a file called something.view_extension.
You can send to render like this : $this->render($method.'.view_extension');
Just a bulk idea you can work around. :)
In CakePHP we have beforeFilter and afterFilter to run methods before or after any controller methods (e.g. save log or check logged in etc.)
How can I do this in CodeIgniter?
You'll want to make use of hooks in Codeigniter, that is where they have implemented your desired functionality of running code before certain points of the framework code.
https://www.codeigniter.com/user_guide/general/hooks.html
There are some built-in hooks that allow you to call a method or class at various points during the request:
pre_system
pre_controller
post_controller_constructor
post_controller
display_override
cache_override
post_system
So what you want is probably something like pre_system or pre_controller.
Check out the _remap() function. It allows you to redirect to your own function before calling the normal controller function. You can include your own _remap function in your controller like this (copied from the User Guide):
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
The second segment of the URI gets passed to the _remap function as a parameter (in the example as $method), and you can then redirect the process however you need.
The segments in a URI normally follow this pattern in Codeigniter:
XYZ.com/Class/Method/param1/param2
This works as expected when the called method is defined in the controller, but nothing works if I supply the URI with some undefined method to invoke the __call magic method that takes care of any undefined method.
__call is only invoked if its called from within the controller itself, not when I call some undefined method from the URI
Any explanation?
Thanks
In CodeIgniter, there is _remap. So if you go to
XYZ.com/Class/UndefinedMethod/param1/param2
then _remap will be called (actually _remap will always be called, so we need to make sure that methods that do exist are called correctly).
function _remap($method, $params=array()){
$funcs = get_class_methods($this);
if(in_array($method, $funcs)){ // We are trying to go to a method in this class
return call_user_func_array(array($this, $method), $params);
}
// else do something else
}
Look in the server (Apache?) log file. Undoubtedly you will see PHP errors which caused processing to abort. Unless you cover undefined functions by remapping them to an error page, random URLs will cause "nothing" to seem to happen.
I have finally got a zend view helper working using this in my helper file:
class MY_View_Helper_Table extends Zend_View_Helper_Abstract
{
private $table_data="",$table_head="";
public function Table($data=''){
return "hello";
}
}
and this in my view:
print $this->Table();
This just prints out the returned value of the constructor, I think. How do I go about calling other methods of the class? I dont really know how to refer to the instanced object to access its methods.
I have managed to sort of do it using
method chaining, in Table I return
$this; but there must be a better and
normal way of doing it.
Actually no. Thats typically how you do it. Because of how view helpers work, if you need access to other methods on the helper then you either always return $this from your table method or you detect what to invoke by the parameter signature passed to it. For eaxmple:
public function table($options = null)
{
if(null === $options){
return $this;
}
if(is_array($options)){
return $this->tableFromArray($options);
}
// etc..
}
You can also get the helper instance with $this->getHelper('name') and then chain to the method you want... but IMO thats more confusing than doing parameter detection of just treating the default method as a getter.