2

基本的に、次のようなベースURLが与えられます

file:///path/to/some/file.html

そして、次のような相対 URL

another_file.php?id=5

出たい

file:///path/to/some/another_file.php?id=5

このスクリプト(これはこれと同じです)を見つけましたが、file://スキームでは機能しないようです。file://コードを公開する前にいくつかのローカル テストを行っているので、 と の両方に取り組みたいと思いhttp://ます。

これを行うスクリプト/関数を知っている人はいますか?

C# では、Uri(Uri base, string rel)を使用します。


上記はほんの一例です。にスローできるすべてのURL で動作するはずです<a href="xxx">


これは私がこれまでに得た中で最高..のものですが、おそらく他のいくつかのことを処理できません:

function rel2abs($base, $rel) {
    if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel;
    if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel;
    $parse = parse_url($base);
    $path = preg_replace('#/[^/]*$#', '', $parse['path']);
    if ($rel[0] == '/') $path = '';
    $abs = (isset($path['host'])?$path['host']:'')."$path/$rel";
    $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
    for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
    return $parse['scheme'].'://'.$abs;
}
4

6 に答える 6

2

parse_url()を使用して URL を部分に分割し、スラッシュ文字の「パス」部分を分割できます。これにより、それらを再組み立てして最後の部分を交換できるようになります。

このようなもの(疑似コード、テストされていない、有効なPHP構文であるかどうかさえわかりません):

$url_parts = parse_url($url_text);
$path_parts = explode('/', $url_parts[path]);

$new_url = $url_parts[scheme] + ":";

if ($url_parts[scheme] == "file") {
    $new_url .= '///';
} else {
    $new_url .= '//';
}

$new_url .= $url_parts[hostname] . '/';
for (int i = 0; i < count($path_parts) - 1; i++) {
    $new_url .= $path_parts[i] . "/";
} 

$new_url .= $REPLACEMENT_FILENAME

必要に応じて、最後にクエリ文字列やアンカー フラグメント (# で始まる) を追加できます。配列内の URL 部分のリストについては、parse_url() マニュアル ページを参照してください。

于 2012-06-26T20:43:56.203 に答える
1
<?php
/* strings from your exemple */
$base_url = "file:///path/to/some/file.html";
$relative_url = "another_file.php?id=5";

/* split up urls folder parts into an array */
$base_url_parts = explode('/', $base_url);
$relative_parts = explode('/', $relative);

/* remove last element (in this case "file.html") */
array_pop($base_url_parts);

/* merge absolute_url from base and relative */
$absolute_url_parts = array_merge($base_url_parts, $relative_parts);

/* reverser the list before the search of '..' */
$absolute_url_parts = array_reverse($absolute_url_parts);

/* count of current number of unhandled '..' */
$parent_folder_count = 0;

/* loop throught all elements looking for '..' */
foreach($absolute_url_parts as $part_nr => $part_value)
{
    /* if we find '..', remove this and the next element */
    if($part_value = '..')
    {
        $parent_folder_count++;
        unset($absolute_url_parts[$part_nr]);
    }

    /* if we find '.' remove this element */
    else if($part_value = '.')
    {
        unset($absolute_url_parts[$part_nr]);
    }

    /* if this is a normal element, and we have unhandled '..', then remove this */
    else if($parent_folder_count > 0)
    {
        unset($absolute_url_parts[$part_nr]);
        $parent_folder_count--;
    }

    /* else: keep it */
}

/* restore the order by reversing again */
$absolute_url_parts = array_reverse($absolute_url_parts);

/* restore the list to a string again */
$absolute_url = implode('/', $absolute_url_parts);

/* done */
?>
于 2012-06-26T20:54:55.500 に答える
1

最も簡単な解決策は、 dirname()関数を使用することだと思います。

$url = 'file:///path/to/some/file.html';
$rel = 'another_file.php?id=5';

$final = dirname($url).'/'.$rel;
于 2012-06-26T21:10:33.847 に答える
0
$ab="file:///path/to/some/file.html";
$rel="another_file.php?id=5";

$exab=explode("/",$ab);
$exab[count($exab)-1]=$rel;

$newab=implode("/",$exab);

おそらく最もエレガントなソリューションではありませんが、機能します。

于 2012-06-26T20:47:25.347 に答える
0
$file1 = "file://path/to/some/file.html";
$file2 = "anotherfile?q=1";

$newurl = substr_replace($file1, $file2, strrpos($file1, "/")+1);

http://codepad.org/370Yp1M7

于 2012-06-26T20:49:14.300 に答える