PHP:构建URL路径

时间:2010-09-14 16:38:05

标签: php

我有几个字符串要组合以构建完整路径。 e.g。

$base = "http://foo.com";
$subfolder = "product/data";
$filename = "foo.xml";

// How to do this?
$url = append_url_parts($base, $subfolder, $filename); ???

字符串连接不起作用,这将省略必要的正斜杠。

在Win32中,我使用PathCombine()或PathAppend(),它将处理在字符串之间添加任何必要的斜杠,而不会加倍。在PHP中,我应该使用什么?

8 个答案:

答案 0 :(得分:3)

试试这个:

$base = "http://foo.com";
$subfolder = "product/data";
$filename = "foo.xml";

function stripTrailingSlash(&$component) {
    $component = rtrim($component, '/');
}
$array = array($base, $subfolder, $filename);
array_walk_recursive($array, 'stripTrailingSlash'); 
$url = implode('/', $array);

答案 1 :(得分:3)

当涉及到类似的东西时,我喜欢使用具有无限参数的特殊功能。

define('BASE_URL','http://mysite.com'); //Without last slash
function build_url()
{
    return BASE_URL . '/' . implode(func_get_args(),'/');
}

OR

function build_url()
{
    $Path = BASE_URL;
    foreach(func_get_args() as $path_part)
    {
        $Path .= '/' . $path_part;
    }
    return $Path;
}

这样当我使用我能做的功能时

echo build_url('home'); //http://mysite.com/home
echo build_url('public','css','style.css'); //http://mysite.com/public/css/style.css
echo build_url('index.php'); //http://mysite.com/index.php

希望这对您有所帮助,特别是在框架环境中,我的工作非常好。

与params一起使用,你可以像这样简单地附加网址。

echo build_url('home') . '?' .  http_build_query(array('hello' => 'world'));

会产生:http://mysite.com/home?hello=world

答案 2 :(得分:0)

不确定为什么你说string concat不会这样做,因为像这样的东西基本上类似于字符串concat。 (未经测试的半伪)

function append_url_parts($base, $subf, $file) {
    $url = sprintf("%s%s%s", $base, (($subf)? "/$subf": ""), (($file)? "/$file": ""));
    return $url;
}

使用字符串concat,我们必须编写一个稍长的块,如下所示:

function append_url_parts($base, $subf, $file) {
    $subf = ($subf)? "/$subf": "";
    $file = ($file)? "/$file": "";
    $url = "$base$subf$file";
    return $url;
}

答案 3 :(得分:0)

我通常很简单:

<?
    $url = implode('/', array($base, $subfolder, $filename));

或者使用框架,然后使用它拥有的任何路由系统。

答案 4 :(得分:0)

首先要考虑一些因素。

  1. 您是否有兴趣获取脚本的当前路径或其他路径?
  2. 您需要多大的灵活性?它是否会一直在改变?管理员会设置一次忘记吗?
  3. 你要小心不要在你的文档最后添加斜杠时包含斜杠bug,因为你太懒了,无法弄清楚如何将目录变量与文件var分开。每个URL只有一个文件和一个基数,每个路径中的目录数量都是未知的,对吗? :)

答案 5 :(得分:0)

如果你想确保结果路径中没有重复的斜杠,我喜欢这个小函数...简单地传递一个你想要组合的路径部分数组,它将返回一个格式化的路径 - 不用担心是否有任何部件包含斜杠alerady:

function build_url($arr) 
{
    foreach ( $arr as $path ) $url[] = rtrim ( $path, '/' );
    return implode( $url, '/' );
}

这也适用于所有版本的PHP。

答案 6 :(得分:0)

不是我的代码,而是一个方便的函数,它接受一个绝对的URL和一个相对的URL,并将两者结合起来创建一个新的绝对路径。

该函数已被修改为忽略作为相对传递的绝对URL(基本上包含模式的任何内容)。

$url = "http://www.goat.com/money/dave.html";
$rel = "../images/cheese.jpg";

$com = InternetCombineURL($url,$rel);
public function InternetCombineUrl($absolute, $relative) {
        $p = parse_url($relative);
        if(isset($p["scheme"]))return $relative;

        extract(parse_url($absolute));

        $path = dirname($path); 

        if($relative{0} == '/') {
            $cparts = array_filter(explode("/", $relative));
        }
        else {
            $aparts = array_filter(explode("/", $path));
            $rparts = array_filter(explode("/", $relative));
            $cparts = array_merge($aparts, $rparts);
            foreach($cparts as $i => $part) {
                if($part == '.') {
                    $cparts[$i] = null;
                }
                if($part == '..') {
                    $cparts[$i - 1] = null;
                    $cparts[$i] = null;
                }
            }
            $cparts = array_filter($cparts);
        }
        $path = implode("/", $cparts);
        $url = "";
        if($scheme) {
            $url = "$scheme://";
        }
        if(isset($user)) {
            $url .= "$user";
            if($pass) {
                $url .= ":$pass";
            }
            $url .= "@";
        }
        if($host) {
            $url .= "$host/";
        }
        $url .= $path;
        return $url;
    }

答案 7 :(得分:0)

我在所有情况下都编写了此函数,以合并没有重复斜杠的url部分。 它接受许多参数或部分数组。 某些部分可能是空字符串,不会产生双斜杠。 如果存在斜杠,它将保持开始和结束斜杠。

SUBSTRING_INDEX

这是单元测试的清单。左数组是输入,右部分是结果字符串。

function implodePath($parts)
{
    if (!is_array($parts)) {
        $parts = func_get_args();
        if (count($parts) < 2) {
            throw new \RuntimeException('implodePath() should take array as a single argument or more than one argument');
        }
    } elseif (count($parts) == 0) {
        return '';
    } elseif (count($parts) == 1) {
        return $parts[0];
    }
    $resParts = [];
    $first = array_shift($parts);
    if ($first === '/') {
        $resParts[] = ''; // It will keep one starting slash
    } else {
        // It may be empty or have some letters
        $first = rtrim($first, '/');
        if ($first !== '') {
            $resParts[] = $first;
        }
    }
    $last = array_pop($parts);

    foreach ($parts as $part) {
        $part = trim($part, '/');
        if ($part !== '') {
            $resParts[] = $part;
        }
    }
    if ($last === '/') {
        $resParts[] = ''; // To keep trailing slash
    } else {
        $last = ltrim($last, '/');
        if ($last !== '') {
            $resParts[] = $last; // Adding last part if not empty
        }
    }
    return implode('/', $resParts);
}

它可以用作implodePath('aaa','bbb')或implodePath(['aaa','bbb'])