20190627のlaravelに関する記事は6件です。

phpunit.xmlの設定が反映されない

問題:phpunit.xmlが反映されない

        <env name="APP_ENV" value="testing" />

Laravelの開発で phpunit.xml の環境名の上書きを下記のテストで確認したところ、反映されませんでした。

tests\Unit\DemoTest.php

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class DemoTest extends TestCase
{
    /**
     * @test
     */
    public function 環境確認()
    {
        $this->assertEquals('testing', $this->app->environment());
    }
}
   │ Failed asserting that two strings are equal.
   │ --- Expected
   │ +++ Actual
   │ @@ @@
   │ -'testing'
   │ +'local'
   │
   │ /home/vagrant/code/demo-vue-practice/tests/Unit/DemoTest.php
   │

Time: 2.09 seconds, Memory: 16.00 MB

解決策: force=trueを設定

https://stackoverflow.com/questions/45922358/why-phpunit-is-not-getting-the-correct-app-env-as-specified-in-phpunit-xml

        <env name="APP_ENV" value="testing"  force="true"/>

またphp artisan config:clearも行う必要がありそうでした。
https://stackoverflow.com/questions/48227569/failure-to-set-app-env-to-testing-for-unit-testing-in-laravel-5-5

これで先のテストが通りました。

Unit\DemoTest
 ✔ 環境確認

Time: 2.07 seconds, Memory: 16.00 MB

以上です。

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

Swift_Message で CC とか BCC を取得する

Laravel が使っている Swift_Mailer というライブラリを使って色々独自実装を持ちたい時で、生成されたメールデータに用事がある時に毎回忘れて感覚で使ってエラーだすので書き残す。

メール本文やヘッダに持つデータは Swift_Message に格納される事になる。
そのため、表題の通り CC や BCC を取りたい場合 (それ以外も) このクラスの所有する API を使う。

$mailer->getCc();
$mailer->getBcc();

それぞれはこれだけの話なんだけど、上記で取得出来るデータの構造が連想配列で、よりにもよって key にアドレスが格納されている。

[
  "sample@sample.com" => null,
]

こんな感じ。多分、実装意図としては、連想配列の key に入れる事で集合と同じ効果を狙っている (挿入されたメールアドレスが重複した場合に 1 つにまとまる事を期待) と思うんだけど、取得する時までこの構造のままなので実に困る。(単純に考えると、配列として取得できる気がするのが困り所)

BCC に設定する時に複数を設定する場合と 1 つしか絶対に入れない時があり、今回は 1 つだけ欲しかったので下記で対応した。

key($mailer->getBcc());

全部を配列で取得する必要がある場合は下記とか。

array_keys($mailer->getBcc());
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サイトのプレビュー画像(og:image)を取得するAPIを作成

  • 仕様言語 PHP
  • フレームワーク Laravel

やりたいこと

サイトのURLから、プレビュー画像のURLを取得

方法

Goutteを使用し、metaタグのOGPを探す
OGPからプロパティog:imageがあった場合、画像URLを返す
OGPについて

実装

スクレイピング用のライブラリGoutteをインストール

$ composer require weidner/goutte

Configファイルの編集

config/app.php
'providers' => [
  ...
  Weidner\Goutte\GoutteServiceProvider::class,
  ...
],
'aliases' => [
  ...
  'Goutte' => Weidner\Goutte\GoutteFacade::class,
  ...
],

ルートに下記を追加

http://127.0.0.1:8000/api/scrape?url=https://www.facebook.com/
このようなAPIを実行すると、プレビュー画像のURLが返ってくる想定

route/api.php
Route::group(['namespace' => 'API', 'as' => 'api.'], function() {
    Route::get('scrape', 'ScrapeController@index')->name('scrape');
});

controllerの記述

Controllers/API/ScrapeController.php
<?php

namespace App\Http\Controllers\API;

use Goutte\Client;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class ScrapeController extends Controller
{
    public function index(Request $request)
    {
        $client = new Client();
        // 受け取ったURLへリクエストを送信
        $crawler = $client->request('GET', $request->url);
        // metaタグを取得し、propertyがog:imageのものの場合は、contentの中身を返す
        // propertyがog:imageでないものはnullを返す
        $contentList = $crawler->filter('meta')->each(function ($node) {
            if ($node->attr('property') === 'og:image') {
                return $node->attr('content');
            }
            return null;
        });

        // valueがnullでない(URLが格納されている)ものだけを返す
        // (goutteのfilter()でもっと上手くフィルタリングできる方法があればこの処理は不要。。)
        foreach ($contentList as $key => $content) {
            if ($content === null) {
                continue;
            }
            $imageUrl = $contentList[$key];
        }

        // URLが取得できていなかった場合はNULLを返す
        return response()->json([
            'image_url' => $imageUrl ?? NULL;
        ]);
    }
}

結果

APIを実行

$ curl http://127.0.0.1:8000/api/scrape?url=https://qiita.com

実行結果

https://cdn.qiita.com/assets/qiita-fb-2887e7b4aad86fd8c25cea84846f2236.png

実行結果

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

Laravel で アプリのオリジナルデフォルト環境を設定する

はじめに

先日 LARAVELの設定はどこを変更すべきなのか を上げたばかりですが、調べてみるとオリジナル環境を構築するために皆さまあの手この手と工夫していて、やはり頭のいい人はひと味違うもんだと感心しきり。それらの先人の知恵を拝借の上、自分のやりたいことに近づける方法を模索した記録です。

自分の環境とか

  • 開発環境はWSL上でnginxを常駐させてCドライブ上のLaravelアプリを読み込ませてる。
  • 実行環境は社内ローカルネットワーク上のサーバ。
  • DBは現在使用しているものを使用する。

なにがしたいのか

  • DBの情報をデフォルト設定としてパッケージに含めたい
  • 開発を進める途中で必要なデフォルト設定を追加したい

先人の方法とか

拙著にて「'/.env'をいじればいいんじゃね?」と書いたのはよいのですが、Laravel公式ドキュメントでは
「.envファイルは、アプリケーションのソースコントロールに含めるべきでありません。各ユーザー/サーバは異なった環境設定が必要だからです。さらに、侵入者がソースコントロールリポジトリへアクセスすることが起きれば、機密性の高い情報が漏れてしまうセキュリティリスクになります。」
などと書いてあり、まあ勉強不足ながらも、いや、勉強不足だからこそお作法には可能な限り従いたいと考えたわけです。それをふまえて
takaday 様著 [Laravel 5.5] 読み込む.envファイルを環境ごとに切り替える

Laravel使用時に困った点と対処方法
を拝見したところ、

  • '.env'を複数用意する('/.env','/.env.hoge','/.env.fuga' etc)

までは共通ですが、

  1. 'artisan' コマンドに '--env=[環境名]' をつける( 'artisan [コマンド] --env="hoge"' とか)
  2. '.htaccsess' に切替設定を書込む
  3. '/bootstrap/app.php' に切替設定を書込む
  4. 必要に応じて '/.env' を丸ごと書換える

という方法があるようです。

結局

公式ドキュメント上には上記 1. の方法(とphpUnit)で切り替えること以外は、
Laravel の .env の値は config() 経由で使う。
の方法ををどうにかしてオリジナル環境設定を読み込むことができそうですが、基本は

  • '/.env' を起動時に読み込んで '/config/*.php'を経由して設定を読み込む
  • 作成した環境キャッシュから読み込む

のどちらかのようで、それ以外の方法はどこか公式ドキュメント外の方法をとる必要があるようです。

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

LaravelでLeague/Csvを使ってDBから取得したデータをcsvで吐き出す

前提

この記事の続編ですので環境構築などはこの記事を参照してください。
LaravelでLeague/Csvを使ってアップロードされたcsvを読み込みDBに保存する

やりたいこと

Eloquentで取得したデータをcsvに吐き出し、webからダウンロードできるようにしたい。

実装

ClientController.php
public function export()
{
    $csv = \League\Csv\Writer::createFromFileObject(new \SplTempFileObject());

    // csvのヘッダーを配列で渡す
    $csv->insertOne(['id', '名前', '企業', 'メールアドレス']);

    Client::all()->each(function($client) use($csv) {
        $csv->insertOne($client->toArray());
    });

    return new Response($csv->getContent(), 200, [
        'Content-Encoding' => 'none',
        'Content-Type' => 'text/csv; charset=UTF-8',
        'Content-Disposition' => 'attachment; filename="'.'ファイル名.csv'.'"',
        'Content-Description' => 'File Transfer',
    ]);
}

実際の使い方

僕が使った時はServiceクラス作って

ClientController.php
public function exportCSV(ClientCsvExportService $service)
{
    return $service->setHeader(['id', '名前', '企業', 'メールアドレス'])
                ->setFileName(now().'ファイル名.csv')
                ->export();
}

的な感じで抽象化しました。
ClientCsvExportService内でLeague/csvを使ってます。

感想

めっちゃ楽だった。
csvインポートでLeague/csv使った時はShift_JIS対応のためのShift_JISとUTF-8での処理の分岐がめんどかったんです。
楽な書き方がエンコードするとできなくなるみたいなのがあって…
けど、今回はとても楽で良かったです。

参考文献

https://mattstauffer.com/blog/export-an-eloquent-collection-to-a-csv-with-league-csv/
https://csv.thephpleague.com/9.0/connections/output/

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

Vue + Vue Router + Vuex + Laravel 写真共有アプリチュートリアルの環境をDockerで構築する

はじめに

今年1月にQiitaに投稿されて以来、1,500以上のいいねを獲得している下記の人気チュートリアル。

Laravel + Vue.jsでのSPA開発のほか、Laravelでのテストコードの書き方など幅広い知識が同時に学べ、非常にオススメです。

このチュートリアルでは、開発環境構築にLaravel Valetを使っていますが、私の場合はDocker(Laradock)で環境を構築しました。

Dockerで環境を構築したい方は、参考にしてみてください。

環境

  • macOS High Sierra 10.13.6
  • Docker 18.09.2

ディレクトリ構造

本記事での環境構築を終えると、下記のディレクトリ構造が出来上がります。

├── data // データベースのディレクトリ
├── laradock // Docker関連ファイルのディレクトリ
└── vuesplash // Laravelのルートディレクトリ

環境構築手順

本記事での環境構築手順は、

Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (3) SPA開発環境とVue Router

「Laravelプロジェクトを作成する」「フロントエンドの準備」の直前

までに相当します。

チュートリアルの

までを読み進めたら、本記事での環境構築を実施し、その後は「フロントエンドの準備」から先を進めてください。

1. Laradockのコピー

プロジェクトのルートとなるディレクトリに、Laradockをコピーします。

$ git clone https://github.com/Laradock/laradock.git

2. Laradockの.envファイルの編集

laradockディレクトリが出来上がるので、その配下のenv-exampleファイルをコピーし、.envファイルを作成します。

$ cd laradock
laradock $ cp env-example .env

laradock/.envの以下2つの設定を編集します。

laradock/.env
APP_CODE_PATH_HOST=../vuesplash

DATA_PATH_HOST=../data

3. PostgreSQLのバージョンの指定

チュートリアルではPostgreSQLのバージョン指定はありませんが、9.6.12を使用することにします。
PostgreSQLのDockerファイルを以下の通り編集します。

laradock/postgres/Dockerfile
FROM postgres:9.6.12

LABEL maintainer="Ben M <git@bmagg.com>"

CMD ["postgres"]

EXPOSE 5432

4. コンテナのビルド

コンテナをビルドします。

laradock $ docker-compose up -d --build workspace postgres php-fpm nginx

5. Laravelのインストール

Laravelをインストールします。
バージョンはチュートリアルで使用されている5.7.19にします。

下記コマンドを実行してください。
laravel/laravel . "5.7.19"の部分にある.を忘れずに入力してください。

laradock $ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.7.19"

6. Laravelの.envファイルの編集

Laravelの.envファイルを編集し、LaravelからPostgreSQLに接続できるようにします。

vuesplash/.env
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=vuesplash
DB_USERNAME=default
DB_PASSWORD=secret

7. データベースを作成する

まず、PostgreSQLに接続します。

laradock $ docker-compose exec workspace psql -U default -h postgres

パスワードを入力します。

Password for user default: 

続いて、データベースを作成します。
データベース名は、チュートリアルで指定されているvuesplashにします。

default=# create database vuesplash;

PostgreSQLとの接続を終了します。

default=# \q

8. Laravelのlocale設定を日本にする

vuesplash/config/app.php
<?php
return [
// 略
  'locale' => 'ja',
// 略
];

9. Laravelの動作確認

http://localhost/にブラウザでアクセスし、LaravelのWelcome画面が表示されることを確認してください。

10. 後はチュートリアルを再開してください

ここまでの作業が完了したら、チュートリアルの「フロントエンドの準備」から先を進めてください。

なお、チュートリアル記事中でコマンドを実行するよう記載があった場合は、例えばそれがnpm installであれば

laradock $ docker-compose exec workspace npm install

といった具合に実行すればOKです。

最後に

以上です。

本記事が、この素晴らしいチュートリアルに取り組む方のお役に立てば幸いです:wink:

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