What is an efficient way to get the part of a string after the occurrence of a certain needle, only if that needle is at the start of the haystack. Similar to strstr()
, but excluding the needle, and only when found at the beginning of the string.
If it isn't found, it should preferably return false.
I have the feeling I'm overlooking some very obvious PHP functions here, but I can't seem to think of them right now.
For example:
$basePath = '/some/dir/';
$result = some_function( '/some/dir/this/is/the/relative/part', $basePath );
/*
should return:
this/is/the/relative/part
*/
$result = some_function( '/fake/dir/this/is/the/relative/part', $basePath );
$result = some_function( '/pre/some/dir/this/is/the/relative/part', $basePath );
/*
last example has '/some/dir/' in it, but not at start.
should both preferably return:
false
*/
I'll be using this for a filesystem service that should act as a sandbox, and should be able to give out and take in paths, rela开发者_StackOverflow社区tive to the base sand box directory.
This case calls for strncmp:
function some_function($path, $base) {
if (strncmp($path, $base, $n = strlen($base)) == 0) {
return substr($path, $n);
}
}
Put more simply than the other examples:
function some_function($path,$base){
$baselen = strlen($base);
if (strpos($path,$base) === 0 && strlen($path)>$baselen)
return substr($path,$baselen);
return false;
}
DEMO
Alternate using strncmp, too: DEMO
function some_function($haystack, $baseNeedle) {
if (! preg_match('/^' . preg_quote($baseNeedle, '/') . '(.*)$/', $haystack, $matches)) {
return false;
}
return $matches[1];
}
function some_function($path, $basePath) {
$pos = strpos($path, $basePath);
if ($pos !== false) {
return substr($path, strlen($basePath));
} else {
return false;
}
}
But what about this?
some_function('/base/path/../../secret/password.txt', '/base/path/safe/dir/');
You likely want to call realpath()
on $path
first, so that it is fully simplified, before using some_function()
.
Not sure if there's a built-in function for this.
function some_function($str1, $str2) {
$l = strlen($str2);
if (substr($str1, 0, $l) == $str2)
return substr($str1, $l);
else
return false;
}
For long $str1
and short $str2
, I think this is going to be faster than using strpos
.
If you're using this for paths, you might want to do some checking if the slashes are at the right place.
How about regular expressions?
$regexp = preg_quote($basepath, '/');
return preg_replace("/^$regexp/", "", $path);
精彩评论