- 投稿日:2020-06-27T23:52:10+09:00
Laravel MySQL DBのカラム名を途中で変更する
目的
- Laravelにて新規作成後のDBのカラム名の変更方法をまとめる
実施環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.5) ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) プロセッサ 2 GHz クアッドコアIntel Core i5 メモリ 32 GB 3733 MHz LPDDR4 グラフィックス Intel Iris Plus Graphics 1536 MB
- ソフトウェア環境
項目 情報 備考 PHP バージョン 7.4.3 Homwbrewを用いて導入 Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする 前提情報
- MySQLを使用しているが確認箇所以外はそのほかのRDSでも作業内容は変わらない。
- カラム名を変更するとLaravelアプリで自分で実装したデータ取得処理を変更しないといけない場合があるので注視する。
- すでに存在するカラムの名前を変更する際の方法を記載する。
- 本方法と応用するとカラムタイプなどの変更可能となる。
- 公式ドキュメントに記載されている内容を元に自分なりにまとめてみる。
概要
- ライブラリのインストール
- マイグレーションファイルの作成と記載
- マイグレート
- 確認
詳細
ライブラリのインストール
アプリ名ディレクトリで下記コマンドを実行してライブラリをインストールする。
$ composer require doctrine/dbalマイグレーションファイルの作成と記載
アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを作成する。
$ php artisan make:migration rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table --table=所属テーブル名アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。
$ vi database/migrations/YYYY_MM_DD_XXXXXX_rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table.phpマイグレーションファイルを下記の様に修正する。(
public function up()
にはマイグレーションにより実行したい処理(今回だとカラムのリネーム)処理を記載する。public function down()
にはロールバックで実行したい(カラムのリネームを直す)処理)database/migrations/YYYY_MM_DD_XXXXXX_rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table.php<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class Rename変更する前のカラム名To変更した後のカラム名Onテーブル名Table extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('テーブル名', function (Blueprint $table) { //下記を追記する $table->renameColumn('変更する前のカラム名', '変更した後のカラム名'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('テーブル名', function (Blueprint $table) { //下記を追記する $table->renameColumn('変更した後のカラム名', '変更する前のカラム名'); }); } }マイグレート
アプリ名ディレクトリで下記コマンドを実行してマイグレートを実行する。
$ php artisan migrate確認
下記コマンドを実行してMySQLにターミナルからログインする。(MySQLのパスワードを忘れてしまった方はこちら→Mac ローカル環境の MySQL 8.0 のrootパスワードを忘れた時のリセット方法)
$ mysql -u root -p下記を実行してカラム名が変更されたことを確認する。
mysql> show columns from DB名.テーブル名;参考文献
- 投稿日:2020-06-27T21:22:11+09:00
Laravel入門学習ノート part5 『データベース接続』
おことわり
勉強始めたばかりなので都度修正したり追記したりすると思います。
もちろん、内容はコアな部分ではなく初心者向けのものです。今回の内容
DB接続
結論から言うと
安定して接続できる(=使い慣れている)DBの情報を/.env
に書き込むだけ。
DBがないならたぶんxampp入れるのが一番安定する。Laravelの設定
config/database.php
にLaravelからDBを利用する際の設定が書かれている。
見てみると、設定項目は連想配列でsqliteやmysqlのように分かれており、さらにその子のキー名からなんの設定かわかる。config/database.php<?php use Illuminate\Support\Str; return [ 'default' => env('DB_CONNECTION', 'mysql'), 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'url' => env('DATABASE_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), ], 'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], // 省略.envの設定
database.php
に設定が書かれているが、env(...)
という関数が使われている。
env
関数は.envファイルに書かれた設定を参照する関数。
.envファイルはlaravelアプリフォルダの直下にある。.envファイルを使用するDBに合わせて下記のように設定する。
(例)/.envDB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=practice DB_USERNAME=root DB_PASSWORD=abcd1234この.envファイルの中からenv関数の第一引数に指定された項目を参照する。
なかった場合、第二引数で指定したものがデフォルトが返ってくる。env('DB_DATABASE', 'forge')この場合、.envの
DB_DATABASE
にはpractice
が設定されているのでpractice
が返ってくる。
設定されていない時は、forge
が返ってくる。DB接続のようにほぼ固定な情報は.envにまとめておくのがいい気がする。
dbnameやportなどもろもろ設定する。接続確認
設定したら接続確認。
いきなりDBを操作してもいいけど不安な時はコマンドで確認できる。プロジェクトフォルダに移動してartisanのtinkerコマンドを使用する。
cd laravel_project php artisan tinker
>>>
が出てきてプログラムを1行ずつ実行できるようになる。
その状態で下記を実行。DB::connection()->getConfig(); // ...(1) DB::connection()->getPdo(); // ...(2)(1)では、今回DB接続に使用する設定が出力される。
(2)では、接続したDBの情報が表示される。確認ができたら
exit();で終了。
接続が失敗すると(2)で赤文字でいろいろ言われるっぽい。
うまくつながらない時は.envの設定やDBの状態などを確認。.envを変更した時は
exit();
で終了し、再度php artisan tinker
からやり直さないと設定が反映されないので注意。
- 投稿日:2020-06-27T18:26:24+09:00
【Laravel】グローバルスコープを用いてコード量を減らす
はじめに
実装していてモデルのクエリに制約で何度も同じ実装することはありませんか。
そんな時はグローバルスコープというLaravelの機能のグローバルスコープを使って1回の実装で済むようにするのも1つの方法かなと思います。グローバルスコープとは
グローバルスコープにより、指定したモデルの全クエリに対して、制約を付け加えることができます。Laravel自身のソフトデリート機能は、「削除されていない」モデルをデータベースから取得するためにグローバルスコープを使用しています。独自のグローバルスコープを書くことにより、特定のモデルのクエリに制約を確実に、簡単に、便利に指定できます。
グローバルスコープを1回の実装すれば特定のモデルのクエリに制約ができ、かなり便利です。
グローバルスコープの実装
Illuminate\Database\Eloquent\Scope
配下に適当なファイルを作成します。walkingMinutes.php<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class walkingMinutesScope implements Scope { /** * Eloquentクエリビルダへ適用するスコープ * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function setGlobalScope(Builder $builder, Model $model) { static::addGlobalScope('walking_minute', function (Builder $builder) { $builder->orderByRaw('walking_minute' ASC NULLS LAST); }); } }こんな感じに実装するとどこでもwalking_minutes(徒歩時間)が短い順に表示できるようになります。
おわりに
いかがでしたでしょうか。
うまく実装して無駄な実装を減らしていきましょう。
- 投稿日:2020-06-27T16:27:52+09:00
Laravel開発用のDockerイメージできたのでシェアします。
これからLaravelを使って開発とかしていく予定だったので、すぐにスタートできるようにDockerでイメージ作りました。
同じ環境で開発してる方など、よかったら持ってってください。https://hub.docker.com/r/ryuki0529/webserver
大まかなイメージ環境
- OS:CentOS 7.8
- サーバー:Apache 2.4.6
- PHP 7.4.7
- PHPMyAdmin 5.0.2
- Composer 1.10.7
- Laravel Installer 3.1.0
- Git 2.9.5
- データベース:mysql Ver 15.1 Distrib 10.4.13-MariaDB
注意点
docker run
でコンテナ作るときに、--privileged
と起動時のコマンドで/sbin/init
を指定しないとsystemctl
コマンド周りが使えないので注意です。これで3時間ほどハマってしまいました。詳しくは下記の記事で説明されてます。
CentOS7のコンテナでsystemctlを使うための方法ということで、最終的にコマンドは以下になります。
docker run -itd -p 80:80 --privileged webserver:1.0.2 /sbin/init docker exec -it webserver /bin/bash
- 投稿日:2020-06-27T12:04:38+09:00
S3 に アップロードした view ファイルの URL を一時的なものにする。( Severless Framework x Laravel )
はじめに
セキュリティの面で、S3 にアップロードしている view ファイルの URL を一時的なものに変更する必要があったので、その手順を残します。
S3 に view ファイルをアップロードする記事はこちら
https://qiita.com/soma_sekimoto/items/5cdeb4b51141e95ba9721. .env の "AWS_ACCESS_KEY=" などの AWS 関連の部分を複製する。そして、S3 のバケットのポリシーを持つキーを入力する。
AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= + AWS_ACCESS_KEY_ID_S3=XXXXXXXXXXXX + AWS_SECRET_ACCESS_KEY_S3=XXXXXXXXXXXX + AWS_DEFAULT_REGION_S3=XXXXXXXXXXXX + AWS_BUCKET_S3=XXXXXXXXXXXX理由としては、serverless framework を利用したときに、lambda の 環境変数がすでにセットされているため、それを使って S3 にアクセスしようとすると、Access Denied のエラーが出るから。
2. config/filesystems.php に以下のように記述
disks => { ~省略~ 's3'=> [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID_S3'), 'secret' => env('AWS_SECRET_ACCESS_KEY_S3'), 'region' => env('AWS_DEFAULT_REGION_S3'), 'bucket' => env('AWS_BUCKET_S3'), 'url' => env('AWS_URL_S3'), 'endpoint' => env('AWS_ENDPOINT_S3'), ] ~省略~ }3. app/helpers.php 作成・編集
<?php if (!function_exists('s3_asset')) { function s3_asset($path) { return \Illuminate\Support\Facades\Storage::disk('s3')->temporaryUrl($path, now()->addMinute()); } }4. composer.json に追記
"autoload": { "psr-4": { "App\\": "app/" }, "classmap": [ "database/seeds", "database/factories" ], + "files" : [ #<= ここから追記 + "app/helpers.php" + ] },5. composer dump-autoload 実行。
$ composer dump-autoloadこれで、helpers.php の s3_asset 関数が使えるようになりました。
6. resources/views/layouts/app.blade.php に 関数の記述
@if(env('APP_ENV') == 'local') <link href=" {{ mix('css/app.css') }} " rel="stylesheet"></link> @else <link href=" {{ s3_asset('css/app.css') }} " rel="stylesheet"></link> @endif # 条件分岐で、local環境では違うところから asset をとってくるようにしている。7. 以下コマンドを実行
$ npm run dev $ php artisan config:clear $ sls deploy -v終わりに
Lambda の環境変数と S3 の環境変数、両方を扱わなくてはいけないので、ちょっと面倒ですが、これだけやってしまえれば、あとはもう何もしなくていいので、便利です。
- 投稿日:2020-06-27T11:53:17+09:00
S3 に view ファイルをアップロード ( Severless Framework x Laravel )
はじめに
この記事に書かれているのは、AWS コンソールで、IAM と S3 bucket を作成した後の手順なので、それ以前の設定はご自身でご自由にしてください。
1. .env を編集
ASSET_URL=https://[S3 のバケット名].s3-ap-northeast-1.amazonaws.com AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXX AWS_DEFAULT_REGION=ap-northeast-1 AWS_BUCKET= S3 のバケット名2. Serverless Framework にプラグインインストール
$ sls plugin install -n serverless-s3-sync3. serverless.yml への記述
plugins: - ./vendor/bref/bref - serverless-domain-manager + - serverless-s3-sync custom: + s3Sync: + # A simple configuration for copying static assets + - bucketName: ${self:service.name}-${opt:stage, self:provider.stage}-asset + localDir: public # required +resources: + Resources: + StaticContentS3: + Type: AWS::S3::Bucket + Properties: + BucketName: ${self:service.name}-${opt:stage, self:provider.stage}-asset4. s3 と laravel を連携させるパッケージをインストール
$ composer require league/flysystem-aws-s3-v3これで
Illuminate\Support\Facades\Storage::disk('s3')
で使うことができます。おわりに
Serverless Framework と laravel での開発にも慣れてきて、記事もまあそれとなく書けるようになってきましたが、まだまだ理解浅いと感じているので、間違いや、不足している部分などありましたら、どんどんコメントしてください!
こちらの記事も読んでみてください。
S3 に アップロードした view ファイルの URL を一時的なものにする。( Severless Framework x Laravel )
https://qiita.com/soma_sekimoto/items/bd16bbc6c2b650af79f9
- 投稿日:2020-06-27T11:03:17+09:00
WSL2+Docker+Laravel既存コードでの開発環境作成(XAMPPからの移行)
PC移行に伴い新たな開発環境を構築する必要が出てきたが、XAMPP入れるのも古いかな(nginx使いたいし)、WSL上にごちゃごちゃ入れると何入れたかわからなくなる、と思ったのでDockerでなんとかならないかと試してみることに。
Dockerが動く状況なら移行先でも同様の開発環境がすぐに構築できるようになったはず。WSLを入れるところから長々書いているので、答えだけdockerのファイルの答えだけ見たい方は、下の方を見るか
https://github.com/miyawa-tarou/docker-test/commit/5d5c78633a6c0e94b0c25849cf683c9a459b891e
あたりを見てください。WSL2を入れる
Windowsのアップデート
- Windows 10、バージョン 2004、ビルド 19041 以上である必要があるので、アップデートします。
- WindowsUpdateのところからできる場合もあるようですが、ゆっくりと順次配布のためない場合は下記からダウンロードできます
仮想化を有効にする
BIOS
- ここはメーカーによるから細かい方法は置いておくが、BIOSに入って
- Intel Virtualizationとかがdisalbeになっていたらenableにする
Windows
Windowsの仮想化を有効に(GUIからやる方法もあるはず)
PowerShellを管理者モードで開き下記を実行> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux > Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform再起動
WSL2の設定
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
再びPowerShellを管理者モードで開き下記を実行> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart > dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestartWSLのデフォルトをバージョン2にしておく
powershell
wsl --set-default-version 2
「最新の WSL2 Linux カーネル更新プログラム パッケージ」が必要なこともあるかもしれない。
その場合は下記からダウンロード。https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel
ディストリビューションを入れる
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#install-your-linux-distribution-of-choice
WindowsStoreから好みを入れる(自分はUbuntuを入れた)
入ったら一回起動しておく(ここは起動しなくて動くか確かめてない)ディストリビューションをあとからWSL2にする
WSL1で入れてしまった場合は、下記コマンドで変換する
> wsl -l -v NAME STATE VERSION * Ubuntu-18.04 Stopped 1 Ubuntu Running 1 > wsl --set-version Ubuntu 2変換なのでちょい時間がかかる
Docker Desktopを入れる
https://www.docker.com/products/docker-desktop
Enable WSL2 Windows Featuresのチェックは付けたまま
これでDocker環境の準備は整ったはず既存ファイル郡にDockerのファイルを追加する
ここからはDockerの話
既存コードににDocker設定を入れる
- ドキュメントルートに
docker-composer.yml
- それ以外のDocker関連ファイルを
./docker/
以下に置くdocker-composer.yml
XAMPPからの移行だが、本番はに近づけるため、
nodeサーバー、php-fpm、MariaDBと、XAMPPを意識するという点で今回はphpmyadminを入れるそれぞれ別のコンテナで動かす
docker-composer.ymlversion: '3' services: test_db: image: mariadb:latest volumes: # データ永続化用 - ./docker/dbdata:/var/lib/mysql # 初期データ用(ここに置いたsqlファイル等は実行される) - ./docker/initdb:/docker-entrypoint-initdb.d environment: - MYSQL_ROOT_PASSWORD=mariadb ports: # Docker外(ローカル)からも3306で繋がるようにしておく - 3306:3306 test_myadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 # 上のDBコンテナ名 - PMA_HOST=test_db # root固定 - PMA_USER=root # 上のMYSQL_ROOT_PASSWORDの値 - PMA_PASSWORD=mariadb links: # DBコンテナにつながるようにする - test_db ports: # ローカルのブラウザからはlocalhost:8080で見られるようにする - 8080:80 test_nginx: image: nginx:alpine depends_on: - test_php volumes: # nginxの設定 - ./docker/nginx/docker.conf:/etc/nginx/conf.d/default.conf # nginxのrootに合わせる(rootにはpublicを付ける必要がある) - .:/var/www/test ports: - 80:80 environment: - NGINX_PORT=80 test_php: # これだけ素のイメージでは足りないのでDockerfileを利用する(Dockfileのパスを指定) build: ./docker/php links: - test_db volumes: # php.iniの設定を送る(今回は特にめだった何かはしていない) - ./docker/php/php.ini:/usr/local/etc/php/php.ini - .:/var/www/test ports: - 9000:9000Dockerを理解してないがゆえに割と悩んだのが、多くの環境構築系資料で、ここにおいたコードが実行されるでしょみたいの書かれるけど、「え?どうやって編集するの?」ということ
結論としては、volumes以下はコピーされるのではなくマウントされるので、更新すれば自動で反映される。なので
volumes - .:/var/www/hogeとかやれば、ファイル全体が自動的にマウントされる、Dockerコンテナ側に反映される
Dockerfile(PHPサーバー)
docker/php/DockerfileFROM php:7.3-fpm RUN apt-get update \ # Laravel実行には必要 && apt-get install -y zlib1g-dev libzip-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql \ # XDebug用(今回は不要) && pecl install xdebug \ && docker-php-ext-enable xdebug COPY --from=composer /usr/bin/composer /usr/bin/composercomposerは必須ではないが、後述のLaravelクソ重い問題で利用する
Docker に Composer をインストールするベストプラクティス(と解説)
Nginxのconf
docker/nginx/docker.confserver { # nginxコンテナのポートの右側の数値 listen 80; server_name localhost; charset utf-8; # volumesでマウントしているところと一致させる(Laravelなのでこちらはpublicをつける) root /var/www/test/public; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { # test_phpはdockerのPHPコンテナ名、9000はそのポート(右側の数字) fastcgi_pass test_php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }初期SQLを置く
docker-compose.yml
のファイル内のコメントに書いたが、データベース系のコンテナだあと
/docker-entrypoint-initdb.d に置かれたファイルは自動でよしなにしてくれるらしい。
ここに.sql
,.sql.gz
をおけばSQLが実行、.sh
を置けばシェルが走るらしい。
artisanでmigrationで行う場合は.sh
で書けば良い上のdocker-composerで/docker/initdb においたものが/docker-entrypoint-initdb.d にコピーされるのでそこにおいておく
なお、いきなりテーブル作成をしてしまうとエラーになる。ちゃんとdatabaseの作成・指定から行う。
Laravelの.env設定
関係あるのはDB周りだけなので、そこの部分だけ修正する。
DB_CONNECTION=mysql # DBコンテナ名 DB_HOST=test_db # DBコンテナで指定したポート(右側) DB_PORT=3306 # 実際に使っているもの次第(今回は初期データがここに入ってる) DB_DATABASE=docker_test DB_USERNAME=root # 指定したパスワード DB_PASSWORD=mariadb起動してみる
composer-docker.ymlのある場所まで移動して
$ docker-compose up -dWindows側でもWSL側でも動くはずである。
ミスがなければ起動するはず。
DockerDesktop側のDashboardからも起動が確認できる動作確認
- phpMyAdminへのアクセスは:http://localhost:8080/
- 上でおいたSQLも動いていることを確認
- http://localhost/
- 表示されるはず
問題点1:Laravelがクソ重い
上のを実行すると気づくとも思うが、何もしてない処理でもクソ重い。
大して何もしてないページなのに表示に数秒かかる・・・。これではさすがに厳しい。
どうやら調べてみると、「マウントするファイルが多いと重くなる」模様
下記が解決策として実行したもの・浮かんだもの不要なファイルはマウントしない(今回やった解決策)
自分で触ることのないファイルはわざわざ、マウントする必要がない
- vendor以下は依存を変えない限りは不要である
- storage以下は自動で作られるファイルだからこちらかアップすることはない
しかし単にマウントしないだけだと以下の問題が起きる
- vendor以下がないため、composer installをする必要がある
- storage以下のファイルが存在しないからエラーになる
一旦ファイルを送ってからマウントを切るという手もあるが、一発で構築できないという点でイケてない。
構築後に中に入って準備をするのもイケてない。なので、必要なファイルはDockerfileで取得するようにする
docker-compose.ymlvolumes: # php.iniの設定を送る - ./docker/php/php.ini:/usr/local/etc/php/php.ini - .:/var/www/test # 除外 - /var/www/test/storage - /var/www/test/vendorDockerfileに下記を追加
docker/php/Dockerfile# storageファイルはマウントしないのでもともと必要なディレクトリは作成する RUN mkdir -p /var/www/test/storage/app/public RUN mkdir -p /var/www/test/storage/framework/cache/data RUN mkdir -p /var/www/test/storage/framework/sessions RUN mkdir -p /var/www/test/storage/framework/testing RUN mkdir -p /var/www/test/storage/framework/views RUN chmod -R 777 /var/www/test/storage # vendorはマウントしないのでcomposerで入れる COPY composer.lock /var/www/test/composer.lock # いらないかも COPY composer.json /var/www/test/composer.json # composer.jsonで必須になっているもの(autoloadまわり) RUN mkdir -p /var/www/test/database/seeds RUN mkdir -p /var/www/test/database/factories # cd /var/www/test && composer install でも動きそう WORKDIR /var/www/test # scriptsでファイルチェックをしているが、マウント前のこの時点では存在しないのでそれは避ける RUN composer install --no-scriptsこれで再作成
$ docker-compose build --no-cache表示に1秒かからなくなった!
その他解決策1:docker-syncを使う
WindowsもLinuxもベータ版らしい
Docker for MacのLaravel アプリケーションのが遅い?それ、ファイルをいっぱいマウントしてるからかもです。
Macだとこれが普通に行われている記事をよく見る
その他解決策2:ファイルwatch+rsyncする
上のdocker-syncはrsyncしているだけなので、自分で動かすこともできる気がする。
実際うまく動くかは不明https://medium.com/@imranhsayed/rsync-using-phpstorm-on-save-b1e73c079db0
問題点2:同じ.envファイルでWSLとDocker上両方動かせない
.env
でDB_HOST=test_db
としているがDocker内での名称であり、WSL側では認識せず動かせない
そのため、開発を行うWSL側からphp artisan
などを実行してもDB周りが上手く動かない
- 127.0.0.1だとDockerコンテナからは127.0.0.1ではないため動かない
- Connection refused.
- localhostだとsocketのエラーが出る
- SQLSTATE[HY000] [2002] No such file or directory
Socketファイルを云々している記事もあったがこれじゃない感。
Docker側から見てlocalhostとはなにかというと、
host.docker.internal
であり、これを入れて見るとartisanも動いたし、Dockerホスト側からも動いた.envDB_HOST=host.docker.internal最終形
こちらにLarvelのテストファイルと共に置いてます:https://github.com/miyawa-tarou/docker-test/commit/5d5c78633a6c0e94b0c25849cf683c9a459b891e
docker-compose.yml
docker-compose.ymlversion: '3' services: test_db: image: mariadb:latest volumes: # データ永続化用 - ./docker/dbdata:/var/lib/mysql # 初期データ用(DB系イメージだとここに置いたsqlファイル等が実行される) - ./docker/initdb:/docker-entrypoint-initdb.d environment: - MYSQL_ROOT_PASSWORD=mariadb ports: # Docker外からも3306で繋がるようにしておく - 3306:3306 test_myadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 # 上のDBコンテナのホスト - PMA_HOST=test_db # root固定 - PMA_USER=root # 上のMYSQL_ROOT_PASSWORDの値 - PMA_PASSWORD=mariadb links: # DBコンテナにつながるようにする - test_db ports: # ブラウザからはlocalhost:8080で見られるようにする - 8080:80 test_nginx: image: nginx:alpine depends_on: - test_php volumes: - ./docker/nginx/docker.conf:/etc/nginx/conf.d/default.conf ports: - 80:80 environment: - NGINX_PORT=80 test_php: # これだけ素のイメージでは足りないのでDockerfileを利用する(Dockrfileのパスを指定) build: # composer.lockをDockerfile内で使うために実行場所は変えない(通常だとDockerfileの位置からの参照、親ファイルは読めない) context: . dockerfile: ./docker/php/Dockerfile links: - test_db volumes: # php.iniの設定を送る - ./docker/php/php.ini:/usr/local/etc/php/php.ini - .:/var/www/test # 除外 - /var/www/test/storage - /var/www/test/vendor ports: - 9000:9000docker/php/Dockerfile
docker/php/DockerfileFROM php:7.3-fpm # composer.jsonで必須になっているもの RUN mkdir -p /var/www/test/database/seeds RUN mkdir -p /var/www/test/database/factories RUN apt-get update \ # Laravel実行には必要(多分) && apt-get install -y zlib1g-dev libzip-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql \ # XDebug用 && pecl install xdebug \ && docker-php-ext-enable xdebug COPY --from=composer /usr/bin/composer /usr/bin/composer # storageファイルはマウントしないのでもともと必要なディレクトリは作成する RUN mkdir -p /var/www/test/storage/app/public RUN mkdir -p /var/www/test/storage/framework/cache/data RUN mkdir -p /var/www/test/storage/framework/sessions RUN mkdir -p /var/www/test/storage/framework/testing RUN mkdir -p /var/www/test/storage/framework/views RUN chmod -R 777 /var/www/test/storage # vendorはマウントしないのでcomposerで入れる COPY composer.json /var/www/test/composer.json COPY composer.lock /var/www/test/composer.lock # composer.jsonで必須になっているもの(autoloadまわり) RUN mkdir -p /var/www/test/database/seeds RUN mkdir -p /var/www/test/database/factories # cd /var/www/test && composer installでも動きそう WORKDIR /var/www/test # scriptsでファイルチェックをしているが、この時点ではないのでそれは避ける(後でマウントされるため) RUN composer install --no-scriptsdocker/nginx/docker.conf
docker/nginx/docker.confserver { # nginxコンテナのポートの右側の数値 listen 80; server_name localhost; charset utf-8; # volumesでマウントしているところと一致させる root /var/www/test/public; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { # test_phpはdockerのPHPコンテナ、9000はそのポート(右側の数字) fastcgi_pass test_php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }.env(差分では.env.exampleに置いてます)
.envDB_CONNECTION=mysql DB_HOST=host.docker.internal DB_PORT=3306 # 実際に使っているもの次第 DB_DATABASE=docker_test DB_USERNAME=root DB_PASSWORD=mariadb
Xdebug入れてますが、まだ設定はしていない・・・。
- 投稿日:2020-06-27T00:23:58+09:00
laravel × react × ajax でformを送信する
環境
・Laravel Framework 7.16.1
・react
・jqueryコード
form
名前、メッセージ、画像を送信します。
import React from 'react'; function Post() { return( <> <div> <form className="main_form" action="" method="post"> <p>NAME:<input type="text" name="name"></input></p> <textarea spellCheck="false" name="message" id="" cols="30" rows="10"></textarea> <p>Image:<input type="file" name="path"></input></p> <p><button type="submit">Post!</button></p> </form> </div> {posts.map((post) => <div key={post.id}> <p>{post.name}</p> <img src={'/storage/' + post.path}></img> <p>{post.message}</p> </div> )} </> ) } export default Post;ajaxの処理
※FormDataは送信が可能な、フォームフィールドおよびそれらの値から表現されるキーと値のペアのセットを簡単に構築する手段を提供します。下記コードは空のFormDataにappendを使ってinputの値を入れています。
以下のコード内の
processData: false, contentType: falseについて。
ザックリ言うと、Ajaxはデータ送信時にデータ形式を変換しようとするのですが、それを許すとエラーが出るらしいので形式変換させないように指定しています。welcome.blade.php<head> ~ <meta name="csrf-token" content="{{ csrf_token() }}"> ~ </head> <body> <div id="app"></div> <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script> <script> $(function(){ $.ajaxSetup({ headers: { 'X-CSRF-TOKEN' : $('meta[name="csrf-token"]').attr('content') } }) $('.main_form').submit(function(event) { event.preventDefault(); var formData = new FormData(); formData.append('name', $("input[name=name]").val()); formData.append('message', $("textarea[name=message]").val()); formData.append('path', $("input[name=path]")[0].files[0]); $.ajax({ url: "{{ action('ReactController@post') }}", type: 'POST', data: formData, processData: false, contentType: false }) .done(function(data) { console.log('succecss') }) .fail(function(data) { console.log('fail') }); }); }); </script> </body>postされたデータを保存するためのコントローラー
web.phpRoute::post('/post', 'ReactController@post');名前、メッセージ、画像を保存する
ReactController.phppublic function post(Request $request) { $post = new Post; $form = $request->all(); unset($form['_token']); $file_name = $request ->file('path') ->getClientOriginalName(); :kissing_heart: $request->file('path')->storeAs('public', $file_name); $post->name = $request->name; $post->message = $request->message; $post->path = $file_name; $post->save(); return redirect('/user'); }以上です。
素人の日記なので、気になるところはしっかり調べて正しい情報を得ることをお勧めします。