2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Laravel5.3】url(), redirect()使用時にURLが変わる場合の対処方法

Last updated at Posted at 2017-03-19

使用環境

  • php7
  • Laravel5.3
  • Apache2.4

※上記を使用していますが、他Laravelバージョンでも応用可能かと思います。

問題点

プロキシサーバを通したあとの処理で、__『url(), redirect()を使用するとURLが変わってしまう』__という問題が発生した。

たとえばurl('/user')とした際に、希望としてはhttp://example.co.jp/userというURLを取得したいにもかかわらず、http://hoge01.example.co.jp/userとプロキシサーバからサーバへアクセスするためのURLが使用されてしまう。

url()redirect()や、AuthまわりのReferrer機能をそのまま使用したい…

解決法

url()を探るとUrlGenerator.phpto()で絶対URLを取得している様子。

ということで、
vendor/laravel/framework/src/Illuminate/Contracts/Routing/UrlGenerator.phpto()をoverwriteできれば解決しそうです。

app/Providers/AppServiceProvider.phpregister()を修正

app/Providers/AppServiceProvider.php
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $url = $this->app['url'];
        $this->app->singleton('url', function () use ($url) {
            return new CustomUrlGenerator($url);
        });
    }

app/Providers/CustomUrlGenerator.php作成(2017/3/26修正)

app/Providers/CustomUrlGenerator.php
<?php
namespace App\Providers;

use Illuminate\Routing\UrlGenerator;

/**
 * Class CustomUrlGenerator
 * @package App\Providers
 */
class CustomUrlGenerator extends UrlGenerator
{
    /**
     * Create a new manager instance.
     *
     * @param Illuminate\Routing\UrlGenerator $url
     */
    public function __construct(UrlGenerator $url)
    {
        parent::__construct($url->routes, $url->request);
    }

    /**
     * Generate an absolute URL to the given path.
     *
     * @param  string $path
     * @param  mixed $extra
     * @param  bool $secure
     * @return string
     */
    public function to($path, $extra = [], $secure = null)
    {
        // First we will check if the URL is already a valid URL. If it is we will not
        // try to generate a new one but will simply return the URL as is, which is
        // convenient since developers do not always have to check if it's valid.
        if ($this->isValidUrl($path)) {
            return $path;
        }

        $scheme = $this->getScheme($secure);

        $extra = $this->formatParameters($extra);

        $tail = implode('/', array_map(
            'rawurlencode', (array) $extra)
        );

        // Once we have the scheme we will compile the "tail" by collapsing the values
        // into a single string delimited by slashes. This just makes it convenient
        // for passing the array of parameters to this URL as a list of segments.
        
        // Original
        //$root = $this->getRootUrl($scheme);
        $root = 'http://example.co.jp';

        if (($queryPosition = strpos($path, '?')) !== false) {
            $query = mb_substr($path, $queryPosition);
            $path = mb_substr($path, 0, $queryPosition);
        } else {
            $query = '';
        }

        return $this->trimUrl($root, $path, $tail).$query;
    }
}

まとめ

これで__url(), redirect()__を無事プロキシサーバを通す前のURLで取得できました。

$root = 'http://example.co.jp'; は少し雑かもしれませんが、現時点ではこれで問題は特に起きていません。
getRootUrl()に手をいれるのもありかも知れません。

上記を行わずともプロキシサーバを通す前のURLを取得する方法がありましたら、教えていただければ幸いです。:bow_tone1:

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?