获取PHP中URL的最后一部分

82

我想知道如何使用PHP提取URL的最后一部分。

示例URL是:

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

现在我该如何使用PHP提取最后一部分?

9393903

URL中的变量数量始终相同,并且id始终位于末尾。

14个回答

186

最简单的方法是使用basename()函数。

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

这将会打印

9393903

当然,如果末尾有查询字符串,它也会被包含在返回的值中,此时接受的答案是更好的解决方案。


经过许多正则表达式的尝试,我终于找到了这个答案。为什么我之前没有发现呢?如此简单明了。 - NME New Media Entertainment

107

将其分开并获取最后一个元素:

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

编辑: 为支持 Apache 风格的规范化 URL,rtrim 很方便:

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

以下是另一个更易读的示例(演示):


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

这个例子同时考虑了只在URL路径上工作。


经过多年的又一次编辑,规范化并包含使用PCRE正则表达式的易于UTF-8替代方案(通过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"

这个例子比较粗糙,但展示了如何在PCRE正则表达式模式中使用preg_match来进行更细粒度的控制。为了让这个底层示例更有意义,它应该被包装在一个自己的函数中(这也会使别名变得多余)。只是出于简洁性而以这种方式呈现。


1
请注意:这段代码利用了 PHP 中可能被视为漏洞的东西。我会更新答案。 - hakre
2
@hakre +1,但是如果$url中有尾随斜杠,你将得不到任何东西。最好先使用array_filter删除空元素 - $pathFragments = array_filter(explode('/', $path)); - jibiel
1
@jibiel:或者进行“rtrim”操作,我编辑了答案,请查看现在的第三个代码示例。 - hakre
如果我猜的话,这个解决方案的性能可能介于basename/str*解决方案和preg解决方案之间。虽然这是一种直观简单的方法,但它会带来一些运行时开销。 - quickshiftin
1
@hakre 演示链接已经失效,请您修复一下。 - Michael Okoli
@MichaelPeter:重新创建了演示,我删除了另一个,因为代码实际上已经存在,并且示例已更改,因为PHP已更改。最后一个示例可以保留。 - hakre

30

如果你正在寻找一个强大的版本,可以处理任何形式的URLs,那么这个应该很好用:

<?php

$url = "http://foobar.example/foo/bar/1?baz=qux#fragment/foo";
$lastSegment = basename(parse_url($url, PHP_URL_PATH));

1
这是我最喜欢的一款。强大、高效且简洁。 - quickshiftin
比其他的要容易得多 - balping

28
您可以使用preg_match来匹配URL中想要的部分。
在这种情况下,由于模式比较简单,我们正在查找一个正斜杠(\/并且我们必须转义它,因为正斜杠表示正则表达式模式的开始和结束),以及字符串末尾的一个或多个数字(\d+)。括号中的\d+用于捕获我们想要的部分:即末尾。然后我们将所需的结尾($end)分配给$matches[1](而不是$matches[0],因为那与$url相同,即整个字符串)。
$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.
}

注意:您可能需要将这个正则表达式更加复杂化。例如,如果您知道您的URL字符串将始终http://开头,则正则表达式可以变为/^http:\/\/.*\/(\d+)$/(其中.*表示零个或多个字符(不包括换行符))。


不错。也可以用 preg_replace 在一行中完成。我会添加一个答案。 - Jorge Orpinel Pérez
3
这个方案可能是这些方案中最慢的一个;不是抱怨,只是说说而已。 - quickshiftin
1
那么,如果是 example.com/123/my-slug/1235,你需要的是 1235 吗? - zanderwar
它适用于字符串。但是你如何从URL中获取最后一部分呢? - Cornelius

15

这个解决方案可能是最快的,除非适用basename()解决方案。 - quickshiftin
这个解决方案非常有帮助,而且非常简单。 - Malki Mohamed
这个解决方案对我也非常有帮助。 - STA

7
另一个选择:
$urlarray=explode("/",$url);
$end=$urlarray[count($urlarray)-1];

6

最优雅的解决方案之一在这里:获取URL中最后一个 / 后面的字符

作者:DisgruntledGoat

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

strrpos函数获取最后一个斜杠出现的位置;substr函数返回该位置后的所有内容。

3

一句话简述: $page_path = end(explode('/', trim($_SERVER['REQUEST_URI'], '/')));

获取URI,去除斜杠,转换为数组,获取最后一部分。


当前PHP(2020年1月)会导致错误:https://dev59.com/3m445IYBdhLWcg3w6eXz#4636183 - dmikester1

2
一种故障安全的解决方案是:
引用自https://dev59.com/5nE95IYBdhLWcg3wi-Qc#2273328
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

1
function getLastPathSegment($url) {
    $arr = explode('/', $url);
    return $arr[count($arr) - 1];
}

1
虽然这段代码可能回答了问题,但提供关于它如何解决问题以及为什么解决问题的额外上下文信息将会提高答案的长期价值。 - Sven Eberth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接