81

I'm just wondering how I can extract the last part of a URL using PHP.

The example URL is:

http://domain.example/artist/song/music-videos/song-title/9393903

Now how can I extract the final part using PHP?

9393903

There is always the same number of variables in the URL, and the id is always at the end.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Belgin Fish
  • 19,187
  • 41
  • 102
  • 131

14 Answers14

184

The absolute simplest way to accomplish this, is with basename()

echo basename('http://example.com/artist/song/music-videos/song-title/9393903');

Which will print

9393903

Of course, if there is a query string at the end it will be included in the returned value, in which case the accepted answer is a better solution.

nikc.org
  • 16,462
  • 6
  • 50
  • 83
107

Split it apart and get the last element:

$end = end(explode('/', $url));
# or:
$end = array_slice(explode('/', $url), -1)[0];

Edit: To support apache-style-canonical URLs, rtrim is handy:

$end = end(explode('/', rtrim($url, '/')));
# or:
$end = array_slice(explode('/', rtrim($url, '/')), -1)[0];

A different example which might me considered more readable is (Demo):

$path = parse_url($url, PHP_URL_PATH);
$pathFragments = explode('/', $path);
$end = end($pathFragments);

This example also takes into account to only work on the path of the URL.


Yet another edit (years after), canonicalization and easy UTF-8 alternative use included (via PCRE regular expression in PHP):

<?php

use function call_user_func as f;
use UnexpectedValueException as e;

$url = 'http://example.com/artist/song/music-videos/song-title/9393903';

$result = preg_match('(([^/]*)/*$)', $url, $m)

    ? $m[1]
    : f(function() use ($url) {throw new e("pattern on '$url'");})
    ;

var_dump($result); # string(7) "9393903"

Which is pretty rough but shows how to wrap this this within a preg_match call for finer-grained control via PCRE regular expression pattern. To add some sense to this bare-metal example, it should be wrapped inside a function of its' own (which would also make the aliasing superfluous). Just presented this way for brevity.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • 1
    Mind the gap: This code exploits something that could be considered a bug in PHP. I'll update the answer. – hakre Sep 13 '11 at 00:05
  • 2
    @hakre +1, but you'll get nothing if there's trailing slash in the `$url`. Better use [array_filter](http://php.net/array_filter) to remove empty elements first — `$pathFragments = array_filter(explode('/', $path));` – jibiel Mar 15 '13 at 15:47
  • 1
    @jibiel: Or do the `rtrim`-boogie, I edited the answer, see the now third code-example. – hakre Mar 15 '13 at 16:35
  • This solution probably performs somewhere in between the `basename`/`str*` solutions and the `preg` solutions if I had to guess. While it's an intuitively simple approach, it comes with some runtime overhead. – quickshiftin Nov 15 '14 at 20:48
  • 1
    @hakre Demo link is broken. Please kindly fix it – Michael Okoli Jun 21 '17 at 11:37
  • @MichaelPeter: re-created the demo, the other one I removed as the code is practically there and also the examples changed as PHP has changed. The last example can stay. – hakre Jun 21 '17 at 12:21
29

If you are looking for a robust version that can deal with any form of URLs, this should do nicely:

<?php

$url = "http://foobar.example/foo/bar/1?baz=qux#fragment/foo";
$lastSegment = basename(parse_url($url, PHP_URL_PATH));
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Peter
  • 29,454
  • 5
  • 48
  • 60
28

You can use preg_match to match the part of the URL that you want.

In this case, since the pattern is easy, we're looking for a forward slash (\/ and we have to escape it since the forward slash denotes the beginning and end of the regular expression pattern), along with one or more digits (\d+) at the very end of the string ($). The parentheses around the \d+ are used for capturing the piece that we want: namely the end. We then assign the ending that we want ($end) to $matches[1] (not $matches[0], since that is the same as $url (ie the entire string)).

$url='http://domain.example/artist/song/music-videos/song-title/9393903';

if(preg_match("/\/(\d+)$/",$url,$matches))
{
  $end=$matches[1];
}
else
{
  //Your URL didn't match.  This may or may not be a bad thing.
}

Note: You may or may not want to add some more sophistication to this regular expression. For example, if you know that your URL strings will always start with http:// then the regex can become /^http:\/\/.*\/(\d+)$/ (where .* means zero or more characters (that aren't the newline character)).

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
15
$id = strrchr($url,"/");
$id = substr($id,1,strlen($id));

Here is the description of the strrchr function: http://www.php.net/manual/en/function.strrchr.php

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Tamer Shlash
  • 9,314
  • 5
  • 44
  • 82
7

Another option:

$urlarray=explode("/",$url);
$end=$urlarray[count($urlarray)-1];
someone
  • 1,468
  • 8
  • 9
5

One of the most elegant solutions was here Get characters after last / in url

by DisgruntledGoat

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

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

Community
  • 1
  • 1
Robert Sinclair
  • 4,550
  • 2
  • 44
  • 46
3

One liner: $page_path = end(explode('/', trim($_SERVER['REQUEST_URI'], '/')));

Get URI, trim slashes, convert to array, grab last part

Justin
  • 26,443
  • 16
  • 111
  • 128
2

A fail safe solution would be:

Referenced from https://stackoverflow.com/a/2273328/2062851

function getLastPathSegment($url) {
    $path = parse_url($url, PHP_URL_PATH); // to get the path from a whole URL
    $pathTrimmed = trim($path, '/'); // normalise with no leading or trailing slash
    $pathTokens = explode('/', $pathTrimmed); // get segments delimited by a slash

    if (substr($path, -1) !== '/') {
        array_pop($pathTokens);
    }
    return end($pathTokens); // get the last segment
}

echo getLastPathSegment($_SERVER['REQUEST_URI']); //9393903
samjco-com
  • 365
  • 5
  • 14
1

this will do the job easily to get the last part of the required URL

$url="http://domain.example/artist/song/music-videos/song-title/9393903";
$requred_string= substr(strrchr($url, "/"), 1);

this will get you the string after first "/" from the right.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
XxANxX
  • 121
  • 8
  • Do mind: if there's a trailing slash at the end this will fail. See the comments at the solution of hakre and his edit. Check out Peter's solution: the basename() function is made for this. – metatron Feb 09 '16 at 11:03
1
$mylink = $_SERVER['PHP_SELF'];
$link_array = explode('/',$mylink);
echo $lastpart = end($link_array);
showdev
  • 28,454
  • 37
  • 55
  • 73
Shuhad zaman
  • 3,156
  • 32
  • 32
1
function getLastPathSegment($url) {
    $arr = explode('/', $url);
    return $arr[count($arr) - 1];
}
Swaroop Maddu
  • 4,289
  • 2
  • 26
  • 38
Tushar
  • 13
  • 3
  • 1
    While this code may answer the question, providing additional context regarding *how* and/or *why* it solves the problem would improve the answer's long-term value. – Sven Eberth Jul 10 '21 at 22:23
0

1-liner

$end = preg_replace( '%^(.+)/%', '', $url );

// if( ! $end ) no match.

This simply removes everything before the last slash, including it.

Jorge Orpinel Pérez
  • 6,361
  • 1
  • 21
  • 38
0

One line working answer:

$url = "http://www.yoursite/one/two/three/drink";
echo $end = end((explode('/', $url)));

Output: drink

George Chalhoub
  • 14,968
  • 3
  • 38
  • 61