How do I get the request object from inside the bootstrap file?
I can try this methods but not work.
$request= new Zend_Controller_Request_Http();
$request = Zend_Controller_FrontController::getInstance()->getRequest();
If you really want to, you may achieve this calling:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new Zend_Controller_Request_Http());
$request = $front->getRequest();
}
However, this should be avoided, because the most data you need from the Response object will be available after the front controller is dispatched (eg. module, controller or action name).
The other variables stored in the Response object are extracted from global arrays such as $_SERVER, $_POST or $_GET which you may exceptionally read directly in bootstrap.
But most likely, you want to use Response object in front controller plugin:
class Your_Controller_Plugin_PluginName extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// do anything with the $request here
}
}
You shouldn't get the request objet, since if you see the dispatch loop, the idea is that the bootstrap are actions prior to execute in a request.
If you need to alter someway of the application use a Controller Plugin to do that.
You need to bootstrap the frontController first, try something like:
function initFoo()
{
$this->bootstrap('frontController');
$req = $this->frontController->getRequest();
}
Related
I am using Slim Framework for my application. I am using routes. All is working fine. But now I want to do some pre-process working under my constructor on Request and Response.
So that I should not rework on every function of the class. Like getting host and token in every function. I am using middle-ware for many pre-process. But I also want to do some work in class constructor. When I am trying to access request and response interface in constructor, It is showing the error, Please show me the right way of using Request and Response in a class constructor. Will I have to append $app, or will need to work with container.
If it can be done without help of middleware, It will be great for me.
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app->group('/products', function() {
new \Products($this);
});
And I have a class called Products.
class Products
{
public function __construct($app)
{
$app->map(['GET','POST'], '/createupdate', array($this, 'createupdate'));
//I want to use Request and Response here in constructor. But it is showing error.
$this->req_data['request_token'] = $request->getAttribute('request_token');
}
public function createupdate($request, $response, $args) {
//This is working fine.
$this->req_data['request_token'] = $request->getAttribute('request_token');
}
}
When you really want to do this, then you could get the request/response object from the container.
class Products
{
public function __construct($app)
{
$app->map(['GET','POST'], '/createupdate', array($this, 'createupdate'));
$request = $app->getContainer()->get('request');
$this->req_data['request_token'] = $request->getAttribute('request_token');
}
// [..]
}
But, also this will not make much difference $this->req_data['request_token'] is nearly as long as $request->getAttribute('request_token'); so you should use this inside the code.
Note: I expect you to set this attribute already inside middleware, so it may not be available here, because first the container will create a new request object and second cause the middleware is not run when php executes your constructor code.
When you now still want to use $this->req_data['request_token'] inside your class then you should do this:
$products = new \Products();
$app->group('/products', function() use ($products) {
$products->addRoutes($this);
})->add($products); // add the class as middleware as well to set there the class attributes (__invoke function)
class Products
{
public function addRoutes($app)
{
$app->map(['GET','POST'], '/createupdate', array($this, 'createupdate'));
}
public function __invoke($request, $response, $next) // this is middleware function
{
$this->req_data['request_token'] = $request->getAttribute('request_token');
return $next($request, $response); // next in this example would be your route function like createupdate()
}
}
Ofcourse you will get an error, $request is not defined.
public function __construct($app)
{
$app->map(['GET','POST'], '/createupdate', array($this, 'createupdate'));
// Where does $request comes from?!
$this->req_data['request_token'] = $request->getAttribute('request_token');
}
Slim way of doing pre-processing is by using middlewares.
When a route is called, it is automatically injected with the Request and Response objects (and the request route params if any), but when a class is created for the route, it is not automatically injects those instances to the constructor, so they are not available "out of the blue".
If you have pre-processing, I would stick to middlewares, it is much cleaner code (although this is my opinion).
I have an upload form, which is displayed on overlay/lightbox/toplayer. It's available only for several actions in several controllers.
Creating this form needs ~6 lines of code and needs access to REQUEST object to grab params from it.
Where should I put this code, so I could easily create my form in actions I need.
I'd put this functionality in an Action Helper. An action helper can be called directly from any controller action (and is lazy loaded) and action helpers have access to everything the controller action does including the request object and view.
Example:
<?php
class My_Action_Helper_FormCreator extends Zend_Controller_Action_Helper_Abstract {
public function direct($options = null)
{
$request = $this->getRequest();
$view = $this->getActionController()->view;
$form = new Application_Form_SomeForm();
// set form options here...
$view->form = $form; // optional - assign form directly to the view
return $form;
}
}
Place that code in library/My/Action/Helper/FormCreator.php (or where desired and change the class name).
Then, in your actions, call it like this:
$form = $this->_helper->FormCreator();
Lastly, we need to tell the helper broker where to find this action helper. To do so, add this to your bootstrap:
protected function _initActionHelpers() {
Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helper');
}
Hope that helps.
I'm little bit new to Zend, I want to use a controller action through out the entire application automatically, I don't have a clear idea to how to use it, thought about init() method, action helpers, etc.
Then instead of simply creating controller action create controllerAction Helper . Here you can find more about it
http://framework.zend.com/manual/en/zend.controller.actionhelpers.html
My_Helper_Magic extends Zend_Controller_Action_Helper_Abstract
{
public function preDispach()
{
//code inside here will run for entire application automatically
}
}
In your bootstrap do
Zend_Controller_Action_HelperBroker::addHelper(new My_Helper_Magic());
In Response to comment .
It depends upon your 'code fragment' , If your code fragment does not required to know nothing about module , controller, action , base url then you can use Bootstrap init function
like
public function _initAlways()
{
//see how this function name is prefixed with _init hence it will be called by ZF //everytime. You can put your code fragment here
//If your code fragment depends upon some stuff like baseurl then do action controller
// registration here instead
Zend_Controller_Action_HelperBroker::addHelper(new My_Helper_Magic());
}
In Response To comment
You can save any instance of your object inside Zend_Registy and retrieve it whereever you like
Inside Bootstrap.php
public function _initSetup()
{
$object = new My_Custom_Object();
Zend_Registry::set('my_custom_object',$object);
}
Later in your view or controller do
$myObject = Zend_Registry::get('my_custom_object'); //to access it
How can I access an action controller inside controller plugin?
I need to acces it in the preDispatch method.
class My_Controller_Plugin_MyPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$actionController = ?;
}
}
I know that I'm 2 years late to the party, but since I stumbled across this while looking for it myself I figured I'd post anyway. What you're looking for is:
//$module = $request->getModuleName(); // Not everyone uses modules.
$controller = $request->getControllerName();
$action = $request->getActionName();
Caveat... This is only giving you what was requested. If you change the request after dispatch this won't be accurate anymore.
Something like this should work:
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$actionController = $this->getActionController();
}
Edit
Actually this won't work in plugin (will work in action helper).
Some possible workarounds:
subclass Zend_Controller_Action
instead accessing the controller, access the plugin from controller using plugin broker
move plugin logic to action helper
store the data as bootstrap param
store the data in the Registry
How do I extend the Zend_Controller_Request_Http, and let the application know of My_Controller_Request_Http ??
Solution
This is how i got it working following Gordons pointers.
Firts save the following file your library: My/Controller/Request/Http.php
<?php
class My_Controller_Request_Http extends Zend_Controller_Request_Http {
/* Add all your custom functions here */
}
In the bootstrap class i added the following.
function _initApplication ()
{
/* Doing some other stuff here */
$this->bootstrap('frontcontroller');
$front = $this->getResource('frontcontroller');
$front->setRequest('My_Controller_Request_Http');
/* Registering some plugins here, not relevant */
}
From http://framework.zend.com/manual/en/zend.controller.front.html
setRequest() and getRequest() let you specify the request class or object to use during the dispatch process and to retrieve the current object. When setting the request object, you may pass in a request class name, in which case the method will load the class file and instantiate it.
From API:
Zend_Controller_Front setRequest (string|Zend_Controller_Request_Abstract $request)
The class can also likely (not sure) be set from a config by passing the correct values to Zend_Application_Resource_Frontcontroller
Subclassing the Request object is explained in
http://framework.zend.com/manual/en/zend.controller.request.html