[PHP]LaravelのTask Scheduler(Cron)でPHPの場所やバージョンを指定して実行する

LaravelにはCronタスク管理機能が有り、一つのCronジョブを「* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1」のように指定しておくとスケジューラーが実行されたタイミングで条件に合うタスクが自動的に実行されます。
laravel 5.2 の場合 app\Console\Kernel.php で管理ができ、 直接 $schedule->exec() でコマンドを実行する他、$schedule->command() を使って作成済みのコマンドを実行することも出来ます。
protected function schedule(Schedule $schedule)
{
    $schedule->command('emails.send')->cron('0 */3 * * *');
}

上記の例では cron() で指定された時間にコマンドが実行されます。表記は「分 時 日 月 曜日」の順で、「*」は「すべて」、「5」は5の時に、「*/5」は毎を表し、分に使うと5分おきにという意味になります。曜日は 0〜7 で日曜日から始まります。「1-3」のようにすると範囲を指定でき、「1,3」のように区切ると複数指定できます。指定した時間にスケジューラー自体が実行されている必要があるため、スケジューラーを1時間おきに実行するにCronがセットされている時、Laravel側に5分おきのコマンドを設定しても1時間おきにしか実行されません。

条件に一致した時、「/usr/bin/php artisan コマンド名」のような形で実行されます。

しかし、Xserver での「/usr/bin/php」は執筆時点では PHP 4.3.9 を指すため、バージョンが古すぎて正しく実行されません。
バージョンを変更して実行するためには「/usr/bin/php5.6」や「/usr/bin/php7.0」を指定する必要があります。

変更する場合は .env ファイル内に PHP_PATH という定数を新たに書き加えます。

PHP_PATH=/usr/bin/php7.0

これによってタスクスケジューラーからの実行時にも適切なバージョンの PHP バイナリが使われます。

[PHP]Laravelのビューで@includeしているパーツに値を渡す(View Composers)

多くのサイトはヘッダー、メイン、サイドカラム、フッターなどのパーツに分かれており、それぞれのパーツはページが変わってもメイン以外はほぼ同じの内容を表示しています。
例えばブログの場合、サイドバーに表示される内容は新着記事の一覧やカテゴリー一覧などが表示されていることが多いと思います。

通常 Laravel 5.0 では次のようにしてコントローラーから表示に必要な変数を受け取ります。

public function index()
{
    $data = array();
    $data['categories'] = Post::Category->all();
    return view('index', $data);
}

配列のキー部分が変数名になるので、Blade ビューでは「$categories」にカテゴリー一覧が格納されることになります。

しかし、サイトのページが1つしかないならこの方法でも構いませんが、実際には多くのページとそれに対応するコントローラがあり、サイドバーに表示するためだけに同じ記述をすべてのビューコントローラーに繰り返し書くのは良い方法ではありません。

そこで、View Composers を使い、それぞれパーツに対応するコントローラを作成することで、そのパーツが読み込まれるたびに必要な変数が自動的に用意されるようします。

まずはプロバイダー「ComposerServiceProvider」を作成します。
「app/Providers/ComposerServiceProvider.php」となるようにファイルを作成して下さい。
内容は次のようにします。

<?php namespace App\Providers;

use View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider {

	public function boot()
	{
		//
	}

	public function register()
	{
		//
	}

}

boot() にビューに対応する処理を記述します。
方法は2種類あり、クロージャーを使ってこのファイルに直接書く方法と、コントローラーを指定して別ファイルに詳細を記述する方法です。
まずは単純にクロージャーを使ってサイドバーテンプレート「views/sidebar.blade.php」が読み込まれた際にカテゴリー一覧が取得できるようにしてみます。

public function boot()
{
    View::composer('sidebar', function($view)
    {
        $view->categories = Category::all();
    });
}

これでビューの $categories にすべてのカテゴリーが格納されます。
第一引数にはテンプレートファイルを指定します。もしテンプレートファイル sidebar.blade.php が layouts フォルダなどに入っている場合は第一引数を「layouts.sidebar」とします。
例では Category モデルを使っているのでファイルの最初に「use App\Category;」の記述を忘れないようにして下さい。

このままでは ComposerServiceProvider.php は読み込まれないので、「app/config/app.php」の providers に「App\Providers\ComposerServiceProvider」を追加します。
コンソールで「composer dump-autoload」とすると適用されます。

次に、コントローラーを指定して別ファイルで同じ処理をしてみます。
コントローラーは「app/Http/Controllers/ViewComposers/SidebarComposer.php」となるようにフォルダとファイルを作ります。
内容は次のとおりです。

<?php namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;
use App\Category;

class SidebarComposer {

	protected $categories;

	public function __construct()
	{
		$this->categories = Category::all();
	}

	public function compose(View $view)
	{
		$data = array();
		$data['categories'] = $this->categories;
		$view->with($data);
	}

}

継承しやすいようにコンストラクタでカテゴリー一覧を取得しています。
compose() でビューに変数を渡しています。

コントローラーの作成が済んだら ComposerServiceProvider.php に戻り、boot() を次のようにします。

public function boot()
{
    View::composer('sidebar', 'App\Http\ViewComposers\SidebarComposer');
}

第2引数には先ほど作ったコンポーザークラスへのパスを記述します。
これでパーツが読み込まれた際に自動的に SidebarComposer での処理が行われます。

処理が複雑な場合はコントローラーに、単純な場合はクロージャーに書くなど、目的に応じて使い分けることになると思います。

[PHP]WindowsでHomesteadを使ってLaravel5開発環境を作る(2/2)

前回の続き)

前回の記事で Vagrant に Homestead をインストールし、Windows から仮想OSを起動するところまで行いました。次は仮想環境に Laravel アプリケーションを作成してみます。

Homestead にはすでに Web サーバーや MySql、Composer などの環境が揃っています。SSH でログインすればすぐにそれらを利用できます。

cd ~/Homestead
vagrant ssh

これだけで SSH ログインが可能です。もし「vagrant ssh」を使わずに使い慣れたツールからログインするなら次の設定でもログインできます。

IP: 127.0.0.1
Port: 2222
User: vagrant
Password: vagrant

前回「C:\Users\ユーザー名\Code\Laravel\public\index.php」にテスト用のファイルを置いて動作を確認しました。今回は実際に Laravel プロジェクトを「/Home/Code/Laravel」に作ってみます。動作テストで作った Laravel フォルダは不要なので削除しておいて下さい。(Windows側からでも構いません)

rm -r ~/Code/Laravel

プロジェクト作成は仮想環境側から行います。書式は「composer create-project laravel/laravel プロジェクト名 –prefer-dist」です。

cd ~/Code
composer create-project laravel/laravel Laravel --prefer-dist

無事にインストールが済んだらブラウザで「http://homestead.app」にアクセスしてみます。正常なら Laravel の初期画面が表示されているはずです。

laravel5

これでプロジェクト作成は完了です。Windows 側からもホームの Code フォルダに同じプロジェクトフォルダが存在するのが確認できるはずです。


サイトの追加

サイトが一つ出来たので、さらにもう一つサイトを追加してみます。
今回は「http://sample.homestead.app」にアクセスしたら「/home/vagrant/Code/sample/public」の内容が表示されるようにしてみます。
コマンドはこちらです。SSH ログインした仮想環境側で実行して下さい。

serve sample.homestead.app /home/vagrant/Code/sample/public

あとは Windows に戻り、「C:\Windows\System32\drivers\etc\hosts」に管理者権限で追記します。

192.168.10.10    sample.homestead.app

あとは先程と同様に Laravel プロジェクトを仮想環境上に作成します。

cd ~/Code
composer create-project laravel/laravel sample --prefer-dist

これで Code フォルダ内に sample が作られ、「http://sample.homestead.app」からアクセスできるようになりました。


データベース管理ツール

データベースの操作はコマンドでもできますが、phpMyAdmin などの GUI ツールがあると便利です。まずは apt-get で仮想環境にインストールしてみます。

sudo apt-get install phpmyadmin

ユーザー vagrant のパスワードは「vagrant」です。sudo で必要ならそのように入力して下さい。phpmyadmin は「/usr/share/phpmyadmin/」にインストールされます。先ほどと同じように serve コマンドを使って「http://phpmyadmin.app」のアドレスから「/usr/share/phpmyadmin/」にアクセスできるようにします。

serve phpmyadmin.app /usr/share/phpmyadmin/

Windows の hosts にも次の行を書き加えます。

192.168.10.10    phpmyadmin.app

これで「http://phpmyadmin.app」から phpMyAdmin ページに移動できます。
mysql のユーザー名 homestead、パスワード secret でログイン可能です。

phpMyAdmin の代わりに Windows のアプリケーションを使って管理することも出来ます。代表的な管理ツールとして、公式の MySQL Workbench などが有ります。
基本的な設定は次のようにします。

Host: 127.0.0.1
Port: 33060
Username: homestead
Password: secret

/etc/mysql/my.cnf の bind-address の設定によっては Host の IP が変わるかもしれませんが、こちらの環境では上記で接続出来ました。