- 投稿日:2021-03-15T23:33:15+09:00
Laravel+Guzzleを使用してAPIトークンを取得する方法
こんにちは、くりぱんです。
この記事で実現できること
- Guzzleのインストール
- Laravel+GuzzleでAPIトークンの取得
説明
今回はPHPのHTTPクライアントであるGuzzleを使用して、とあるAPIのトークンを取得していきたいと思います。
開発環境
- Laravel: 6.2
- Guzzule: 7.2
実装の流れ
- Laravelプロジェクトの作成
- Guzzleのインストール
- 日本時間にする
- データベース設定
- Route
- Controller
- View
実装
1. Laravelのプロジェクトの作成
$ composer create-project --prefer-dist laravel/laravel testAPI "6.*"
testAPI
というLaravel6のプロジェクトが作成されます。2. Guzzleのインストール
$ composer require guzzlehttp/guzzle
composer.jsonで確認していきます。
composer.json{ ーー省略ーー "license": "MIT", "require": { "php": "^7.2.5|^8.0", "fideloper/proxy": "^4.4", "guzzlehttp/guzzle": "^7.2", // ここチェック "laravel/framework": "^6.20", "laravel/tinker": "^2.5" }, ーー省略ーー }私の場合composer.jsonには
"guzzlehttp/guzzle": "^7.2"
となっていますが、バージョンが多少異なっていても特に問題はありません。3. 日本時間にする
APIトークンの有効期限も画面に出したいので、一応日本時間にしておきます。
config/app.php
を編集します。app.phpreturn [ ーー省略ーー 'timezone' => 'Asia/Tokyo', ーー省略ーー ]4. データベース設定
今回はMySQLを使用していきます。
mysql -u root -p
などでMySQLに入り、test_api
というデータベースを作成してください。mysql> CREATE DATABASE test_api;
.env
に作成したデータベースの設定をしていきます。.env// データベース関連のところを抜粋 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=test_api // 今回作成したデータベース名 DB_USERNAME=ユーザー名 DB_PASSWORD=パスワード5. Route
routes/web.php
でルートの設定を行っていきます。web.php<?php Route::get('/', 'TestApiController@index'); // ここを追記
http://127.0.0.1:8000/
にアクセスするとこれから作成するTestApiController
のindexメソッド
が走るようになりました。6. Controller
$ php artisan make:controller TestApiController
このコマンドで、以下のような
app/Http/Controllers/testApiController.php
が作成されます。<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TestApiController extends Controller { // }今回は例として下記の情報で接続したと過程します。
- ベースURL:
openapi.test.api.jp
- HTTP リクエスト:
POST openapi.test.api.jp/v2/test
- API_KEY:
hjfdksaJhjfkdw134fjdklsaKJ93JKL
- user_id:
user_id
- password:
password
先程コマンドで作成した
app/Http/Controllers/testApiController.php
を編集していきます。TestApiController.php<?php namespace App\Http\Controllers; use Facade\Ignition\QueryRecorder\Query; use Illuminate\Http\Request; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Header; class TestApiController extends Controller { public function index() { // ベースURL $base_url = 'openapi.test.api.jp'; // インスタンス作成 $client = new Client([ 'base_url' => $base_url, ]); // API_KEY $api_key = 'hjfdksaJhjfkdw134fjdklsaKJ93JKL'; // オプション $options = [ // デバック(デバックしたい時は記述) 'debug' => true, // // パラメーター(Header) 'headers' => [ 'api-key' => $api_key, ], // パラメーター(Query) 'query' => [ 'user_id' => 'user_id', ], // パラメーター(Body) 'json' => [ 'password' => 'password', ], ]; // パス $path = '/v2/test'; // リクエストするURL(openapi.test.api.jp/v2/test) $send_url = $base_url . $path; $response = $client->request('POST', $send_url, $options); // JSONデータとして取得 $json = $response->getBody(); // JSONデータを連想配列にする $api_token = json_decode($json, true); return view('welcome', compact('api_token')); } }passwordはTypeがBodyだったのですが、json指定だとうまい感じで変換してくれます。
7. View
JSONを連想配列で取得しているので、有効期限とAPIトークンをそれぞれ取得していきます。
resources/views/welcome.blade.php
を下記の通り編集してください。welcome.blade.php<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> </head> <body> <p>有効期限:{{ date('Y年m月d日 H時i分s秒', $api_token['expires_at']) }}</p> <p>APIトークン:{{ $api_token['token'] }}</p> </body> </html>有効期限はミリ秒で取得されるので、date関数でフォーマットを整えています。
これで、php artisan serve
してからブラウザで確かめると、無事有効期限とAPIトークンを取得できるかと思います。最後に
APIはまだまだわからないことばかりなので、ぜひご指摘等ありましたらコメント欄にお願いいたします。
少しでも役に立った!という時は、LGTMをポチッと、、、笑
1つでもLGTMが付くとその日がハッピーになるんです!
役に立たなかった時は、怒らないでコメント頂けると幸いです笑Twitterもやってます!
プログラミングや金融知識についてやエンジニアの現実についてつぶやいています!
よかったら見てみてくださいね!
- 投稿日:2021-03-15T21:52:13+09:00
VPSにLaravelが動く環境を作る
VPSにLaravel環境を作る デプロイはgithubから行う
より本運用に近い形をイメージして github にリポジトリを作成、productionブランチからサーバーにデプロイするイメージで作成する。
プロジェクトを用意
GitHubにプロジェクトを作る
開発用Macにclone
git clone git@github.com:sugie/my_laravel.git orgorgディレクトリにリポジトリがクローンされる。
Laravelプロジェクトを新規作成
> composer create-project laravel/laravel=6.* my_project Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. Nothing to install, update or remove Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. 67 packages you are using are looking for funding. Use the `composer fund` command to find out more!composer installを実行
> composer install Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. Nothing to install, update or remove Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. 67 packages you are using are looking for funding. Use the `composer fund` command to find out more!artisan serveを実行
> php artisan serve Laravel development server started: http://127.0.0.1:8000 [Mon Mar 15 17:19:41 2021] PHP 7.4.12 Development Server (http://127.0.0.1:8000) started [Mon Mar 15 17:19:46 2021] 127.0.0.1:57585 Accepted [Mon Mar 15 17:19:46 2021] 127.0.0.1:57586 Accepted [Mon Mar 15 17:19:46 2021] 127.0.0.1:57585 Closing [Mon Mar 15 17:19:47 2021] 127.0.0.1:57586 [200]: GET /favicon.ico [Mon Mar 15 17:19:47 2021] 127.0.0.1:57586 Closingブラウザで
http://127.0.0.1:8000
を開くいて、LaravelのWelcomeページが表示されることを確認。githubにpush
> cp -pR ../org/.git .ステータスを確認
> git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) .editorconfig .env.example .gitattributes .styleci.yml README.md app/ artisan bootstrap/ composer.json composer.lock config/ database/ package.json phpunit.xml public/ resources/ routes/ server.php storage/ tests/ webpack.mix.js nothing added to commit but untracked files present (use "git add" to track)AddしてCommitしてPush
>git add .>git commit -m 'First commit' [master (root-commit) 5b38273] First commit 84 files changed, 9914 insertions(+) create mode 100644 .editorconfig create mode 100644 .env.example create mode 100644 .gitattributes create mode 100644 .styleci.yml create mode 100644 README.md create mode 100644 app/Console/Kernel.php create mode 100644 app/Exceptions/Handler.php create mode 100644 app/Http/Controllers/Auth/ConfirmPasswordController.php create mode 100644 app/Http/Controllers/Auth/ForgotPasswordController.php create mode 100644 app/Http/Controllers/Auth/LoginController.php create mode 100644 app/Http/Controllers/Auth/RegisterController.php create mode 100644 app/Http/Controllers/Auth/ResetPasswordController.php create mode 100644 app/Http/Controllers/Auth/VerificationController.php create mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Kernel.php create mode 100644 app/Http/Middleware/Authenticate.php create mode 100644 app/Http/Middleware/CheckForMaintenanceMode.php create mode 100644 app/Http/Middleware/EncryptCookies.php create mode 100644 app/Http/Middleware/RedirectIfAuthenticated.php create mode 100644 app/Http/Middleware/TrimStrings.php create mode 100644 app/Http/Middleware/TrustProxies.php create mode 100644 app/Http/Middleware/VerifyCsrfToken.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/Providers/AuthServiceProvider.php create mode 100644 app/Providers/BroadcastServiceProvider.php create mode 100644 app/Providers/EventServiceProvider.php create mode 100644 app/Providers/RouteServiceProvider.php create mode 100644 app/User.php create mode 100755 artisan create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/auth.php create mode 100644 config/broadcasting.php create mode 100644 config/cache.php create mode 100644 config/database.php create mode 100644 config/filesystems.php create mode 100644 config/hashing.php create mode 100644 config/logging.php create mode 100644 config/mail.php create mode 100644 config/queue.php create mode 100644 config/services.php create mode 100644 config/session.php create mode 100644 config/view.php create mode 100644 database/factories/UserFactory.php create mode 100644 database/migrations/2014_10_12_000000_create_users_table.php create mode 100644 database/migrations/2014_10_12_100000_create_password_resets_table.php create mode 100644 database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100644 database/seeds/DatabaseSeeder.php create mode 100644 package.json create mode 100644 phpunit.xml create mode 100644 public/.htaccess create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 public/web.config create mode 100644 resources/js/app.js create mode 100644 resources/js/bootstrap.js create mode 100644 resources/lang/en/auth.php create mode 100644 resources/lang/en/pagination.php create mode 100644 resources/lang/en/passwords.php create mode 100644 resources/lang/en/validation.php create mode 100644 resources/sass/app.scss create mode 100644 resources/views/welcome.blade.php create mode 100644 routes/api.php create mode 100644 routes/channels.php create mode 100644 routes/console.php create mode 100644 routes/web.php create mode 100644 server.php create mode 100644 storage/app/.gitignore create mode 100644 storage/app/public/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/cache/data/.gitignore create mode 100644 storage/framework/sessions/.gitignore create mode 100644 storage/framework/testing/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100644 tests/CreatesApplication.php create mode 100644 tests/Feature/ExampleTest.php create mode 100644 tests/TestCase.php create mode 100644 tests/Unit/ExampleTest.php create mode 100644 webpack.mix.jsgit push origin master Authenticated to github.com ([52.69.186.44]:22). Counting objects: 110, done. Delta compression using up to 12 threads. Compressing objects: 100% (93/93), done. Writing objects: 100% (110/110), 62.85 KiB | 0 bytes/s, done. Total 110 (delta 11), reused 0 (delta 0) remote: Resolving deltas: 100% (11/11), done. Transferred: sent 67160, received 3404 bytes, in 2.1 seconds Bytes per second: sent 32330.1, received 1638.7 To git@github.com:sugie/my_laravel.git * [new branch] master -> masterプロダクションブランチを作成してpush
> git checkout production error: pathspec 'production' did not match any file(s) known to git. > git branch * master > git checkout production error: pathspec 'production' did not match any file(s) known to git. > git branch production > git checkout production Switched to branch 'production' > git merge master -m 'merge from master' Already up-to-date. > git push origin production Authenticated to github.com ([52.192.72.89]:22). Total 0 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'production' on GitHub by visiting: remote: https://github.com/sugie/my_laravel/pull/new/production Transferred: sent 2740, received 2764 bytes, in 1.8 seconds remote: Bytes per second: sent 1531.3, received 1544.7 To git@github.com:sugie/my_laravel.git * [new branch] production -> production >git flowの手順にしたがって
productionブランチにはデプロイする内容を入れる。VPSにサーバーを作る
今回はvultr.comを使う。さくらのVPSでもConoHaのVPSでも基本は同じだと思う。
vultrでfirewallを設定する方法は
https://qiita.com/Shiro-neko-kamen/items/0b4a8504eb87a459c7d8
こちらを参照。サーバーインスタンスができたら詳細画面に遷移
ターミナルでログインする
Macでターミナルアプリを起動。
コピーアイコンをクリックしてIPアドレスをコピー。
ssh root@コピーしたIPアドレスをペーストパスワードを聞かれるので、サーバー詳細のrootパスワードをコピーしてペースト。
52 updates can be installed immediately.
とか出てくるのでアップデートを最初に行う。apt-get updateapt-get upgrade作業用アカウントを用意する
visudo のエディタをvimに変更。nanoエディタを使いたい人は以下のコマンドを実行しない。
update-alternatives --set editor /usr/bin/vim.basic
ユーザー名を決める。taroでも、hanakoでも、itadoriでもtanjiroでもなんでも良い。今回はblueを使う。
adduser blueパスワードを設定。uShieh#oo8agを設定。
blueをsudoできるようにする。
visudoblue ALL=(ALL) NOPASSWD:ALL
を27行目くらいに挿入して保存。blueの公開鍵を設定
作業ユーザーは鍵認証でsshログインするようにする。鍵認証の詳細は割愛。説明希望の人はコメント欄に説明希望と書いてください。追記します。
su blue cd mkdir .ssh vi .ssh/authorized_keys 公開鍵をペーストして保存 パーミッションを設定 chmod 0700 .ssh chmod 0400 .ssh/authorized_keysこの設定をすると作業ユーザーでsshログインできるようになる。
Macのターミナルから以下のコマンドを実行
bash
ssh blue@139.180.207.51
sudo できることを確認
bash
sudo pwd
成功したらrootでのリモートログインを禁止して、パスワードログインを禁止してセキュリティ向上をしたいところ。
使いそうなモジュールをインストール
サーバーに作業ユーザーでログインしてapt-get installを実行。
ssh blue@139.180.207.51 sudo apt-get install curl wget net-tools vim vim-gtk3 vim-tiny neovim vim-athena vim-gtk vim-nox python vim-gui-common vim-runtime mycli tree nkfズラーっといろいろ表示される。
Apacheをインストール
ppa:ondrej/apache2 リポジトリを追加
sudo add-apt-repository ppa:ondrej/apache2 sudo apt-get update sudo apt-get updateApacheをインストール
sudo apt-get install apache2 w3mインストールされていることを確認
> systemctl | grep apache apache2.service loaded active running The Apache HTTP Serverブラウザで確認
http://サーバーのIPアドレス
せっかくだからドメインの設定をする
お名前.comのDOMナビの例。DNSの説明は割愛します。
作ったサーバーのIPアドレスを指定して反映。
登録したURLをブラウザで開いてみる。
ある程度時間が経ってDNSが浸透したら開けるようになる。
MySQLデータベースをインストール
https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04-ja
このサイトを参考にしました。sudo apt install mysql-serversudo mysql_secure_installation Press y|Y for Yes, any other key for No: NO New password: ohcue3Olu Remove anonymous users? (Press y|Y for Yes, any other key for No) : yes Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y Reload privilege tables now? (Press y|Y for Yes, any other key for No) : YMYSQLユーザーの作成
sudo mysql CREATE USER 'myproject'@'%'; CREATE DATABASE IF NOT EXISTS myproject; GRANT ALL PRIVILEGES ON myproject.* TO 'myproject'@'%'; CREATE USER 'myproject'@'localhost'; GRANT ALL PRIVILEGES ON myproject.* TO 'myproject'@'localhost'; use mysql ALTER USER 'myproject'@'localhost' identified BY 'ooH8Tho8umo'; flush privileges;別のターミナルからログインできることを確認
blue@mylaravel:~$ mysql -umyproject -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.23-0ubuntu0.20.10.1 (Ubuntu) Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>mycliでもログインしてみる。コマンドラインからmysqlに繋ぐならmysqlコマンドよりmycliコマンドのほうが便利だ。
blue@mylaravel:~$ mycli -umyproject Password: mysql 8.0.23-0ubuntu0.20.10.1 mycli 1.22.2 Chat: https://gitter.im/dbcli/mycli Mail: https://groups.google.com/forum/#!forum/mycli-users Home: http://mycli.net Thanks to the contributor - Zane C. Bowers-Hadley mysql myproject@localhost:(none)> mysql myproject@localhost:(none)> quit Goodbye! blue@mylaravel:~$PHPのインストール
sudo apt-get install php7.4-cli php7.4-common php7.4 php7.4-mbstring php7.4-xml php7.4-dom php7.4-gd php7.4-mysqlnd php7.4-pdo php7.4-zip php7.4-redis php7.4-curlバージョンを確認
php --version
>php -version PHP 7.4.9 (cli) (built: Oct 26 2020 15:17:14) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.9, Copyright (c), by Zend Technologiescompoesrをインストール
sudo apt-get install composergithubから持ってくる
cd ~ vi mygithub.secret # GitHubに登録した秘密鍵を配置 # 保存したら以下のコマンドでパーミッションを設定 chmod 0400 ~/.ssh/mygithub.secret vi ~/.ssh/config Host github.com User #GitHubAccount# Port 22 HostName github.com IdentityFile ~/.ssh/mygithub.secret TCPKeepAlive yes IdentitiesOnly yesクローン
productionブランチを指定git clone git@github.com:sugie/my_laravel.git --branch production
my_laravelディレクトリを移動
sudo mkdir /var/sites/ sudo mv /home/blue/my_laravel /var/sites/my_laravel sudo chown www-data:www-data -R /var/sites/my_laravelcomposer を実行
cd /var/sites/my_laravel sudo -u www-data composer installwww-dataユーザーでgit pullできるように設定
sudo mkdir /var/www/.ssh -p sudo cp -p /home/blue/.ssh/#MY_GITHUB_SECRET#.secret /var/www/.ssh/.所有者をwww-dataにする
sudo vi /var/www/.ssh/config Host github.com User #MY_GITHUB_ACCOUNT# Port 22 HostName github.com IdentityFile ~/.ssh/#MY_GITHUB_SECRET#.secret TCPKeepAlive yes IdentitiesOnly yessudo chown www-data:www-data -R /var/wwwpullしてみる
cd /var/sites/my_laravel sudo -u www-data git pull将来本番サーバーに反映させるときは
productionブランチを用意して、pullを行って反映させる。環境ファイルの用意
cd /var/sites/my_laravel sudo cp -p .env.example .env sudo -u www-data vi .envデータベースの設定を.envに反映。さっき作ったMySQLユーザーとパスワードを記述。
DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=myproject DB_USERNAME=myproject DB_PASSWORD=ooH8Tho8umoKey generate
sudo -u www-data php artisan key:generate.envに
APP_KEY=base64:3epehyg5v9XIHz2ZxTquvcpVdnbKGxlDmHPCaLTdU9w=
が設定される。migrateを実行
sudo -u www-data php artisan migrateApacheの設定
既存の設定ファイルを削除。
cd /etc/apache2/sites-enabled sudo rm 000-default.conf新しい仮想ホストの設定ファイルを作る
cd ../sites-available/ #設定ファイルはドメイン名+.confを勧めますsudo vi myproject.ice2nd.mobi.conf
<VirtualHost *:80> ServerName myproject.ice2nd.mobi ServerAdmin admin@email.address DocumentRoot /var/sites/my_laravel/public <Directory /var/sites/my_laravel/public> AllowOverride All Options All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>cd /etc/apache2/sites-enabled sudo ln -s ../sites-available/myproject.ice2nd.mobi.conf . sudo apache2ctl configtest Syntax OK sudo apache2ctl startブラウザで確認
https化する
https化するにはSSL証明書が必要。このサイトは正しいサイトですよ。と認証局に認定してもらう。証明書は購入することもできるが、無料でも入手できる。
無料で使えるSSL証明書はLets encryptと呼ばれている。
今回はlets encryptを使って証明書をインストールし、1ヶ月で自動更新するようにする。cetbotをインストールするためにリポジトリを追加する。
sudo apt-get install certbot python3-certbot-apache証明書のインストール
sudo certbot --apacheブラウザでhttpsになっていることを確認。
vultr.com でサーバーを作りなら
https://www.vultr.com/?ref=8408139-6G
このリンクから申し込むと100$分の利用料がもらえるので、よかったら使ってください。
- 投稿日:2021-03-15T21:15:16+09:00
【未経験者】PHPとLaravelそれぞれで類似ポートフォリオ作ってみた
はじめに
こんにちは、おーもとと申します。エンジニアに転職をするため学習している初学者です。
私は車が好きで、「近年の若者の車離れ」という問題にフォーカスしたアプリを制作しようと思いました。
色々あって、生のPHPとLaravelの二通りの類似ポートフォリオを制作したので、記事にしてみました。制作背景
若者が車を持たない理由には様々な理由があると思いますが、
「欲しいと思えるほど魅力を感じる車に出会っていないからなのでは?」
と思い、
・かわいいやかっこいいというスタイル
・大きさ
・国産か外車か
・アウトドアや街乗りという用途
これらの項目に当てはまる車を、結果として表示するアプリを制作することにしました。
(これらの特徴は全て私が定めているため、投票などにより特徴を決める機能をつけたいです)11月 PHPでアプリ開発
10月からPHPの学習を始めていたので、そのアプリはPHPで制作しました。
カーセンサーAPIを使用して、車の情報を取得します。
解説動画:https://www.youtube.com/watch?v=ZXbgUtjxKM8
機能
ユーザー登録関連
⚪︎ ログイン
⚪︎ ログアウト
⚪︎ 新規登録
⚪︎ ユーザー件数を表示車の検索機能
⚪︎ 車の見た目→「かわいい」「かっこいい」「シンプル」「おしゃれ」「レトロ」
⚪︎ 車のサイズ→「ふつう」「すごくおおきい」「おおきい」「ちいさい」
⚪︎ 車の製造国→「国産車」「外車」
⚪︎ 車の用途 →「街乗り」「アウトドア」「スポーツ」カーセンサーAPI連携
⚪︎ DBにある車情報と合致した車情報を取得
⚪︎ cronでキャッシュファイル自動生成苦労した点
検索結果の画像表示高速化
検索の度にAPIからデータを取得していたので、電波の悪い場所では結果の表示に1分以上かかっていました。
そのため、毎日APIからデータを取得するバッチ処理をcronで自動化し、キャッシュ化することで、ユーザーにストレスのない速度で結果を表示させることができました。EC2へデプロイ
公式ドキュメントを参考にしデプロイしました。
その際、インフラの知識が不足していたため、デプロイに一週間以上かかりました。APIのサービス終了!!
転職活動を始めようとした際、一週間後にカーセンサーAPIサービスが終了すると知りました。
急いで提供元へ問い合わせたところ、
「完全に提供が終了すること」「24時間以上のキャッシュデータの保有も禁止」、ということを告げられました。
その後、他の車データAPIの提供元を調べましたが他にありませんでした。
画像だけでもどうにかならないかと思い、ト◯タや◯産などの画像利用規約を確認しましたが、
営利目的ではない&提供元のURLなどの情報を記載する
としても、利用は禁止でした。
そのためLaravelの勉強も兼ねて、画像問題を解決できるアプリの制作に取り掛かりました。1月 Laravelでアプリ開発
12月末からLaravelの学習を始め、1月からアプリの制作に取り掛かりました。
前回のPHPで制作したポートフォリオとの違い
画像の取得にAPIを用いていましたが、ユーザーから愛車の画像を提供してもらう方針に変更し、機能の追加などを行いました。
完成
アプリのURL:https://pf-kurushira.com
(スマホサイズにも対応しています)
使用技術
使用言語
⚪︎ HTML
⚪︎ CSS
⚪︎ SCSS
⚪︎ PHP 7.4.14
⚪︎ Laravel 6.20.11インフラ
⚪︎ Github Actions 自動デプロイ
⚪︎ Docker 20.10.2 / docker-compose 1.27.4
⚪︎ nginx 1.18
⚪︎ mysql 5.7.31 / PHPMyAdmin
⚪︎ AWS ( EC2, ALB, ACM, S3, RDS, Route53, VPC, EIP, IAM)インフラ構成図
機能一覧
機能 概要 ユーザー管理機能 新規登録・ログイン・ログアウトができます 簡単ログイン機能 ログイン画面のゲストログインをクリックすることで、ゲストユーザーとしてログインできます おすすめ車種検索機能 条件を選択すると、それにあった車種一覧を表示します 検索履歴機能 直近の検索履歴・結果を表示します 画像提供機能 ユーザーの所有している車の画像を提供できます 提供した画像の削除機能 提供した画像を削除できます 提供画像一覧表示機能 自身が提供した画像一覧を表示します。 ユーザー情報編集機能 ご登録いただいたユーザー名・メールアドレスを変更できます Twitterシェア機能 車の検索結果をツイートすることができます レスポンシブ機能 スマホサイズ(320~540px)にも対応しています DB設計
各テーブルについて
テーブル名 説明 users 登録ユーザー情報 cars 登録車情報 histories 直近の検索結果の情報 car_images 提供画像の情報 苦労した点
ユーザー情報編集ページのバリデーション
LaravelのAuth機能のバリデーションを使いまわそうとしましたが、ブラックボックスになっていて苦労しました。
→新しくバリデーションを作成。S3からオブジェクト削除
画像の削除機能でDBからだけでなく、S3からもオブジェクトを削除する必要があり苦労しました。
→解決方法を記事にしました
laravel6でS3に画像アップロード&削除今後の課題
機能
機能 概要 英訳機能 Google Cloud Translation APIを利用して翻訳 通報機能 ユーザーの投票で不適切な画像を削除 技術
⚪︎ テスト
⚪︎ Dockerを用いた本番環境の構築
⚪︎ ECSへデプロイ参考にした学習教材など
PHP/Laravel
・【Udemy】PHP+MySQL(MariaDB) Webサーバーサイドプログラミング入門
・【書籍】詳細!PHP 7+MySQL 入門ノート
・【書籍】PHPフレームワークLaravel入門 第2版
・【書籍】PHPフレームワーク Laravel実践開発
・Laravel6.0(PHP7.3)+MySQL+Laradockで簡易的なECサイトを作るAWS
・【Udemy】AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得
Docker
・【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
さいごに
生のPHPでひとつPFを制作したのは、基礎力が身についたので良かったと思います。
今回ポートフォリオ完成を優先したため、ECSではなくEC2へデプロイしました。
まだ課題も多いですが、ブラッシュアップしていきたく思っています。
長くなりましたが、ここまで読んでくださりありがとうございました!!
- 投稿日:2021-03-15T20:53:40+09:00
【Laravel】Viewの文字列とパスを変数に置き換えてメンテ性と汎用性を上げる方法。route、__()、config()、ヘルパーの活用
ビューを作成するときに、メンテ性や汎用性を向上させるため、極力直接入力をなくす。見た目もなんとなくカッコよくなる。
文字列はlangファイルにまとめて記述し、関数で取得するようにする。
パスもメソッドとヘルパーを使って表示するようにする。
実例(Before & After)
構造化マークアップ(Website)を例とする。
before(index.blade.php)<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Website", "name": "サイトの名前", "url": "サイトのURL", "description": "サイトの説明", "potentialAction": { "@type": "SearchAction", "target": "サイトのURL?q={search_term_string}", "query-input": "required name=search_term_string" } } </script>↓ リファクタリング
after(index.blade.php)<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Website", "name": "{{__('page.index.title')}}", "url": "{{route('index')}}", "description": "{{__('page.origin.description')", "potentialAction": { "@type": "SearchAction", "target": "{{route('index')}}?q={search_term_string}", "query-input": "required name=search_term_string" } } </script>複数のサイト間で共有できる文字列はそのままとし、固有のものを変数に置き換えた。
パッと見ややこしいが、中身はかなり簡単。
目次
1. 文字列の取得
最初に文字列を変数に置き換える方法について。
resources配下にあるlangディレクトリの中に配列形式とオブジェクトで文字列を記載してく。
1-1. 設定言語を日本語に変更
デフォルトではenになっているので、jaに変更する。
config > app.php の中の localeを参照。
修正後'locale' => 'ja',1-2. 文字列を記述
page.phpファイルを作成し、呼び出しの元となる単語や文章を記載する。(ファイル名は任意)
page.php<?php return [ 'index' => [ 'title' => 'サイトの名前', 'description' => 'サイトの説明', ] ];今回は、index.blade.phpの情報を作成。プロパティ名と値は必要に応じて変更・追加していく。
1-3. 呼び出し
langファイルに設定した文字列を呼び出す。
__()
というヘルパ関数を使う。呼び出し方は、ファイル名(拡張子なし)の後に、ドットでプロパティ名を繋ぐ。
・
__('ファイル名.プロパティ名')
page.phpの中の、indexn中のtitleを呼び出しは以下のようになる。
サイトの名前を呼び出す"name": "サイトの名前", ↓ 置き換え "name": "{{__('page.index.title')}}"以上で文字列の呼び出しが完了。
2. URLの取得
次に、URLを変数に置き換える。これには
route
メソッドを使う。・
route('ルート名', ['変数'=>渡すデータ])
2-1. ルート名をつける
URLの呼び出しにはルート名を使うため、ルーティング(web.php)に名前を追加する。
ルーティングの後ろに
->name('ルート名')
をつける。web.phpRoute::get('/',[IndexController::class, 'index']) ->name('index');これで、https://ドメイン にindexと名付けることができた。
2-2. ルートを呼び出す
"url": "サイトのURL", "target": "サイトのURL?q={search_term_string}", ↓ 置き換え "url": "{{ route('index') }}", "target": "{{ route('index') }}?q={search_term_string}",これでURLを変数で呼び出すことができる。
2-3. パラメータ付きのURLの場合
記事詳細ページなど、idやページ番号といった変数が割り当てられている場合がある。その場合は、データを渡す必要がある。
web.phpRoute::get('/article-{articleId}/', [ArticleController::class, 'show']) ->name('article.show');https://ドメイン名/article-23 のように末尾に数字がつくパターン。ルート名はarticle.show。
ルーティングの設定で、数値の部分が
articleId
という変数に格納されて、コントローラのアクションに渡される。ビューの中でルートで呼び出す時も、articleIdの指定が必須。
コントローラ(ArticleController.php)public function show (string $articleId) { $article = Article::article($articleId); $articleId = $articleId; return view('pages.articles.show', compact( 'article', 'articleId', )); }Articleモデルから、指定の番号の記事データを取得し、変数articleに代入。
また、ルーティングから受け取った変数articleIdを同じ名前でビューに渡す。
ビュー(show.blade.php)"url": "{{ route('article.show'), ['articleId' => $articleId] }}",これで、現在のページのURLを呼び出すことができる。
3. confファイルとヘルパーの活用
応用編として、.envに記載されているサイト設計用のデータを使って変数を作り出すこともできる。
例として、.envにサイトのドメイン情報がある場合に、そこからヘルパーでホストを作成する方法について。
3-1. データ取得の流れ
- .envファイル: プロジェクトの基本情報
- config/app.phpファイル :環境設定用ファイル
- Helper/ViewHelper.php :自分でヘルパー関数を作成
- index.blade.php: ビューで呼び出す
3-2. .envのデータをconfigに呼び出す
.envの中で使いたいデータを、configディレクトリ配下のファイルに記述する。
.envは重要な情報が載っているため公開しない。config配下のファイルにデータを記述すると、
config
ヘルパーを使って簡単に呼び出すことができる。今回は、下記の
example.com
を使う場合を考える。.envAPP_ORIGIN_DOMAIN=example.com↓
config/app.phpの中に以下を記述。
app.php'origin_domain' => env('APP_ORIGIN_DOMAIN'),env関数を使って、.envファイルの中のデータを抜き出し、変数に格納する。
3-3. 自分でヘルパー関数を作成
envファイルから取得したドメイン名を使って、引数にパスを入れると、
https://example.com/引数で渡したパス
を返す自作のヘルパ関数を作成する。3-3-1. ヘルパ関数を定義
app直下に、Helpers > ViewHelper.phpを作成する。
ViewHelper.php<?php if (! function_exists('origin_url')) { function origin_url(string $path):string { return "https://" . config('app.origin_domain') . $path; } }・
if (! function_exists('origin_url'))
既存のヘルパ関数と名前が被ってないか確認。被っている場合に上書きしないようにしている。ヘルパ関数の作成時は必須。
・
function origin_url(string $path):string
関数名origin_url。引数で変数pathを渡す(型はString)。末尾の:string
は戻り値の型を指定している。戻り値がstring以外だとエラーが発生する。
・
return "https://" . config('app.origin_domain') . $path;
戻り値で https://example.com$path を返す。3-3-2. ヘルパ関数の読み込み
ヘルパ関数を定義したらcomposerで読み込む必要がある。
ルートディレクトリにあるcomposer.jsonのautoloadに以下を追記する。
composer.jsoncomposer.json "autoload": { "files": [ "app/Helpers/ViewHelper.php" ], }autoloadを更新すれば読み込み完了。
$ composer dump-autoloadこれで、定義したヘルパ関数をビューで呼び出せるようになった。
3-4. ビューで呼び出し
直接URLを書き込んでいる箇所を、
{{ }}
で囲ってヘルパ関数を呼び出せばOK。index.blade.php"url": "https://example.com", ↓ 変換 "url": "{{origin_url()}}",
配下のディレクトリも指定する場合は引数でパスを渡す。index.blade.php"url": "https://example.com/src/logo.png", ↓ 変換 "url": "{{origin_url(`/src/logo.png`)}}",
以上。
- 投稿日:2021-03-15T20:35:23+09:00
【Laravel】関数名の末尾のコロン型(:array, : int, : stringなど)は何を表しているのか?
Laravelで定義した関数名の末尾にコロン型(:array, : int, : stringなど)がついていたため、何の意味があるのか調べてみた。
結論からいうと、戻り値の型を指定している。
function 関数名(引数の型 引数):戻り値の型 { 処理 }
:
の後ろはスペースを開けてもいい。:int
でも: int
でもどちらでも問題ない。指定した型と異なる場合はTypeErrorが発生する。
errorErrors with: Fatal error: Uncaught TypeError: Return value of 関数名() must be an instance of 型
例#例1 function origin(string $path):string { 処理 } #例2 function counter(?string $src, int $number):int { 処理 } #例3 function page_arr(int $current, int $last):array { 処理 }
PHP公式 戻り値 下部の英語の部分に記載されている。
- 投稿日:2021-03-15T19:32:03+09:00
Docker環境のLaravelアプリをHerokuデプロイした後、画像をS3を利用して表示できるようにする
概要
Docker、Laravel、Heroku、S3(AWS)の勉強がてら画像アップロードができる掲示板アプリを作ったのですが、S3での画像表示にてこずったので備忘録として記事にしました。
この記事はあくまで本番環境でS3を使用して画像表示をするための記事ですので、ローカル環境で画像アップロード機能が仕上がっている事が前提となります。
自分はこちらの記事を参考に画像アップロード機能を作りました↓
https://note.com/koushikagawa/n/n74380a1f3643アプリケーションについて
簡単な掲示板アプリです。
新規投稿ページです↑
詳細ページにて画像が表示されます↑
トップページには画像を表示しないので省略します。AWS
AWSの登録等は省略します。S3に移動しバケットを作成します。
バケット名を入力します↑
バケットの設定をこのようにして「バケットを作成」を押します。コード
画像アップロードに関係するコードを載せていきます。
create.blade.php<form action="/posts" method="post" enctype="multipart/form-data"> {{ csrf_field() }} <input type="file" name="image_url"> @if ($errors->has('image_url')) <div>{{ $errors->first('image_url') }}</div> @endif </form>postsテーブルの画像のカラム名もimage_urlにしています。変えた方がわかりやすかったかもしれないですね。
PostController.phppublic function store(request $request) { $post = new Post(); $post->body = $request->body; // ローカル // $time = date("Ymdhis"); // $post->image_url = $request->image_url->storeAs('public/post_images', $time.'_'.Auth::user()->id. '.jpg'); $image = $request->file('image_url'); $path = Storage::disk('s3')->putFile('/', $image, 'public'); $post->image_url = $path; $post->user_id = $id; $post->save(); return redirect()->to('/'); } public function show(Post $post) { $user_id = $post->user_id; $user = DB::table('users')->where('id', $user_id)->first(); return view('posts.detail', [ 'post' => $post, 'user' => $user, // ローカル // 'image_url' => str_replace('public/', 'storage/', $post->image_url) 'image_url' => $post->image_url ]); } public function update(request $request) { $id = $request->post_id; $post = Post::findOrFail($id); $post->body = $request->body; if($request->hasFile('image_url')) { // ローカル // Storage::delete('public/post_images/' . $post->image_url); // $time = date("Ymdhis"); // $post->image_url = $request->image_url->storeAs('public/post_images', $time.'_'.Auth::user()->id. '.jpg'); $image = $request->image_url; Storage::disk('s3')->delete($image); //画像削除 $path = Storage::disk('s3')->putFile('/', $image, 'public'); $post->image_url = $path; } $post->save(); return redirect()->to('/'); }detail.blade.php@if ($image_url) // ローカル // <img src="/{{ $image_url }}" width="250px" height="250px"> <img src="https://バケット名.s3.ap-northeast-1.amazonaws.com/{{ $image_url }}" width="250px" height="250px"> @endifローカルのコードも一応載せています。無視してもらって結構です。
HerokuにAWSの環境変数を設定
terminal% heroku config:set AWS_ACCESS_KEY_ID=◯◯◯◯◯◯◯◯◯◯ % heroku config:set AWS_BUCKET=バケット名 % heroku config:set AWS_DEFAULT_REGION=ap-northeast-1 % heroku config:set AWS_SECRET_ACCESS_KEY=△△△△△△△△△△アクセスキーとシークレットキーをそれぞれ入力します。
terminal% git push heroku mainこれで本番環境で画像が表示できました。
- 投稿日:2021-03-15T19:32:03+09:00
S3を利用して画像を表示できるようにする
概要
Docker、Laravel、Heroku、S3(AWS)の勉強がてら画像アップロードができる掲示板アプリを作ったのですが、S3での画像表示にてこずったので備忘録として記事にしました。
この記事はあくまで本番環境でS3を使用して画像表示をするための記事ですので、ローカル環境で画像アップロード機能が仕上がっている事が前提となります。
自分はこちらの記事を参考に画像アップロード機能を作りました↓
https://note.com/koushikagawa/n/n74380a1f3643アプリケーションについて
簡単な掲示板アプリです。
新規投稿ページです↑
詳細ページにて画像が表示されます↑
トップページには画像を表示しないので省略します。AWS
AWSの登録等は省略します。S3に移動しバケットを作成します。
バケット名を入力します↑
バケットの設定をこのようにして「バケットを作成」を押します。コード
画像アップロードに関係するコードを載せていきます。
create.blade.php<form action="/posts" method="post" enctype="multipart/form-data"> {{ csrf_field() }} <input type="file" name="image_url"> @if ($errors->has('image_url')) <div>{{ $errors->first('image_url') }}</div> @endif </form>postsテーブルの画像のカラム名もimage_urlにしています。変えた方がわかりやすかったかもしれないですね。
PostController.phppublic function store(request $request) { $post = new Post(); $post->body = $request->body; // ローカル // $time = date("Ymdhis"); // $post->image_url = $request->image_url->storeAs('public/post_images', $time.'_'.Auth::user()->id. '.jpg'); $image = $request->file('image_url'); $path = Storage::disk('s3')->putFile('/', $image, 'public'); $post->image_url = $path; $post->user_id = $id; $post->save(); return redirect()->to('/'); } public function show(Post $post) { $user_id = $post->user_id; $user = DB::table('users')->where('id', $user_id)->first(); return view('posts.detail', [ 'post' => $post, 'user' => $user, // ローカル // 'image_url' => str_replace('public/', 'storage/', $post->image_url) 'image_url' => $post->image_url ]); } public function update(request $request) { $id = $request->post_id; $post = Post::findOrFail($id); $post->body = $request->body; if($request->hasFile('image_url')) { // ローカル // Storage::delete('public/post_images/' . $post->image_url); // $time = date("Ymdhis"); // $post->image_url = $request->image_url->storeAs('public/post_images', $time.'_'.Auth::user()->id. '.jpg'); $image = $request->image_url; Storage::disk('s3')->delete($image); //画像削除 $path = Storage::disk('s3')->putFile('/', $image, 'public'); $post->image_url = $path; } $post->save(); return redirect()->to('/'); }detail.blade.php@if ($image_url) // ローカル // <img src="/{{ $image_url }}" width="250px" height="250px"> <img src="https://バケット名.s3.ap-northeast-1.amazonaws.com/{{ $image_url }}" width="250px" height="250px"> @endifローカルのコードも一応載せています。無視してもらって結構です。
HerokuにAWSの環境変数を設定
terminal% heroku config:set AWS_ACCESS_KEY_ID=◯◯◯◯◯◯◯◯◯◯ % heroku config:set AWS_BUCKET=バケット名 % heroku config:set AWS_DEFAULT_REGION=ap-northeast-1 % heroku config:set AWS_SECRET_ACCESS_KEY=△△△△△△△△△△アクセスキーとシークレットキーをそれぞれ入力します。
terminal% git push heroku mainこれで本番環境で画像が表示できました。
- 投稿日:2021-03-15T18:47:24+09:00
【JavaScript】axiosでCSVを受け取りブラウザでファイルダウンロードに移行させる方法。
前提
サーバーサイドはLaravel、フロントはVue.jsです。
今回はJavaScriptの話がメインなのでPHPやLaravelが分からない方でも支障なく読んでいただけると思います。やりたかったこと
ユーザー目線:ブラウザに表示されているダウンロードボタンをクリックすると、CSVファイルをダウンロードできる。
僕目線:LaravelでCSVを吐き出すAPIを用意し、axiosを使ってAPIを叩きCSVをダウンロードできるようにする。
起こった問題
ブラウザの検索タブでエンドポイントに直接アクセスするとうまくダウンロードできるが、axiosを使ってエンドポイントにアクセスするとダウンロードできない。(CSVの内容はデータとして返ってくるが、ブラウザがダウンロード画面に移行しない。)
失敗した方法
CSVを返すAPIを単純に叩いてダウンロードできると思ったのですが、うまくいきませんでした。
※関係ない部分は色々省略してます。sample.jsdownloadCsv() { axios .get("/api/download/csv", { }) .catch((error) => { console.log(error.messagae); }); },CSVのデータはちゃんと返ってきますが、ブラウザがダウンロードに移行しません。(ユーザー目線だと何も起こらない。)
うまくいった方法
コードを下記のようにかえるとうまくダウンロードできました。
sample.jsimport saveAs from "file-saver"; // 省略 downloadCsv() { axios .get("/api/download/csv", { responseType: "blob", }) .then((res) => { let mineType = res.headers["content-type"]; const name = res.headers["content-disposition"]; const blob = new Blob([res.data], { type: mineType }); saveAs(blob, name); }) .catch((error) => { console.log(error.messagae); }); };追記部分を解説していきます。
リクエスト時の処理
sample.js.get("/api/download/csv", { responseType: "blob", })データをBLOBとして受け取ります。
BLOBとはBinary Large OBject
の略で、IT用語辞典では以下のように解説されています。BLOBとは、データベースのフィールド定義などで用いられるデータ型の一つで、テキスト(文字列)や整数のように既存のデータ型としては用意されていない任意のバイナリデータを格納するためのもの。
つまり、BlOBはテキストファイルだけではなく画像やPDFなどいろいろな形式のファイルを扱うことができる訳です。
そしてJavaScriptでは受け取ったデータをBOLBにするとこで、ファイルにすることが可能になります。
CSVはテキストデータなのでBLOBにする必要はないのでは?と思ったのですが、データをファイルにするために必要なようです。
レスポンスを受け取った後の処理
sample.js.then((res) => { let mineType = res.headers["content-type"]; const name = res.headers["content-disposition"]; const blob = new Blob([res.data], { type: mineType }); saveAs(blob, name); })
res.headers["content-type"]
にはLaravel側で設定した'text/csv'
が格納されています。今回は必ず'text/csv'
が返るようになっていますが、ダウンロード用のメソッドを色々な形式に対応できるようにするためにこのように書く必要がありますね。
res.headers["content-disposition"]
にはLaravel側で設定したファイル名が格納されています。
new Blob([res.data], { type: mineType });
JavaScriptのBlobオブジェクトのインスタンスを生成しています。
BlobオブジェクトはBLOBをJavaScriptで扱うためのオブジェクトです。
第一引数にファイルの内容の配列、第二引数にファイルの種類を指定して使います。
saveAs(blob, "file");
'file-server'
というライブラリを使ってファイルを保存しています。
詳しくは割愛しますが、ブラウザ間で異なるファイル保存の処理を1行で書けます。文字化けを修正
無事CSVをダウンロードすることができましたが、ファイルの内容が文字化けしていました。
はっきりとした原因は分かりませんでしたが、Laravel側でSJIS
形式に変換していた部分をUTF-8
に変換するように変更すると文字化けしなくなりました。sample.php// mb_convert_encoding($content, 'SJIS', 'auto'); mb_convert_encoding($content, 'UTF-8', 'auto');HTMLのmetaタグでUTF-8に指定しているのが原因なのか?
とりあえず、これで内容も分かるCSVファイルをダウンロードできるようになりました。めでたしめでたし。最後に
aixosを使ってファイルをダウンロードするにはひと手間いることが分かりました。
BLOBについては恥ずかしながら全然知らなかったです。今回はLaravel側でCSVを作成しましたが、データをJSON形式で送るようにしてVue側でCSVを作成することもできそうです。
他にもこんな方法があるとか、ここ間違ってるよとかあればご指摘等よろしくお願いします!
ではでは。
- 投稿日:2021-03-15T18:27:18+09:00
Laravel Mixで環境に応じて複数の.envで環境変数を管理する
はじめに
こんにちは。先日、ランニングシューズ以外でいい靴を買ってしまいました、筆者です
さて、LaravelでWebpack使っているので、Laravel Mixを使用しております。
その際に.envで環境変数を分ける機会がありましたので、共有します。
結論
急いでいる方はこちらご参照くださいませ。Laravel Mixのドキュメントの書いてあるんです
(ただ、スターが超少ないのが気になります...
)
解説
1.
mix-env-file
をインストールする。$ npm install mix-env-file2.
dotenv
をインストールする。あとでコンパイルするときにインストールしろと怒られるのでこちらもインストールします。
(ドキュメントには書いてないんです)
$ npm install dotenv3. package.jsonを編集する。
サンプルはこちら↓
package.json"scripts": { "dev": "cross-env ENV_FILE=./.env.dev npm run development", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "watch": "npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "cross-env ENV_FILE=./.env.prod npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }上記の場合、以下の動きをします。
npm run dev
したときは、./.env.dev
を読みます。
npm run prod
したときは、./.env.prod
を読みます。4.
webpack.mix.js
を編集する。webpack.mix.jslet mix = require('laravel-mix'); require('mix-env-file'); // Then pass your file to this plugin // If this is not set, this plugin won't do anything and the default .env variables will remain mix.env(process.env.ENV_FILE);以上です
おわりに
.env便利でした
それでは!
- 投稿日:2021-03-15T15:38:10+09:00
Docker composeでngrokを簡単に使う方法(QOL爆上がりな件)
docker-composeで開発をしていて、お手元のスマートフォンでの確認や、他の人にサービスを見てもらう際に、
毎度デプロイすることは難あり。
そういった時に、ngrok
を使用すると、簡単にローカル環境を外部に一時的に公開することができる。今回はLaravelの開発においての使用とし、開発環境はdockerである。
laravelが8000ポートで、
データベースが3000ポートとしている。また、
brew install ngrok
を済ませていることが前提。手順
1 Dockerを起動しておく
docker-compose up -d2 ngrokを起動する
ngrok http 8000このコマンドでngrokが起動する。
この時の注意点は、
docker自体にngrokなど特に何もインストールする必要はなく、
起動したいサーバーのポート番号を指定する。laravelアプリは
localhost:8000
だから、
ngrok http 8000
となる。
データベースのポート番号、3000は指定する必要はないと確認している。そうすると、ngrokの起動画面に切り替わり、
forwarding
と記載されているurlが実際にchromeなどでアクセス
する際のurlになる。ngrokの使用を停止する時は、
controll + c
で止まる。これ使ってQOL爆上がりです。
- 投稿日:2021-03-15T15:07:00+09:00
laravelとreact 一緒に使うけど 厳密に言うと APIじゃない件について
めっちゃ時間無駄にしたので戒めのためのメモ
状況
laravelで作ったサービスをあとからreact化しようとした際 遭遇
axiosにて記事情報を post すると 何故か リレーションしているuser_idがnillになり処理が完了しない。結論
・routes/api.phpにかかない
普通にweb.phpに書くここに書くとpostするとauthのガードに引っかかってuser_idがnillになってエラー
※
ちなみに私は トークン とかいろいろ 迷子になって laravel passportまでいれて結局関係にことにあとで気づきました・・。 勉強にはなったが。。。
- 投稿日:2021-03-15T14:47:26+09:00
PHPでQRコードを作ってみた
今回は動的にサイトのURLを作成したかったので、PHPでQRコードを作成したみました。
結論から言いますと、全く難しくないです!!
読み取りもしっかりと行えます!
なので、肩の力を抜いてご覧ください。
それでは説明していきます!
まずはQRコードを作成するためのライブラリをダウンロードしてください。
compose require endroid/qr-code後は下記の記述を参考にQRコードを作成します。
今回はコントローラーでQRコードを作成します。
<?php namespace App\Http\Controllers; use App\Models\Qr; use Illuminate\Http\Request; use Endroid\QrCode\Color\Color; use Endroid\QrCode\Encoding\Encoding; use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow; use Endroid\QrCode\QrCode; use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; use Endroid\QrCode\Writer\PngWriter; class QrCodeController extends Controller { public function generate(Request $request) { $writer = new PngWriter(); $origin_URL = 'https://www.example.com'; // Create QR code $qrCode = QrCode::create($origin_URL) ->setEncoding(new Encoding('UTF-8')) ->setErrorCorrectionLevel(new ErrorCorrectionLevelLow()) ->setSize(300) ->setMargin(10) ->setRoundBlockSizeMode(new RoundBlockSizeModeMargin()) ->setForegroundColor(new Color(0, 0, 0)) ->setBackgroundColor(new Color(255, 255, 255)); // QRコードの出力 $result = $writer->write($qrCode); header('Content-Type: '.$result->getMimeType()); echo $result->getString(); // // QRコードの画像ファイルを保存 // $result->saveToFile(__DIR__.'/qrcode.png'); // // QRコードのURL // $dataUri = $result->getDataUri(); } }このようにしてQRコードを作成することができます!
実際にコントローラーを適用しているURLに移動すると下記のように表示されます。
めちゃめちゃ簡単!
以上、「PHPでQRコードを作ってみた」でした!
Thank you for reading
- 投稿日:2021-03-15T14:42:23+09:00
Dockerで作成したLaravelで「bash: composer: command not found」と出たときの対処法
Dockerって環境構築が簡単に行えてすごく便利ですよね。
特にデータベースとかわざわざインストールしなくてもできてしまいますもんね。
そんなDockerで
composer
を使ってあるものをインストールしようとしたのですが、下記のようなエラーが起きました。bash: composer: command not foundDockerのコンテナ外では
composer
コマンドを打てるのですが、コンテナ内では打てませんでした。結論から言いますと、Dockerのイメージをビルドするときにcomposerをインストールすれば解決します。
Dockerのphpを構築する
Dockerfile
で以下の記述を加えて下さい。ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ && php composer-setup.php \ && php -r "unlink('composer-setup.php');" \ && mv composer.phar /usr/local/bin/composer一応僕の
Dockerfile
のコードを載せておきますね。FROM php:7.4-fpm-buster COPY ./backend /work COPY ./docker/php/php.ini /usr/local/etc/php/php.ini LABEL maintainer="ucan-lab <info@u-can.tech>" SHELL ["/bin/bash", "-oeux", "pipefail", "-c"] # tinker(psysh) ARG PSYSH_DIR=/usr/local/share/psysh ARG PSYSH_PHP_MANUAL=$PSYSH_DIR/php_manual.sqlite ARG PHP_MANUAL_URL=http://psysh.org/manual/ja/php_manual.sqlite # timezone ARG TZ=Asia/Tokyo # composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin RUN apt-get update && \ apt-get -y install git unzip libzip-dev libicu-dev libonig-dev libjpeg-dev libpng-dev libfreetype6-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ docker-php-ext-install intl pdo_mysql zip bcmath && \ docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ && \ docker-php-ext-install gd # Install Composer RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ && php composer-setup.php \ && php -r "unlink('composer-setup.php');" \ && mv composer.phar /usr/local/bin/composer # Install Node.js RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \ && apt-get update \ && apt-get install -y nodejs RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime RUN apt-get install -y cronこんな感じでコンテナ内に入り、
composer -V
と打ちバージョンが返ってくれば成功です。以上、「Dockerで作成したLaravelで「bash: composer: command not found」と出たときの対処法」でした!
Thank you for reading
- 投稿日:2021-03-15T02:54:39+09:00
Laravelの学習をしてウェブアプリを作ったのでやったことまとめ
制作アプリについて
アプリ概要
会員登録、ログイン、プロフィール編集
投稿時画像加工、投稿・編集・削除現在の不具合状況について
・アップロード画像が2MBを超えるものの投稿ができない
・投稿した画像が横向きに反転してしまう作った経緯と目的
・転職時に必要なため
・自分自身のあったらいいなをアプリ化
1つ目。自分自身何かエンジニアとしての能力証明ができる術を持っていなかったので、転職時のポートフォリオとしてのスキル証明用になればと思い制作
2つ目。自分が必要としていることは誰かもまた必要としているのかなと思い「自分自身のあったらいいな
」というものを実現させた。
具体的には、
「○○って字を綺麗に書きたいけど検索しても自分の気に入る字体がみつからない」
「参考になる字体を検索して探したい」
という課題の解消させた。
イメージとしては、お手本の字をただ真似て書くのではなく、自分の書きたい文字について探してからお手本にして書く。
プログラミング学習するときに、課題で出されたものを作るのではなく、自分の作りたいものを調べながら作るという感じです。開発期間
Laravel の基礎学習期間二週間とアプリ開発に1ヶ月ほど
ER図
開発環境
・言語:PHP7, Bootstrap, HTML, CSS(Sass)
・フレームワーク:Laravel8
・DB:SQLite→postgreSQL
・環境:ローカル環境(MacOS), VSCode
・インフラ:AWS S3, heroku主な機能
・CRUD
・会員登録、ログイン、ログアウト
・画像アップロード
・DBリレーション
・検索機能
・マイページ
・ペジネーション
・画像加工
・バリデーション追加できたらいいもの
・2枚以上の画像投稿
・タグ機能
・お気に入り
・JavaScriptでのデザイン、操作
勉強中であり多言語の知識が必要で時間がかかりそうなため一時保留
画像加工は強制的にしているので何かしらの形で修正したい感想
簡単に手書きで欲しい機能、デザイン、DB設計などを考えてから始めたものの
途中途中であれもいいかもこれもいいかもなんてことを思いよく脱線したので、一番初めにしっかりと考えてからやれたらもっと早く作り終えたと思う。
でもその中で何が必要で何があったら便利で何がいらない機能なのかなどひとつひとつ客観的に物事を考えて自分自身で試行錯誤するところは楽しかったし面白かったです。
エンジニアの挫折率が高い所以の一つに、エラーや不具合があると思うけど、この模索している時がなんだかんだ一番面白く、丸1日動かなかったエラーが解消されたときはとても気持ちが良かったです。
GitHubにコードあげ忘れることが多かったのでもう少し意識してできたら良かった。その他メモ
フロントエンド側のデザインUI/IXに関してはあまり自分の希望する分野ではないので最低限に収めてバックグラウンドの方に重きを置いていたので、フロントエンド側にももう少し手を加えて改善したい。
GitHubの使い方、DB操作、他言語、インフラなど知って行くたびに自分の知らないことが多いのでこれからも少しずつ学習していきたい。
- 投稿日:2021-03-15T02:09:55+09:00
Laravel8 ReactHooks & MySQL Create処理
やりたいこと
フロントはReactHooksを使用して、LaravelはAPIサーバーでバックエンド処理をおこなう。
バックエンド処理はaxiosを使用。完成図
開発環境
- Laravel 8.0
- php 7.3
- MySQL 8
State
- const [ name, setName ] = useState(null);
入力値name(名前)のState
- const [ email, setEmail ] = useState(null);
入力値email(メールアドレス)のState
- const [ city, setCity ] = useState(null);
入力値city(住所)のState
- const [ address, setAddress ] = useState(null);
入力値address(市区町村)のState
- const [ phone, setPhone ] = useState(null);
入力値phone(電話番号)のState
入力フォーム
map処理はkeyを明示する必要があるので注意
keyの明示についてはVirtualDOMのdiffから実際のDOMに反映させるときに最小限の変更にするために使われる。
formimport React, { useEffect, useState } from 'react'; import employeeServices from "../services/Employee" function Form(){ const [ name, setName ] = useState(null); const [ email, setEmail ] = useState(null); const [ city, setCity ] = useState(null); const [ address, setAddress ] = useState(null); const [ phone, setPhone ] = useState(null); const [ rol, setRol ] = useState(null); const [ listRol, setListRol ] = useState([]); useEffect(() => { async function fetchDataRol() { // load data from API const res = await employeeServices.list(); setListRol(res.data) } fetchDataRol(); },[]); const saveEmployee = async () => { const data = { name, email, city, address, phone, rol } const res = await employeeServices.save(data); if (res.success) { alert(res.message) } else { alert(res.message) } } return( <div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="firstName">Name employee </label> <input type="text" className="form-control" placeholder="Name" onChange={(event)=>setName(event.target.value)} /> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="email">Email</label> <input type="email" className="form-control" placeholder="you@example.com" onChange={(event)=>setEmail(event.target.value)} /> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="phone">City </label> <select id="inputState" className="form-control" onChange={(event)=> setCity(event.target.value)}> <option selected>Choose...</option> <option value="London">London</option> <option value="Madrid">Madrid</option> <option value="New York">New York</option> </select> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="address">Address</label> <input type="text" className="form-control" placeholder="1234 Main St" onChange={(event)=>setAddress(event.target.value)} /> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="phone">Phone </label> <input type="text" className="form-control" placeholder="123467890" onChange={(event)=>setPhone(event.target.value)} /> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <label htmlFor="phone">Rol </label> <select id="inputState" className="form-control" onChange={(event)=> setRol(event.target.value)}> <option selected>Choose...</option> { listRol.map((item)=>{ return( <option key={item.rol_id} value={item.rol_id}>{item.rol_name}</option> ) }) } </select> </div> </div> <div className="row"> <div className="col-md-6 mb-3"> <button className="btn btn-primary btn-block" type="submit" onClick={()=>saveEmployee()}>Save</button> </div> </div> </div> ) } export default Form;saveEmployee押化後、axiosのemployee.saveが呼び出されてlocalhost:8000/api/employee/createにPOSTする。
axios通信
axiosconst baseUrl = "http://localhost:8000/api/employee" import axios from "axios"; const employee = {}; employee.save = async (data) => { const urlSave= baseUrl+"/create" const res = await axios.post(urlSave,data) .then(response=> {return response.data }) .catch(error=>{ return error; }) return res; } export default employeeapi.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); Route::post('/employee/create', 'App\Http\Controllers\API\EmployeeController@create');Laravel側のControllerが呼び出され、実際に処理をするcreateアクションを呼び出します。
保存処理の最後にはresponseを返してあげる。今回は動作確認のため、失敗時にエラーメッセージのみを返しています。
コントローラー
EmployeeController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Employee; class EmployeeController extends Controller { public function index(){ return view("employee"); } public function create(Request $request){ try { $insert['name_lastname'] = $request['name']; $insert['email'] = $request['email']; $insert['city'] = $request['city']; $insert['direction'] = $request['address']; $insert['phone'] = $request['phone']; Employee::insert($insert); $response['message'] = "Save succesful"; $response['succes'] = true; } catch (\Exception $e) { $response['message'] = $e->getMessage(); $response['error'] = true; } return $response; } }createアクションはこのような流れで実装できます
指摘などがございましたらコメントで教えていただけると幸いです^_^
おわり
次はレコードをmapで繰り返し表示する方法など記事にしていこうと思います〜!
- 投稿日:2021-03-15T02:09:55+09:00
Laravel8+ReactHooks+MySQL Create処理
やりたいこと
フロントはReactHooksを使用して、LaravelはAPIサーバーでバックエンド処理をおこなう。
バックエンド処理はaxiosを使用。開発環境
- Laravel 8.0
- php 7.3
- MySQL 8
ModelはItem カラムはtext/commentと仮定しています。
State
- const [ text, setText ] = useState("");
入力値textのState
- const [ comment, setComment] = useState("");
入力値commentのState
入力フォーム
入力値をSetStatで更新。submitでsaveEmployeeを呼び出す。
formreturn ( <form className="add-form"> <div className="add-text"> <label>内容</label> <input type="text" value={text} onChange={(event)=>setText(event.target.value)}/> </div> <div className="add-comment"> <label>コメント</label> <input type="number" value={amount} onChange={(event)=>setComment(event.target.value)}}/> </div> <div className="form-row"> <color="primary" aria-label="add" type="submit" onClick={()=>saveEmployee()}>追加</div> </form> )呼び出されたsaveEmployeeはdataに定義された値を保持してemployeeServices.saveにアクセス。
この際、dataに定義されているtextとcommentはuseStateを参照しています。axiosconst saveEmployee = async () => { const data = { text, comment, }; const res = await employeeServices.save(data); setItemlist(res.data) }saveEmployeeから渡された値(data)を引数に、LaravelのAPIサーバーにPOSTする。
employeelet url = location.href; const baseUrl = url + 'api/employee'; const employee = {}; employee.save = async (data) => { const urlSave = baseUrl+"/save" const res = await axios.post(urlSave,data) .then(response=>{ return response.data; }) .catch(error=>{ return error; }) return res; }Laravel側のapi.phpが呼び出され、実際に処理をするcreateアクションを呼び出します。
api.phpuse App\Http\Controllers\EmployeeController; Route::match(['get', 'post'],'/employee/itemcreate', [EmployeeController::class, 'itemcreate']);itemcreateメソッド内で保存処理を行い、responseに$itemsを渡してreturnしてあげる。
ItemController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Item; class EmployeeController extends Controller { public function itemcreate(Request $request){ try { $items = new Item(); $items->text = $request->text; $items->amount = $request->comment; $items->save(); $response['data'] = $items; $response['message'] = '成功'; $response['success'] = true; } catch (\Exception $e) { $response['message'] = $e->getMessage(); $response['success'] = false; } return $response; } }createアクションはこのような流れで実装できます
指摘などがございましたらコメントで教えていただけると幸いです^_^
次はレコードをmapで繰り返し表示する方法など記事にしていこうと思います〜!