[CakePHP]$this->request->query() is URL decoded properly
Aug 28, 2020
PHP
CakePHP
url encoding
get parameter
url decoding
Validated environment
・CakePHP2 ・CakePHP3.8
Why I wrote this article
As the title says.
I think it’s common to pass a GET parameter and get it in the controller with $this->request->query()
.
At that time, a URL encoded value may be passed to the GET parameter.
And when I get that GET parameter with $this->request->query()
in the controller, it becomes a URL-decoded value before I knew it.
// When you want to pass multiple user IDs separated by commas
// URL encode 1234,5678,9012 and pass it as a GET parameter.
https://sample.com/users/index?user_id=1234%2C5678%2C9012
// get user_id in controller
$user_id = $this->request->query('user_id');
// The content of the acquired user_id is "1234,5678,9012".
(URL decoded)
It may be common sense, but if you think “it can be acquired like this and it is such a specification”, “It’s better to check the official documentation or the source code. It’s something like this, so don’t do it with ~” I was pointed out, so I decided to confirm.
Check official documentation
Cookbook https://book.cakephp.org/3/ja/controllers/request-response.html#cake-request
In the “Query string parameters” section here, URL encoding/decoding is not particularly written.
Check source code
Look at the CakePHP source code and check if there is any URL decoding process. Here, it explains with the source code of CakePHP3 series.
According to the above document, request data is defined in Cake\Http\ServerRequest
.
public function __construct($config = [])
{
if (is_string($config)) {
$config = ['url' => $config];
}
// omitted
$this->_setConfig($config);
}
First, receive the request data with __construct
and pass it to the _setConfig
function.
protected function _setConfig($config)
{
// omitted
$querystr = ``;
if (strpos($config['url'],'?') !== false) {
list($config['url'], $querystr) = explode('?', $config['url']);
}
// Here, put the URL separated by "?" in the array
// Right side of "?" of url, that is, GET parameter is assigned to variable $querystr
// omitted
$this->data = $this->_processFiles($config['post'], $config['files']);
$this->query = $this->_processGet($config['query'], $querystr);
// Here, the value that can be used in $this->request->query() is entered
$this->params = $config['params'];
$this->session = $config['session'];
}
In the _setConfig
function, we put the GET parameter in the variable $querystr
and pass it to the _processGet
function.
I put the value returned by the _processGet
function in $this->query
.
protected function _processGet($query, $queryString = ``)
{
$unsetUrl ='/' .str_replace(['.',''],'_', urldecode($this->url));
unset($query[$unsetUrl], $query[$this->base .$unsetUrl]);
if (strlen($queryString)) {
parse_str($queryString, $queryArgs);
// The URL-encoded value is URL-decoded and put into a variable by the parse_str function
$query += $queryArgs;
}
return $query;
}
The variable $queryString
containing the GET parameter received as the second argument is processed by the parse_str
function and put in the variable $queryArgs
.
With the parse_str
function, the variable $queryArgs
will contain the URL-decoded value.
And it means returning it.
parse_str function https://www.php.net/manual/ja/function.parse-str
Note:
The values of all created variables (values that will be set in the array if the second argument is set) have already been urldecode()'ed.
So, as I said at the beginning, if you pass the URL encoded value with the GET parameter and get the GET parameter using $this->request->query()
in the CakePHP controller, the URL is already It was confirmed that the process is to get the decoded value.
As you can see by outputting the value actually obtained, it is not “because it will be so”, but “is it really that kind of specification? It’s not in the official document, but really?” By confirming, I was able to know with a basis.