Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Routing Problem
  • Hi, I'm trying to set up a restful api that can be versioned and I'm running into some trouble with routes.  For example:
    return array(
        ':apivers/accesspoint(/:id)' => 'accesspoint',
    );

    should match all of the following and tell me what api version I should be using:

    But it only successfully matches the first.  I've been playing with the matching pattern and the best I've been able to get is this:

    <?php

    $search = '#^(?P<apivers>.+?)/accesspoint(?:|/(?P<id>.+?))$#uD';

    $match = preg_match($search, '2/accesspoint/1234', $matches);
    echo '<pre>'.print_r($matches, true).'</pre>';

    $match = preg_match($search, '2/accesspoint/', $matches);
    echo '<pre>'.print_r($matches, true).'</pre>';

    $match = preg_match($search, '2/accesspoint', $matches);
    echo '<pre>'.print_r($matches, true).'</pre>';

    $match = preg_match($search, '2/accesspoint/1234/abcd', $matches);
    echo '<pre>'.print_r($matches, true).'</pre>';
    ?>
    outputs:
    Array
    (
    [0] => 2/accesspoint/1234
    [apivers] => 2
    [1] => 2
    [id] => 1234
    [2] => 1234
    )
    Array
    (
    )
    Array
    (
    [0] => 2/accesspoint
    [apivers] => 2
    [1] => 2
    )
    Array
    (
    [0] => 2/accesspoint/1234/abcd
    [apivers] => 2
    [1] => 2
    [id] => 1234/abcd
    [2] => 1234/abcd
    )

    Obviously I don't want to hack the core, and if there is a better way to achieve these results with the existing routing I'd rather do that, but it does seem like a fairly standard way to implement versioning for a rest api.  Thanks in advance :-)
  • HarroHarro
    Accepted Answer
    The second one will never work, because trailing slashes are not accepted in a URI segment based framework. So it will be equal to the third one.

    The third one doesn't match because route variables are not optional, so it expects :id there. The brackets around it are not needed, :id itself will be replaced by a regex is brackets to get the variable out...
  • Harro, thanks for responding... I didn't realize that route variables were not optional...  Prior to adding the version, is was optional and it was working as I would have expected.  Just occurred to me after reading your post that I could solve this with multiple routes to the same controller:
        ':apivers/accesspoint' => 'accesspoint',
        ':apivers/accesspoint/:id' => 'accesspoint',

    It's now working just like I want :-)
  • HarroHarro
    Accepted Answer
    Alternatively

    ':apivers/accesspoint(.*)' => 'accesspoint',

    works too, but then you don't have the named variable, you'll have to use the method arguments (and make those optional in case nothing was passed).
  • Excellent, Thanks again Harro!

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion