Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the lifecycle of a CakePHP request?

Spoiler: I'd like to better understand the lifecycle of a request to a CakePHP app.

Background: I'm on CakePHP v2.3. I'm debugging a problem that results in an undesired redirect which I can't find. I'm trying to work my way through the lifecycle of the request by incrementally adding die() to try to identify where the redirection is getting triggered.

I hit a dead end because I can kill the execution from inside the controller's beforeFilter(), but the redirect happens if I move the die() into the actual action.

So my specific question is: what happens after the beforeFilter but before the action? I know of beforeRender(), which had no effect when I placed the die() there.

My more general / better question is: is there documentation for the full lifecycle of a CakePHP request?

An answer to either of these would be great.

Update

Thanks to Mathew F.'s helpful suggestions, I'm focusing my attention on the Auth component because it's almost the only candidate and the redirect I'm debugging looks like it's handiwork (the user arrives at the authRedirect location). However, when I trie to die() at the top of the AppController's isAuthorized() nothing happens. And my controller has no isAuthorized() of its own. So this leaves me a bit stumped again.

like image 441
emersonthis Avatar asked Dec 01 '22 17:12

emersonthis


2 Answers

I hit a dead end because I can kill the execution from inside the controller's beforeFilter(), but the redirect happens if I move the die() into the actual action.

That is a big clue that the redirect was performed by a component.

beforeFilter() is called before anything is configured for the request. This includes the controller and it's components. Components are initialized before a controller's action is called. So it's possible for a component to redirect (i.e. the AuthComponent does this).

So my specific question is: what happens after the beforeFilter but before the action? I know of beforeRender(), which had no effect when I placed the die() there.

The request is first processed by the dispatcher. Where it's routed to a controller's action. That controller is then instantiated and all of it's components are then instantiated. For each component their initialize() method is called. After that the controller's beforeFilter() method is called. Followed by all the components startup() method. The controller's action is then called.

http://book.cakephp.org/2.0/en/controllers/components.html#component-api

You can try excluding components to find the one causing the trouble. Another option is to add echo "hello" to your index.php in the webroot. This will force a header can not be modified error at the spot the redirect is being sent.

like image 177
Reactgular Avatar answered Dec 11 '22 03:12

Reactgular


Good question! Taken from the book:

Typical request

  1. Ricardo clicks the link pointing to http://www.example.com/cakes/buy, and his browser makes a request to your web server.
  2. The Router parses the URL in order to extract the parameters for this request: the controller, action, and any other arguments that will affect the business logic during this request.
  3. Using routes, a request URL is mapped to a controller action (a method in a specific controller class). In this case, it’s the buy() method of the CakesController. The controller’s beforeFilter() callback is called before any controller action logic is executed.
  4. The controller may use models to gain access to the application’s data. In this example, the controller uses a model to fetch Ricardo’s last purchases from the database. Any applicable model callbacks, behaviors, and DataSources may apply during this operation. While model usage is not required, all CakePHP controllers initially require at least one model.
  5. After the model has retrieved the data, it is returned to the controller. Model callbacks may apply.
  6. The controller may use components to further refine the data or perform other operations (session manipulation, authentication, or sending emails, for example).
  7. Once the controller has used models and components to prepare the data sufficiently, that data is handed to the view using the controller’s set() method. Controller callbacks may be applied before the data is sent. The view logic is performed, which may include the use of elements and/or helpers. By default, the view is rendered inside of a layout.
  8. Additional controller callbacks (like afterFilter) may be applied. The complete, rendered view code is sent to Ricardo’s browser.
like image 25
Guillermo Mansilla Avatar answered Dec 11 '22 02:12

Guillermo Mansilla