読者です 読者をやめる 読者になる 読者になる

Laravel の新しいプロジェクトの作成

Laravel

前提

How to

  • Laravel の新しいプロジェクトの作成は、新しいプロジェクトのディレクトリを作成することである

  • Laravel のインストール(数分かかる)

    • git clone して、composer install を動かすのと同じ動きをしている
$ composer create-project laravel/laravel --prefer-dist project_name
$ cd project_name
$ php artisan --version
Laravel Framework 5.4.17

参照

qiita.com

Macにcomposerをbrewでインストール

composer Terminal

What?

$ brew install composer
...
Error: No similarly named formulae found.
==> Searching taps...
These formulae were found in taps:
homebrew/php/composer                                             Caskroom/cask/multimarkdown-composer
homebrew/php/composer@1.2                                         Caskroom/versions/multimarkdown-composer-beta
Caskroom/cask/multimarkdown-composer-pro
To install one of them, run (for example):
  brew install homebrew/php/composer

How to?

$ brew install homebrew/php/composer

Macへのgollumインストールでエラー

Ruby

What?

$ gem install gollum
Fetching: charlock_holmes-0.7.3.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing gollum:
    ERROR: Failed to build gem native extension.

checking for main() in -licui18n... no
checking for main() in -licui18n... no

Why?

  • icu4cライブラリがない

How to resolve?

$ brew install icu4c

参考

ruby - ERROR: Error installing gollum: ERROR: Failed to build gem native extension - Stack Overflow

Laravel5.4: Form作成(illuminate/htmlではなくて、laravelcollective/htmlで)

Laravel

Why?

  • フォームヘルパーを使うと、Form作るのが楽になる
  • laravelcollective/htmlパッケージをプロジェクトに導入しなくてはならない
    • NG: illuminate/html メンテ止まってる
    • OK: laravelcollective/html メンテされてる
  • Laravel Collective は、Laravel本体から外されたパッケージをメンテするプロジェクト

How to?

laravelcollective/htmlをプロジェクトに追加

  • インストールコマンドでvendorに追加(何気に時間がかかる)
$ composer require laravelcollective/html
  • その結果、composer.json に laravelcollective/html が追加され、インストールもされた
$ cat composer.json
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "laravelcollective/html": "^5.4"
    },
...
  • ProviderとAliaseを登録
    'providers' => [
...
        Collective\Html\HtmlServiceProvider::class,
...

    'aliases' => [
...
        'Form' => Collective\Html\FormFacade::class,
        'Html' => Collective\Html\HtmlFacade::class
...

登録フォームの実装

  • Routingを追加(順番注意): routes/web.php
Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');
  • Controllerを追加(順番注意): app/Http/Controllers/ArticlesController.php
public function create() {
    return view('articles.create');
}
  • Viewを書く: resources/views/articles/create.blade.php
@extends('app')

@section('content')
  <h1>Write a New Article</h1>
  <hr />

  {!! Form::open(['url' => 'articles']) !!}
    <div class="form-group">
      {!! Form::label('title', 'Title') !!}
      {!! Form::text('title', null, ['class' => 'form-control']) !!}
    </div>
    <div class='form-group'>
      {!! Form::label('body', 'Body') !!}
      {!! Form::text('body', null, ['class' => 'form-control']) !!}
    </div>
    <div class='form-group'>
      {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}
    </div>
  {!! Form::close() !!}
@stop

登録APIの実装

  • Routingを追加(順番注意): app/Http/routes.php
Route::post('articles', 'ArticlesController@store');
  • Controllerを追加
namespace App\Http\Controllers;

use Request;
use App\Article;
use Carbon\Carbon;

class ArticlesController extends Controller
{
    ...
    public function store() {
        $input = Request::all();
        $input['publishd_at'] = Carbon::now();
        Article::create($input);
        return redirect('articles');
    }

逆順ソートで表示

  • リスト表示時にlatestを使う
class ArticlesController extends Controller {
 
    public function index() {
        $articles = Article::latest('published_at')->get();
        return view('articles.index', compact('articles'));
    }
  • vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
    public function latest($column = 'created_at')
    {
        return $this->orderBy($column, 'desc');
    }

ハマりどころ

参照

Laravel 5.4: Non-static method Illuminate\Http\Request::all() should not be called statically のエラー

Laravel

What?

  • Laravel 5.4 で Non-static method Illuminate\Http\Request::all() should not be called statically のエラーがでる

Why?

  • Request ファサードまで、リクエストが届いていない
  • config/app.php に以下のエイリアスが書いてあるので、Request を直接呼ぶ
    • 'Request' => Illuminate\Support\Facades\Request::class,

Solution

  • 以下に変更
use Illuminate\Http\Request;

use Request;

参照

Laravel 5.4: Fatal error: Uncaught Error: Class 'Illuminate\Foundation\Application' のエラー

Laravel composer

What?

  • Fatal error: Uncaught Error: Class 'Illuminate\Foundation\Application'
    • のエラーがでる

Why?

  • Composerがおかしくなってて、ライブラリが見つけられない

How to?

  • ライブラリの Install しなおし & autoload の dump ファイルの更新
$ composer install
$ composer dump-autoload

Laravel 5.4: Class 'Form' not found エラーが出る

What?

  • illuminate/html を使って、フォームを作ろうとすると、Class 'Form' not found (View: /home/vagrant/Code/laravel/resources/views/articles/create.blade.php) エラーが出る

Why?

  • Laravel 5.2 から仕様がちょっと変わった
    • illuminate/html ではなく、 laravelcollective/htmlを使う
  • Collective\Html\HtmlServiceProvider::class,HTMLを大文字にしてた。。。

How to?

  • composer require laravelcollective/htmlする
$ composer require laravelcollective/html
Using version ^5.4 for laravelcollective/html
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader
The compiled services file has been removed.
laravel vagrant master *%$ composer dump-autoload -o
Generating optimized autoload files
  • config/app.php
'providers' => [
    ...
    Collective\HTML\HtmlServiceProvider::class,
    ...
],

...

'aliases' => [
    ...
    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class,
    ...
],
  • ん?できない。
    • エラーが変わった
FatalThrowableError in ProviderRepository.php line 201:
Class 'Collective\HTML\HtmlServiceProvider' not found
  • なんでだよ。。。ちゃんとインストールしてるよ。マッピングされてるよ。。キャッシュもクリアしてオートロードできてるはずなんだよ。。
$ ls -la vendor/laravelcollective/html/src/HtmlServiceProvider.php
-rw-r--r-- 1 vagrant vagrant 1489 Mar  9 15:10 vendor/laravelcollective/html/src/HtmlServiceProvider.php
$ composer info | grep laravel
laravel/framework                     v5.4.15 The Laravel Framework.
laravel/tinker                        v1.0.0  Powerful REPL for the Laravel framework.
laravelcollective/html                v5.4.1  HTML and Form Builders for the Laravel Framework
$ grep -r HtmlServiceProvider vendor/composer/
vendor/composer/autoload_classmap.php:    'Collective\\Html\\HtmlServiceProvider' => $vendorDir . '/laravelcollective/html/src/HtmlServiceProvider.php',
vendor/composer/autoload_static.php:        'Collective\\Html\\HtmlServiceProvider' => __DIR__ . '/..' . '/laravelcollective/html/src/HtmlServiceProvider.php',
  • 3日悩んだ結果。
'providers' => [
    ...
    Collective\Html\HtmlServiceProvider::class,
    ...
],
  • 答え: HTMLじゃなくてHtmlな。。。
    • ディレクトリ名なので大文字小文字が厳密に判断される
      • composerを使って、オートロードしているので、以下と一緒じゃなきゃだめ
$ less vendor/composer/installed.json
        "autoload": {
            "psr-4": {
                "Collective\\Html\\": "src/"
            },

次、困ったときは順番にこれをやる

  • Issue composer require “laravelcollective/html”:“^5.3.0”.
  • Verify that the vendor/laravelcollective/html directory exists.
  • Verify that your composer.json file has been updated and there’s an entry for laravelcollective/html package in your dependencies (require block).
  • Add Collective\Html\HtmlServiceProvider::class to your providers array of config/app.php.
  • Add ‘Form’ => Collective\Html\FormFacade::class and ‘Html’ => Collective\Html\HtmlFacade::class to your aliases array.
  • Confirm that the API exists: Issue a php artisan tinker command and try playing with Form:: APIs. See if throws any errors.

知見

  • ハマったら、キャッシュクリアしたり、再インストールしたりする(今回あんま関係なかったけど)
$ composer dump-autoload
$ composer update
$ composer clear-cache
$ php artisan route:clear
$ php artisan cache:clear
$ php artisan config:clear
$ composer remove laravelcollective/html
$ composer require laravelcollective/html

参考