php 2大 web フレームワークの徹底比較!

82
PHP 2大 web フレームワークの 徹底比較! サポーターズ勉強会@株式会社ウィルゲート Room0

Upload: shohei-okada

Post on 21-Jan-2018

6.061 views

Category:

Software


0 download

TRANSCRIPT

PHP 2大web フレームワークの

徹底比較!

サポーターズ勉強会@株式会社ウィルゲート Room0

池添 誠(いけぞえまこと)

• 開発グループ コンテンツユニット所属

• 2015年にウィルゲートに新卒入社(3年目)

• クラウドソーシングサービスのサグーワークスの開発

• 今日は CakePHP 担当

2

自己紹介

池添 誠(いけぞえまこと)

• 開発グループ コンテンツユニット所属

• 2015年にウィルゲートに新卒入社(3年目)

• クラウドソーシングサービスのサグーワークスの開発

• 今日は CakePHP 担当

3

自己紹介

テストコードいいぞ

岡田 正平(おかだしょうへい)

• 開発グループ ソリューションユニット所属

• 2015年にウィルゲートに新卒入社(3年目)

• webコンサルティングツールの開発

• 今日は Laravel 担当

4

自己紹介

岡田 正平(おかだしょうへい)

• 開発グループ ソリューションユニット所属

• 2015年にウィルゲートに新卒入社(3年目)

• webコンサルティングツールの開発

• 今日は Laravel 担当

5

自己紹介

Vue.js いいぞ

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

6

目次

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

7

目次

• もともと CakePHP のみを利用していた

• オフショア開発をやっていた時代にベトナムの開発チームからLaravel を使いたいという要望が出て採用

• 以降、ソリューションチームでは Laravel が主流に

• 1つ1つのシステムが小粒なので毎回違う技術を選べる

• Slim や FuelPHP を採用したシステムも

• 「チーム移動時のコスト」 < 「多様性により得られる恩恵」

• 同じPHP なので、そこまで大きなギャップではない

• 新たな知見を得られやすい

8

背景 - なぜフレームワークが混在しているか

• サグーワークスのリニューアル(2017年1月)

• CakePHP 1.3 → CakePHP 3.2 にバージョンアップ

• https://www.wantedly.com/companies/willgate2/post_articles/70451

• 新しいコンサルティングツール開発(現在開発中)

• Laravel 5.4 を採用

• 社内に双方の最新メジャーバージョンの知見

• → 「比較・考察は価値のある情報になるのでは?」

9

背景 – 今回の勉強会開催の理由

10

11

徹底比較!!

注意:対象バージョン

• 特に断りのない限り、メインのプロダクトで採用されている

を対象とします。

※2017年9月13日現在の最新バージョンは CakePHP 3.5 および Laravel 5.5

CakePHP 3.2 Laravel 5.4

12

注意:スライドの内容

• 公式サイト等からの引用については枠線で囲い斜字体で表記します

例)

• 実際に利用したうえでの私見や考察には「【私見】」や「【考察】」と明記します

13

The Model layer represents the part of your application that implements the

business logic.

モデル層はビジネスロジックを実装するアプリケーションの部品を表します。

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

14

目次

• ディレクトリ

15

Model 層の比較

The Model layer represents the part of your application that implements the

business logic.

モデル層はビジネスロジックを実装するアプリケーションの部品を表します。

.├── src/: :│ ├── Model/│ │ ├── Behavior/│ │ ├── Entity/│ │ └── Table/: :

• CakePHP ORM

• 3つの概念に分かれる

• Table

• Entity

• Behavior

16

Model 層の比較

The CakePHP ORM borrows ideas and concepts from both ActiveRecord and

Datamapper patterns. It aims to create a hybrid implementation that

combines aspects of both patterns to create a fast, simple to use ORM.

CakePHP の ORM はアクティブレコードやデータマッパーパターンのアイデアやコンセプトを拝借しています。 その目的は、早く作成し、シンプルに ORM を利用するという2つの利点を混成させるためです。

• Table

• Entity

17

Model 層の比較

They allow you to save new records, modify/delete existing ones, define

relations, and perform bulk operations.

これらを利用することで、新しいレコードを保存したり、 既存データの編集/削除、リレーションの定義、そして一括処理ができます。

Entities represent individual records and allow you to define row/record level

behavior & functionality.

エンティティーは、個々のレコードを意味し、 行/レコードレベルの振る舞いや機能の定義を可能にします。

• Behavior

• 【考察】

• 処理の種類ごとに記述する場所が規約で決められている

• どこに書くべきか、悩まずに記述できる

• 組み合わせやすい分類になっている

• 共通処理は Behavior

• テーブル単位の操作の Table

• レコード単位の操作は Entity

18

Model 層の比較

Behaviors provide a convenient way to package up behavior that is common

across many models.

ビヘイビアーは、多くのモデルで共通の振る舞いをまとめる便利な方法を提供します。

• “Models” のようなディレクトリは存在しない

• 【私見】意訳すると、「“models” という言葉が指す意味は人によって変わるので、開発したいモノに合わせて各々が判断した場所に置けばよい」

19

Model 層の比較

When getting started with Laravel, many developers are confused by the lack

of a models directory. However, the lack of such a directory is intentional. We

find the word "models" ambiguous since it means many different things to

many different people.

For this reason, we choose to place Eloquent models in the app directory by

default, and allow the developer to place them somewhere else if they

choose.

• 明示的に Model と言っているのは Eloquent ORM のみ

• php artisan make:model の説明「Create a new Eloquent model class」

• 【考察】

• ORM 即ち Model という意味ではない

• Eloquent model class にビジネスロジックを記述してもよい

• Eloquent model class を単なる ORM とみなし他の階層構造にビジネスロジックを記述してもよい

20

Model 層の比較

• Eloquent ORM

• 【私見】「Laravel 強み」としてよく挙げられる

• 【考察】比較的シンプルな記述ができるのが理由か

• 読み方がよく議論になる

• 【私見】では「エロクワント」と読む

21

Model 層の比較

The Eloquent ORM included with Laravel provides a beautiful, simple

ActiveRecord implementation for working with your database.

実現したいこと

• 異なるテーブルのレコード「クライアントお問い合わせ」「ユーザお問い合わせ」

• どちらも問い合わせ内容を body というカラムに格納

• 保存する前に body 内に含まれる特殊文字をHTML エンティティに変換したい

22

Model 層の比較 - コード比較 case 1

※これくらいの処理は本来、ミューテータを使えば良い

23

Model 層の比較 - コード比較 case 1

class SafeStringBehavior extends Behavior{

public function beforeSave($event, $entity, $options){

// h() -> htmlspecialchars()$entity->body = h($entity->body);

return true;}

}

class ClientContactsTable extends Table{

public function initialize(array $config){

parent::initialize($config);// SafeStringBehavior の読み込み$this->addBehavior('SafeString');

}}

// UserContractsTable も同様に記述

24

Model 層の比較 - コード比較 case 1

class SafeStringBehavior extends Behavior{

public function beforeSave($event, $entity, $options){

// h() -> htmlspecialchars()$entity->body = h($entity->body);

return true;}

}

class ClientContactsTable extends Table{

public function initialize(array $config){

parent::initialize($config);// SafeStringBehavior の読み込み$this->addBehavior('SafeString');

}}

// UserContractsTable も同様に記述する

• 共通の挙動は Behavior に記述する• 保存前実行される処理は beforeSave

関数に記述する

25

Model 層の比較 - コード比較 case 1

class SafeStringBehavior extends Behavior{

public function beforeSave($event, $entity, $options){

// h() -> htmlspecialchars()$entity->body = h($entity->body);

return true;}

}

class ClientContactsTable extends Table{

public function initialize(array $config){

parent::initialize($config);// SafeStringBehavior の読み込み$this->addBehavior('SafeString');

}}

// UserContractsTable も同様に記述する

• Table に addBehavior() を記述する

パターン1

26

Model 層の比較 - コード比較 case 1class ContactObserver{

public function saving(Model $model){

// e() -> htmlspecialchars()$model->body = e($model->body);

}}

// UserContact も同様に記述class ClientContact extends Model{}

class AppServiceProvider extends ServiceProvider{

public function boot(){

ClientContact::observe(ContactObserver::class);UserContact::observe(ContactObserver::class);

}}

パターン1

27

Model 層の比較 - コード比較 case 1class ContactObserver{

public function saving(Model $model){

// e() -> htmlspecialchars()$model->body = e($model->body);

}}

// UserContact も同様に記述class ClientContact extends Model{}

class AppServiceProvider extends ServiceProvider{

public function boot(){

ClientContact::observe(ContactObserver::class);UserContact::observe(ContactObserver::class);

}}

• 保存処理の前に発火する“saving” イベントを観測するObserver を作成

パターン1

28

Model 層の比較 - コード比較 case 1class ContactObserver{

public function saving(Model $model){

// e() -> htmlspecialchars()$model->body = e($model->body);

}}

// UserContact も同様に記述class ClientContact extends Model{}

class AppServiceProvider extends ServiceProvider{

public function boot(){

ClientContact::observe(ContactObserver::class);UserContact::observe(ContactObserver::class);

}}

• ServiceProvider 内で対象 Model にObserver を登録

パターン1

29

Model 層の比較 - コード比較 case 1class ContactObserver{

public function saving(Model $model){

// e() -> htmlspecialchars()$model->body = e($model->body);

}}

// UserContact も同様に記述class ClientContact extends Model{}

class AppServiceProvider extends ServiceProvider{

public function boot(){

ClientContact::observe(ContactObserver::class);UserContact::observe(ContactObserver::class);

}}

• 欠点:Modelの定義から処理を辿れない

パターン2

30

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

パターン2

31

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

• Model に “saving” イベントを登録

パターン2

32

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

• Model に対応するEvent を定義

パターン2

33

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

• Event を捕捉した際に処理を行うListener を定義

パターン2

34

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

• ServiceProvider 内でEvent と Listener の対応を登録

パターン2

35

Model 層の比較 - コード比較 case 1// UserContact も同様に記述class ClientContact extends Model{

protected $events = ['saving' => ClientContactSaving::class,

];}

class Event{}

// UserContractSaving も同様に記述class ClientContactSaving extends Event{

public $target;

public function __construct(ClientContact $clientContact){

$this->target = $clientContact;}

}

class ConvertToSafeString{

public function handle(Event $event){

$event->target->body = e($event->target->body);}

}

class EventServiceProvider extends ServiceProvider{

protected $listen = ['ClientContactSaving' => [

ConvertToSafeString::class,],'UserContactSaving' => [

ConvertToSafeString::class,],

];}

長所• Model から処理を追跡できる

短所• 記述量が多い• 実現するために考えることが多い

• 突如として現れる基底クラス Event など

実現したいこと

• クライアントと担当コンサルタントの多対多関係

• 担当コンサルタントの一括更新

36

Model 層の比較 - コード比較 case 2

clients

- id

- name

consultants

- id

- name

client_consultant

- client_id

- consultant_id

client_id consultant_id

1 1

1 2

1 3

client_id consultant_id

1 1

1 4

1 5

37

Model 層の比較 - コード比較 case 2

$Clients = TableRegistry::get('Clients');$Clients->belongsToMany(

'Consultants',['saveStrategy' => 'replace']

);$clientEntity = $Clients->get(

1,['contain' => 'Consultants']

);$clientEntity->consultants = $Clients->Consultants

->find('all')->where(['id IN' => [1, 4, 5]])->all()->toArray();

$clientEntity->dirty('consultants', true);$Clients->save($clientEntity);

class Client extends Model{

public function consultants(){

return $this->belongsToMany('App¥Consultant');}

}

class Consultant extends Model{}

$client = Client::find(1);$client->consultants()->sync([1, 4, 5]);

38

Model 層の比較 - コード比較 case 2

$Clients = TableRegistry::get('Clients');$Clients->belongsToMany(

'Consultants',['saveStrategy' => 'replace']

);$clientEntity = $Clients->get(

1,['contain' => 'Consultants']

);$clientEntity->consultants = $Clients->Consultants

->find('all')->where(['id IN' => [1, 4, 5]])->all()->toArray();

$clientEntity->dirty('consultants', true);$Clients->save($clientEntity);

class Client extends Model{

public function consultants(){

return $this->belongsToMany('App¥Consultant');}

}

class Consultant extends Model{}

$client = Client::find(1);$client->consultants()->sync([1, 4, 5]);

データ取得・更新の処理

CakePHP Laravel

ビジネスロジック Model 層に記述する 記述箇所は規定されていない(開発者の判断に委ねられている)

Model 層の構造 Table/Entity/Behavior の3つの概念に分かれている

ActiveRecord 実装の ORM のみを提供

考察 • 各々にどのような処理を書くのかが定まっている→悩まず書ける

• 簡単な処理であればクラス定義は必要ない→コードを書く量が少ない

• ロジックを Model に書いても良いし、それ意外の場所に別の名前で書いても良い→場面にあわせた設計思想の取り入れができる

• ORM に関する記述はシンプルになりやすい

39

【考察】Model 層比較

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

40

目次

• ディレクトリ

41

View 層の比較

Views are responsible for generating the specific output required for the

request.

ビューはリクエストに対する出力を生成する役割を担います。

.├── src/: :│ ├── Template/│ │ ├── Element/: : :│ │ ├── Layout/│ │ └── Pages/│ └── View/│ ├── Helper/: :

• CakePHP Template

• 「PHP 別の構文」(原文:alternative PHP syntax)

42

View 層の比較

CakePHP のテンプレートファイルは既定の拡張子を .ctp (CakePHP

Template) としており、 制御構造や出力のために PHP 別の構文 を利用することができます。

条件分岐 繰り返し

<?php if ($isSucceeded): ?><?= $message ?>

<?php endif; ?>

<?php foreach ($items as $item): ?><?= $item['name'] ?>

<?php endforeach; ?>

• CakePHP Template

• 「PHP 別の構文」(原文:alternative PHP syntax)

• つまりPHP

43

View 層の比較

CakePHP のテンプレートファイルは既定の拡張子を .ctp (CakePHP

Template) としており、 制御構造や出力のために PHP 別の構文 を利用することができます。

条件分岐 繰り返し

<?php if ($isSucceeded): ?><?= $message ?>

<?php endif; ?>

<?php foreach ($items as $item): ?><?= $item['name'] ?>

<?php endforeach; ?>

• 4つの概念に分かれる

• Layout

• View

• Element

• Helper

44

View 層の比較

• Layout

45

アプリケーションの多くのインターフェイスをくるむ表示コードを入れるテンプレートファイルです。ほとんどのビューはレイアウトの中に描画されます。

View 層の比較

• Layout

46

View 層の比較

アプリケーションの多くのインターフェイスをくるむ表示コードを入れるテンプレートファイルです。ほとんどのビューはレイアウトの中に描画されます。

サイドバー

メインコンテンツ

メニューバー

• View

47

View 層の比較

テンプレートは実行中のアクション固有のページの一部分です。 アプリケーションの応答の中心となります。

• View

48

View 層の比較

テンプレートは実行中のアクション固有のページの一部分です。 アプリケーションの応答の中心となります。

サイドバー

メインコンテンツView

メニューバー

• Element

49

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

• Element

50

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

メニューバーエレメント

• Element

51

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

サイドバー

• Element

52

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

バナーエレメント

• Element

53

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

タブエレメント

• Element

54

View 層の比較

小さな、再利用可能なちょっとしたコードです。エレメントは通常、ビューの中で描画されます。

案件一覧エレメント

• Helper

55

View 層の比較

これらのクラスはビューレイヤーの様々な場所で必要とされるロジックをカプセル化します。

• Helper

56

View 層の比較

これらのクラスはビューレイヤーの様々な場所で必要とされるロジックをカプセル化します。

案件ヘルパー

案件ヘルパー

• 【考察】

• 処理の種類ごとに記述する場所が規約で決められている

• どこに書くべきか、悩まずに記述できる

• 組み合わせやすい分類になっている

57

View 層の比較

• 表示のためのロジックを切り離すもの

• ディレクトリ

• views 以下には blade template ファイルのみが置かれる

58

View 層の比較

Views contain the HTML served by your application and separate your

controller / application logic from your presentation logic.

.:├── resources: :│ └── views:

• Blade

• シンプルかつ強力

• <?php ?> タグを使わずに記述

• ヘルパー等は別途実装するかパッケージインストールが必要

59

View 層の比較

Blade is the simple, yet powerful templating engine provided with Laravel.

Unlike other popular PHP templating engines, Blade does not restrict you

from using plain PHP code in your views.

条件分岐 繰り返し

@if ($isSucceeded){{ $message }}

@endif

@foreach ($items as $item){{ $item['name'] }}

@endforeach

• 継承等の機能も Blade 自体が提供

60

View 層の比較 - コード比較 case 1

<html><head>

<title>@yield('title')</title></head><body><div>

@yield('content')</div></body></html>

@extends('layouts.master')

@section('title')ここにタイトル

@endsection

@section('content')ここにコンテンツ

@endsection

views/layouts/master.blade.php views/index.blade.php

• Layout の場合は記述を省略できる

61

View 層の比較 - コード比較 case 1

<html><head>

<title><?= $this->fetch('title'); ?></title></head><body><div>

<?= $this->fetch('content'); ?></div></body></html>

<?php// layoutの継承は自動で行われる// $this->extend('layout/master');

$this->assign('title', 'ここにタイトル');

// viewの出力はすべて content に出力されるので不要//$this->start('content');?>

ここにコンテンツ<?php // $this->end(); ?>

Layout/top.ctp View/top/index.ctp

62

View 層の比較 - コード比較 case 2

{{-- パッケージ "laravelcollective/html" のインストール・設定が必要 --}}

{!!Form::open(

['url' => '/user','method' => 'post',

]);

!!}

{!!Form::text('email', '[email protected]');

!!}

// デフォルトで利用可能

echo $this->Form->create($userEntity,[

'url' => '/user','type' => 'POST',

]);

echo $this->Form->input('email',[

'type' => 'text','value' => '[email protected]',

]);

63

【考察】View 層比較

CakePHP Laravel

View 層の構造 • Layout / View / Element / Helper の4層に分かれる

• 表示の制御に携わる部分は全て Blade が担う

• CakePHP の Helper に該当するものは実装またはインストールが必要

考察 • Model 層と同様、各々にどのような処理を書くのかが定まっている→迷わず書ける

• 共通処理の実装をどこに書くかは規定されていない→ヘルパーの実装・Facade・blade 拡張など実現方法は多岐にわたる

• Blade template の記法がシンプル

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

64

目次

• ディレクトリ

65

Controller 層の比較

.:├── src/: :│ ├── Controller/│ │ └── Component/: :

Your controller should handle interpreting the request data, making sure the

correct models are called, and the right response or view is rendered.

Controllers can be thought of as middle layer between the Model and View.

コントローラーはリクエストを解釈して、適切なモデルが 呼ばれるのを確認して、正しいレスポンスまたはビューを書き出します。コントローラーはモデルとビューの 中間層とみなすことができます。

• Component

• ルーティング

• フォールバックメソッド

• デフォルトで /Controller名/action名 のルーティングが読み込まれる

66

Controller 層の比較

コンポーネントはコントローラー間で共有されるロジックのパッケージです。

• ドキュメント内に「Controller とは何か」という説明は明示されていない

• 【考察】単にリクエストをハンドリングするロジックを記述するクラスという位置づけ

• ディレクトリ

67

Controller 層の比較

Instead of defining all of your request handling logic as Closures in route

files, you may wish to organize this behavior using Controller classes.

.├── app: :│ ├── Http/│ │ ├── Controllers/│ │ :: :

• メソッドインジェクション

• メソッドの引数に型情報を与えることでクラスの依存性解決を自動的に行う

• ¥Illuminate¥Http¥Request を引数に指定することでリクエストパラメータを扱うことができる

68

Controller 層の比較

In addition to constructor injection, you may also type-hint dependencies on

your controller's methods.

class UserController extends Controller{

/*** Store a new user.* * @param Request $request* @return Response*/public function store(Request $request){

$name = $request->name;

//}

}

69

【考察】Controller 層比較

CakePHP Laravel

特徴 • Component• 共通処理を記述

• デフォルトで/Controller名/action名 のルーティングが読み込まれる

• メソッドインジェクション• 引数に型情報を

与えることで依存性解決

考察 機能に関しての違いがあるが基本的な役割は2つのフレームワーク間で変わらない

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

70

目次

71

同様な概念の比較

CakePHP Laravel

CLI /bin/cake /artisan

設定変数の読み書き

Configure::read(‘debug’);

Configure::write(‘debug’, true);

config(‘app.debug’);

config([‘app.debug’ => true]);

バリデーション 「保存しようとするデータ」が対象

「リクエスト内のデータ」が対象

日時操作 Cake¥I18n¥Time(Chronos ベース)

Carbon※ Chronos へ移行するProposal あり

ログ Cake¥Log(独自)

Monolog

単体テストフレームワーク

PHP Unit PHP Unit

• Utility

• 例)

• Hash 配列操作をサポート

• Text 文字列操作をサポート

• Number 数値操作をサポート

• Debug Kit

72

その他特徴

DebugKit は、CakePHP アプリケーションを簡単にデバッグするためのツールバーを提供する コアチームがサポートしているプラグインです。

Debug Kit

73

その他特徴

Debug Kit

74

その他特徴

Debug Kit

75

その他特徴

• Service Container

• クラス依存性解決のための仕組み

• 複数の解決方法が提供されており、場面に合わせた方法を選ぶことができる

• DI(依存性注入)がやりやすい→テストの書きやすいコードに

76

その他特徴

The Laravel service container is a powerful tool for managing class

dependencies and performing dependency injection.

class UserController extends Controller{

protected $users;

public function __construct(UserRepository $users){

$this->users = $users;}

}

• Facade

• Service Container に格納されているインスタンスのメソッドを static メソッドのように利用可能

• デフォルトで Log, DB, Session などといったFacade を提供

• 自分で Facade 実装することもできる

77

その他特徴

Facades provide a "static" interface to classes that are available in the

application's service container. Laravel ships with many facades which

provide access to almost all of Laravel's features.

¥DB::transaction(function () {// トランザクション開始

});

¥Log::debug('debug log');¥Log::info('info log');¥Log::error('error log');

• Laravel を取り巻くサービス・プロダクトが豊富

78

その他特徴

• Laravel を取り巻くサービス・プロダクトが豊富

• Homestead

• Vagrant を利用した開発環境

• Laracasts

• Laravel および PHP に関するチュートリアル動画を配信しているサイト

• Laravel Mix

• webpack の設定の wrapper (npm パッケージ)

• デフォルトで Vue.js や SASS を利用可能

• など

79

その他特徴

1. 背景

2. Model 層の比較

3. View 層の比較

4. Controller 層の比較

5. その他特徴

6. 全体考察・まとめ

80

目次

81

【考察】全体考察・まとめ

CakePHP Laravel

特徴 「設定より規約」にもとづいて少ないコードで機能を実現する

拡張のための機能を提供しコードを美しく保つ

長所 • 規約に則れば絶対的なコード記述量が少なくて済む

• 「正しい書き方」を公式が提示してくれている

• 「特有の書き方」「暗黙の了解」を強制される場面が少ない

• ORM や View テンプレートの記述が比較的シンプル

• 拡張するための仕組みが提供されている

短所 • 「正しい書き方」を把握していないといびつな造りになるおそれがある

• 自力で拡張するためには CakePHP の実装レベルの理解が必要になる

• クラスの階層構造などの設計を自力でできないと道に迷ってしまう

• 設定を明示的に書くことが多いため絶対的な記述量は多くなりがち

82

【考察】全体考察・まとめ

CakePHP Laravel

特徴 「設定より規約」にもとづいて少ないコードで機能を実現する

拡張のための機能を提供しコードを美しく保つ

長所 • 規約に則れば絶対的なコード記述量が少なくて済む

• 「正しい書き方」を公式が提示してくれている

• 「特有の書き方」「暗黙の了解」を強制される場面が少ない

• ORM や View テンプレートの記述が比較的シンプル

• 拡張するための仕組みが提供されている

短所 • 「正しい書き方」を把握していないといびつな造りになるおそれがある

• 自力で拡張するためには CakePHP の実装レベルの理解が必要になる

• クラスの階層構造などの設計を自力でできないと道に迷ってしまう

• 設定を明示的に書くことが多いため絶対的な記述量は多くなりがち

規約に則り、記述を減らすことで早く書きたい → CakePHP

自力で進み方を決め、柔軟に拡張していきたい → Laravel