Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.
   1  <?php
   2  
   3  declare(strict_types=1);
   4  
   5  namespace GuzzleHttp\Psr7;
   6  
   7  final class Query
   8  {
   9      /**
  10       * Parse a query string into an associative array.
  11       *
  12       * If multiple values are found for the same key, the value of that key
  13       * value pair will become an array. This function does not parse nested
  14       * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
  15       * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
  16       *
  17       * @param string   $str         Query string to parse
  18       * @param int|bool $urlEncoding How the query string is encoded
  19       */
  20      public static function parse(string $str, $urlEncoding = true): array
  21      {
  22          $result = [];
  23  
  24          if ($str === '') {
  25              return $result;
  26          }
  27  
  28          if ($urlEncoding === true) {
  29              $decoder = function ($value) {
  30                  return rawurldecode(str_replace('+', ' ', (string) $value));
  31              };
  32          } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
  33              $decoder = 'rawurldecode';
  34          } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
  35              $decoder = 'urldecode';
  36          } else {
  37              $decoder = function ($str) {
  38                  return $str;
  39              };
  40          }
  41  
  42          foreach (explode('&', $str) as $kvp) {
  43              $parts = explode('=', $kvp, 2);
  44              $key = $decoder($parts[0]);
  45              $value = isset($parts[1]) ? $decoder($parts[1]) : null;
  46              if (!array_key_exists($key, $result)) {
  47                  $result[$key] = $value;
  48              } else {
  49                  if (!is_array($result[$key])) {
  50                      $result[$key] = [$result[$key]];
  51                  }
  52                  $result[$key][] = $value;
  53              }
  54          }
  55  
  56          return $result;
  57      }
  58  
  59      /**
  60       * Build a query string from an array of key value pairs.
  61       *
  62       * This function can use the return value of `parse()` to build a query
  63       * string. This function does not modify the provided keys when an array is
  64       * encountered (like `http_build_query()` would).
  65       *
  66       * @param array     $params   Query string parameters.
  67       * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
  68       *                            to encode using RFC3986, or PHP_QUERY_RFC1738
  69       *                            to encode using RFC1738.
  70       */
  71      public static function build(array $params, $encoding = PHP_QUERY_RFC3986): string
  72      {
  73          if (!$params) {
  74              return '';
  75          }
  76  
  77          if ($encoding === false) {
  78              $encoder = function (string $str): string {
  79                  return $str;
  80              };
  81          } elseif ($encoding === PHP_QUERY_RFC3986) {
  82              $encoder = 'rawurlencode';
  83          } elseif ($encoding === PHP_QUERY_RFC1738) {
  84              $encoder = 'urlencode';
  85          } else {
  86              throw new \InvalidArgumentException('Invalid type');
  87          }
  88  
  89          $qs = '';
  90          foreach ($params as $k => $v) {
  91              $k = $encoder((string) $k);
  92              if (!is_array($v)) {
  93                  $qs .= $k;
  94                  $v = is_bool($v) ? (int) $v : $v;
  95                  if ($v !== null) {
  96                      $qs .= '=' . $encoder((string) $v);
  97                  }
  98                  $qs .= '&';
  99              } else {
 100                  foreach ($v as $vv) {
 101                      $qs .= $k;
 102                      $vv = is_bool($vv) ? (int) $vv : $vv;
 103                      if ($vv !== null) {
 104                          $qs .= '=' . $encoder((string) $vv);
 105                      }
 106                      $qs .= '&';
 107                  }
 108              }
 109          }
 110  
 111          return $qs ? (string) substr($qs, 0, -1) : '';
 112      }
 113  }