Search code examples
phparraysstringsortingstrpos

How to prioritize strpos to find me the most accurate result


I have an array:

$array_of_routes = ['users/', 'articles/more', 'users/get', 'homepage/'];

And, For example I have a string:

$route = "users/get/1"; 

So I tried to find it by using strpos but because 'users/' comes a head of 'users/get' in $array_of_routes I get the 'users/' in return and not the 'users/get', This is makes sense because that is what I asked the code to do.

But is there a way to priorotize or make the result more accurate when trying to find a substring in a string?

Note: when removing 'users/' from the array I get the 'users/get'

This is my code:

foreach($array_of_routes as $uri){
  if(strpos($current_uri, $uri) !== false)
    return $uri;

}

Thanks you for your help!


Solution

  • You need to break apart the $route and match it with the highest specificity available in $array_of_routes

    <?php
    $array_of_routes = ['users', 'articles/more/', 'users/get', 'homepage'];
    $route = "users/get/1/fgd/d/fg/";
    
    // No reason to have trailing nor leading slashes or spaces; they are just noise
    $array_of_routes = array_map(function($v){return trim(trim($v, '/'));}, $array_of_routes );
    $route = trim(trim( $route, '/' ));
    
    // Get the requested route pieces
    $route_pieces = explode('/', $route);
    
    // Make sure we loop enough times to account for all of the pieces
    for($i = 0; $i<count($route_pieces); ++$i)
    {
        // With each loop, build the route with one piece less and check if it exists in $array_of_routes
        if(in_array(implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i))), $array_of_routes))
        {
            echo 'Most specific route: '.implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i)));
            echo 'Arguments: '.implode('/', array_slice($route_pieces, (count($route_pieces)-$i)));
            break;
        }
    }
    

    Output for $route = "users/get/1/fgd/d/fg/";:

    Most specific route: users/get
    Arguments: 1/fgd/d/fg