- 投稿日:2020-05-31T22:42:16+09:00
かんたんLaravel + Vue.jsでVueUIを使用してログイン、登録の実装
LaravelにはwebpackのようなLaravel-Mixがあり、それを使うことによりLaravel上で
Vue.jsが実装できます。
今回は、いくつかのコマンドを打つことでかんたんにVueUIを使用してログイン、登録の実装します。ターミナルにコマンドを打ち込んでいきます。
# laravelプロジェクト作成 laravel new 「プロジェクト名」#作成したプロジェクトに移動 cd 「プロジェクト名」npmは、Node Package Managerの略でNode.jsのパッケージ(Package)を管理する(Manager)ツールです。
インストール方法は、以下のgithubを参考してください。
https://github.com/npm/cli
ダウンロードは、以下のリンク
https://nodejs.org/en/download/#npmをインストール npm install#一度コンパイルをします。 npm run dev問題がなければVueのログイン・php登録UIをインストールします。
2回コマンドを入力しなければなりません。#1 インストールに時間がかかります。 composer require laravel/ui #2 1が終了後 php artisan ui vue --auth
最後に
npm install && npm run dev
サーバーを立ち上げて確認します。
php artisan serve
完成!!!
以下のパスにExampleComponent.vueもインストールされてます。
resources/js/components/ExampleComponent.vue
これの表示の仕方は、次回します。bootsrapも使えるように設定されており、bootsrapを使うためにJquery,Popper.jsも入れられています。
package.jsonを確認するとわかります。
PHPをすぐに始めることができるMAMP(Mac), XAMPP(Windows)があります。
MAMP
https://www.mamp.info/en/mac/
XAMPP
https://www.mamp.info/en/mac/laravelの環境構築は、すごく大変でした。。。
MacOS違いだけでもやり方が違ったり。僕は、Udemyを利用して環境構築をしました。
【2日でできる】はじめての PHP 7 x Laravel 6 入門
https://www.udemy.com/course/php7study/少しでも参考になれば幸いです。
- 投稿日:2020-05-31T20:05:38+09:00
【PHP(Laravel)】ControllerからViewにデータを渡す2つの方法
概要
- ビューメソッドを使用してデータを渡すビューを指定する。
- データを渡す。(方法2つ)
1.ビューメソッドを使用してビューを指定する
例)articlesコントローラーのindexファイルを指定する
return view('articles.index')2.データを渡す。(方法2つ)
データが入った変数 $articles をビューに渡す。
1.Withメソッドでデータを渡す。
return view('articles.index')->with(['articles' => $articles]);2.Compact関数でデータを渡す。
return view('articles.index', compact('articles'));
- 投稿日:2020-05-31T18:07:01+09:00
WSL2+Ubuntu+Docker+Laravel+MariaDB
下記の記事を参考に、動かなかった部分などを調整しながら実施。
https://qiita.com/A-Kira/items/1c55ef689c0f91420e81
https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4最終的に以下のように実行してうまくいった。
開発環境のセットアップ
前提として、前回の記事を参考に実行環境を準備しておく。
Windows10+WSL2+Ubuntu+Dockerディレクトリ・ファイル構成
以下のように、Windows側でフォルダおよびファイルを作った。
project
├── docker
│ ├── app
│ │ ├── Dockerfile
│ │ ├── php-fpm.d
│ │ │ └── zzz-www.conf
│ │ └── php.ini
│ ├── db
│ │ ├── my.cnf
│ └── nginx
│ └── default.conf
├── server
└── docker-compose.ymldocker-compose.ymlversion: '3' services: app: container_name: app build: ./docker/app volumes: - ./server:/var/www/html nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./server:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app db: image: mariadb:10.4 container_name: db environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: laravel_db MYSQL_USER: laravel MYSQL_PASSWORD: secret TZ: Asia/Tokyoa volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306app/DockerfileFROM php:7.4-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ zlib1g-dev \ unzip \ vim \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install \ gd \ zip \ pdo_mysql ENV TZ=Asia/Tokyo \ COMPOSER_ALLOW_SUPERUSER=1 \ COMPOSER_HOME=/composer COPY --from=composer /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www/htmlapp/php-fpm.d/zzz-www.conf[www] listen = /var/run/php-fpm/php-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0666app/php.inizend.exception_ignore_args = off expose_php = on max_execution_time = 30 max_input_vars = 2000 upload_max_filesize = 32M post_max_size = 32M memory_limit = 512M error_reporting = E_ALL display_errors = on display_startup_errors = on log_errors = on error_log = /dev/stderr default_charset = UTF-8 [Date] date.timezone = ${TZ} [mysqlnd] mysqlnd.collect_memory_statistics = on [Assertion] zend.assertions = 1 [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"db/my.cnf[mysqld] character_set_server = utf8mb4 # Error Log log-error = mariadb_error.log # Slow Query Log slow_query_log = 1 slow_query_log_file = mariadb_slow.log long_query_time = 1.0 log_queries_not_using_indexes = 0 # General Log general_log = 1 general_log_file = mariadb_general.log [mysql] default-character-set = utf8mb4 [client] default-character-set = utf8mb4nginx/default.confserver { listen 80; index index.php index.html; server_name localhost; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/html/public; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }Docker環境の起動
docker-compose up -d # 上記完了後、appコンテナに入る docker-compose exec app bashLaravelのセットアップ
composer create-project "laravel/laravel=6.*" . chmod 766 storage -R chmod 766 bootstrap/cache -R chown www-data:www-data storage -R chown www-data:www-data bootstrap/cache -R vim .env.envDB_HOST=db DB_PORT=3306 DB_DATABASE=laravel_db DB_USERNAME=laravel DB_PASSWORD=secretphp artisan config:cache php artisan migrateWindows側のブラウザで、http://localhost/にアクセスすると、Laravelページが表示される。これが完了。
分からなかったこと
app/Dockerfileのところで、Laravelアプリを直接インストールしようとしてエラーは出なかったけど、コンテナが起動したあと見に行ったら無かった。
以下の文を入れたらいけるかなーと思ったのだけど。
RUN composer create-project "laravel/laravel=6.18" .
- 投稿日:2020-05-31T17:53:36+09:00
Laravelでメモリリーク??? 実はそんなわけなかったというしょうもない話
タイトルで若干ネタバレしてますが、ほんとしょうもない話です。ただ、おそらく同様のことで悩まれている方が何人かいるようなので、記事にしてみます。最後の方にちょっとした知見もありますが、ほぼ読み物です。
ちなみにSQSキューワーカーでメモリリークが起きるという記事がQiitaにありますが、今回の記事はこの件と直接関係はありません。
参考)
https://qiita.com/sh-ogawa/items/d64cafce2a2646b7abc6単純な処理でなぜか延々と膨れ上がるメモリ使用量
Laravel 6.xでデータベース(今回はMySQLですがこの話に関係はない)に数万行のデータをインポートしようと試みたある日のことでした。CSVファイルから1000行ずつデータを読み出して1行ずつインサートするという
手抜き超簡単なプログラムです(Laravel Excelを使用)。インポートプログラムが完成して数万行あるCSVファイルを食わせてバッチを実行したところ、数千行まで処理が走った瞬間にPHP Fatal error: Allowed memory size of xxx bytes exhausted.「ああん? いやいや、たかが数千行でメモリ食い潰すほどのことはなかろう。てか、1000行ずつデータとってBULK INSERTすらもせずゆっくりインサートしてるのにどこでこんなにメモリなんか使ってるんだ??? ははーん・・・・、これはなんかメモリリーク的なことが起きてるのでは????」
そもそもPHPでは意図的にメモリを確保したり解放したりなんてまずしませんし、メモリリーク的なことが起きるとしても循環参照が起きるなどでかなりレアケースではありますが…。以下を参考。
【PHP7.4新機能】弱参照(WeakReference)とGCとメモリリークについて整理したよ!
https://qiita.com/miracle-FJSW/items/f35c3e90a5d14eb6eba3なんて変に勘ぐってしまったのが事の始まりでした。
プロセスのメモリ使用量を監視してみると、確かに徐々にメモリ使用量が膨れ上がり、1分間くらいで数十MBずつくらい物理メモリ(RES)が盛り盛りと増えていくのです。これは何事か!?
4000行くらい入れただけで436MBも使っちゃってる・・・さらっと調べてみてもどうも同様のケースは見つけられない
データを読み込んで、そのデータをDBにインサートするだけという普通のことをしているだけなので、さすがに調べたら見つかるだろうと思ったのですが、どうにも見つかりません。でてくるのは「クエリログがメモリを食い潰しているのでそれを切れ!(
\DB::connection()->disableQueryLog();
)」的な記事がちらほら出てくるのですが、どうもLaravel5.5時代の話のようです。
参考
Memory leak on database insert function
https://github.com/laravel/framework/issues/30012今はデフォルト設定でそのようなことは起きない模様。
ただ、DBのインサートをする行だけコメントアウトしてプログラムを実行すると、たしかにメモリ使用量は増えないので、Eloquentあたりになにかバグでもあってそれを踏んでいるのだろうか?なんてこの時点では思ってしまいました。
Laravel Telescope の存在に気づく
こまったなぁ、と思いつつ解決できないこと数か月・・・(一時的にphp.iniの設定をいじり、メモリがっつり増やせばデータは全件入るのでめちゃくちゃ困ってるわけではなかった)。
ある日、ぼんやりとプロジェクトファイル全体を眺めていたら、Laravel Telescopeを入れていることにふと気づきました。今までまったく使ってないのになんでこんなもん入れてるんだ? なんて思いつつ、すごく嫌な予感がしました。Laravel Telescopeをご存じでない方に、説明ページの冒頭を引用させていただきます。
Laravel TelescopeはLaravelフレームワークのエレガントなデバッグアシスタントです。Telescopeはアプリケーションへ送信されたリクエスト、例外、ログエンティティ、データクエリ、キュージョブ、メール、通知、キャッシュ操作、スケジュールされたタスク、さまざまなダンプなどを提示します。TelescopeはLaravelローカル開発環境における、素晴らしいコンパニオンです。
あー、これは危険な香りがプンプンする!!!ということで、これを無効にする設定(.envに
TELESCOPE_ENABLED=false
)をいれてphp artisan config:cache
したあとにスクリプトを実行すると・・・ はいビンゴでした。君か・・・ 数か月も見つけられなかったよ・・・
Laravel Telescope の一部機能を無効にする方法は色々ある模様
上の例では機能全体を無効にしましたが、一部機能だけ無効にすることもできます。詳しくはLaravel Telescopeのドキュメントを見ていただくといいと思いますが、今回の場合だと、Queryワッチャーをオフにすればメモリの使用量は大幅に減ります。ただ、Queryワッチャー以外でもメモリは使用しているので、ちょろちょろとメモリ使用量が増えてはいきます。
コード内の一部のみLaravel Telescopeを無効にしたい場合は
use Laravel\Telescope\Telescope; //〜略〜 Telescope::stopRecording(); //Laravel Telescopeでメモリ食いの処理 Telescope::startRecording();という感じで書けばメモリ問題も上手く捌けるようです。
参考)
Query builder memory leak on large insert
https://github.com/laravel/framework/issues/27539
↑
この記事はLaravel Telescopeの件で気づいた後に見つけたけど、やっぱりメモリリークって勘違いするよなぁw結論
Laravel Telescopeはメモリ食うから気をつけろ。
そして、入れたことを忘れるな(普通は忘れないよねw)
- 投稿日:2020-05-31T13:25:00+09:00
Laravelでメール送信する
前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っていますGmailのアプリパスワード取得
今回はLaravelからGmailを使ってメールを送信しようと思います
そのためにGmailのアプリパスワードを取得します(1) googleアカウントにアクセス
(2) セキュリティをクリックし2段階認証プロセスをONにする
(3) セキュリティをクリックしアプリパスワードをクリックする
(4) パスワードの取得
アプリを選択→メール
デバイスを選択→その他(名前入力) 適当な名前を入力する
生成をクリック表示されたパスワードをメモしておく
SMTPサーバの情報を設定
/sample/.envを編集
‥‥ MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=XXXXX@gmail.com MAIL_PASSWORD=XXXXXXXXXX MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=XXXXX@gmail.com MAIL_FROM_NAME="sample sender" ‥‥MAIL_USERNAME、MAIL_FROM_ADDRESSは送信元のGmailアドレス
MAIL_FROM_NAMEは送信者名
MAIL_PASSWORDは先ほど取得したアプリパスワード(半角スペースはいらない)ここで設定した値は/sample/config/mail.phpで使われます
Mailableクラス作成
(1)コマンドラインで
cd sample
php artisan make:mail SampleMail
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Mail/SampleMail.phpが現れます(2) SampleMail.php修正
SampleMail.php<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class SampleMail extends Mailable { use Queueable, SerializesModels; public $sample; private $imgName; private $imgMineType; private $imgData; public function __construct($sample, $imgName, $imgMineType, $imgData) { $this->sample = $sample; $this->imgName = $imgName; $this->imgMineType = $imgMineType; $this->imgData = $imgData; } public function build() { return $this->view('sample.mailContentHtml') ->text('sample.mailContentText') ->subject('sample mail') ->attachData( $this->imgData, $this->imgName, [ 'mime' => $this->imgMineType, ]); } }変数宣言
$sample
、$imgName
、$imgMineType
、$imgData
を追記
public変数はメール本文のview内で使用できるようになります
コンストラクタを変数受け取れるように修正
buildメソッド実装
viewはメール本文HTML用。後でmailContentHtml.blade.phpを作成します
textはメール本文HTML用。後でmailContentText.blade.phpを作成します
subjectはメールタイトル
attachDataは添付ファイルControllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpに下記を追記
use App\Mail\SampleMail;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
(2) /sample/app/Http/Controllers/SampleController.phpにmailメソッドを追記
public function mail() { $stream = Storage::readStream('sample.png'); $imgData = stream_get_contents($stream); fclose($stream); Mail::to("XXXXXXXXXXXXXXXX@gmail.com") ->cc("XXXXXXXXXXXXXXX@gmail.com") ->bcc("XXXXXXXXXXXXXXXXX@gmail.com") ->send(new SampleMail('sample text', 'sample.png', 'image/png', $imgData)); return view('sample.mail'); }Storageクラスは/sample/storage/app配下のファイルを扱えるクラス。どのフォルダを扱えるようにするかは、/sample/config/filesystems.phpで設定されている
Storage::readStream('sample.png')で/sample/storage/app/sample.pngのリソースを取得している
toは送信先
ccはカーボンコピー
bccはブラインドカーボンコピー
sendで先ほど作成したMailableクラスを指定(3) サンプル用の添付ファイル
適当な画像作成ソフトでsample.pngを作成し、/sample/storage/app/sample.pngに保存(4) /sample/routes/web.phpに下記を追記
Route::get('sample/mail', 'SampleController@mail');
viewの作成
(1) /sample/resources/views/sample/mail.blade.phpファイル作成
mail.blade.php<html> <head> <title>sample</title> </head> <body> メール送信しました </body> </html>(2) /sample/resources/views/sample/mailContentHtml.blade.phpファイル作成
mailContentHtml.blade.php<html> <body> <div style="font-weight: bold; color: red;">{{ $sample }}</div> </body> </html>(3) /sample/resources/views/sample/mailContentText.blade.phpファイル作成
mailContentText.blade.php{{ $sample }}Mailableクラスのpublic変数sampleを出力しています。
Mailableクラスのpublic変数はメール本文のviewで使うことができます動作確認
http://localhost/laravelSample/sample/mail
メール送信しましたメールが送信され受信できました
- 投稿日:2020-05-31T01:37:27+09:00
Laravelとjsのfetchの組み合わせで躓いた話
何が起きたか
jsでajax通信がしたく以下のように書いた。
fetch(url, { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8" }, body: JSON.stringify(parameters) })これで、バリデーションエラーで弾かれた場合、Laravelからはステータスコード422とエラーメッセージが帰ってくるはずだった。
なのに、ステータスコードは405でしかもエラーメッセージは何も帰ってこない。
これの解決に3時間くらいかかってしまったのでここに残しておく。結論
headersには
"X-Requested-With": "XMLHttpRequest"
が必要。解説
結論を見れば分かるかもしれないが、Laravel(正確には拡張元のsymfony)はリクエストヘッダーの上記を見てajaxかどうかを判断している。
なのでこれを入れないと、Laravelは通常のリクエストと判断しフォーム画面に戻すべくRedirectResponseを返す。
これにより、何等かの原因で405というおかしなコードが帰ってきた(この時点でおかしいことは分かったのでこれ以上は詳しくは見ていない)。実際にソースを追ってみたところ以下のようになっている。
- まずここで、バリデーションに引っ掛かった場合は
failedValidation()
を実行しValidationExceptionをthrow- 例外ハンドラがValidationExceptionをcatchし、ここでJsonResponseを返すかRedirectResponseを返すかを分岐
expectsJson()
はここでajax()
の結果からajax通信かどうかを見ておりajax()
はここでxmlHttpRequestかを見ており- xmlHttpRequestかはここで
"X-Requested-With": "XMLHttpRequest"
かを見ている所感
「laravel fetch 405」とかでググってもヒットしないものだから苦労した。。常識なのだろうか。
常識なのであればこの機会に知ってよかったと思うことにする。