153

I want to get the characters after the last / in an url like http://www.vimeo.com/1234567

How do I do with php?

Johan
  • 18,814
  • 30
  • 70
  • 88
  • You might find [`s($str)->afterLast('/')`](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L445) helpful, as found in [this standalone library](https://github.com/delight-im/PHP-Str). – caw Jul 27 '16 at 00:20

10 Answers10

318

Very simply:

$id = substr($url, strrpos($url, '/') + 1);

strrpos gets the position of the last occurrence of the slash; substr returns everything after that position.


As mentioned by redanimalwar if there is no slash this doesn't work correctly since strrpos returns false. Here's a more robust version:

$pos = strrpos($url, '/');
$id = $pos === false ? $url : substr($url, $pos + 1);
DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290
  • This cuts of the first character if there is no slash at all. – redanimalwar Nov 02 '15 at 13:55
  • @redanimalwar I added another solution – DisgruntledGoat Nov 02 '15 at 14:56
  • 11
    I am wondering why the `$str = basename($url)` is not getting more upvotes, works perfectly fine for me. – redanimalwar Nov 02 '15 at 16:39
  • 3
    @redanimalwar (1) basename is intended for file paths, not URLs - I think it will always return the same result but there may be edge cases like backslashes; (2) basename only works for slashes whereas my answer can be easily modified if someone else wants to do the same thing with a different character. – DisgruntledGoat Nov 02 '15 at 20:39
66

Check out basename(). It should work like this:

$string = basename($url);
space97
  • 153
  • 1
  • 4
  • 19
GZipp
  • 5,386
  • 1
  • 22
  • 18
  • 2
    Does this work on urls? Isn't basename intended for file paths? – random_user_name Apr 05 '13 at 18:24
  • 3
    Seems to work fine, It's a string function; it doesn't check if the path exists. – Gifford N. Mar 24 '16 at 17:06
  • Careful if you use this on strings other than URLs, e.g. classnames (__ CLASS __). basename() will work on Windows as the DIRECTORY_SEPARATOR is a backslash, but on Linux, basename() only looks for a slash, so basename('App\Class') will return "Class" on Windows but "App\Class" on Linux. – Select0r Jul 02 '21 at 06:45
13

You could explode based on "/", and return the last entry:

print end( explode( "/", "http://www.vimeo.com/1234567" ) );

That's based on blowing the string apart, something that isn't necessary if you know the pattern of the string itself will not soon be changing. You could, alternatively, use a regular expression to locate that value at the end of the string:

$url = "http://www.vimeo.com/1234567";

if ( preg_match( "/\d+$/", $url, $matches ) ) {
    print $matches[0];
}
Sampson
  • 265,109
  • 74
  • 539
  • 565
  • `explode` always seems like more overhead to me, though I haven't ever timed it to see how fast it is. – DisgruntledGoat Sep 01 '09 at 10:47
  • It appears explode() is a bit slower. On 10k instances, this is the amount of time taken for both. substr() first: 0.013657/0.045038 – Sampson Sep 01 '09 at 10:54
  • Might be slower, but I prefer the explode here. Specifically if the url doesn't contain any "/" the +1 in the strrpos answer makes a mess explode is able to overcome. – Noam May 15 '14 at 08:28
  • 2
    The example throws a notice and should definetly be re-worked. – Xatenev Nov 22 '16 at 13:57
  • 1
    Yes, exploded data must be a variable – ymakux Sep 30 '17 at 15:38
12

You can use substr and strrchr:

$url = 'http://www.vimeo.com/1234567';
$str = substr(strrchr($url, '/'), 1);
echo $str;      // Output: 1234567
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
Gabriel
  • 715
  • 1
  • 9
  • 17
10
$str = "http://www.vimeo.com/1234567";
$s = explode("/",$str);
print end($s);
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
1

array_pop(explode("/", "http://vimeo.com/1234567")); will return the last element of the example url

nikc.org
  • 16,462
  • 6
  • 50
  • 83
1
Str::afterLast($url, '/');

A helper method in Laravel since Laravel 6.

brad
  • 1,407
  • 19
  • 33
0

Two one liners - I suspect the first one is faster but second one is prettier and unlike end() and array_pop(), you can pass the result of a function directly to current() without generating any notice or warning since it doesn't move the pointer or alter the array.

$var = 'http://www.vimeo.com/1234567';

// VERSION 1 - one liner simmilar to DisgruntledGoat's answer above
echo substr($a,(strrpos($var,'/') !== false ? strrpos($var,'/') + 1 : 0));

// VERSION 2 - explode, reverse the array, get the first index.
echo current(array_reverse(explode('/',$var)));
  • @redburn, Using `end()` this way in php 5.4+ and up will throw a notice. According to docs: "*you must pass it a real variable and not a function returning an array because only actual variables may be passed by reference.*". – But those new buttons though.. May 07 '20 at 17:15
0

My version is:

trim(strrchr($url, "/"), "/");

https://www.php.net/manual/function.strrchr

-1

Here's a beautiful dynamic function I wrote to remove last part of url or path.

/**
 * remove the last directories
 *
 * @param $path the path
 * @param $level number of directories to remove
 *
 * @return string
 */
private function removeLastDir($path, $level)
{
    if(is_int($level) && $level > 0){
        $path = preg_replace('#\/[^/]*$#', '', $path);
        return $this->removeLastDir($path, (int) $level - 1);
    }
    return $path;
}
Mahmoud Zalt
  • 30,478
  • 7
  • 87
  • 83