Jump to content

router cache - preg_grep()


Recommended Posts

hey guys i'm currently trying to create a cache system for my router, which i think i'm always there but i'm having a slight problem with preg_grep()

 

here is how it goes...the routes are added

Router::add_route('/register', array());
Router::add_route('/register/:activation_code', array());

(this is an example - i wouldnt really need to add two routes for /register page)

 

the routes get added to my router class and then get passed to the route pattern class where the patterns will get phased.

<?php

namespace Router;

use Exception\Exception as Exception;

class Route_Pattern
{
    const ROUTE_VARIABLES         = '(?<=\/)(?[ahis])(?=?!.*?\{)))?(?:\w++)(?!\{\w+\}))?(?\*)|\{([\w-]+(?:\|[\w-]+)+)*\})?(?<!\/)';
    const ROUTE_OPTIONAL_SEGMENTS = '(?:^|\G)[^\[\]]*(\[\/((?:[ahis]??[\w-]+)(?:\[\/((?:[ahis]??[\w-]+)\])?\])(?=\[|$)';
    
    private $_character_types = array(
        'i'  => '[\d]++',
        'a'  => '[\dA-Za-z]++',
        'h'  => '[\dA-Fa-f]++',
        's'  => '[\w-]++',
    );
    
    private $_route_pattern;
    
    public function phase($route_pattern)
    {
        if (is_null($route_pattern))
        {
            throw new Exception('Route Pattern: Route pattern is empty.');
        }
        
        $this->_route_pattern = $route_pattern;
        
        $this->optional_segments();
        $this->variables();
       
        return $this->_route_pattern;
    }
    
    private function variables()
    {
        $parameters = $this->match(self::ROUTE_VARIABLES, $this->_route_pattern);
     
        if ($parameters)
        {
            $count = count($parameters[0]);
    
            for ($i = 0; $i < $count; $i++)
            {
                $match          = $parameters[0][$i];
                $character_type = $parameters[1][$i];
                $parameter      = $parameters[2][$i];
                $all_variable   = $parameters[3][$i];
                $static_values  = $parameters[4][$i];
                
                if ($static_values)
                {
                    $replace = '(' . $static_values . ')';
                }
                else
                {
                    $replace = $this->character_type($character_type);
                }
                
                if ($parameter)
                {
                    $replace = '(?P<' . $parameter . '>'. $replace . '+)';
                }

                $this->_route_pattern = $this->replace($match, $replace, $this->_route_pattern);
            }
        }

        return $this->_route_pattern;
    }

    private function optional_segments()
    {
        $parameters = $this->match(self::ROUTE_OPTIONAL_SEGMENTS, $this->_route_pattern);

        if ($parameters)
        {
            $count = count($parameters[0]);
        
            for ($i = 0; $i < $count; $i++)
            {
                $match    = $parameters[1][$i];
                $segment1 = $parameters[2][$i];
                $segment2 = $parameters[3][$i];
               
                $replace = '(/' . $segment1;
                
                if ($segment2)
                {
                    $replace .= '/' . $segment2;
                }
                
                $replace .= ')?';
                    
                $this->_route_pattern = $this->replace($match, $replace, $this->_route_pattern);
            }
        }
        
        return $this->_route_pattern;
    }

    private function character_type($character_type = null)
    {
        if (isset($this->_character_types[$character_type]))
        {
            return '(' . $this->_character_types[$character_type] . ')';
        }

        return '[^\s]';
    }

    private function replace($search, $replace, $subject)
    {
        $search = '#' . preg_quote($search) . '#';
        
        return preg_replace($search, $replace, $subject, 1);
    }
    
    private function match($pattern, $subject)
    {
        $pattern = '#' . $pattern .'#';
    
        if (preg_match_all($pattern, $subject, $matches))
        {
            return $matches;
        }
         
        return false;
    }
}

uri:                                          /register/aqwrgj73ffgsegr2h   

route pattern                          /register/:activation_code

route pattern phased:           /register/(?P<activation_code>[^\s]+

 

so i decided i'd cache the phased route pattern and use preg_grep (which i'm new to) to match the uri to a single pattern.

 

now here is the problem at hand

$uri = '/register/aqwrgj73ffgsegr2h';

$routes = array(
    '/register',
    '/register/(?P<activation_code>[^\s]+'
);

$match = preg_grep($uri, $routes, PREG_GREP_INVERT);

print_r($match);

which returns

Array
(
    [0] => /register
    [1] => /register/(?P<activation_code>[^\s]+
)

so my question is why is key 0 (/register) present? as its not even a match

 

what i'd expect to have matched is /register/(?P<activation_code>[^\s]+

 

any help on this or my methods would be greatly appreciated...thanks guys

Edited by Destramic
Link to post
Share on other sites

It matches both because you aren't using anchors to enforce a match against the entire string. All you're doing now is checking if the string contains those patterns.

Link to post
Share on other sites

i tried that but even then it returns the same array

 

 

Array
(
[0] => /register
[1] => /register/(?P
<activation_code>[^\s]+
)

 

i did just realised that  /register/(?P<activation_code>[^\s]+)    didnt have a ) at the end

 

still the same problem though

$uri = '#^/register/aqwrgj73ffgsegr2h$#';

$routes = array(
    '/register',
    '/register/(?P<activation_code>[^\s]+)'
);

$match = preg_grep($uri, $routes, PREG_GREP_INVERT);
print_r($match);

Edited by Destramic
Link to post
Share on other sites

Looks like you have your arguments backwards. I don't think preg_grep is what you want anyway. Just do a loop with preg_match.

 

if i'm correct the PREG_GREP_INVERT allows it to work this way also

Link to post
Share on other sites

if i'm correct the PREG_GREP_INVERT allows it to work this way also

No, that flag just makes it return the input strings that do not match, instead of those that do. It doesn't flip the input and pattern parameters.

Link to post
Share on other sites

doh!...sorry i read something wrong, you are correct....i just got the manuel up

 

 

If set to PREG_GREP_INVERT, this function returns the elements of the input array that do not match the given pattern.

 

a function like this would be great...a loop with preg_match is is then...i'm not sure it's going to save time caching it this way though...time will tell :)

Edited by Destramic
Link to post
Share on other sites
This thread is more than a year old.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.