$request->getQueryParams() always returns etmpty even with variables set

I have a site that I am building using Slim Framework. I have a login and registration system that uses POST variables and those routes are working fine. However, on my admin the $_GET variables just do not want to seem to register. Can anyone help me figure out what I am doing wrong? I’m using Controllers for my routes set up as:

src/Controller/Controller.php

<?php

namespace App\Controller;
use Awurth\Slim\Validation\Validator;
use Cartalyst\Sentinel\Sentinel;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Interop\Container\ContainerInterface;
use Slim\Exception\NotFoundException;
use Slim\Flash\Messages;
use Slim\Router;
use Slim\Views\Twig;

class Controller
{
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function redirect(Response $response, $route, array $params = array())
    {
        return $response->withRedirect($this->router->pathFor($route, $params));
    }

    public function redirectTo(Response $response, $url)
    {
        return $response->withRedirect($url);
    }

    public function json(Response $response, $data, $status = 200)
    {
        return $response->withJson($data, $status);
    }

    public function write(Response $response, $data, $status = 200)
    {
        return $response->withStatus($status)->getBody()->write($data);
    }

    public function flash($name, $message)
    {
        $this->flash->addMessage($name, $message);
    }

    public function notFoundException(Request $request, Response $response)
    {
        return new NotFoundException($request, $response);
    }

    public function __get($property)
    {
        return $this->container->get($property);
    }
}

src/Controller/AdminController.php

<?php  

namespace App\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

class AdminController extends Controller{

    public function dashboard(Request $request, Response $response){

        return $this->view->render($response, 'Admin/dashboard.twig');

    }

    public function users(Request $request, Response $response){

        $users = new \App\Model\Users;

        return $this->view->render($response, 'Admin/users.twig', ["users" => $users->get()]);

    }

    public function usersEdit(Request $request, Response $response, $args){

        print_r($request->getQueryParams());
    }

}

routes/admin.php

<?php
$app->group('/dashboard', function () {
    // Dashboard Home
    $this->get('', 'AdminController:dashboard')
    	->setName('dashboard');


    // Admin Users
    $this->get('/users', 'AdminController:users')
        ->setName('admin-users');

    $this->get('/users/edit/{username}', 'AdminController:usersEdit')
        ->setName('admin-users-edit');
});

I just noticed that if I output $args inside usersEdit as echo args; the result is the {username} $_GET variable. However, $request->getQueryParams(); remains empty.

For the URL http://example.com/users/edit/akrabat?foo=bar the username (“akrabat”) isn’t a query parameter, it’s a route parameter. The query parameter is “foo” which has a value of “bar”.

You access route parameters from $args or from the request’s attributes. That is:

$username = $args['username'] ?? '';

or

$username = $request->getAttribute('username');

Thank you for your quick reply. That makes much more sense! I do have one more question then. When I try to run echo $args['username']; I get the following error and then it spits out the first letter of the username:

Warning: Illegal string offset ‘username’ in …\src\Controller\AdminController.php on line 28

a

However, if I run echo $args it will spit out the username. Also, if I add a second route parameter only the first route parameter is accessible through $args.

I’m not seeing that with this minimal app:

<?php

require __DIR__ . '/../vendor/autoload.php';

$config = [
    'settings' => [
        'displayErrorDetails' => true, // set to false in production
        'addContentLengthHeader' => false, // Allow the web server to send the content-length header
 
    ],
];
$app = new \Slim\App($config);

$app->get("/user/edit/{username}", function ($request, $response, $args) {

    echo $args['username'];
    exit;
});

// Run!
$app->run();

Not sure how to help, now. Can you check if this minimal example works for you with your set up?

That bit of code worked fine on my set up. I have traced the problem to have something to do with the boilerplate template that I started with.

awurth/quickslim

I have submitted an issue to see if he has any suggestions for the problem here:

https://github.com/awurth/quickslim/issues/1