We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

How to get $_GET from URI?

This is the URI: /search/index?keyword=value

Using nginx as my server.

Phalcon version: 2.0.9

This is my router for that URI:


$di->set('router', function () {
    $router = new Router();

    $router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI);
    $router->setDefaultModule('front');
    $router->removeExtraSlashes(true);

    // START FRONT SEARCH ROUTE
    $router->add(
        '/search/index',
        [
            'controller' => 'search',
            'action' => 'index',
        ]
    );

    return $router;
);

And my SearchController.php:


class SearchController extends ControllerBase
{
    public function indexAction()
    {
        $this->view->disable();

        var_dump($this->dispatcher->getParam('keyword'));   # shows NULL

        var_dump($this->dispatcher->getParams());   # shows empty Array

        var_dump($this->request->getQuery('keyword'));   # shows NULL

        var_dump($this->request->getQuery());   #shows empty Array

        var_dump($this->request->get());   # shows empty Array

        var_dump($_SERVER['REQUEST_URI']);   # shows: /search/index?keyword=value

        var_dump($this->router->getRewriteUri());   # shows: /search/index

        var_dump($_GET);   # shows empty Array

    }
}

So, anyone knows how to get that $_GET['keyword']? Seems I am out of the ideas.

You need to tell phalcon to use REQUEST_URI. In router definition add this: $router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI);



12.2k

@Wojciech

If you look at my initial post, you'll see that I am doing exactly that, therefore I don't know what I can do more...

This is the excerpt from the nginx .conf file

    try_files $uri $uri/ /index.php;

    location ~ \.php {
        try_files    $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index  /index.php;
        fastcgi_pass   127.0.0.1:9000;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }


145.0k
Accepted
answer
edited May '16

Oh right i missed it ! My config looks like this :

    root /var/customers/webs/webtest3/samochody.sidormedia.pl/public;
    index index.php index.html index.htm;

    try_files $uri $uri/ @rewrites;

    location @rewrites {
        try_files $uri $uri/ /index.php?_url=$uri&$args;
    }

    location ~ ^(.+?\.php)(/.*)?$ {
        try_files $1 = 404;

        include /etc/nginx/fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)\$;
        fastcgi_param SCRIPT_FILENAME $document_root$1;
        fastcgi_param PATH_INFO $2;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
    }


12.2k
edited May '16

Thank you @Wojciech, this works. Seems my nginx config was missing some stuff you pointed out :)

added $args to index.php


try_files $uri $uri/ /index.php?$args;

You don't really need $args if you set router component correctly.

try_files $uri $uri/ /index.php is enough.

Also, instead of:

    $router = new Router();
    $router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI);

Change to:

    $router = new Router();
    $router->setUriSource($router::URI_SOURCE_SERVER_REQUEST_URI);
edited May '16

location @rewrites { try_files $uri $uri/ /index.php?_url=$uri&$args; }

You can safely remove _url part if you're using $router->setUriSource($router::URI_SOURCE_SERVER_REQUEST_URI); as a source in a Router component.



12.2k

@stamster

I changed "Router" to "$router" as per your advice which is spot on.

When I remove ?$args in nginx, args are not passed to my script any more. When you said "set router component correctly" - what I need to change exactly (taking into account my first post)?

If you just set your router component to use:

    $router->setUriSource($router::URI_SOURCE_SERVER_REQUEST_URI);

It should work with nginx passing every request to your public index.php (Front Page Controller pattern).



12.2k

Yes, it should, but unfortunately it doesn't work as it is visible from my first post. And my router setup is plain vanilla, nothing fancy.

$_SERVER['REQUEST_URI'] has the data (as a complete URI string), but that data is not extracted to any variable as far as I can see.

edited May '16

Sorry, I'm using RESTful interfaces so parameters are passed as a part of URI directly through Router component.

 $auth->post('/login/{digest}', 'validateHmac');

So URL would end up being i.e. https://myapi.com/login/0xff

function validateHmac($digest = null){
// We can access $digest here as it is passed by router component as a part of URI
}

The thing is, if you need to access superglobals in Front Page controller designed app, you need to tell FPC which parameters are passed by the client.

Nginx does fill out [QUERY_STRING] by default:

fastcgi_param QUERY_STRING $query_string;

BUT, the problem is with Front Page Controller which does not seem to know how to handle it from index.php throughout application. That's why it works only on index.php via $_GET / _REQUEST / _POST, or $request->getQuery() etc. methods.

This should be easy to achieve on internals of the Phalcon so we can pull request on github.

Currently, this is correct set up of nginx in this scenario:

try_files $uri $uri/ /index.php?$query_string;

UPDATE

I managed to override Router component and to inject QUERY_STRING from $_SERVER superglobal. It's dirty and hack. But at least then everyting works w/o need to pass arguments directly to Front Page controller.

I would strongly recommend the following approach as a production ready solution alongside URI_SOURCE_SERVER_REQUEST_URI as source for router:

location / {
try_files $uri $uri/ /index.php$is_args$query_string;
}