Query Params Slim x Angular 4

Angular 4 per pattern transforms an array object with multiple values as follows status=approved&status=handling has some way to retrieve this array in the slim

/api/order?start=2018-04-08&end=2018-05-08&status=approved&status=handling&limit=10&offset=0

Hi @elvisreis

By default this is not possible with PHP or Slim. BUT you could use this function to parse the Query string like you expected:

Code

function proper_parse_str($str)
{
    // result array
    $arr = [];

    // split on outer delimiter
    $pairs = explode('&', $str);

    // loop through each pair
    foreach ($pairs as $i) {
        // split into name and value
        list($name, $value) = explode('=', $i, 2);

        // if name already exists
        if (isset($arr[$name])) {
            # stick multiple values into an array
            if (is_array($arr[$name])) {
                $arr[$name][] = $value;
            } else {
                $arr[$name] = [$arr[$name], $value];
            }
        } else {
            // otherwise, simply stick it in a scalar
            $arr[$name] = $value;
        }
    }

    // return result array
    return $arr;
}

Source

Usage

$queryString = $request->getServerParam('QUERY_STRING');
$params = proper_parse_str($queryString);

Putting this into a middleware would also be possible.

Result

image

This and exactly what I need I just did not understand how to return to the slim the modified query string

<?php
/**
 * Created by PhpStorm.
 * User: elvis
 * Date: 09/05/2018
 * Time: 07:06
 */

namespace App\Middleware;


use Slim\Http\Request;
use Slim\Http\Response;

class QueryStringMiddleware
{
    /**
     * Example middleware invokable class
     *
     * @param  \Slim\Http\Request $request PSR7 request
     * @param  \Slim\Http\Response $response PSR7 response
     * @param  callable $next Next middleware
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function __invoke(Request $request, Response $response, $next)
    {
        $queryString = $request->getServerParam('QUERY_STRING');
        $queryString = $this->proper_parse_str($queryString);
        $_SERVER['QUERY_STRING'] = http_build_query($queryString);
        $response = $next($request, $response);
        return $response;
    }

    private function proper_parse_str($str): array
    {
        // result array
        $arr = [];

        // split on outer delimiter
        $pairs = explode('&', $str);

        // loop through each pair
        foreach ($pairs as $i) {
            // split into name and value
            list($name, $value) = explode('=', $i, 2);

            // if name already exists
            if (isset($arr[$name])) {
                # stick multiple values into an array
                if (is_array($arr[$name])) {
                    $arr[$name][] = $value;
                } else {
                    $arr[$name] = [$arr[$name], $value];
                }
            } else {
                // otherwise, simply stick it in a scalar
                $arr[$name] = $value;
            }
        }

        return $arr;
    }
}

Ok then try this:

  1. Rename the class method proper_parse_str to parseQueryString
  2. Change the middleware __invoke method as follows:
public function __invoke(Request $request, Response $response, $next)
{
    $queryString = $request->getServerParam('QUERY_STRING');
    $queryParams = $this->parseQueryString($queryString);
    $request = $request->withQueryParams($queryParams);
    
    return $next($request, $response);
}

Then read the query parameters in your controller / action as follows:

$status = $request->getQueryParam('status');