2016-11-27 2 views
2

にURLを参加します簡単な方法は、彼が現在のページでリクエストと一致する変数に$new_path変数を追加し、新しいURLを取得することです。 $new_pageは、のいずれでも良いことをは、私はグット/クライアントを持っている(グットは、要求のためにsymfonyを使用しています)、私はパスに参加して、最終的なURLを取得したいと思いsymfonyの/グット

注:

new_page ==> http://DOMAIN/some/path/new_page 
../new_page ==> http://DOMAIN/some/new_page 
/new_page ==> http://DOMAIN/new_page 

のsymfony /グット/がつがつ食うが、そうする任意の簡単な方法を提供していますか?

私はSymfony\Component\HttpFoundation\RequestからgetUriForPathを見つけましたが、私はあなたがURLのパスを取得するためにparse_urlを使用することができますHttpFoundation\Request

+0

あなたは本当に、URLのパスをcanonizeする必要がありますか? guzzleは 'http:// DOMAIN/some/path /../ new_page'へのリクエストを問題なく処理できなければなりません – Federkun

+0

ええ、私はいくつかの他のバリデーションのために必要です(特定のリクエストではありません)。また、 '$ new_page'が'/new_page'の場合は、最終的なURLにいくつか問題があるかもしれません。 – Dekel

答えて

1

Symfony\Component\BrowserKit\Requestを変換する簡単な方法が表示されない:

$components = parse_url('http://DOMAIN/some/path/'); 
$path = $components['path']; 

、あなたはそれを正当化する方法が必要です。 This answerあなたを助けることができますURLを再構築して行うには残って

function normalizePath($path, $separator = '\\/') 
{ 
    // Remove any kind of funky unicode whitespace 
    $normalized = preg_replace('#\p{C}+|^\./#u', '', $path); 

    // Path remove self referring paths ("/./"). 
    $normalized = preg_replace('#/\.(?=/)|^\./|\./$#', '', $normalized); 

    // Regex for resolving relative paths 
    $regex = '#\/*[^/\.]+/\.\.#Uu'; 

    while (preg_match($regex, $normalized)) { 
     $normalized = preg_replace($regex, '', $normalized); 
    } 

    if (preg_match('#/\.{2}|\.{2}/#', $normalized)) { 
     throw new LogicException('Path is outside of the defined root, path: [' . $path . '], resolved: [' . $normalized . ']'); 
    } 

    return trim($normalized, $separator); 
} 

すべては、あなたがthis commentを見ることができます:

function unparse_url($parsed_url) { 
    $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; 
    $host  = isset($parsed_url['host']) ? $parsed_url['host'] : ''; 
    $port  = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; 
    $user  = isset($parsed_url['user']) ? $parsed_url['user'] : ''; 
    $pass  = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; 
    $pass  = ($user || $pass) ? "[email protected]" : ''; 
    $path  = isset($parsed_url['path']) ? $parsed_url['path'] : ''; 
    $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; 
    $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; 
    return "$scheme$user$pass$host$port/$path$query$fragment"; 
} 

最終パス:

$new_path = '../new_page'; 

if (strpos($new_path, '/') === 0) { // absolute path, replace it entirely 
    $path = $new_path; 
} else { // relative path, append it 
    $path = $path . $new_path; 
} 

はすべて一緒にそれを置く:

// http://DOMAIN/some/new_page 
echo unparse_url(array_replace($components, array('path' => normalizePath($path)))); 
+0

答えをいただきありがとうございます、私はSymfonyがこれに対してより簡単な解決策を提供することを願っていました。あなたが気にしないことを願っています - これを正解とマークする前にもう少しお待ちしております。 – Dekel

+0

'/ new_page'(最終的なURLは' http:// example.org/new_page')で 'http:// example.org/page /'をどのように扱いますか分かりません。説明できますか? – Dekel

+0

最後の例( 'echo resolveUrl( 'http://example.org/page/'、 '/ new_page')、" \ n ";')では、 'http:// example.org/page'の代わりに' http:// example.org/new_page'と入力します。 – Dekel

3

Uri::resolve()guzzlehttp/prs7パッケージを使用してください。このメソッドを使用すると、 URLをベースと相対部分から正規化したを作成できます。

(優れたpsysh shellを使用)例:

Psy Shell v0.7.2 (PHP 7.0.12 — cli) by Justin Hileman 
>>> $base = new GuzzleHttp\Psr7\Uri('http://example.com/some/dir') 
=> GuzzleHttp\Psr7\Uri {#208} 
>>> (string) GuzzleHttp\Psr7\Uri::resolve($base, '/new_base/next/next/../../back_2') 
=> "http://example.com/new_base/back_2" 

UriNormalizer classを見てみましょう。問題に接続している例(test case)があります。

テストケースから:

$uri = new Uri('http://example.org/../a/b/../c/./d.html'); 
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS); 

$this->assertSame('http://example.org/a/c/d.html', (string) $normalizedUri); 
+0

'/ new_page'で結合された' http:// example.org/page/'をどのように扱うのかよくわかりません(最後のURLは' http:// example.org/new_page')。説明できますか? – Dekel

+0

あなたは正しいです。 'guzzlehttp/prs7'で答えを正しいものに更新しました。 –

+0

ありがとうございます。私が使用しているgoutteバージョンはちょっと古くて、最新バージョンのguzzle(prs7とUriResolveを持っています)を持っていないようです。しかし、あなたは私のupvoteをここに持っています:)あなたの助けをもう一度ありがとう! – Dekel

関連する問題