Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.の意味

What?

  • Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.と表示されて意味がわからん
$ composer remove laravelcollective/html
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 1 removal
  - Removing laravelcollective/html (v5.4.1)
Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize


  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Class 'Collective\HTML\HtmlServiceProvider' not found


Script php artisan optimize handling the post-update-cmd event returned with error code 1

Removal failed, reverting ./composer.json to its original content.
  • 直訳: Dependency “laravel/framework” is also a root requirement, but is not explicitly whitelisted. Ignoring.

    • 依存関係にある"laravel/framework"はrootの必須項目です。しかし、明示的にホワイトリストに入っていません。無視します。
  • ホワイトリスト

    • Composerではパッケージ更新時に引数として与えられる依存パッケージリストをホワイトリストと呼んでいる
    • e.g. $ composer update hoge fuga piyo
  • つまり、今回指定されたのは、laravelcollective/htmlだけで、明示的にlaravel/frameworkが引数として指定されたわけではないので、laravel/frameworkは消さないよ。ということです。

composer removeとかupdateとかできない

What?

  • Class hogehoge not foundと表示されて、composerでライブラリ操作ができなくなる
$ composer remove illuminate/html
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "laravel/framework" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 1 removal
  - Removing illuminate/html (v5.0.0)
Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize


  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Class 'Collective\HTML\HtmlServiceProvider' not found


Script php artisan optimize handling the post-update-cmd event returned with error code 1

Removal failed, reverting ./composer.json to its original content.

How to

  • config/app.phpprovidersに使っていないものが書いてあるので、消す
'providers' => [
    ...
    // Collective\HTML\HtmlServiceProvider::class,
    ...
],
  • おっけー
$ composer remove illuminate/html
Package "illuminate/html" listed for update is not installed. Ignoring.
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.
$ 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)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravelcollective/html (v5.4.1) Downloading: 100%
Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader
The compiled services file has been removed.

How to その2

  • php artisan optimizeでコケてるので、--no-scripts オプションで実行後スクリプトを実行させない
$ composer remove --no-scripts laravelcollective/html
Package "laravelcollective/html" listed for update is not installed. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
$ composer require --no-scripts 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

vim NERDTree 更新(リロード)の仕方

Why?

  • ファイルを更新したのにNERDTreeに反映されなくてつらい

How to

  • Tree上の更新したいディレクトリの上にカーソルを乗せて r を押す
  • 更新の進捗状況は一番下の行
    • NERDTree: Refreshing node. This could take a while... DONE と表示されればOK

Homestead をリロードしようとしたらエラーになる

What?

  • カフェに行ってPCを開いて、起動しっぱなしのHomesteadサーバにアクセスしたらエラー
  • vagrantからリロードしても以下のエラーが出て立ち上がらない
$ vagrant reload
==> homestead-7: Attempting graceful shutdown of VM...
==> homestead-7: Checking if box 'laravel/homestead' is up to date...
==> homestead-7: Clearing any previously set forwarded ports...
==> homestead-7: Clearing any previously set network interfaces...
The specified host network collides with a non-hostonly network!
This will cause your specified IP to be inaccessible. Please change
the IP or name of your host only network so that it no longer matches that of
a bridged or non-hostonly network.

Why?

  • 英語を読もう(雑訳)

    • ホストオンリーではないネットワークで、特定のホストネットワークが衝突してます
    • これは、あなたが設定したIPにアクセス出来ないということです
    • そのホストはブリッジされているもしくはホストオンリーではないネットワークにおいて、もうマッチしていないので、あなたのホストオンリーネットワークのIPか名前を変えてください。
  • つまりは、外で作業を初めて、今のIP(homesteadのデフォルトIP: 192.168.10.10)が他の人と被ったから

Solution

  • .homestead/Homestead.yaml
ip: "192.168.10.10"

ip: "192.168.10.11"

とかに変更する。

  • /etc/hosts も変更することを忘れずに

Laravel 5.4: Model, Controller, Viewワークフロー

Why?

  • Articleの一覧、詳細を作ることで、一通りのModel, Controller, Viewワークフローを流す

How to

Articleの一覧を作る

  • app/Http/routes.phpにRoutingを追加
Route::get('articles', 'ArticlesController@index');
  • Controllerを追加 (laravel 5.2から–plainオプションはデフォルトになったので不要)
    • app/Http/Controllers/ArticlesController.phpが追加される
$ php artisan make:controller ArticlesController
  • app/Http/Controllers/ArticlesController.phpにindexメソッドを追加 (まずはviewに渡さずにプレーンに表示)
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;

class ArticlesController extends Controller
{
    public function index() {
        $articles = Article::all();
        return $articles;
    }
}
  • プレーンなレスポンスが帰ってくる
[
    {
        id: 1
        title: "My Update First Article"
        body: "Lorem ipsum"
        ...
    }
]
  • app/Http/Controllers/ArticlesController.phpViewからViewに渡す
    public function index() {
        $articles = Article::all();
        return view('articles.index', compact('articles'));
    }
  • View resources/views/articles/index.blade.php を追加
@extends('app')

@section('content')
  <h1>Articles</h1>
  <hr />
  @foreach ($articles as $article)
    <article>
      <h2>{{ $article->title }}</h2>
      <div class="body">{{ $article->body }}</div>
    </article>
  @endforeach
@stop

Articleの詳細を作る

  • app/Http/routes.phpにRoutingを追加
Route::get('articles/{id}', 'ArticlesController@show');
  • app/Http/Controllers/ArticlesController.phpにshowメソッドを追加
    public function show($id) {
        $article = Article::findOrFail($id);
        return view('articles.show', compact('article'));
    }
  • View resources/views/articles/show.blade.php を追加
@extends('app')

@section('content')
  <h1>{{ $article->title }}</h1>
  <article>
    <div class="body">{{ $article->body }}</div>
  </article>
@stop

一覧と詳細ページを繋げる

  • resources/views/articles/show.blade.phpにリンク追加
@extends('app')

@section('content')
  <h1>{{ $article->title }}</h1>
  <article>
    <div class="body">{{ $article->body }}</div>
  </article>
  <a href="/articles/">&lt; Back to list</a>
@stop
  • resources/views/articles/index.blade.phpにリンク追加
@extends('app')

@section('content')
  <h1>Articles</h1>
  <hr />
  @foreach ($articles as $article)
    <article>
      <h2><a href="/articles/{{ $article->id }}">{{ $article->title }}</h2></a>
      <div class="body">{{ $article->body }}</div>
    </article>
  @endforeach
@stop

参考

Laravel 5.4: Eloquent ORMを使ってみる

What?

  • Eloquent ORM: Laravel5にデフォルトで組み込まれているORマッパー
  • RailsのActive Recodeみたいに使える

How to

DBにモデルを保存

  • モデルを作る -> app/Article.php ができている
$ php artisan make:model Article
$ cat app/Article.php
<?php namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class Article extends Model {
 
    //
 
}
  • モデルができているかtinkerで確認
$ php artisan tinker

>>> $article = new App\Article;                                                                      => App\Article {#668}
  • モデルを使う (オブジェクトを作って、値を入れる)
>>> $article = new App\Article;
=> App\Article {#673}
>>> $article->title = 'My First Article';
=> "My First Article"
>>> $article->body = 'Lorem ipsum';
=> "Lorem ipsum"
>>> $article->published_at = Carbon\Carbon::now();
=> Carbon\Carbon {#682
     +"date": "2017-03-04 11:53:09.134952",
     +"timezone_type": 3,
     +"timezone": "UTC",
   }
>>> $article;
=> App\Article {#673
     title: "My First Article",
     body: "Lorem ipsum",
     published_at: Carbon\Carbon {#682
       +"date": "2017-03-04 11:53:09.134952",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
   }
  • 作ったオブジェクトをセーブする
>>> App\Article::all()->toArray();
=> []
>>> $article->save();
=> true
>>> App\Article::all()->toArray();
=> [
     [
       "id" => 1,
       "title" => "My First Article",
       "body" => "Lorem ipsum",
       "created_at" => "2017-03-04 11:53:44",
       "updated_at" => "2017-03-04 11:53:44",
       "published_at" => "2017-03-04 11:53:09",
     ],
   ]
$ mysql --user=homestead --password=secret homestead
mysql> select * from articles\G;
*************************** 1. row ***************************
          id: 1
       title: My First Article
        body: Lorem ipsum
  created_at: 2017-03-04 11:53:44
  updated_at: 2017-03-04 11:53:44
published_at: 2017-03-04 11:53:09
1 row in set (0.00 sec)

DBからモデルを読み込みアップデートしてみる

  • tinker でDBから情報を1行読み込んで、更新後、セーブする
>>> $article = App\Article::all()->first();
=> App\Article {#689
     id: 1,
     title: "My First Article",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 11:53:44",
     published_at: "2017-03-04 11:53:09",
   }
>>> $article->title = 'My First Article Updated';
=> "My First Article Updated"
>>> $article->save();                                                                                => true
  • DBを確認
mysql> select * from articles\G;
*************************** 1. row ***************************
          id: 1
       title: My First Article Updated
        body: Lorem ipsum
  created_at: 2017-03-04 11:53:44
  updated_at: 2017-03-04 12:09:32
published_at: 2017-03-04 11:53:09
1 row in set (0.00 sec)

色々な方法でデータを検索する

>>> App\Article::find(1);
=> App\Article {#684
     id: 1,
     title: "My First Article Updated",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 12:09:32",
     published_at: "2017-03-04 11:53:09",
   }
>>> App\Article::where('body', 'Lorem ipsum')->get();
=> Illuminate\Database\Eloquent\Collection {#656
     all: [
       App\Article {#692
         id: 1,
         title: "My First Article Updated",
         body: "Lorem ipsum",
         created_at: "2017-03-04 11:53:44",
         updated_at: "2017-03-04 12:09:32",
         published_at: "2017-03-04 11:53:09",
       },
     ],
   }
>>> App\Article::where('body', 'Lorem ipsum')->first();
=> App\Article {#693
     id: 1,
     title: "My First Article Updated",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 12:09:32",
     published_at: "2017-03-04 11:53:09",
   }

createメソッドを使ってみる

  • createメソッドはまとめて値を入力できるので便利

    • ただし、ユーザの突っ込んできた値の全てを受け入れると危険
    • $fillableで、createでアサインできる値のホワイトリストを指定できる
    • $guardedで、createでアサインできる値のブラックリストを指定できる
  • App\Article::create()でまとめて作ろうとするとMassAssignmentExceptionエラーが出る

>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
  • app/Article.phpモデルを修正する
<?php namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class Article extends Model {
 
    protected $fillable = [ // 
        'title',
        'body',
        'published_at'
    ];
 
}
  • ん?まだ、MassAssignmentExceptionエラーが出る
>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
  • tinkerを立ち上げなおしてリトライ。できた。
>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
=> App\Article {#670
     title: "New Article",
     body: "Lorem ipsum",
     published_at: Carbon\Carbon {#661
       +"date": "2017-03-04 12:17:28.029855",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
     updated_at: "2017-03-04 12:17:28",
     created_at: "2017-03-04 12:17:28",
     id: 2,
   }

参考

php artisan tinker の使い方

Why?

  • Laravel チュートリアルやってて、突然出現した
  • pryっぽいけど、なにができるのか疑問

What?

  • https://github.com/laravel/tinker
  • REPL (Read-Eval-Print Loop) 。対話的シェル。
    • Ruby の pry と似たもの
    • 初めての言語を試しに(とりま、echoしたいとか)触りたいときとかに便利
    • 対話的にデバッグするときに便利
  • コンソールにどういう状況のものが表示されるのか?
    • 再起動するまで変数値などは保存される。再起動したら、変数とかがリセットされる。
    • モデルとかを使うときは、立ち上げ時のコードの状態が反映されているので、コードをいじったらコード反映のために再起動する必要がある
    • デバッグのときは、ブレークポイントの状態のものが表示される。
  • ラッパー

How to use?

  • プロジェクトディレクトリ内で $ php artisan tinker すると立ち上がる。
$ php artisan tinker
Psy Shell v0.8.1 (PHP 7.1.1-1+deb.sury.org~xenial+1 — cli) by Justin Hileman

New version is available (current: v0.8.1, latest: v0.8.2)
>>>
  • phpコマンドを逐次実行できる (hogeは標準出力、=> nullは返り値)
>>> echo "hoge";
hoge⏎
=> null
  • tinderコマンドは色々ある
>>> help
  help             Show a list of commands. Type `help [foo]` for information about [foo].      Aliases: ?
  ls               List local, instance or class variables, methods and constants.              Aliases: list, dir
  dump             Dump an object or primitive.
  doc              Read the documentation for an object, class, constant, method or property.   Aliases: rtfm, man
  show             Show the code for an object, class, constant, method or property.
  wtf              Show the backtrace of the most recent exception.                             Aliases: last-exception, wtf?
  whereami         Show where you are in the code.
  throw-up         Throw an exception out of the Psy Shell.
  trace            Show the current call stack.
  buffer           Show (or clear) the contents of the code input buffer.                       Aliases: buf
  clear            Clear the Psy Shell screen.
  history          Show the Psy Shell history.                                                  Aliases: hist
  exit             End the current session and return to caller.                                Aliases: quit, q
  clear-compiled   Remove the compiled class file
  down             Put the application into maintenance mode
  env              Display the current framework environment
  migrate          Run the database migrations
  optimize         Optimize the framework for better performance
  up               Bring the application out of maintenance mode
  inspire          Display an inspiring quote
>>> ls -gl

Global Variables:
  $app                         Illuminate\Foundation\Application {#3 …15}
  $argc                        2
  $argv                        [ …2]
  $GLOBALS                     [ …13]
  $input                       Symfony\Component\Console\Input\ArgvInput {#20}
  $kernel                      App\Console\Kernel {#22}
  $_COOKIE                     []
  $_FILES                      []
  $_GET                        []
  $_POST                       []
  $_REQUEST                    []
  $_SERVER                     [ …35]
  $__composer_autoload_files   [ …8]

参照