Laravel 路由 - 相同路由的自定义域

Posted

技术标签:

【中文标题】Laravel 路由 - 相同路由的自定义域【英文标题】:Laravel routing - custom domain for same routes 【发布时间】:2016-02-20 02:57:18 【问题描述】:

假设我有这些路线:

http://mylaravelapp.com/slug
http://mylaravelapp.com/slug/page
http://mylaravelapp.com/slug/another/custom_slug

我希望从自定义域访问相同的路由,指向我的 laravel 应用程序的 IP。像这样:

http://customdomain.com/
http://customdomain.com/page
http://customdomain.com/another/custom_slug

这是如何以最好的方式实现的?

我现在的丑陋方式

我已经制定了自己的解决方案,这很丑陋。它涉及大量重复代码和令人讨厌的控制器。这就是我实现它的方式:

routes.php

/**
 * Serving from my app:
 */

    Route::get('/slug', ['uses' => 'MyController@show', 'as' => 'page']);
    Route::get('/slug/page', ['uses' => 'MyController@page', 'as' => 'page.page']);
    Route::get('/slug/another/custom_slug', ['uses' => 'MyController@another', 'as' => 'page.another']);

/**
 * Serving from custom domain
 */

    Route::group(['domain' => 'custom_domain.tld'], function($domain) 
        Route::get('/', ['uses' => 'MyController@show', 'as' => 'page.customdomain']);
        Route::get('/page', ['uses' => 'MyController@page']);
        Route::get('/another/custom_slug', ['uses' => 'MyController@another']);
    );

MyController.php

class MyController extends Controller 
    /**
     * Find by slug or custom domain
     * 
     * @return [type]             [description]
     */
    public function findBySlugOrDomain($domain, $domain_tld, $slug) 
        if($domain && $domain_tld) 
            /**
             * Find by custom domain name
             */

                $page = $this->page->findByDomain($domain.'.'.$domain_tld)->firstOrFail();
         else 
            /**
             * Find by slug (no custom domain)
             * @var [type]
             */

                $page = $this->page->findBySlugOrFail($slug);
        

        return $page;
    

    /**
     * Display the specified resource.
     */

    public function show($domain = null, $domain_tld = null, $slug = null, $type = 'home', $custom_slug = null)
    

        /**
         * Cases
         */

            if(str_contains(config('app.url'), $domain . '.' . $domain_tld)) 
                /**
                 * Incoming request to HOME (i.e. http://mylaravelapp.com/)
                 */

                    return app('App\Http\Controllers\HomeController')->index();
             elseif($domain && !$domain_tld) 
                /**
                 * Request to page on http://mylaravelapp.com/slug/page
                 */

                    $slug = $domain;
                    $domain = null;
                    $domain_tld = null;
             else if($domain && $domain_tld && !$slug) 
                /**
                 * Request to page with slug on http://mylaravelapp.com/slug/another/custom_slug
                 */

                    $slug = $domain;
                    $custom_slug = $domain_tld;

                    $domain = null;
                    $domain_tld = null;

             else if($domain && $domain_tld && $slug) 
                /**
                 * Request to page on http://customdomain.com/
                 */


             else if($domain && $domain_tld && $slug) 
                /**
                 * Request to page with slug on http://customdomain.com/another/custom_slug
                 */

                    $custom_slug = $slug;
            

        $page = $this->findBySlugOrDomain($domain, $domain_tld, $slug);

        switch ($type) 
            case 'page':
                return view('page.page', compact('page'));
            break;

            case 'another':

                $anotherPage = $page->another()->whereSlug($custom_slug)->firstOrFail();

                return view('page.another', compact('page', 'anotherPage'));
            break;

        

        return view('page.home', compact('page', 'js_variables'));
    

    /**
     * Page: page
     * 
     * http://mylaravelapp.com/slug/page
     * 
     * http://customdomain.com/page
     */

        public function showPage($domain = null, $domain_tld = null, $slug = null) 
            return $this->show($domain, $domain_tld, $slug, 'gallery');
         

    /**
     * Page: another
     * 
     * http://mylaravelapp.com/slug/another/custom_slug
     * 
     * http://customdomain.com/another/custom_slug
     */

        public function showAnother($domain = null, $domain_tld = null, $slug = null, $custom_slug = null) 
            return $this->show($domain, $domain_tld, $slug, 'page', $custom_slug);
        

这种方式的局限性:

大量重复代码 每次添加新路线,都需要更新两次 长而难以理解的控制器 控制器增加了很多新的复杂性,如果我们需要,比如 URL 中的两个自定义 slug (http://mylaravelapp.com/slug/another/custom_slug/third_slug)

【问题讨论】:

只是个傻问题,你有没有看路由,为什么不尝试将页面路由放在第一个slug路由之上 你能详细说明这个问题吗? 抱歉,忘记我的问题。我在想你的路线放置(顺序)有问题。 为什么customdomain.com/page 不需要路由中的slug? 因为在我的域中,slug 引用了特定页面。访问自定义域时,无需将slug引用为“自定义域”,引用具体页面。 【参考方案1】:

如果应用程序相同,您可以使用服务器虚拟主机。

在 Ubuntu + nginx 中,您可以使用this recipe 来指导您。

您既可以创建两个虚拟主机,也可以添加,例如在 Nginx 中,这种重定向:

server 
        #implemented by default, change if you need different ip or port
        #listen *:80 | *:8000;
        server_name customdomain.com;
        return 301 $scheme://mylaravelapp.com$request_uri;

会发生什么变化:

http://customdomain.com/
http://customdomain.com/page
http://customdomain.com/another/custom_slug

对此,自动:

http://mylaravelapp.com/
http://mylaravelapp.com/page
http://mylaravelapp.com/another/custom_slug

Apache 的另一种方法。

【讨论】:

以上是关于Laravel 路由 - 相同路由的自定义域的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 带有模板的自定义插件

是否可以将 Laravel 策略应用于路由和自定义函数?

Lumen/Laravel - 使用自定义路由器

WPF 自定义路由事件问题

我的自定义身份验证 react-router 路由有啥问题?

为啥带有 useContext 触发器的自定义路由 HOC 会重新渲染?