PHP
laravel5.4

Laravelでpublicフォルダを移動する

More than 1 year has passed since last update.

概要

publicフォルダを通常の場所から移動させないといけない要件があり、
その時に調べた内容をメモしておく。

publicフォルダの構成

通常、下記のような構造になっている

フォルダ構造
┗ laravel
   ┣ app
   ┗ public

これを、下記のようにするだけであればシンボリッックリンクを貼る

ターミナル
$ ln -s laravel/public public_html

だけで対応可能と思われる。

フォルダ構造
┣ laravel
┃  ┣ app
┃  ┗ public
┃
┗ public_html -> laravel/public/

フォルダ階層を変更する目的

ただし、他のフレームワークなどが混在しているなど、
シンボリックリンクを貼ることが困難な場合もある。

フォルダ構造
┣ cakephp2
┣ codeigniter2
┣ fuelphp1.7
┣ laravel5.4
┣ wordpress
┗ public_html -> laravel/public/
   ┣ .htaccess
   ┣ article
   ┣ index.php
   ┣ index_cake.php
   ┣ index_codeigniter.php
   ┣ index_fuel.php
   ┗ index_laravel.php

こんな構造はあまり運用したくないですが、大人の事情(笑)で、
新・旧フレームワークが一時的に混在する場合もあるかと思います。

そういった場合に、publicフォルダを移動せざるを得ないので移動を検討する。

フォルダ階層の移動

物理的にフォルダを移動

mvコマンドにてpublicフォルダをリネームしながら移動する

$ mv ./laravel/public ./public_html

index.phpファイルのパスを修正

「./public_html/index.php」内のパスを2つ修正する

Register_The_Auto_Loader
# require __DIR__.'/../bootstrap/autoload.php';
require __DIR__.'/../laravel/bootstrap/autoload.php';
Turn_On_The_Lights
# $app = require_once __DIR__.'/../bootstrap/app.php';
$app = require_once __DIR__.'/../laravel/bootstrap/app.php';

公開フォルダのパスのズレを修正

laravel内で公開フォルダ(public)のパスを取得するものがある。
そのパスが、デフォルトのままとなっており、下記のような処理で不具合が発生する。

不具合

確認できているだけでも下記のような不具合が発生する

public_path関数のパスがおかしい

echo public_path();
結果 ****/laravel/public

サーバが起動しない

$ php artisan serve

  [ErrorException]
  chdir(): No such file or directory (errno 2)

改善方法

app/Applicaiton.phpを作成し、Applicaitonクラスの「publicPath」メソッドを上書きする。

app/Applicaiton.php
<?php

namespace App;

class Application extends \Illuminate\Foundation\Application
{
    public function publicPath()
    {
        return dirname($this->basePath) . DIRECTORY_SEPARATOR . 'public_html';
    }
}

上記ファイルを適用する

laravel/bootstrap/app.php
# $app = new Illuminate\Foundation\Application(
$app = new App\Application(
    realpath(__DIR__.'/../')
);

また、「server.php」にもパスがあるので修正

laravel/app/server.php
# if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
if ($uri !== '/' && file_exists(dirname(__DIR__).'/public_html'.$uri)) {
    return false;
}

# require_once __DIR__.'/public/index.php';
require_once dirname(__DIR__).'/public_html/index.php';

以上です。

参考サイト