20200329のlaravelに関する記事は7件です。

【laravel5.8】php artisan migrate --seedでseedが効かない時

database>seeds>DatabaseSeeder.phpに自分が作ったSeederが登録されてるか確認してみてください。

DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(GroupsTableSeeder::class);
        $this->call(AgendasTableSeeder::class);
        $this->call(CommentsTableSeeder::class);
    }
}

laravel公式リファレンスだとマイグレーションと一緒にテストデータを流し込む際に「php artisan migrate --seedで一髪完了!」と書いてあるのになかなかできなかったので調べてみました。
同じエラーで困ってる方がいたらご参考までに。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelのfactoryでInvalidArgumentException: Unable to locate factory with name [default] [hogehoge]. が出た

はじめに

上記でググってきた、ありがちな 'hogehoge' の参照方法が間違っていたわけではなかった。

結論から書くと

php artisan make:test hogeTest --unit でUnitテストを生成したときに
use PHPUnit\Framework\TestCase; でUnitテストが作成されていたので
use Tests\TestCase; と書き直した

考察

「そもそも今までUnitテスト内でfactoryを使ってたのになぜ急に!」
と思い、今までのと比較してみたら上記が違いましたよ、と。
検証してはないけど、Laravelのバージョンを5系から6系に変えたのでそのタイミングで変わったのかもしれない。

また本来、 use PHPUnit\Framework\TestCase; でもfactoryを呼び出せるようにすることが正しい解決方法だとは思う。

https://qiita.com/kawagashira/items/30b6fbd7a865f4005a90
現状結論の解決方法で良かった。
しかし単体テストを名乗ってはいけなかった。

追記

https://laravel.com/docs/5.8/testing
https://laravel.com/docs/6.x/testing

を比較するとやはりバージョンアップが関わっているようだ。が。factory使えないのはなんでだろう?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

実行された全てのSQLクエリをログに出力するLaravelプラグイン

Laravelで新しいプロジェクトを作るたびに毎回似たようなコードを書いている気がしてきたので、プラグインにして公開しました。

https://github.com/ngmy/laravel-query-log-tracker

Demo

PHP 7.2〜7.4、Laravel 5.6以上、6.x、7.xで動作するはずです。
PHP 7.2〜7.4とLaravel 7.xでユニットテストしています。
PHP 7.3.16とLaravel 7.3.0で実際に動作確認しました。

ログには次の項目が出力されます。

  • バインド後のSQL
  • バインド変数
  • 実行時間(ミリ秒)
  • コネクション名

インストール方法はREADMEに書いていますが、Composerでインストールして、(パッケージディスカバリーを使っていない場合は)サービスプロバイダとファサードをconfig/app.phpに追加するだけです。

実行時にログを無効化することもできます。

QueryLogTracker::beginDisable();
// ログを無効化したいSQL
QueryLogTracker::endDisable();
QueryLogTracker::disable(function () {
    // ログを無効化したいSQL
});

設定ファイルで次の項目を設定できます。

  • ログレベル
  • ログから除外するSQLのパターン(正規表現)
  • ログスタック
  • ログチャンネル

テストはしていますがOSSなので自己責任で使ってください。
本番環境で使う場合は無効化や除外パターンを使って、ログに個人情報や秘密情報が出力されないように注意してください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPのArrayAccessインタフェースをざっくり解説

初心者向け記事。
PHPには、それを実装することでクラスに言語構造レベルの機能を持たせることができるインタフェースがいくつかある。

定義済みのインターフェイスとクラス

Laravelなどのフレームワークの中でも使われるケースがあり、ソースコードを追ったりする際は知っておく必要が出てくる。今回はArrayAccessインタフェースを例にとって、どのように使われるのかをみていく。

(間違いなどあればご指摘ください...:pray:

ArrayAccessインタフェース

PHPのオブジェクトは、ArrayAccessインタフェースを実装することで配列のように操作することができるようになる。

ArrayAccess {
    /* メソッド */
    abstract public offsetExists ( mixed $offset ) : bool
    abstract public offsetGet ( mixed $offset ) : mixed
    abstract public offsetSet ( mixed $offset , mixed $value ) : void
    abstract public offsetUnset ( mixed $offset ) : void
}

引数の$offsetは配列のキー、$valueは格納する値に相当する。
それぞれのメソッドの役割は以下のようになる。

  • offsetExists()は指定したキーに値がセットされているかをbool値で返す。isset()による判定を可能にする。
  • offsetGet()はキーを元に値を取得する。
  • offsetSet()は指定したキーと値をペアで格納する。
  • offsetUnset()は指定したキーとそのペアの値を削除。unset()による割り当ての解除を可能にする。

引数にはmixedが指定されており、様々な型を受け入れてくれることがわかる。

Illuminate\Container\Containerクラスの例

例えばLaravelのサービスコンテナ(Illuminate\Foundation\Applicationクラス)が継承しているIlluminate\Container\ContainerクラスはArrayAccessインタフェースを継承している。
以下は該当のテストコードを一部変更して引用したものになる。

ContainerTest.php
use PHPUnit\Framework\TestCase;

class ContainerTest extends TestCase
{
    public function testArrayAccess()
    {
        $container = new Container;
        $container['something'] = 'foo'; // offsetSet()
        $this->assertTrue(isset($container['something'])); // offsetExists()
        $this->assertSame('foo', $container['something']); // offsetGet()

        unset($container['something']); // offsetUnset()
        $this->assertFalse(isset($container['something']));
    }
}

コードを見るとわかる通り、実装するContainerクラスは当然オブジェクトだが、配列と同じように操作していることがわかる。 ArrayAccessインタフェースを実装することで、このテストがパスすることを確認する。

実装

Container.php
class Container implements ArrayAccess
{   
    private $container = [];

    public function offsetExists($key): bool
    {
        return isset($this->container[$key]);
    }

    public function offsetGet($key)
    {
        return $this->container[$key];
    }

    public function offsetSet($key, $value): void
    {
        $this->container[$key] = $value;
    }

    public function offsetUnset($key): void
    {
        unset($this->container[$key]);
    }
}

本来のIlluminate\Container\Containerクラスでは結合処理などを行なっているのでもう少し混み入っているが、ArrayAccessインタフェースを使用してオブジェクトに配列操作を持たせるだけならこんな感じでも十分。

Containerクラスのインスタンスは自身が保持する$containerプロパティに実際に与えられるキーと値を格納する(実際のサービスコンテナの場合、ここにキーと解決処理などをバインドする)。

それぞれ4つのメソッドの中では実際に配列をもつプロパティ$containerにアクセスして必要な操作を行うことになるため、issetunsetなどをその中で使用することが普通。
offsetExistsメソッドはissetを使用し、$containerプロパティに指定されたキーをもつ値が格納されているかをboolで返す。offsetUnsetメソッドも同様にunsetを使用してキーとその値の割り当てを解除。offsetGetメソッドとoffsetSetメソッドは$containerプロパティに対し、指定されたキーでアクセスし、値を取得するか、新規に値を登録する。

これを実装したら、テストが通ることを確認する。

$ ./vendor/bin/phpunit tests/ContainerTest.php
PHPUnit 9.0.1 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 141 ms, Memory: 4.00 MB

OK (1 test, 3 assertions)

Laravelでは他にもEloquent\ModelクラスやHttp\RequestクラスなどでArrayAccessインタフェースを実装してたりする。Containerはまだしもこの辺は正直不要だと思うが、それでも実装されてしまっているので読む際には知らないと??となりがちなので、基本的なPHPの知識として押さえておきましょう。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravelのbladeでapp.phpにエイリアスを定義せずにconst使う

app.phpにエイリアス定義したくなかった系です。

blade
@php
use App\Enums\HogeCode;
@endphp

{{HogeCode::teacher}}
HogeCode
<?php

namespace App\Enums;

final class HogeCode
{
    // 定数メンバ
    const student = 1;
    const teacher = 2;

    // key/valueの連想配列
    const enum = [
        self::student=>'生徒',
        self::teacher=>'先生',
    ];
}

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】アロー演算子

はじめに

最近PHPやLaravelを学習し始めた僕ですが、オブジェクトのメンバ(メソッド、プロパティ)を取得する役割のアロー演算子について触れる機会が多くあったので、自分なりにまとめたいと思います。
初学者が故に間違っている点ありましたらご指摘いただけると幸いです。

アロー演算子てなんぞや

->これです。
右辺に使いたいメソッドやプロパティ。左辺にそれらが置いてあるクラスを記述します。

具体的な使い方としては

class PostController extends Controller
{
    private $post;

  public function __construct(Post $instanceClass)
   {
       $this->post = $instanceClass; 
   }

    public function index () {
        $post = $this->post->all(); 
    }
}

$this->post PostControllerで定義した$postを呼んでる。呼び出す時$は取る。
post->all() コンストラクタでPostモデルを$postに代入しているので、モデルクラスの返り値であるCollectionインスタンスのallメソッドを実行できる。
モデルクラスの返り値がなぜcollectionインスタンスかについては下記参照してください。
Laravel 5.8 コレクション

読み解くコツは返り値を把握すること

個人的にはそのメソッドがどういう処理を行って、どんな値を返すのかを一つ一つ読み解くのがポイントだと思います。
返り値を把握する方法は、みなさん大好きなdd()でコツコツとデバッグしていくのがベストです。

最後に

railsを学習してた僕からしたらアロー演算子の表記が違和感ありすぎて理解に苦しみました。
単純にオブジェクトのメソッドやプロパティを呼び出すために使用しているものだと考えれば、さくさく読めるようになると思います。
ひとつひとつのアロー演算子で区切られた処理を地道にddしていき、メソッドの返り値を理解することが、初学者にとっては最善の策だと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】アロー演算子の読み解き方

はじめに

最近PHPやLaravelを学習し始めた僕ですが、オブジェクトのメンバ(メソッド、プロパティ)を取得する役割のアロー演算子について触れる機会が多くあり、読み解くのに苦労したので自分なりにまとめたいと思います。
初学者が故に間違っている点ありましたらご指摘いただけると幸いです。

アロー演算子てなんぞや

->これです。
右辺に使いたいメソッドやプロパティ。左辺にそれらが置いてあるクラスを記述します。

具体的な使い方としては

class PostController extends Controller
{
    private $post;

  public function __construct(Post $instanceClass)
   {
       $this->post = $instanceClass; 
   }

    public function index () {
        $post = $this->post->all(); 
    }
}

$this->post PostControllerで定義した$postを呼んでる。呼び出す時$は取る。
post->all() コンストラクタでPostモデルを$postに代入しているので、モデルクラスの返り値であるCollectionインスタンスのallメソッドを実行できる。
モデルクラスの返り値がなぜcollectionインスタンスかについては下記参照してください。
Laravel 5.8 コレクション

読み解くコツは返り値を把握すること

個人的にはそのメソッドがどういう処理を行って、どんな値を返すのかを一つ一つ読み解くのがポイントだと思います。
返り値を把握する方法は、みなさん大好きなdd()でコツコツとデバッグしていくのがベストです。

最後に

railsを学習してた僕からしたらアロー演算子の表記が違和感ありすぎて理解に苦しみました。
単純にオブジェクトのメソッドやプロパティを呼び出すために使用しているものだと考えれば、さくさく読めるようになると思います。
ひとつひとつのアロー演算子で区切られた処理を地道にddしていき、メソッドの返り値を理解することが、初学者にとっては最善の策だと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む