I see that everywhere where the request is involved in Magento 2, the request is an implementation of \Magento\Framework\App\RequestInterface
.
This interface does not contain the methods getPost
(used in \Magento\Catalog\Controller\Adminhtml\Category\Widget\CategoriesJson
) and getPostValue
(used in \Magento\Catalog\Controller\Adminhtml\Product\Save
) but they are still called.
Is it OK to assume that these methods are always going to be there for http requests?
or should I use something else in my modules to get the $_POST
data?
-
1I feel that half a year later, with Magento 2.1, this situation still hasn't improved at all :-( – peedee Aug 25 '16 at 11:31
Is it OK to assume that these methods are always going to be there for http requests?
Don't think so. They're breaking their own class contract. As you can imagine, that's not OOP-ish at all.
As per the usual recommendation, I would stay away from using anything that's not declared in Magento\Framework\App\RequestInterface
because a) you'll make Liskov happy and because b) they'll soon realise the problem and fix it (hopefully), thus breaking your code (or not; but if they do, they're justified: you were not using the API contract, right?).
If they won't fix it, they'll have a very capable API implementation (i.e. Magento\Framework\App\Request\Http
) which nobody will really use.
Always stay within the contract!
-
This looks like a good approach in an ideal world. Unfortunately I found no other way to get the post data with methods only from the
RequestInterface
. But what you are saying sounds resonable. I will avoid as much as possible these methods. – Marius♦ Nov 10 '15 at 15:27 -
It looks like they're aware. Only recently: github.com/magento/magento2/issues/1675 – nevvermind Nov 11 '15 at 10:14
-
An easy way to check whether or not those are available to you would be to do an
if($this->getRequest() instanceof \Magento\Framework\App\Request\Http) {
- if that check passes, you can use those parameters! – Navarr Dec 20 '16 at 20:02
getPostValue()
is written in
lib\internal\Magento\Framework\HTTP\PhpEnvironment\Request.php
/**
* Retrieve POST parameters
*
* @param string $name
* @param mixed $default
* @return mixed|ParametersInterface
*/
public function getPostValue($name = null, $default = null)
{
$post = $this->getPost($name, $default);
if ($post instanceof ParametersInterface) {
return $post->toArray();
}
return $post;
}
then It get the getPost
value from
vendor\zendframework\zend-http\src\Request.php
public function getPost($name = null, $default = null)
{
if ($this->postParams === null) {
$this->postParams = new Parameters();
}
if ($name === null) {
return $this->postParams;
}
return $this->postParams->get($name, $default);
}
Hope you will get atleast some hint.
And yes you can use
$post = $this->getRequest()->getPostValue();
To get post
value,,you can also check Contact
module to get some hint
-
1Thanks for the "code hunt". But that was not my question. I already found the definition. That's why I asked "are always going to be there for http requests?". My question is "Is it safe to use these methods even if they are not in the RequestInterface?" and this is used everywhere. – Marius♦ Nov 9 '15 at 8:02
To get Post data in controller you need to use following in your execute function.
public function execute(){
$post = $this->getRequest()->getPostValue();
echo "<pre>";
print_r($post);
exit; }
In Magento 2.1, if we get the request object by calling $this->getRequest()
, it will return Magento\Framework\App\Request
which is extend Magento\Framework\HTTP\PhpEnvironment\Request
. this is why the method getPostValue can be called.
I got the problem when I try to create a unit test for my controller which call the getPostValue. As the getPostValue is not defined in the RequestInterface, Instead of creating a mock object for RequestInterface directly, we create the mock object for Magento\Framework\App\Request\Http
.
Is it OK to assume that these methods are always going to be there for http requests?
No.
The method will be changed in the future version if it is not in the interface. We should use the methods in the interface as much as possible. Because of API contract, existing methods in API will not be changed except in major version upgrades.
Should I use something else in my modules to get the $_POST data?
Yes.
In the interface Magento\Framework\App\RequestInterface
, the method getParams()
could get the post data array, the method getParam($key, $defaultValue = null)
could get the specific data in post.