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

Route params deep parse

I'm trying to replace my own routing module (pure php) with Phalcon. Example: "/catalog/catalog_name/param1-val1_val2_val3/param2-val4"

Here's how I got:

//Main route
$route = $router->add("/catalog/([a-zA-Z0-9\_\-]+)/([^\?]+)", [
    "controller" => "catalog",
    "action" => "show",
    "name" => 1,
    "params" => 2,
]);
$route->convert(
    'params',
    function ($string) {
        return var_export(explode('-', $string),true);
    });

As far as I understand $route->convert() handler allow you to pass string and must return string. Is it?

So to get what i need i should redefine native convert function?

No, it can return theortically everything, just make sure that number of parameters in action and types will match.



412
Accepted
answer
edited Sep '18

I think i found an answer. The problem is that $route->convert()handler works before splitting by /. this is a source code snippet https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/router.zep

            /**
             * Check for parameters
             */
            if fetch paramsStr, parts["params"] {
                if typeof paramsStr == "string" {
                    let strParams = trim(paramsStr, "/");
                    if strParams !== "" {
                        let params = explode("/", strParams);
                    }
                }

                unset parts["params"];
            }

            if count(params) {
                let this->_params = array_merge(params, parts);
            } else {
                let this->_params = parts;
            }

So if $route->convert() handler returned an array $router->handle() just unset it.

edited Sep '18

Just use other route pattern then to have catalog_name in other paraemter and the rest of params in other.

Also you know there is thing called query parameters? You should really use those. Like doing:

/catalog/catalog_name?param1[]=val1&param1[]=val2&param1[]=val3

Will cause that in $_GET['param1'] you will already have array, and in phalcon just access it like $this->request->getQuery('param1')

Better already use what's possible and built-in then doing some weird and fancy stuff.



412

No it is not an option. I need the same functionality as i got now. I need friendly URLs.

Just use other route pattern then to have catalog_name in other paraemter and the rest of params in other.

Also you know there is thing called query parameters? You should really use those. Like doing:

/catalog/catalog_name?param1[]=val1&param1[]=val2&param1[]=val3

Will cause that in $_GET['param1'] you will already have array, and in phalcon just access it like $this->request->getQuery('param1')

Better already use what's possible and built-in then doing some weird and fancy stuff.



412
edited Sep '18

I'll try to parse params on the controller level. $route->convert() is useless.

Then use other route pattern to have catalog_name as separeted argument and the rest of the pattern as other argument.



412

Thank you for your help. I'm too slow, sorry.

This as an answer:

//Main route
$route = $router->add("/catalog/([a-zA-Z0-9\_\-]+)/([^\?]+)", [
    "controller" => "catalog",
    "action" => "show",
    "name" => 1,
    "params_" => 2,
]);

$route->convert(
    'params_',
    function ($string) {
        $array = explode('/', $string);
        array_walk($array, function(&$string){
            $string = explode('-', $string);
        });
        return $array;

    });

Then use other route pattern to have catalog_name as separeted argument and the rest of the pattern as other argument.