vendor/api-platform/core/src/Util/RequestParser.php line 39

  1. <?php
  2. /*
  3.  * This file is part of the API Platform project.
  4.  *
  5.  * (c) Kévin Dunglas <dunglas@gmail.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace ApiPlatform\Util;
  12. use Symfony\Component\HttpFoundation\Request;
  13. /**
  14.  * Utility functions for working with Symfony's HttpFoundation request.
  15.  *
  16.  * @internal
  17.  *
  18.  * @author Teoh Han Hui <teohhanhui@gmail.com>
  19.  * @author Vincent Chalamon <vincentchalamon@gmail.com>
  20.  */
  21. final class RequestParser
  22. {
  23.     private function __construct()
  24.     {
  25.     }
  26.     /**
  27.      * Parses request parameters from the specified source.
  28.      *
  29.      * @author Rok Kralj
  30.      *
  31.      * @see https://stackoverflow.com/a/18209799/1529493
  32.      */
  33.     public static function parseRequestParams(string $source): array
  34.     {
  35.         // '[' is urlencoded ('%5B') in the input, but we must urldecode it in order
  36.         // to find it when replacing names with the regexp below.
  37.         $source str_replace('%5B''['$source);
  38.         $source preg_replace_callback(
  39.             '/(^|(?<=&))[^=[&]+/',
  40.             static fn ($key): string => bin2hex(urldecode($key[0])),
  41.             $source
  42.         );
  43.         // parse_str urldecodes both keys and values in resulting array.
  44.         parse_str($source$params);
  45.         return array_combine(array_map('hex2bin'array_keys($params)), $params);
  46.     }
  47.     /**
  48.      * Generates the normalized query string for the Request.
  49.      *
  50.      * It builds a normalized query string, where keys/value pairs are alphabetized
  51.      * and have consistent escaping.
  52.      */
  53.     public static function getQueryString(Request $request): ?string
  54.     {
  55.         $qs $request->server->get('QUERY_STRING''');
  56.         if ('' === $qs) {
  57.             return null;
  58.         }
  59.         $parts = [];
  60.         foreach (explode('&', (string) $qs) as $param) {
  61.             if ('' === $param || '=' === $param[0]) {
  62.                 // Ignore useless delimiters, e.g. "x=y&".
  63.                 // Also ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
  64.                 // PHP also does not include them when building _GET.
  65.                 continue;
  66.             }
  67.             $keyValuePair explode('='$param2);
  68.             // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
  69.             // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str. This is why we use urldecode and then normalize to
  70.             // RFC 3986 with rawurlencode.
  71.             $parts[] = isset($keyValuePair[1]) ?
  72.                 rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
  73.                 rawurlencode(urldecode($keyValuePair[0]));
  74.         }
  75.         return implode('&'$parts);
  76.     }
  77. }