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]

参照

Laravel 5.4: DBマイグレーション

What?

Why?

  • そもそもなぜDBマイグレーションが必要なのか?
    • MySQL Workbenchとかを使う
      • 問題:
        • .mwbファイルとかSQLファイルとかの管理対象が増える
        • DBのバージョンとソースコードのバージョンがずれたりして死ぬことがある(死んだことがある)

Migration

  • 保存場所
    • database/migrations/
$ php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
$ mysql --user=homestead --password=secret homestead
mysql> show tables;
+---------------------+
| Tables_in_homestead |
+---------------------+
| migrations          |
| password_resets     |
| users               |
+---------------------+
3 rows in set (0.00 sec)

mysql> desc migrations;
+-----------+------------------+------+-----+---------+----------------+
| Field     | Type             | Null | Key | Default | Extra          |
+-----------+------------------+------+-----+---------+----------------+
| id        | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| migration | varchar(255)     | NO   |     | NULL    |                |
| batch     | int(11)          | NO   |     | NULL    |                |
+-----------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> desc users;
+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| id             | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name           | varchar(255)     | NO   |     | NULL    |                |
| email          | varchar(255)     | NO   | UNI | NULL    |                |
| password       | varchar(255)     | NO   |     | NULL    |                |
| remember_token | varchar(100)     | YES  |     | NULL    |                |
| created_at     | timestamp        | YES  |     | NULL    |                |
| updated_at     | timestamp        | YES  |     | NULL    |                |
+----------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

mysql> desc password_resets;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| email      | varchar(255) | NO   | MUL | NULL    |       |
| token      | varchar(255) | NO   | MUL | NULL    |       |
| created_at | timestamp    | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

Rollback

$ php artisan migrate:status
+------+------------------------------------------------+
| Ran? | Migration                                      |
+------+------------------------------------------------+
| Y    | 2014_10_12_000000_create_users_table           |
| Y    | 2014_10_12_100000_create_password_resets_table |
+------+------------------------------------------------+
$ php artisan migrate:rollback
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_000000_create_users_table
$ php artisan migrate:status
+------+------------------------------------------------+
| Ran? | Migration                                      |
+------+------------------------------------------------+
| N    | 2014_10_12_000000_create_users_table           |
| N    | 2014_10_12_100000_create_password_resets_table |
+------+------------------------------------------------+

Make migration

$ php artisan make:migration create_articles_table --create="articles"
Created Migration: 2017_02_14_184315_create_articles_table
$ less database/migrations/2017_02_14_184315_create_articles_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            // ここから
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
            $table->timestamp('published_at')->useCurrent();
            // ここまで追加
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

Edit migration

php artisan migrate
mysql> desc articles;
+--------------+------------------+------+-----+-------------------+----------------+
| Field        | Type             | Null | Key | Default           | Extra          |
+--------------+------------------+------+-----+-------------------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
| title        | varchar(255)     | NO   |     | NULL              |                |
| body         | text             | NO   |     | NULL              |                |
| created_at   | timestamp        | YES  |     | NULL              |                |
| updated_at   | timestamp        | YES  |     | NULL              |                |
| published_at | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
| exceprt      | text             | NO   |     | NULL              |                |
+--------------+------------------+------+-----+-------------------+----------------+
7 rows in set (0.00 sec)

参考

http://site.oganity.pw/232/

Laravel 5.4: DBマイグレーションでエラーになる

What?

このバージョンで

laravel vagrant master %$ php artisan --version
Laravel Framework 5.4.10
laravel vagrant master %$ mysql --version
mysql  Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using  EditLine wrapper
laravel vagrant master %$ php -v
PHP 7.1.1-1+deb.sury.org~xenial+1 (cli) (built: Jan 20 2017 09:20:20) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.1-1+deb.sury.org~xenial+1, Copyright (c) 1999-2017, by Zend Technologies
    with blackfire v1.14.3~linux-x64-non_zts71, https://blackfire.io, by Blackfireio Inc.

このmigrationファイルを

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            // ここから
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
            $table->timestamp('published_at');
            // ここまで追加
        });
    }

migrateすると、エラーになる

$ php artisan migrate


  [Illuminate\Database\QueryException]
  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at' (SQL: create table `articles` (`id
  ` int unsigned not null auto_increment primary key, `title` varchar(255) not null, `body` text not null, `created_at` timestamp nul
  l, `updated_at` timestamp null, `published_at` timestamp not null) default character set utf8mb4 collate utf8mb4_unicode_ci)



  [PDOException]
  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at'

Solution

このmigrationファイルをちょっと書き換え、

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            // ここから
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
            $table->timestamp('published_at')->useCurrent(); // ここ追加
            // ここまで追加
        });
    }

こうする

$ php artisan migrate:refresh --seed
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2017_02_14_184315_create_articles_table
Migrated: 2017_02_23_172823_add_excerpt_to_articles_table

Why?

  • マイグレーションを全部ロールバックし、再度実行する力技コマンド php artisan migrate:refresh --seed を使って、強制帳消し
  • published_atnot nullなのに値が入ってなかったので、useCurrent()を使って突っ込んだ

失敗例

published_atだけ触ればいいのに、その前のtimestampも色々いじってしまった結果。

laravel vagrant master %$ php artisan migrate


  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Call to a member function useCurrent() on null


laravel vagrant master *%$ php artisan migrate


  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Call to a member function default() on null


laravel vagrant master *%$ php artisan migrate


  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Call to a member function nullable() on null

config/database.phpの確認したけど、ちゃんとstrictになってた

'strict' => true,

参考

https://github.com/laravel/framework/issues/3602

Laravel 5.4: メンテナンスモードの使い方、仕組み

メンテナンスモードの使い方

  • 開始
$ php artisan down
  • 復帰
    • Be right back.と表示される
php artisan up

メンテナンスモードの仕組み

  • storage/framework/down が存在していたらメンテナンスモードになっている
$ ls -la storage/framework/down
ls: cannot access 'storage/framework/down': No such file or directory

$ php artisan down
Application is now in maintenance mode.
$ ls -la storage/framework/down
-rw-r--r-- 1 vagrant vagrant 66 Feb 14 03:44 storage/framework/down

$ php artisan up
Application is now live.
$ ls -la storage/framework/down
ls: cannot access 'storage/framework/down': No such file or directory
  • メンテナンスページのテンプレート
    • vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/503.blade.php にある

TODO

  • 部分的にメンテナンスモードにできる?
  • あるIPだけ限定でアクセスさせることができる?

参照

Laravel 5 メンテナンスモード IP制限

Laravel 5.4: 環境設定

DotEnvライブラリ

設定ファイル

  • .env: 各環境で使う設定ファイル
    • git管理対象外
  • .env.example: サンプルファイル
    • git管理対象
$ diff .env.example .env
2c2
< APP_KEY=
---
> APP_KEY=base64key...

設定の適用

  • 設定ファイルの記述
    • .env
DB_DATABASE=homestead
  • 設定の適用
    • .envから値が取れないとき第二引数の値が入る
env('DB_DATABASE', 'foo')
  • 設定の更新
    • storage/framework/config.phpが更新
$ php artisan config:cache

環境名の取得

use App;
$environment = App::environment(); // get "local"
if (App::environment('local'))
{
    // The environment is local
}
 
if (App::environment('local', 'staging'))
{
    // The environment is either local OR staging...
}

TODO

  • 各環境名の設定方法
  • 実際に各環境を立てる

参照

【Laravel5】実行環境と設定ファイルの関係 - Bloq4Developer

Laravel 5.4: Blade テンプレートを使う

if

@if (count($people))

@endif

foreach

@foreach ($people as $person)
  {{ $person }}
@endforeach

Template

  • テンプレート側: @yield('bar')
  • テンプレート利用側:
    • Fooテンプレートの継承: @extends('foo')
    • セクション書き換え: @section('bar'), @stop

  • テンプレート: resources/views/app.blade.php
<body>
    <div class="container">
        @yield('content')
    </div>
 
    @yield('footer')
 
</body>
  • テンプレート利用: resources/views/pages/about.blade.php
@extends('app')
 
@section('content')
 
<h1>About {{$name}}</h1>
 
@if (count($people))
<h3>People I Like:</h3>
 
<ul>
    @foreach ($people as $person)
        <li>{{ $person }}</li>
    @endforeach
</ul>
@endif
 
@stop

参照

http://site.oganity.pw/177/

Laravel 5.4: Viewへデータを引き渡す

Summary

  • テンプレートはBladeファイル: foo.blade.php
  • withを使ってControllerからViewへ渡す

  • Controller側:

    • view('pages.about')->with('name', $name)
  • View側:
    • エスケープ: {{$bar}}
    • 非エスケープ: {!! $bar !!}

How to basic

  • app/Http/routes.php
Route::get('about', 'PagesController@about');
  • コントローラ作成
$ php artisan make:controller PagesController
  • aboutメソッド作成
    • app/Http/Controllers/PagesController.php
class PagesController extends Controller {
 
    public function about() {
        $name = 'Jeffery Way';
        return view('pages.about')->with('name', $name);
    }
 
}
  • テンプレート作成
    • resources/views/pages/about.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <h1>About {{$name}}</h1>
</body>
</html>

How to advance

  • エスケープ

    • エスケープ: {{$bar}}
    • 非エスケープ: {!! $bar !!}
  • データ渡しにwithを使う

    • 単数:
      • Controller: view('pages.about')->with('name', $name)
      • Template: {{$name}}
    • 複数(配列):
      • Controller: view('pages.about')->with(['first' => 'Jeffery', 'last' => Way'])
      • Template: {{$first}} {{$last}}
  • データ渡しにwithを使わない
    • 単数:
      • Controller: view('pages.about', $data)
      • Template: {{$first}} {{$last}}
    • 複数(連想配列):
      • Controller: view('pages.about', $data)
      • Template: {{$name['first']}} {{$name['last']}}
    • 複数(別変数):
      • Controller: view('pages.about', compact('first', 'last'))
      • Template: {{$first}} {{$last}}

参考

http://site.oganity.pw/160/