Destramic Posted July 20, 2016 Share Posted July 20, 2016 (edited) 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 July 20, 2016 by Destramic Quote Link to comment Share on other sites More sharing options...
requinix Posted July 20, 2016 Share Posted July 20, 2016 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. Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 20, 2016 Author Share Posted July 20, 2016 (edited) 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 July 20, 2016 by Destramic Quote Link to comment Share on other sites More sharing options...
kicken Posted July 20, 2016 Share Posted July 20, 2016 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. Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 20, 2016 Author Share Posted July 20, 2016 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 Quote Link to comment Share on other sites More sharing options...
kicken Posted July 20, 2016 Share Posted July 20, 2016 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. Quote Link to comment Share on other sites More sharing options...
Destramic Posted July 20, 2016 Author Share Posted July 20, 2016 (edited) 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 July 20, 2016 by Destramic Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.