Install Laravel 5 app in subdirectory with htacces

2019-02-21 12:16发布

问题:

The Setup

I am trying to install a laravel 5 app in this directory on my server:

public_html/myapp/

And I want it to be accessed at this URL:

http://www.example.com/myapp/

I have created this .htaccess rule and placed it in the myapp folder in order to redirect requests :

RewriteEngine on
RewriteRule ^(.*)$ public/$1 [L]

Problem:

In my browser when I try to access the app I get redirected URLs like:

  • http://www.example.com/myapp/public/index.php
  • http://www.example.com/myapp/public/index.php/dashboard

instead of nice pretty URLs like:

  • http://www.example.com/myapp/
  • http://www.example.com/myapp/dashboard

What do I need to change in my .htaccess file to get proper URLs working?


Update: The laravel app can be moved elsewhere if needed, as long as the desired URL structure above (with the app accessible at example.com/myapp/) can be achieved.

Update: When I try to access example.com/myapp/dashboard I receive the following error message in the browser: NotFoundHttpException in compiled.php line 7793: with a stack trace that starts with:

in compiled.php line 7793
at RouteCollection->match(object(Request)) in compiled.php line 7066
at Router->findRoute(object(Request)) in compiled.php line 7038
at Router->dispatchToRoute(object(Request)) in compiled.php line 7030
at Router->dispatch(object(Request)) in compiled.php line 1989
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))

Update: The following .htaccess file is located in the public folder:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

</IfModule>

回答1:

What you can do is use a symlink.

  1. Place your laravel app somewhere else (outside the public_html folder)
  2. Create a symlink of your app's public folder inside the public_html folder

    cd /path/to/your/public_html

    sudo ln -s /path/to/your/laravel_app/public myapp

You can read more about symlinks here.



回答2:

You can easily achieve this by adding additional .htaccess file in the myapp folder (this will redirect all of your requests in myapp folder to the public as it should):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

You should also modify the .htaccess in your myapp/public directory, like this:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On    
    RewriteBase /myapp/

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule . index.php [L]
</IfModule>

The change here is that you rewrite the base path RewriteBase /myapp/



回答3:

This example should work for following cases:

  • Regular domain: http://example.com
  • Subdomain: http://myapp.example.com
  • Subfolder: http://example.com/myapp

Follow these steps:

  1. Move everything from myapp/public folder to myapp/ folder
  2. Open myapp/index.php and update bootstrap paths to require __DIR__.'/bootstrap/
  3. Open .env and update to your base url like: APP_URL=http://example.com/myapp
  4. Update paths in all views and layout (also in the code if you have any) to use base url, like this: src="{{URL::to('/js/app.js')}}"

It's always recommended to separate public folder from the rest of your app. You can add some protection to Laravel folders by adding .htaccess files inside them that will contain "Deny from all".



回答4:

I was having the same issue, but with the RewriteBase parameter it was possible to fix it.

This is my .htaccess:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On
    RewriteBase /my_app/

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>