CakePHP3 をドキュメントルート外にインストールする


先日、 [初めてCakePHP3をインストール](http://qiita.com/ina_ryu/items/50d1e458af640aa13fc3 "CakePHP3をインストール") する記事を投稿しました。
CakePHP3 のインストール自体は [Composer](https://getcomposer.org/ "Composer") を使用すれば簡単にインストールできることがわかりました。
ただし、ドキュメントルート内にインストールしただけで、CakePHP3 のプログラム群をドキュメントルート内に置くのはあまり好ましくない。。
そこで今回は CakePHP3 をドキュメントルート外に設置し、開発・運用できるようにインストールしてみたいと思います。
**※ この記事での CakePHP3 のインストール方法では、2017年2月4日時点でインストールされる CakePHP3 のバージョンは `3.3.13` でしたので、CakePHP 3.3.13 を元に記事を作成しています。バージョンの違いによって設定方法など変更になる場合があるのご注意下さい。**

## サーバ環境

* CentOS 7.2
* PHP 5.6.26
* Apache 2.4.6
* Composer 1.3.2

今回は、Vagrant を使用して上記の構成で仮想環境を構築しました。

## ドキュメントルートについて

```
[vagrant@localhost ~]$ tree -d -L 2 /vagrant/
/vagrant/
	├── html    <- ドキュメントルート
	└── program
```
**`/vagrant/html` ディレクトリをドキュメントルートとし、 CakePHP3 は `/vagrant/program` ディレクトリ内にインストールする想定で作業を行います。**

## 作業手順

### 1. CakePHP3 インストール

まずは、 CakePHP3 をインストールしないと始まりません。 下記の手順で `/vagrant/program` ディレクトリに CakePHP3 をインストールします。

```
# 1. /vagrant/program ディレクトリに移動
[vagrant@localhost ~]$ cd /vagrant/program/

# 2. composer create-project --prefer-dist cakephp/app cakephp を実行して CakePHP3 をインストールする
[vagrant@localhost program]$ composer create-project --prefer-dist cakephp/app cakephp
```

`Composer` にパスが通ってない場合は、 `php composer.phar create-project --prefer-dist cakephp/app cakephp` を実行して下さい。
これで CakePHP3 のインストールは完了しました。インストールが完了すると以下のようなディレクトリ構成になります。

```
[vagrant@localhost ~]$ tree -d -L 3 /vagrant/
/vagrant/
	├── html
	└── program
    	└── cakephp
        	├── bin
        	├── config
        	├── logs
        	├── plugins
        	├── src
        	├── tests
        	├── tmp
        	├── vendor
        	└── webroot
```

### 2. `webroot` ディレクトリ内のファイルやディレクトリを `/vagrant/html` ディレクトリにコピー

CakePHP3 のインストールが完了したら `/vagrant/program/cakephp/webroot` ディレクトリ内のファイルやディレクトリを `/vagrant/html` ディレクトリにコピーします。

```
# 下記コマンドで /vagrant/program/cakephp/webroot ディレクトリ内のファイルやディレクトリを /vagrant/html ディレクトリにコピーする
[vagrant@localhost ~]$ cp -apvr /vagrant/program/cakephp/webroot/* /vagrant/program/cakephp/webroot/.[^.]* /vagrant/html/
```

`webroot` ディレクトリ内のファイルやディレクトリを無事にコピー出来たなら以下のようなディレクトリ構成になります。

```
[vagrant@localhost ~]$ tree -d -L 3 /vagrant/
/vagrant/
	├── html
	│   ├── css
	│   ├── font
	│   ├── img
	│   └── js
	└── program
    	└── cakephp
        	├── bin
        	├── config
        	├── logs
        	├── plugins
        	├── src
        	├── tests
        	├── tmp
        	├── vendor
        	└── webroot
```

### 3. index.php を編集

`/vagrant/program/cakephp/webroot` ディレクトリ内のファイルやディレクトリのコピーが完了しただけでは正常に動作しません。 `index.php` ファイル内に記述されている内容を編集しなければファイルを読み込むことが出来ずエラーになります。
そこでエラーにならないように `/vagrant/html/index.php` の27行目と33行目あたりのファイルパスとディレクトリパスを以下のように書き換えます。

```php
<?php
/**
 * The Front Controller for handling every request
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @since         0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
// for built-in server
if (php_sapi_name() === 'cli-server') {
    $_SERVER['PHP_SELF'] = '/' . basename(__FILE__);

    $url = parse_url(urldecode($_SERVER['REQUEST_URI']));
    $file = __DIR__ . $url['path'];
    if (strpos($url['path'], '..') === false && strpos($url['path'], '.') !== false && is_file($file)) {
        return false;
    }
}

/** 27行目 ここの require 部分を以下の1行を追加し書き換える **/
// require dirname(__DIR__) . '/vendor/autoload.php';
// cakephp までのパスを生成
$cakephpRoot = realpath(dirname(__FILE__) . '/../program/cakephp');
require $cakephpRoot . '/vendor/autoload.php';

use App\Application;
use Cake\Http\Server;

// Bind your application to the server.
// $server = new Server(new Application(dirname(__DIR__) . '/config'));

/** 33行目 ここの config ディレクトリまでのパスを以下に書き換える **/
$server = new Server(new Application($cakephpRoot . '/config'));

// Run the request/response through the application
// and emit the response.
$server->emit($server->run());
```

## 表示確認

上記の作業手順通りに作業をおこなって、ブラウザからアクセスして以下のように表示されれば無事に CakePHP3 をドキュメントルート外にインストールすることに成功です。
![CakePHP3.png](https://qiita-image-store.s3.amazonaws.com/0/13180/9e59a944-69dd-ce92-ce6c-6fea0e26d396.png "CakePHP3.png")

**もし CakePHP3 をドキュメントルート外に設置したい方は参考にしてみてください。**