20200206のlaravelに関する記事は5件です。

Laravel5.6以降のLog設定の小ネタ

config/log.phpでログを設定するようになってからの設定方法についての小ネタ。
ドキュメントに明示されておらず、StackOverflow等でもなかなか出てこないので書いておく。

monolog driver以外でも、Formatterはconfig/log.phpで指定できる

https://laravel.com/docs/6.x/logging#customizing-monolog-for-channels

Monolog Formatters
When using the monolog driver, the Monolog LineFormatter will be used as the default formatter. However, you may customize the type of formatter passed to the handler using the formatter and formatter_with configuration options:

'browser' => [
    'driver' => 'monolog', // <= simpleドライバなどでもformatter指定できる
    'handler' => Monolog\Handler\BrowserConsoleHandler::class,
    'formatter' => Monolog\Formatter\HtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],
  • ドキュメントには monolog ドライバー用のオプションのように書かれているが、 simpledaily のdriverであっても同様に、formatterパラメータが有効
    • 同様にformatter_withも有効

tap()時、getHandlers()で全ハンドラを回さなくても直接$logger->pushProcessor()できる

ドキュメントの tap() のサンプルが以下のように書かれているため、プロセッサの設定でも同様のループを書いていることが多い

// tapの処理サンプル
public function __invoke($logger)
{
    foreach ($logger->getHandlers() as $handler) {
        $handler->setFormatter(...);
    }
}
public function __invoke($logger)
{
    foreach ($logger->getHandlers() as $handler) {
        // ならこうやろ!
        $handler->pushProcessor(...);
    }
}

※このサンプルに引っ張られて上記Formatterの設定を tap() でやってしまう疑惑

  • __invoke($logger) に渡される実体は Monolog\Logger
  • Loggerのスタック全体に対して適用するProcessorを pushProcessor() で突っ込める ⇒ソース

            public function __invoke($logger)
            {
                // 全部に適用したいならこれで十分
                $logger->pushProcessor(...);
            }
    
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Dusk テストコード作成時の困った場合の対処法

Laravel dusk でブラウザテストを作成していて困った部分の対処法のメモです。
間違っている箇所があればご指摘いただけましたら幸いです。

dusk失敗の原因が知りたい

app\tests\Browser\screenshots配下に失敗時の画面スクリーンショットが作成されます。

The MAC is invalid.

暗号化キーを再生成する → php artisan key:generate
※暗号化したパスワードが複号できなくなるので取り扱い注意
[引用]
https://error-search.com/error-post/detail/144/The%2BMAC%2Bis%2Binvalid.

Operation timed out after 30001 milliseconds with 0 out of -1 bytes received

jsの読み込みがが遅い場合、テストの速度に画面が追い付いていない場合に出現するエラーです。
waitFor waitForText なりを入れてから検証すること。

要素の表示をwaitで待つ

$browser->waitForText('検索', 30);
$browser->waitFor("#search", 30);

jsで最前面に表示される画面の要素のclickができないとき

素のjsでクリックする(サービスプロバイダにマクロを登録する 下記 clickToElement 参照)

//クリックする
$browser->clickToElement(".search_btn");

画面内に表示されていない要素がクリックできないとき

素のjsで要素にスクロールする (サービスプロバイダにマクロを登録する 下記 scrollToElement 参照)

[参考]
https://readouble.com/laravel/5.7/ja/dusk.html (ブラウザマクロ)
https://readouble.com/laravel/5.3/ja/providers.html (サービスプロバイダ)
https://github.com/laravel/dusk/issues/203 (マクロ登録例)

<?php
namespace App\Providers;

use Laravel\Dusk\Browser;
use Illuminate\Support\ServiceProvider;

class DuskServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        Browser::macro('scrollToElement', function ($element = null) {
            $this->script("$('html, body').animate({ scrollTop: $('$element').offset().top }, 0);");

            return $this;
        });

        Browser::macro('clickToElement', function ($element = null) {
            $this->script("document.querySelector('$element').click();");

            return $this;
        });

        Browser::macro('switchFrame', function ($frame = null) {
            if ($frame) {
                $this->driver->switchTo()->defaultContent()->switchTo()->frame($frame);
            } else {
                // Main frame
                $this->driver->switchTo()->defaultContent();
            }
            return $this;
        });
    }
}

testの中断(Ctrl + c)でDB接続先がずれた?

.env / .env.dusk.local の DB_HOST= を確認する。

chromeの設定ファイル (UAを変えたい 画面サイズを変更したいなどはここで)

DuskTestCase.php

$ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.91 Mobile/15E148 Safari/605.1';
        $options->setExperimentalOption('mobileEmulation', ['userAgent' => $ua]);

head部分のテスト

duskはcssセレクターで検証しようとすると先頭に'body'がつくため、bodyタグより上の要素の検証をしたい場合はこの書き方で

 $browser->assertSourceHas("<meta name=\"description\" content=\"Qiitaは情報満載!\">");

xpathを使って要素の値を取り出すことも可能 (xpathも使えます)

use Laravel\Dusk\Browser;
use Facebook\WebDriver\WebDriverBy; //xpath用
略
$browser->driver->findElement(WebDriverBy::xpath("//link[@rel='canonical']"))->getAttribute('href')

Rspec の before after のようなものを実装したい

[参考]
https://cpoint-lab.co.jp/article/201812/7155/

public function setUp() :void
{
    parent::setUp();
    // テストデーターの準備などを行う
}

PHPUnitのアサーションも使えます

$this->assertEquals($element_count, 50);

セッションの破棄

  $browser->driver->manage()->deleteAllCookies();

function日本語化(@testつける)

/**
 * @test
 */
public function ステータステスト()
{
    $res = $this->get("url");
    $res->assertStatus(200);
}

テストをグループ化して実行 (@group アノテーションでグループ化)

php artisan dusk tests/Browser/ --group samplegroup

/**
 * @group samplegroup
 */
public function sampleTest()
{
   //処理

テストをファイル単位で実行

php artisan dusk tests/Browser/SampleTest.php

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

Laravelのbladeで脆弱性を考慮した改行とスペース表示

https://twitter.com/mpyw/status/1224923891924996099
@mpywさんから学んだことをメモします。

結論

image.png

>ヒューマンエラーでXSS脆弱性に結びつくため
・改行したいときはCSSでpre-wrapを当てる
・HTMLを生で出したいときは HTMLString クラスを使う
・基本的には {!! !!} は使用禁止
・メールテンプレート以外では使わない
・HTMLStringを作る場合は、属性値とかテキストとかはかならずe関数でエスケープ
例:PHPでネストした連想配列を の配列に組み立てる

ちなみに

{!! nl2br(e($hoge)) !!}

上記の書き方でもエスケープ処理はされますが、改行しか反映されません。
改行とスペースも反映させたい場合は、下記のようにCSSでpre-wrapあてます。

<div style="white-space:pre-wrap;">{{$message}}</div>

【注意】

<div>
  foo
</div>

ではなく

<div>foo</div>

のように詰めるように!

参考文献

この記事は以下の情報を参考にしました。

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

【laravel】マイグレーション、やり直しコマンドいろいろ

テーブルの修正、再構築のコマンドについて簡単にメモします。

マイグレーションはそのDBのmigrationsテーブルで管理されます。
migrationsテーブルにはbatchというカラムがあり、値の順にmigrateされたことを表します。下のDBではcreate_photos_tableファイルが直近で実行されたということになります。
スクリーンショット 2020-02-05 11.51.43.png

status

マイグレーションの状態を確認します。

php artisan migrate:status

+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | 2014_10_12_000000_create_users_table           | 1     |
| Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
| Yes  | 2019_08_19_000000_create_failed_jobs_table     | 1     |
| Yes  | 2020_02_05_015307_create_albums_table          | 2     |
| Yes  | 2020_02_05_020352_create_photos_table          | 3     |
+------+------------------------------------------------+-------+

このDBでは1,2,3の順でマイグレーションが実行されたこと表しています。

rollback

ロールバック(直前に行った一連のマイグレーションをなかったことにする)
・down()メソッドに書かれた処理が実行されます。
・先ほどのDBではbatchが3のマイグレーションがロールバックされ、状態は「No」と表示される

$ php artisan migrate:rollback

ロールバックが実行されるとRanのところが「No」と表示されます。

+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | 2014_10_12_000000_create_users_table           | 1     |
| Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
| Yes  | 2019_08_19_000000_create_failed_jobs_table     | 1     |
| Yes  | 2020_02_05_015307_create_albums_table          | 2     |
| No   | 2020_02_05_020352_create_photos_table          |       |
+------+------------------------------------------------+-------+

・--stepのオプションで[数値]回のロールバックを行います。
batchの値が3の場合、php artisan migrate:rollback --step=2をするとbatchが1の状態まで戻ります。

$ php artisan migrate:rollback --step=[数値]

reset

すべてのマイグレーションをロールバックします。

$ php artisan migrate:reset
$ php artisan migrate:reset
Rolling back: 2020_02_05_015307_create_albums_table
Rolled back:  2020_02_05_015307_create_albums_table 
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back:  2019_08_19_000000_create_failed_jobs_table 
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table 
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table 

$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| No   | 2014_10_12_000000_create_users_table           |       |
| No   | 2014_10_12_100000_create_password_resets_table |       |
| No   | 2019_08_19_000000_create_failed_jobs_table     |       |
| No   | 2020_02_05_015307_create_albums_table          |       |
| No   | 2020_02_05_020352_create_photos_table          |       |
+------+------------------------------------------------+-------+

すべてのマイグレーションの状態が「No」となります。

refresh

すべてのマイグレーションをロールバックしてから再びマイグレーションします。

$ php artisan migrate:refresh
$ php artisan migrate:refresh

Rolling back: 2020_02_05_020352_create_photos_table
Rolled back:  2020_02_05_020352_create_photos_table (0.02 seconds)
Rolling back: 2020_02_05_015307_create_albums_table
Rolled back:  2020_02_05_015307_create_albums_table (0.02 seconds)
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back:  2019_08_19_000000_create_failed_jobs_table (0.02 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (0.02 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (0.02 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.06 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.06 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.04 seconds)
Migrating: 2020_02_05_015307_create_albums_table
Migrated:  2020_02_05_015307_create_albums_table (0.04 seconds)
Migrating: 2020_02_05_020352_create_photos_table
Migrated:  2020_02_05_020352_create_photos_table (0.04 seconds)

fresh

すべてのテーブルをドロップ(削除)してから再びマイグレーションします。

$ php artisan migrate:fresh

Dropped all tables successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.06 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.06 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.04 seconds)
Migrating: 2020_02_05_015307_create_albums_table
Migrated:  2020_02_05_015307_create_albums_table (0.04 seconds)
Migrating: 2020_02_05_020352_create_photos_table
Migrated:  2020_02_05_020352_create_photos_table (0.04 seconds)

refreshと異なるのはロールバックが行われないこと。つまりdown()メソッドが実行されずにDBの再構築が行われる点。
したがって複数DBを持つプロジェクトではfreshを行うとエラーが出てしまいます。なぜなら一方のDBだけが削除されてしまうためです。

まとめ

status マイグレーションの状態確認
rollback 直前のマイグレーションをロールバック
reset すべてのマイグレーションをロールバック
refresh すべてのマイグレーションをロールバックしmigrateを実行。
fresh すべてのテーブルを削除しmigrateを実行。

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

Laravel/uiを入れたらnpmが通らない[apt-get等でnpmとnodeが古いケース+Docker環境]

ハマったので備忘録。

問題


Laravel/uiを入れた後には
npm installして必要なモジュールをインストールする。

自分の場合は開発環境でdocker越しにlaravelの環境を動かしていて、
npmは

apt-get install -y node npm

でインストールしていた。その後、

$ composer require laravel/ui
$ php artisan ui vue --auth

でlaravel/uiをインストールした後、

$ npm install

が途中で止まって進まない。
という問題に直面した。
IEEEなんたらうろ覚えというモジュールの近辺で静止する。

解決

ログを見ると実行した直後に警告が出ており、現在のnpmとnodeは対応してないという警告が出ていた。
どうもapt-getで得られていたnpmとnodeのバージョンが古いようで、
apt-getではなく、npmとnodeを公式のホームページから直接インストールすることで解決した。
(下のDockerfileの今回の解決手順の所を参考)

dockerのコンテナで動かしていたため、自分はアンインストールは不要だったが、
自動的にnpmとnodeのインストールが破棄されない場合は、
アンインストールの手順が必要になるかもしれない。

Dockerfile[参考]
FROM php:7.4.2-apache
RUN apt-get update

#composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'c5b9b6d368201a9db6f74e2611495f369991b72d9c8cbd3ffbc63edff210eb73d46ffbfce88669ad33695ef77dc76976') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php \
&& php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
RUN composer self-update

#node,npm install--今回の解決手順
#nodeのversionは必要に応じて変更すること。
#Dockerでない場合はnode npmのアンインストールがおそらく必要(手順未確認)。
#アンインストールが成功した場合は、RUN以下をlinuxコマンドに読み替えて実行する。
RUN apt-get install -y wget
RUN wget https://nodejs.org/dist/v12.14.1/node-v12.14.1-linux-x64.tar.xz
RUN tar -xf node-v12.14.1-linux-x64.tar.xz
RUN mv node-v12.14.1-linux-x64/bin/* /usr/local/bin/
RUN mv node-v12.14.1-linux-x64/lib/node_modules/ /usr/local/lib/

#php plugin install
RUN docker-php-ext-install pdo_mysql mysqli

#for Laravel rooting
#このコンテナのイメージ元のphp:7.4.2-apacheではrewirte.soが標準で読み込まれていない。
#Laravelのrootingには必要なモジュールなので読み込ませる。
RUN mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/

#debug soft install
RUN apt-get -y install vim

追記:
Dockerは本当はnpm、http、phpは別コンテナにした方が
良いのかもしれないけれども、参考までに。

追記2:
rootingが動かなかったので動くように参考のDockerfileを修正

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