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

プログラミング初心者でもできる laravel で hello world 画面に表示させるまでの道のり

前提

  • Macbookでの操作になります。
  • ターミナルがなんなのかがわかるくらいのレベルの人向けの記事です。
  • laravelが使える段階まで環境構築を済ませていること。
  • php, homebrew, compser をインストールし終わって環境構築を完了している人
  • ここでは初心者向けに難しい単語などをイメージができるような説明をするため
    実際の意味とは異なる説明をするかもしれません。上級者の方は見て見ぬ振りでお願いします。

プロジェクトの作成

いきなり専門用語でてきますね。
プロジェクトの意味をなんとなくイメージできるように一つ例えをしましょう。

あなたはパキラの種を持っていました。
家の中でパキラを咲かせたいです。
まずやらなければいけないのは器を用意することです。
器がないと何も始まりません。
器があって初めて土を入れられます。

pakira.jpg

プロジェクトはその器だとお考えください。
そしてhello worldを表示させることはパキラ育てること(目的)だと思ってください。

チューリップを育てたい(hello meの表示をしたい)って思った場合でも
やはりまずは器(プロジェクト)がないと何も始まりません。
まずは器(プロジェクト)を手に入れましょう。

これでだいたいイメージはつきましたでしょうか?

では器を手に入れる(プロジェクトを作成する)にはターミナルで下記のコマンドをコピペしましょう。
※現在いるディレクトリにプロジェクトが作成されるため、プロジェクトをおきたい場所に移動してから
下記のコマンドをいれましょう。

composer create-project laravel/laravel pakira

pakiraはプロジェクト(器)の名前です。
pakiraの部分は何をつけても構いません。練習の時は。

動作確認

※ここからは器の話は忘れてくださいね?頭を切り替えていきましょう。

作ったプロジェクトにディレクトリを移動し下記のコマンドを実行する

php artisan serve

Starting Laravel development server: http://127.0.0.1:8000 みたいな結果が出てくるので
そのurlをchromeのurl欄にコピペする
おそらくほとんどの人は http://127.0.0.1:8000 になってるはず。
止める時は キーボードの control + c
スクリーンショット 2021-03-02 23.07.48.png

自分はlaravelのバージョンが8.29.0なのでこう言う画面になってますがバージョンによって表示される内容がちょっと変わったりするそうです。
エラーとかでなければ成功です!

APP_KEYの生成

これも専門的な言葉が出てきますね。とりあえず、laravel取り入れたらこれをやるものなんだって覚えましょう
(他の人laravelをcloneしてきた時も同じ。これを行ってください)
これがないとうまく使えない機能とかあります。そのうち、あれ?なんで動かないんだ?って
一日中原因調査する羽目になったりするかもしれないので。

php artisan key:generate

これをやると .env っていうファイルの中の APP_KEY= っていうところに英数字が追加されてます。
追加されてたら成功!

heroku使う予定がある方

heroku というサービスを使う予定であれば
heroku側でもこのkeyの設定がないとうまく動かないので
※heroku使わない方はここはスキップしてください。

heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)

heroku関連の設定したほうがいいもの

エラーがweb画面で見れるようにする

config/app.php の 'debug' => (bool) env('APP_DEBUG', false), って書いてあるところ
こいつをfalseじゃなくてtrueにすると見れるようになるはず。
42行目あたりにこの記述があると思いますが
なかったらバージョンが変わったことによっての影響なので別途必要に応じて調べれください

config/app.php
'debug' => (bool) env('APP_DEBUG', true),

Procfileを作成

これも
手動でもできますしコマンドでもできます。
ここではコマンドを使って作成する方法を紹介します。
やりたいことはアプリフォルダ直下にProcfileって言う名前のファイルを作ってコピペするだけです。

touch Procfile
echo 'web: vendor/bin/heroku-php-apache2 public/' > Procfile
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

flysystem-aws-s3-v3は~1.0を使いましょう

概要

LaravelからAWS S3に画像をアップロードをしようとしたら起きた事象です。

Class 'League\Flysystem\AwsS3v3\AwsS3Adapter' not found

原因

LaravelのReadableを見たら、

Composerパッケージ
S3やSFTPドライバーを使用するときは、事前にComposerパッケージマネージャーを介して適切なパッケージをインストールする必要があります。
Amazon S3: league/flysystem-aws-s3-v3 ~1.0

と書かれておりました。

何も考えずにインストールしたら、

composer require league/flysystem-aws-s3-v3

2.0が入ってしまっていたので、ダウングレードします。

composer require league/flysystem-aws-s3-v3 ~1.0

無事直せました。

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

初学者がCircleCI/CDを実装する上で感じた注意点

前提

・以下の記事に書かれていることを理解している
いまさらだけどCircleCIに入門したので分かりやすくまとめてみた

・Laravelを用いたアプリケーションに対してCI/CDを実行する
CI・・・Githubプッシュ時にPHPUnitが自動で実行される(テスト用データベースにSQLiteのインメモリ機能を使用)
CD・・・Dockerfileより自前のイメージを作成し、そのイメージをOrbsを利用しECRへ自動プッシュし、そしてそれをECSへ自動デプロイする

環境

PHP Laravel PHPUnit SQLite Docker
7.4.5 7.28.4 8.5 3.28.0 19.03.13

.circleci/config.yml

version: 2.1

orbs:
  aws-ecr: circleci/aws-ecr@6.5.0
  aws-ecs: circleci/aws-ecs@1.2.0

jobs:
  test:
    docker:
      - image: circleci/php:7.4.5-node-browsers
    working_directory: ~/intro-app
    steps:
      - checkout
      - run:
          name: Update apt-get
          command: sudo apt-get update
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "composer.json" }}
            - v1-dependencies-
      - run:
          name: Install PHP libraries
          command: composer install -n --prefer-dist
      - save_cache:
          paths:
            - ./vendor
          key: v1-dependencies-{{ checksum "composer.json" }}
      - run:
          name: Install three libraries related to GD
          command: sudo apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev
      - run:
          name: Support Freetype2 and jpeg
          command: sudo docker-php-ext-configure gd --with-freetype --with-jpeg
      - run:
          name: Install GD library
          command: sudo docker-php-ext-install -j$(nproc) gd
      - run:
          name: Generate php artisan key
          command: php artisan key:generate --env=testing
      - run:
          name: Run PHPUnit
          command: vendor/bin/phpunit

workflows:
  test_and_deploy:
    jobs:
      - test
      - aws-ecr/build-and-push-image:
          requires:
            - test
          context: AWS_ECR_ECS
          repo: intro-app_circleci
          tag: '${CIRCLE_SHA1}'
          filters:
            branches:
              only: master
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          context: AWS_ECR_ECS
          family: 'intro-app'
          cluster-name: 'intro-app'
          service-name: 'intro-app'
          container-image-name-updates: 'container=intro-app,image-and-tag=${AWS_ECR_ACCOUNT_URL}/intro-app_circleci:${CIRCLE_SHA1}'
          filters:
            branches:
              only: master

CIに関するエラー

ダミーファイルを生成できない

CircleCIのテスト時に、ダミーファイルを使用した箇所全てにエラーが表示された。

UploadedFile::fake()->image('photo.jpg'),
Tests\Feature\InformationControllerTest::testStore
Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor()

このメソッドが定義されているIlluminate\Http\UploadedFileクラスをコンテナ内で使うには、PHP GDというPHPのライブラリが必要なので、CircleCI環境下にもインストールしてあげる。

PHP GDのインストールは以下の記事を参考にするとうまくいく(他の記事ではなかなかうまくいかないので要注意)
Docker上でPHP拡張モジュール『GD』を有効化する

.circleci/config.ymlでのインストール箇所

- run:
    name: Install three libraries related to GD
    command: sudo apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev
- run:
    name: Support Freetype2 and jpeg
    command: sudo docker-php-ext-configure gd --with-freetype --with-jpeg
- run:
    name: Install GD library
    command: sudo docker-php-ext-install -j$(nproc) gd

CDに関するエラー

1 Orbsはワークフロー内で使用しなければならない

一度、Orbsを以下のようにjobsの中に書いてみたことがある。

jobs:
  test:
  // 省略
  deploy:
    steps:
      - aws-ecr/build-and-push-image:
          requires:
            - test
          context: AWS_ECR_ECS
          repo: intro-app_circleci
          tag: '${CIRCLE_SHA1}'
          filters:
            branches:
              only: master
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          context: AWS_ECR_ECS
          family: 'intro-app'
          cluster-name: 'intro-app'
          service-name: 'intro-app'
          container-image-name-updates: 'container=intro-app,image-and-tag=${AWS_ECR_ACCOUNT_URL}/intro-app_circleci:${CIRCLE_SHA1}'
          filters:
            branches:
              only: master

workflows:
  test_and_deploy:
    jobs:
      - test
      - deploy:
          requires: test

このように設定すると、「aws-ecr/build-and-push-image」や「aws-ecs/deploy-service-update」はコマンドではない!と怒られる(stepsにはCI環境上で行うコマンドなどを記述する。jobsの下にstepsを配置するのはマスト)。

よってOrbsはworkflow内に記述する。

2 Orbsのパラメータに注意を払う

Orbsのパラメータはいろいろ存在する。

aws-ecr/build-and-push-imageのパラメータ

パラメータ 説明 必須 デフォルト
aws-access-key-id アクセスキー NO AWS_ACCESS_KEY_ID
aws-secret-access-key シークレットアクセスキー NO AWS_SECRET_ACCESS_KEY
account-url ECRアカウントURL NO AWS_ECR_ACCOUNT_URL
repo ECRレポジトリ名 YES なし
region リージョン NO AWS_REGION
tag タグ NO latest
dockerfile ECRへプッシュするイメージを作成するためのDockerfileの指定 NO Dockerfile
context コンテキスト no なし

aws-ecs/deploy-service-updateのパラメータ

パラメータ 説明 必須 デフォルト
aws-access-key-id アクセスキー NO AWS_ACCESS_KEY_ID
aws-secret-access-key シークレットアクセスキー NO AWS_SECRET_ACCESS_KEY
family タスク定義名 YES なし
cluster-name クラスター名 YES なし
service-name サービス名 NO 空文字列
container-image-name-updates デプロイ先のコンテナ名とデプロイするイメージ名 NO 空文字列
context コンテキスト no なし

注意するポイントは以下の2つ。

パラメータにはデフォルト値が設定されている

デフォルト値とCirclCIの環境変数が一致している場合、パラメータの記述を省略しても、そのパラメータに設定したCircleCIの環境変数が適用される。

contextを設定しなければCircleCIの環境変数を参照できない

ここはかなり詰まってしまったところだ。
contextの中に環境変数を設定した場合、パラメータにcontextを設定しなければ、そのcontext内の環境変数を参照できない。

3 vendorディレクトリの不足

デプロイには成功したが、コンテナが落ちてしまった。CloudWatchでコンテナ内で起きたエラーをチェックしてみると以下のエラーメッセージが検出された。

Warning: require(/workdir/vendor/autoload.php): failed to open stream: No such file or directory in /workdir/artisan on line 18

このエラーは、「vendorディレクトリが存在しない」ために起きたもの。
リモートリポジトリにプッシュする際、vendorディレクトリは含まれない設定になっているため(.gitignoreに記述してある)、本番環境にデプロイしたLaravelのコード群の中にもvendorディレクトリは存在しない。

ではどうするか?
vendorディレクトリは「composer install」でインストールできるので、Dockerfileに以下のように記述する。

RUN composer install

補足

「composer install」をDockerfile内のどこにどうやって書けばいいのか悩んでしまったので、その経緯を一応細かく書いておきます。(めちゃくちゃ基礎的なことを理解できていませんでした)

悩んだ原因は、Dockerfileの「RUN」コマンドと「CMD」コマンドを誤って解釈していたからでした。

僕の間違った解釈
RUN・・・イメージを生成するためだけのコマンド
CMD・・・コンテナ内で実行するコマンド

正しい意味
RUN・・・コンテナ内で実行するコマンド
CMD・・・コンテナ起動時一度だけ実行されるコマンド

上記のように解釈していたので、もうCMDコマンドはサーバーを立ち上げるために一度使っているから、どうやって「composer install」を実行すればいいのか?と悩みました。。。

以下の記事が大変参考になりました。
僕はイメージのbuildを間違って捉えていました。。。
DockerのRUNとCMDの違い

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

SQLiteを使ったテストで初学者がはまったエラー ~Laravel~

前提

テスト用データベースはSQLiteインメモリを使用しています。

環境

PHP Laravel PHPUnit SQLite
7.4.5 7.28.4 8.5 3.28.0

エラー内容 「リレーションが辿れない」

前提

SQLiteは以下のデータ型の値しか格納しない。

内容
INTEGER 符号付整数。1, 2, 3, 4, 6, or 8 バイトで格納
NUMERIC 負号付きの整数 (1、2、3、4、6、8バイト)
REAL 浮動小数点数。8バイトで格納
TEXT テキスト。UTF-8, UTF-16BE or UTF-16-LEのいずれかで格納
NONE カラムにデータを指定しなかった場合この型になる

以前Laravelで書いていたマイグレーションファイルの一部はこんな感じ。

profilesテーブル

/**
 * Run the migrations.
 *
 * @return void
 */
 public function up()
 {
     Schema::create('profiles', function (Blueprint $table) {
         $table->increments('id');
         $table->unsignedInteger('user_id');
         $table->string('name');
         $table->text('introduction');
         $table->timestamps();

         $table->foreign('user_id')->references('id')->on('users');
     });
  }

profilesテーブルのuser_idカラムとusersテーブルidカラムで紐付かせている。

エラー

テストする際にこのリレーションの箇所でサーバーエラーが連発した。ここの紐づきだけでなく、他の全てのリレーションを辿るアクションでサーバーエラーが発生した。
ここでかなり詰まってしまった。原因が分からない。。。

原因

いろいろ調べた結果、SQLiteがサポートしている型にエラーの原因が存在することが判明した。

SQLiteのサポートしている型一覧

サポートしている型 実際にSQLiteが格納する型
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
INTENGER
CHARACTER(20)
VARCHAR(255)
VARYING CHARACTER(255)
NCHAR(55)
NATIVE
CHARACTER(70)
NVARCHAR(100)
TEXT
CLOB
TEXT
NUMERIC
DECIMAL(10,5)
BOOLEAN
DATE
DATETIME
NUMERIC
REAL
DOUBLE
DOUBLE PRECISION
FLOAT
REAL
BLOB NONE

どういうことかというと、テーブル作成の際にカラムの型を指定をするが、そのカラムの型がSQLiteでは使用できない型である場合、SQLite自身がSQliteでも扱えるデータ型に強制的に変換し、データを格納する。
表の左側が変換対象のカラムの型、表の右側は変換後の型。

これを踏まえて上のマイグレーションファイルをもう一度確認してみると、外部キーに設定しているuser_idカラムの型は「unsignedInttenger」。
SQLiteを見てみると、「UNSIGED BUG INT」は存在するが、「UNSIGNED INT」は存在しない。

つまり外部キーに設定したカラムの型は、SQLiteではサポートされていなかったということ。
したがってprofilesテーブルのuser_idカラムの値はINTENGERと扱われず、その結果リレーションメソッドを用いても紐づきを辿ることができず、サーバーエラーになったっぽい。

解決案

外部キーカラムを「UNSIGNED INT」型にしてしまえばよい。

僕はLaravel7で新しく導入された外部キーのフォーマットにしたがってマイグレーションファイルを書き換えた。

profilesテーブル(変更後)

/**
 * Run the migrations.
 */
 public function up(): void
 {
     Schema::create('profiles', function (Blueprint $table) :void {
         $table->id();
         $table->foreignId('user_id')->constrained();
         $table->string('name');
         $table->text('introduction');
         $table->timestamps();
     });
  }

変更前の外部キー設定

$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');

変更後の外部キー設定

$table->foreignId('user_id')->constrained();

この変更された外部キー設定の特徴は、
・1行で外部キー設定が完了する(テーブル名とカラム名が規約通りではない場合、constrainedの引数にテーブル名を指定する)
この外部キーのカラムの型は自動的に「unsignedBigInteger」となる

したがって、このフォーマットにしたがって外部キー設定をすることで外部キーカラムの型は「UNSIGNED BIG INT」型になり、SQLiteのサポート範囲内となり、きちんとINTENGER型としてデータを格納してくれる。

結果、リレーションを辿ることができた。

補足
ミドルウェアにて以下のポリシーを用いてアクセス制限をしていた。

/**
 * プロフィール編集の権限があるかチェック
 *
 * @param User $user
 * @return mixed
 */
 public function view(User $user)
 {
      $profile = $user->profiles()->first();
      return $user->id === $profile->user_id;
 }

SQLiteを使用したテストのときだけこのポリシーを通過できなかった。
「===」を使って厳密な型比較せず、「==」に変更した場合はクリアした。
外部キーをunsignedBigIntengerにして、SQLiteにIntengerとして扱ってもらったが、厳密な型比較をすると、なぜか差異がでるそう。。。ここらへんはまだ理解していません。。。

最後に

このように対処することで解決致しましたが、何か間違いがあるかもしれません。
何かお気づきの方いらっしゃいましたら、気軽にコメントのほどよろしくお願い致します。

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

With スコープの外の変数使えない

このように書く。
function($query) use (変数名) {

}

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

With スコープの外の変数使えないので使えるようにするには

このように書く。
function($query) use (変数名) {

}

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

(備忘録)laravelでCURDとデータ操作

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