Laravel project next to Wordpress project (in publ

2019-02-16 06:34发布

问题:

I have a Laravel project in my public_html folder. The domain is for example domain.com My .htaccess file (in public_html folder) is like this:

<IfModule mod_rewrite.c>
    RewriteEngine On

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

There are the following routes:

  • api/licenseplate
  • api/calendar
  • auth/login
  • admin/settings
  • admin/appointments
  • appointment
  • ...

So an example of a URL is http://domain.com/appointment.

Now I would like to have a wordpress website on domain.com. So when you go to domain.com you see the wordpress website. But I also want to have the urls like /appointment of my laravel project.

What's the easiest and cleanest way to do this?

回答1:

You can create symlink to Wordpress public directory in Laravel folder. For example, wp:

/var
     /www
         /laravel
             /public
                 /wp #(symlink to -> /var/www/wordpress/public_html)
                 index.php
                 .htaccess
         /wordpress
             /public_html
                 index.php
                 .htaccess

And describe Laravel routes in .htaccess. Example of code of /var/www/laravel/public/.htaccess:

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

    RewriteEngine On

    RewriteCond %{ENV:REDIRECT_FINISH} .
    RewriteRule ^ - [L]

    # Laravel

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_FILENAME} !.*\.php$
    RewriteRule ^(.*)$ $1 [E=FINISH:1,L]

    RewriteCond %{REQUEST_URI} ^/(api/licenseplate)(\?.*|$) [OR]
    RewriteCond %{REQUEST_URI} ^/(api/calendar)(\?.*|$) [OR]
    RewriteCond %{REQUEST_URI} ^/(admin/settings)(\?.*|$) [OR]
    RewriteCond %{REQUEST_URI} ^/(admin/appointments)(\?.*|$) [OR]
    RewriteCond %{REQUEST_URI} ^/(appointment)(\?.*|$) [OR]
    RewriteCond %{REQUEST_URI} ^/(auth/login)(\?.*|$)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [E=FINISH:1,L]

    # Wordpress

    RewriteCond %{REQUEST_URI} !^/wp
    RewriteRule ^(.*)$ /wp/$1 [E=FINISH:1,L]

</IfModule>

Code of /var/www/wordpress/public_html/.htaccess (just copy of your wordpress .htaccess):

# BEGIN WordPress

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

# END WordPress


回答2:

Server Structure

.htaccess files provide a way to make configuration changes on a per-directory basis. This means that you only need to direct the request to the directory that will have rules for how to best process the request. Thus you will leave the .htaccess files that came with both Laravel and WordPress in their directories. Just create another one for the parent directory that holds them both.

The below assumes that the full path of public_html is /var/www/public_html.

Folder Structure

/var/www/public_html/laravel
/var/www/public_html/wp

/var/www/public_html/.htaccess

# Limit Access To Laravel Public Folder
<Directory "/var/www/public_html/laravel">
    Order Deny,allow
    Deny from all
</Directory>

<Directory "/var/www/public_html/laravel/public">
    Allow from all
</Directory>

# Rewrite Requests
<IfModule mod_rewrite.c>

    RewriteEngine On

    # Do Not Rewrite Directory And File Requests
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^(.*)$ $1 [L]

    # Rewrite Laravel Routes
    RewriteCond %{REQUEST_URI} api/licenseplate [OR]
    RewriteCond %{REQUEST_URI} api/calendar [OR]
    RewriteCond %{REQUEST_URI} admin/settings [OR]
    RewriteCond %{REQUEST_URI} admin/appointments [OR]
    RewriteCond %{REQUEST_URI} appointment [OR]
    RewriteCond %{REQUEST_URI} auth/login
    RewriteRule ^(.*)$ laravel/public/$1 [L]

    # Rewrite To WordPress For Everything Else
    RewriteRule ^(.*)$ wp/$1 [L]

</IfModule>

Application Settings

Both Laravel and WordPress have ways to generate links to their assets (images, CSS, JavaScript).

WordPress is built to easily allow for installation to a sub-directory so you only need to change the WordPress Address and Site Address on the General Settings Screen.

Laravel assumes that it is installed to the top directory. The asset() helper is used to generate paths to asset files. So you will need to override the default function with one of your own. Here is how:

Create app/helpers.php with these contents

/**
 * Generate an asset path for the application
 * with the installation sub-directory 
 * prepended to the path.
 *
 * @param  string  $path
 * @param  bool    $secure
 * @return string
 */
function asset($path, $secure = null)
{
    $path = ltrim($path, '/');
    $dir = basename(dirname(__DIR__)) . '/public';
    $url = app('url')->asset($path, $secure);
    return str_replace($path, $dir . '/' . $path, $url);
}

Add app/helpers.php to the autoload process by editing composer.json

"autoload": {    
    //...
    "files": [
        "app/helpers.php"
    ]
},

If you have command line access, update PHP composer

composer dump-autoload


回答3:

Here is an approach that I took when encountered a similar situation. Install your wordpress in public_html directory and preferably place your laravel application with the WP directory:

wp-admin/  
wp-content/  
wp-includes/  
... other wordpress files ...
app/ <-- laravel application  
     |-> app/
     |-> bootstrap/
     |-> config/
     |-> public/
     |-> ... other laravel files and directories ...

Now to get the WordPress functions available within your Laravel application, include wp-load.php within your Laravel installation and then you can use the enqueueing functions from WordPress to load the assets you need.

Best approach is to follow the Laravel Service Provider Architecture. Write a service provider for including the wp-load.php and use the boot function to load assets:

// app/Providers/WordPressServiceProvider.php

class WordPressServiceProvider extends ServiceProvider {

    protected $bootstrapFilePath = '../../wp-load.php'; // Adjust ur path

    public function boot() {
        // Load assets
        wp_enqueue_style('app', '/app/public/app.css'); // Adjust ur path
    }

    public function register() {
        // Load wordpress bootstrap file
        if(File::exists($this->bootstrapFilePath)) {
            require_once $this->bootstrapFilePath;
        } else throw new \RuntimeException('WordPress Bootstrap file not found!');
    }

}

And add the service provider to your laravel app config, config/app.php:

 /* ... */
   'providers' => [
        // ...

        /*
         * Application Service Providers...
         */
        // ...
        App\Providers\WordPressServiceProvider::class,

Now we have access to our WordPress functions within Laravel and can alter laravel views to something like:

{!! get_header() !!}
        <div class="container">
            <div class="content">
                <div class="title">Laravel 5</div>
                <div class="quote">{{ Inspiring::quote() }}</div>
            </div>
        </div>
{!! get_footer() !!}

Your wordpress site should be accessible at www.urdomain.com and laravel app under url www.urdomain.com/app/appointment or adjust you .htaccess if you wish a different URL pattern. Hope this help.