Vicky Dev
Vicky Dev

Reputation: 2183

PHP Compare 2 path strings and return the unique portion

I have disappointingly searched almost everywhere, but couldn't find any reliable function(neither built-in nor user-defined) in PHP, which could compare two paths (regardless of the OS and path separator differences) and return the actual difference i.e. the unique string between 2 paths.

The 2 paths that I wanna compare are below:

[site_root]\public\module\wysiwyg/
[site_root]\

And post comparison, I want the output to be:

public\module\wysiwyg/

I have checked out substr and strcmp but those only can return the integer values determining whether one string is longer/shorter than the other.

Can anyone help figuring out method for path comparison ?

Upvotes: 1

Views: 485

Answers (2)

Eugene Kaurov
Eugene Kaurov

Reputation: 2991

Symfony has cool functions:

Path::getLongestCommonBasePath(
    '/var/www/vhosts/project/httpdocs/config/config.yaml',
    '/var/www/vhosts/project/httpdocs/config/routing.yaml',
    '/var/www/vhosts/project/httpdocs/config/services.yaml',
    '/var/www/vhosts/project/httpdocs/images/banana.gif',
    '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif'
);
// => /var/www/vhosts/project/httpdocs

and

Path::isBasePath("/var/www", "/var/www/project");
// => true

Path::isBasePath("/var/www", "/var/www/project/..");
// => true

Path::isBasePath("/var/www", "/var/www/project/../..");
// => false

Documentation: https://symfony.com/doc/current/components/filesystem.html#finding-longest-common-base-paths

Source code: https://github.com/symfony/symfony/blob/6.1/src/Symfony/Component/Filesystem/Path.php#method_isBasePath

Upvotes: 0

cOle2
cOle2

Reputation: 4784

What have you tried that is not reliable? At first glance this could be accomplished by normalizing the directory separators, converting to an array, then using array_diff to compare the paths:

//list of directory separaters
$normalizeDirectorySeparator = array('\\', '/', ':');

//our paths to compare
$path1 = '[site_root]\public\module\wysiwyg/';
$path2 = '[site_root]\\';

//normalize directory separators
$path1 = str_replace($normalizeDirectorySeparator, '/', $path1);
$path2 = str_replace($normalizeDirectorySeparator, '/', $path2);

//convert to array
$path1Arr = explode('/', $path1);
$path2Arr = explode('/', $path2);

//get differences
$diff = array_diff($path1Arr, $path2Arr);

//output differences
echo implode('/', $diff); /* public/module/wysiwyg */

Upvotes: 2

Related Questions