In other MVC frameworks, accessing to the current request object is as simple as $this->request. However in the Laravel, I generally see that Request $request is generally injected to each action (public function edit($id, Request $request)). It seems like a boilerplate. Is there any better way to access the request? (I now that I can use inheritance to use $this->request, I am looking for the Laravel way to do that.)
update:
I found out using app('request') I can access to the current request. However, I am not sure of its potential pros and cons.
In Laravel 5, you can use the request() helper:
// to get the current request object
$request = request();
// or to just get a value from the request
$value = request("field", "default");
See https://laravel.com/docs/5.6/helpers#method-request
Related
I'm learning ZF3 from this book, and I came across this:
In my controller, I can get the $_GET['var_name'] in ZF3 like this:
$request = $this->getRequest();
$request->getQuery('var_name');
Or this way:
$this->params()->fromQuery('var_name');
What's the difference between the two? (Rephrasing the question: why there are 2 ways to do the same thing?). Is one preferred over another in specific scenario?
The data is part of the request, so that's why it's held in the request object. The params controller plugin (your second example) provides a more concise way to access this data, so that's what you should use to access the data from a controller.
$this->params()->fromQuery('var_name');
here $this->params() is controller plugin, you can only use it from controller.
but for
$request = $this->getRequest();
$request->getQuery('var_name');
You can access requests from any class, as below-
$request = new Request();
I have a controller which is getting an instance of Illuminate\Http\Request injected through the constructor. Now I need to write an unit test that test a call in the controller which uses the values from the Request instance. I have decided to use Faker. How to use Faker to generate an associative array so that I can use the array in my test case like,
$this->post('the_uri','MyFakerArray')
And the dynamic array will automatically be available in my controllers request.
There is no need to fake/mock the Request object.
When you are simulating a request laravel does that for you, it create a request to the url you request and pass the variables, then you get back the response from your application.
For example:
$response = $this->call('POST', '/user', ['name' => 'Taylor']);
now the $response variable has the data to test on.
I think you have:
getContent() // for getting the reponse body
getCode() // for http code: 200, 401 etc
When you do that, your tests should work with the response, you have no need for Faker in this situation.
I need to call in checkout/confirm.tpl file a custom function that i've made in controller/product.php
what's the best way to make this?
i've tried this, but doesn't work:
$productController = $this->load->model('product/product');
$productController->customFunction();
yes i find the right answer finally!!! sorry for last bad answer
class ControllerCommonHome extends Controller {
public function index() {
return $this->load->controller('product/ready');
}
}
MVC
in an MVC architecture, a template serves solely for rendering/displaying data; it shouldn't (*) call controller/model functions nor it shouldn't execute SQL queries as I have seen in many third-party modules (and even in answers here at SO).
$productController = $this->load->model('product/product');
nifty eye has to discover that you are trying to load a model into a variable named by controller and you are also trying to use it in such way. Well, for your purpose there would have to be a method controller() in class Loader - which is not (luckily)
How it should be done?
sure there is a way how to access or call controller functions from within templates. In MVC a callable function that is invoked by routing is called action. Using this sentence I can now say that you can invoke an action (controller function) by accessing certain URL.
So let's say your controller is CatalogProductController and the method you want to invoke is custom() - in this case accessing this URL
http://yourstore.com/index.php?route=catalog/product/custom
you will make sure that the custom() method of CatalogProductController is invoked/accessed.
You can access such URL in many ways - as a cURL request, as a link's href or via AJAX request, to name some. In a PHP scope even file_get_contents() or similar approach will work.
(*) By shouldn't I mean that it is (unfortunately) possible in OpenCart but such abuse is against MVC architecture.
$this->load->controller('sale/box',$yourData);
To call ShipmentDate() function of box Controller
$this->load->controller('sale/box/ShipmentDate',$yourData);
May be something like this could help you (or anyone who's interested)
// Load seo pro
require_once(DIR_CATALOG."/controller/common/seo_pro.php"); // load file
$seoPro = new ControllerCommonSeoPro($this->registry); // pass registry to constructor
$url = HTTP_CATALOG . $seoPro->rewrite(
$this->url('information/information&information_id=' . $result['information_id'])
);
return $this->load->controller('error/not_found');
in laravel its so simple just write Controller::call('ApplesController#getSomething');
but there i cant made better than this
$config = new Config();
// Response
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$response->setCompression($config->get('config_compression'));
$this->registry->set('response', $response);
$action = new Action('product/ready');
$controller = new Front($this->registry);
$controller->addPreAction(new Action('common/maintenance'));
$controller->addPreAction(new Action('common/seo_url'));
$controller->dispatch($action, new Action('error/not_found'));
$response->output();
in this case its well call product/ready
I am using Zend framework and it does URL rewriting
but I want to handle in controller just regular querysting, get request
seomthing like this transactionsExternal.phppage=1&start=0&limit=100&sort=threadid&dir=ASC&callback=Ext.data.JsonP.callback1
Can somebody tell me how to get this GET request variables in controller? considering that Zend prevents me just to use variables like $_GET[something]
$this->getRequest()->getParams(); also is not returning anything
ZF does not prevent you using $_GET, although doing so is discouraged. $this->getRequest()->getParam('start'), or $this->getRequest()->getParams() will give you the GET params. So if this isn't working for you something else is going wrong somewhere.
Is 'transactionsExternal.php' definitely part of your ZF app?
How are your controllers and actions set up?
Zend Framework 1 works with key/pair values for get parameters. So you might have a transaction controller and a get action. A request would look like so:
domain.com/transactions/get
To append and ID GET parameter you would do:
domain.com/transactions/get/id/10
Then In your controller action you would do the following to get the id value:
$request = $this->getRequest();
$request->getParam('id');
Zend Framework 1 had a very simple way of parsing URL routes and setting found params in the $_GET superglobal for easy access. Sure, you could use ->getParam($something) inside the controller, but if the param was found in the URL, it was also accessible via $_GET.
Example for url mypage.com/mymodule/mycontroller/myaction/someparam/5:
ZF1
$this->getParam('someparam'); // 5
$_GET['someparam']; // 5
ZF2
$this->getEvent()->getRouteMatch()->getParam('someparam'); // 5
$_GET['someparam'] // undefined index someparam
Obviously, the difference is that ZF2 does NOT put the route params into the $_GET superglobal.
How do I make it put the parsed parameters into the $_GET superglobal, since extending the controller and just defining a constructor that does that is out of the question (because RouteMatch is not an object yet and cannot be called from the controller's constructor)?
Calling $_GET = $this->getEvent()->getRouteMatch()->getParam('someparam'); in every one of my controllers would work, but I don't want that.
In other words, following the example URL from above, I want to be able to do $_GET['someparam'] and still get the value "5" in any component in the application.
Edit: Looks like I wasn't clear enough, so I'll try to clarify some more. I want whatever param I enter in the URL via /key/value formation to be available in $_GET instantly. I don't really have a problem with getting the param, I know how to get it and I extended Zend's controller so I can just call $this->getParams again like in ZF1, and now all controllers extend that one, I just want the params from the URL to automatically be in $_GET as well, so I can access them easily in third party components which use $_GET natively.
Edit 2: Updated as reaction to Samuel Herzog's answer:
I don't really mind invalidating the SRP in this case, because the libraries are built in such a way that they need direct access to $_GET - they do their own filtering and directly depend on this superglobal. They also directly fetch $_FILES and $_POST for processing, it's just the way their code works.
I've made the following method in the abstract controller:
$this->mergeGet(); which basically makes $_GET absorb all the route matched params and everything works as intended, but seeing as the libraries will be required in every controller/action, it might get tedious to call that method every time. If only the controller had an init() method like in ZF1...
In ZF2, Im using this
$getparams = $this->getRequest()->getQuery();
First of all, you shouldn't use $_GET or any other superglobal directly if you're building on an object oriented stack. The SRP is invalidated this way.
If you have no possibility to change the way of your (3rd party?) librarys to change you might want to hook into the MvcEvent, listen to --event-- and then get the RouteMatch, you may fill $_GET with a simple loop.
For a most-performant answer, you should know if the named library will be needed for every action, just for one module, or only in certain controllers/actions.
If the latest is your use-case, you should write a controller plugin instead.
some example code for the first approach:
namespace YourModule;
use Zend\EventManager\EventInterface as Event;
use Zend\Mvc\MvcEvent;
class Module
{
...
public function onBootstrap(Event $ev)
{
$application = $e->getApplication();
$eventManager = $application->getEventManager();
$eventManager->attach('route', function(MvcEvent $mvcEvent) {
$params = $mvcEvent->getRouteMatch()->getParams();
foreach ( $params as $name => $value )
{
if ( ! isset($_GET[$name])
{
$_GET[$name] = $value;
}
}
});
}
}
You could use in your controlller:
$paramValue = $this->params()->fromQuery('your_param_here');
Regards