- 投稿日:2020-07-30T23:13:17+09:00
【Laravel】ルートパラメーターを簡単にまとめ
Laravelのルートパラメータは「必須」と「任意」を覚える
必須パラメータ
Laravelのルート定義をする際に、ルートパラメータの設定をする場合があります。
例えば、URLからユーザーIDや記事IDを取り出したい場合、取り出したいURLの部分を{}括弧で囲むことで、その囲まれた部分のパラメーターをコントローラーへ送ることができます。
とまあ、文章で書いてもよくわからないので例文を下記に記述します。Route::get('user/{id}', function ($id) { return 'User '.$id; });上記の例では、URIが「user/○○」だとした場合にマッチングするルート定義になっています。ルートパラメーターの定義は{id}として記述されていますね。
この場合、{id}にあたる部分である「○○」が$idに格納されます。
なので、上記例の場合、最終的には「User ○○」が出力されます。ちなみに、上記の例は「必須パラメータ」と呼ばれ、もし{id}の部分がURIに含まれないケースでは、このルート定義にあてはまりません。
任意パラメータ
パラメータを指定しても、しなくてもOK!というような、任意でパラメータを入力したいということもあります。
その場合は、パラメータ名の最後に?マークを付けると任意指定可能なパラーメータになります。便利!
こちらも例を見てみましょう。Route::get('user/{name?}', function ($name = null) { return $name; }); Route::get('article/{name?}', function ($name = 'study') { return $name; });こんな感じで、{name?}のところはURIであってもなくても良いという感じです。
例えば、「user/masahiro」というURIでアクセスした際は「masahiro」と出力されますし、
「article」だけでアクセスした場合は、デフォルト値が適応されて「study」が出力されます。パラメータの数は自由に書ける
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { // });上記のように、必要に応じて{}を使用することでパラーメータの定義可能です。
{post}は\$postIdに対応していて、{comment}は\$commentIdに対応していますね。
- 投稿日:2020-07-30T14:42:48+09:00
Laravel artisanコマンド 【備忘録】
- 投稿日:2020-07-30T13:05:22+09:00
PHPでPayPayAPIにリクエスト投げて成功するまで
PayPayAPIにリクエスト投げて成功するまでの記事です
PayPay for Developers
PayPay for Developersで登録してAPI_KEY、API_SECRET、MERCHANT_IDの取得が必要(登録方法は割愛)
sdkインストール
composer require paypayopa/php-sdk
成功したソース
<?php namespace App\Helpers; use PayPay\OpenPaymentAPI\Client; use PayPay\OpenPaymentAPI\Models\CreateQrCodePayload; class PayPay { protected Client $paypayClient; function __construct() { $paypayConfig = \Config::get('paypay'); $this->paypayClient = new Client([ 'API_KEY' => $paypayConfig['API_KEY'], 'API_SECRET' => $paypayConfig['API_SECRET'], 'MERCHANT_ID' => $paypayConfig['MERCHANT_ID'], ], true); //Set True for Production Environment. By Default this is set False for Sandbox Environment. // Creating the payload to create a QR Code, additional parameters can be added basis the API Documentation $payload = new CreateQrCodePayload(); $payload->setMerchantPaymentId("my_payment_id" . \time()); $payload->setCodeType("ORDER_QR"); $amount = [ "amount" => 1, "currency" => "JPY" ]; $payload->setAmount($amount); $payload->setRedirectType('WEB_LINK'); $payload->setRedirectUrl('https://paypay.ne.jp/'); $payload->setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1'); //================================================================= // Calling the method to create a qr code //================================================================= $response = $this->paypayClient->code->createQRCode($payload); // 処理がうまくいってなかったら抜ける if($response['resultInfo']['code'] !== 'SUCCESS') { return; } // Collectionに変換しておく $QRCodeResponse = collect($response['data']); //================================================================= // Calling the method to get payment details //================================================================= $response = $this->paypayClient->payment->getPaymentDetails($QRCodeResponse['merchantPaymentId']); // 処理がうまくいってなかったら抜ける if($response['resultInfo']['code'] !== 'SUCCESS') { return; } // Collectionに変換しておく $QRCodeDetails = collect($response['data']); //================================================================= // Calling the method to cancel a Payment //================================================================= $response = $this->paypayClient->payment->cancelPayment($QRCodeResponse['merchantPaymentId']); // 処理がうまくいってなかったら抜ける if($response['resultInfo']['code'] !== 'REQUEST_ACCEPTED') { return; } \Log::info(print_r($QRCodeResponse, true)); \Log::info(print_r($QRCodeDetails, true)); \Log::info(print_r($response, true)); } function __destruct() { } }logの内容
[2020-07-30 06:53:42] local.INFO: Illuminate\Support\Collection Object ( [items:protected] => Array ( [codeId] => 04-PKkfM9UDxn13nFfl [url] => https://qr-stg.sandbox.paypay.ne.jp/28180104PKkfM9UDxn13nFfl [expiryDate] => 1596081556 [merchantPaymentId] => my_payment_id_1596093507 [amount] => Array ( [amount] => 1 [currency] => JPY ) [codeType] => ORDER_QR [redirectUrl] => https://paypay.ne.jp/ [redirectType] => WEB_LINK [isAuthorization] => [deeplink] => paypay://payment?link_key=https%3A%2F%2Fqr-stg.sandbox.paypay.ne.jp%2F28180104PKkfM9UDxn13nFfl ) ) [2020-07-30 06:53:42] local.INFO: Illuminate\Support\Collection Object ( [items:protected] => Array ( [status] => CREATED [acceptedAt] => 0 [requestedAt] => 0 ) ) [2020-07-30 06:53:42] local.INFO: Array ( [resultInfo] => Array ( [code] => REQUEST_ACCEPTED [message] => Request accepted [codeId] => 08100001 ) [data] => [transit] => Array ( [0] => HTTP/2 202 [1] => date: Thu, 30 Jul 2020 06:53:42 GMT [2] => content-type: application/json [3] => x-request-id: OPA4CE2D1787C11436F95A9B13DFEDFE3D6 [4] => x-content-type-options: nosniff [5] => x-xss-protection: 1; mode=block [6] => cache-control: no-cache, no-store, max-age=0, must-revalidate [7] => pragma: no-cache [8] => expires: 0 [9] => x-frame-options: DENY [10] => x-rate-limited: 1 [11] => [12] => ) )つまづきポイント
コメント文のミス?
サンプルコードでは
use PayPay\OpenPaymentAPI\Client; $client = new Client([ 'API_KEY' => 'YOUR_API_KEY', 'API_SECRET'=>'YOUR_API_SECRET', 'MERCHANT_ID'=>'YOUR_MERCHANT_ID' ],false); //Set True for Production Environment. By Default this is set False for Sandbox Environment.
//Set True for Production Environment. By Default this is set False for Sandbox Environment.
って書いてるけどtrue
でステージング環境(開発用)になるサンプルソースのミスその1(ペイロード?を作るとき)
サンプルコードでは
// Creating the payload to create a QR Code, additional parameters can be added basis the API Documentation $payload =new PaypaySdkPayload(); $payload->set_merchant_payment_id("my_payment_id"); $payload->set_code_type("ORDER_QR"); $amount = [ "amount" => 1, "currency" => "JPY" ]; $payload->set_amount($amount); $payload->set_redirect_type('WEB_LINK'); $payload->set_redirect_url('https://paypay.ne.jp/'); $payload->set_user_agent('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1'); // Calling the method to create a qr code $response = $client->code->createQRCode($payload); // Printing if the method call was SUCCESS console.log($response['resultInfo']['code']);こうなってるけど、
PaypaySdkPayload
のようなクラスはない、そしてset_
の関数もないサンプルソースのミスその2(詳細を見るとき)
// Calling the method to get payment details $response = $client->code->getPaymentDetails('<merchantPaymentId>'); // Printing if the method call was SUCCESS, this does not mean the payment was a success console.log($response['resultInfo']['code']); // Printing if the transaction status for the code has COMPLETED/ AUTHORIZED console.log($response['data']['status']);
$client->code->getPaymentDetails('<merchantPaymentId>');
実際は$client->payment->getPaymentDetails('<merchantPaymentId>');
サンプルソースのミスその3(キャンセルするとき)
// Calling the method to cancel a Payment $response = $client->code->cancelPayment('merchantPaymentId'); // Printing if the method call was SUCCESS console.log($response['resultInfo']['code']);
$client->code->getPaymentDetails('<merchantPaymentId>');
実際は$client->payment->getPaymentDetails('<merchantPaymentId>');
および
// Printing if the method call was SUCCESS
って書いてて、ああ上と一緒でSUCCESS
なんだろうなぁって思うかもしれないけど、実際はREQUEST_ACCEPTED
が帰ってきている(ちゃんと読め私w
- 投稿日:2020-07-30T10:59:07+09:00
Laravel 認証機能 (日本語化編)
認証に関わるメッセージ等を日本語に
デフォルトだと「Login」「Register」など英語で表示され、日本人を対象とするサイトでは、日本語の方が好ましいので。
→認証機能自体の実装はLaravel 認証機能 (インストール編)を参照。手順概要
- 「app.php」で、「locale」を設定。
- メッセージ等のマスターとなるファイルを作成、保存。
手順詳細
1.「config」内の「app.php」に記述された「'locale' => 'en'」を「'locale' => 'ja'」に変更する。
2.「lang」直下に「ja.json」というファイルを作成し、下記の内容を記述する。
※コピーする場合は、こちらをご利用ください。
ja.json{ "Login": "ログイン", "Register": "新規登録", "Forgot Your Password?": "パスワードを忘れた場合", "Reset Password": "パスワード再設定", "Send Password Reset Link": "パスワード再設定URLを送信", "Logout": "ログアウト", "Name": "お名前", "E-Mail Address": "メールアドレス", "Password": "パスワード", "Confirm Password": "パスワード(確認用)", "Remember Me": "ログイン状態を保存", "Hello!": "ご利用ありがとうございます。", "Reset Password Notification": "パスワード再設定のお知らせ", "You are receiving this email because we received a password reset request for your account.": "あなたのアカウントでパスワード再発行のリクエストがありました。", "This password reset link will expire in :count minutes.": "再設定URLの有効期限は :count 分です。", "If you did not request a password reset, no further action is required.": "もしパスワード再発行をリクエストしていない場合、操作は不要です。", "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "\":actionText\"ボタンを押しても何も起きない場合、以下URLをコピーしてWebブラウザに貼り付けてください。\n[:actionURL](:actionURL)", "Regards": "よろしくお願いいたします" }※表示する文章の内容は、修正可能です。
3.日本語に切り替わります。
- 投稿日:2020-07-30T10:39:25+09:00
Laravel 任意のディレクトリ直下にモデルファイルを作成する
目的
- 実務でモデルファイルを作成する時に
アプリ名ディレクトリ/app
に作成することよりもアプリ名ディレクトリ/app/Models
直下に作成することが多いため、方法をまとめる実施環境
- ハードウェア環境
項目 情報 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をインストールする 前提条件
- 実施環境と同じLaravelローカル開発環境が構築されていること。
前提情報
- 特になし
読後感
- モデルファイルを
アプリ名ディレクトリ/app
直下の任意のディレクトリ内に作成することができる。例
アプリ名ディレクトリに移動して下記コマンドを実行する。
$ php artisan make:model app直下のモデルファイルを作成したいディレクトリ名/モデルファイル名具体例
アプリ名ディレクトリ/app/Models
直下にTestというモデルファイルを作成したい時はアプリ名ディレクトリで下記コマンドを実行する。(Modelsディレクトリが存在しない時は自動で作成されてその中にモデルファイルが格納される)$ php artisan make:model Models/Testモデルファイルを移動してエラーが出た話
アプリ名ディレクトリ/app
直下にモデルファイルを作成後に手動でモデルファイルをアプリ名ディレクトリ/app/Models
に移動しただけだと下記の様なエラーが発生する可能性があるので注意する。
- 投稿日:2020-07-30T10:31:41+09:00
phpのフレームワークLaravelを触ってみた。(新規コントローラー作成編)
artisanの利用
ArtisanとはLaravelを構成しているコマンドラインインターフェイスの名前です。
ちなみに読み方は「アルチザン」。
使い方は、php artisan listで一覧を表示してくれます。$ php artisan list Laravel Framework 7.21.0 Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug ・ ・ ・ ・ ・ ・ ・ ・※長いので、一部記載。
コントローラの作成
次のコマンドを実行します。
$ php artisan make:controller SampleAppController Controller created successfully. ※これが表示されればちゃんと出来てます。
- 作成されるディレクトリは、こちら
(Laravelアプリディレクトリ)/app/Http/Controllersファイルの中身は、こんな感じです。
app/Http/ControllersSampleAppController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class SampleAppController extends Controller { // }下記の様にindex functionを追加します。
app/Http/ControllersSampleAppController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class SampleAppController extends Controller { //下記のメソッドを追加 public function index() { return view('sampleapp'); } }ルーティングの設定
(Laravelアプリディレクトリ)/routes/web.phpに下記のように追加します。
routes/web.php/* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/','SampleAppController@index');ビュー作成
(Laravelアプリディレクトリ)/resources/views/にsampleapp.blade.phpを作成します。
resources/views/にsampleapp.blade.php<html> <head> <title>Sample App</title> </head> <body> Sample App Viewです。 </body> </html>動作確認
http://localhost:8000/にアクセスして画面が表示される事を確認します。
- 投稿日:2020-07-30T08:35:29+09:00
ドメイン駆動設計のミッション層を設計する手法を紹介
今回の記事では、前回の「エリック・エヴァンスが提唱したアーキテクチャの4層モデルを拡張する」の記事で紹介した
5層アーキテクチャモデルのミッション層を設計する方法について紹介する。前回の記事について以下のURLを参照
https://qiita.com/aLtrh3IpQEnXKN7/items/b7fe2014ccefcbb9e458ミッション層を理解する鍵は抽象表現主義
抽象表現主義とは人間の心象世界を絵画に表現することを目指した表現技法。
現実の世界に基づい絵画を描写する写実主義とは対極に位置する心象風景をモチーフに絵画を記載する手法。
抽象表現主義はオートマティスムと呼ばれる「何か別の存在に憑依されて肉体を支配されているかのように、自分の意識とは無関係に動作を行ってしまう現象」に基づいて絵画を描写する手法を取り入れている。
そのため、抽象表現主義によって取り入れられた絵画は水のような流体状になった作品が仕上がる。
現実の世界を水のような流体として捉える抽象表現主義の描写がミッション層のロジックを理解することに繋がる。
下記は抽象表現主義によって作成された作品。
ミッション層を巨大なキャンバスとして捉える
ミッション層を設計する場合、巨大なキャンバスとして捉えることが設計を行うポイントになる。
キャンバスの中では、登場人物が役割を演じ、特定のシーンが切り取られ作品として完成する。
キャンバスは以下の要素によって構成されている。
・タイトル
・俳優
・俳優が演じる役割
・俳優が使用する道具ミッション層では、外部から取り込んだエネルギーを変換し、別のオブジェクトに変換して出力するというプロセスがロジックの流れになる。
そのため、ミッション層で実行されるロジックは、映画のワンシーンのように脚本に沿って各俳優が役割を演じるというロジックになる。
ミッション層のロジックは文脈に基づいて作成されるため、DCIアーキテクチャによって実装が行われる。DCIアーキテクチャに関する説明は下記の記事参照
https://qiita.com/aLtrh3IpQEnXKN7/items/355ad12f82ac424abea3ミッション層のロジックはクライアントサーバシステム
ミッション層のロジックは、サービスを受けるクライアントとサービスを提供するサーバーに分割する。
サービスを受けるクライアントは外部情報を保持し、外部情報をサーバに提供してサービスを受ける。
サーバーは受け取った外部情報を基に提供するサービスを決定する。アリストテレスの四原因説を使用してミッション層内で発生する力の種類、方向性、役割について把握する
四原因説とはアリストテレスが自著『自然学』の中で論じた、自然学の現象に関する4種類の原因。以下の4つの因子で構成されている。
目的因・・・物事の終り、すなわち物事がそれのためにでもあるそれ(目的)をも原因と言う。
形相因・・・形相または原型。
作用因・・・新たな結果・成果を産出する意味での作用因。力のスタート地点を表す。
質料因・・・存在するものの物質的な原因。銅像においては青銅が、銀盃においては銀が該当四原因説に基づく力の種類、ロジックはドメイン層のメソッドに依存している。
ミッション層では四原因説に該当するドメイン層のメソッドが相互作用し、ロジックを形成する。
四原因説とドメイン層の繋がりを把握することで、ミッション層の全体の流れを把握することができるようになる。
四原因説とドメイン層の繋がりに関しては下記の記事参照
https://qiita.com/aLtrh3IpQEnXKN7/items/0b7abd4ddbc48a8430d6ミッション層を構成する要素
ミッション層を構成するクラス一覧。
Mission・・・目的を表す。ユースケース層のワンシーンを切り取った名称。
Actor・・・役割を演じるためのクラス。Roleを実装だけのクラスなのでメソッドは何も実装されないが、特定のActorのみ演じられるRoleも存在するため、Roleの生成条件を実装する可能性がある。
Role・・・Actorが演じる役割。四原因説の作用因に該当するドメイン層のメソッドが実装される。
Tool・・・Roleが使用する道具。四原因説の質料因と形相因に該当するドメイン層のメソッドが実装される。
- 投稿日:2020-07-30T00:40:48+09:00
LaravelアプリからCloudinaryへの画像投稿
紹介すること
Cloudinary:
画像を保存することができるクラウドサービス
⇒Cloudinary
- Cloudinaryへの登録
- Cloudinary使用のための、Laravelのセットアップ
- Cloudinaryへのアップロードの実装方法
Cloudinaryへ登録
チーム開発では、誰か一人がCloudinaryで実装しデプロイすれば、画像投稿機能が使えますが、
ローカルでも同じようにCloudinaryで動かす場合は、各々がCloudinaryを登録する必要がある。
右上のSIGN UP FOR FREEからCloudinaryにサインアップ
名前、Emailアドレス、パスワード、国、電話番号(オプショナル:企業名又はサイト名、興味)
を記入する。
サインアップが終了すると登録したメールアドレスへ認証メールが届くので、認証を行う。初期設定まで完了!!
Account DetailにあるAPI Key、API Secret、Cloud nameを利用してCloudinaryに登録する。
Laravelのセットアップ
1.Laravelプロジェクトにjrm2k6/cloudderをインストールする。インストールにはcomposerを利用する。
$composer require jrm2k6/cloudder2.config /app.phpの'providers'と'aliases'設定を追加する。
'providers' => [ // ... JD\Cloudder\CloudderServiceProvider::class ], 'aliases' => [ // ... 'Cloudder' => JD\Cloudder\Facades\Cloudder::class, ]3.Cloudinaryの設定ファイルを以下のコマンドから生成する。config/cloudder.phpが生成されるのを確認
php artisan vendor:publish --provider="JD\Cloudder\CloudderServiceProvider"4.Cloudinayの設定を.envファイルに追加する。
設定内容はCloudinaryのAccount Detailから確認する。CLOUDINARY_API_KEY = 'Your API Key' CLOUDINARY_API_SECRET = 'Your API Secret' CLOUDINARY_CLOUD_NAME = 'Your Cloud name'セットアップ終了!
Cloudinaryへのアップロードの実装方法
以下3点を説明しています。
-Migrationファイル作成(カラム追加)
-画像投稿機能/CREATE機能
-画像削除機能/DELETE機能
Migrationファイル作成(カラム追加)
以下は、すでに作成していたAlbumsテーブルのmigrationファイル。
imgカラムはローカルデータベースで画像を保存する際のことを想定していたため、Cloudinary上で管理するためのカラム(public_id)が必要となる。今回は、テストデータを残しておきたかったためrefreshやfreshといったmigrationコマンドを使わず、既存のテーブルにカラムを追加するコマンドを使用。php artisan make:migration add_public_id_to_albums_table作成したmaigrationファイルを以下のように作成する。
記入できたら、以下のコマンドで
php artisan migrateマイグレーションファイル作成(カラム追加)終了!
画像投稿機能/CREATE機能
1.母子手帳アプリ画像投稿フォームのあるページ
albums/create.blade.php
画像投稿する際も、画像投稿のないCreate機能と同様に、POSTメソッドで送り、AlbumController.phpのstoreアクションを動かす。enctype="multipart/form-data"は複合データ型であることを示し、複数の種類のデータ形式を扱う事でできるようになる。(.jpeg /.PNG/.JPGなど )
(albums/create.blade.phpでinput type="file"としているため、必要となってくる。)<form action= "{{route('albums.store')}}" method= "post" enctype="multipart/form-data">2.コントローラの設定(保存処理)
AlbumController.php storeアクション//AlbumController.phpの上部に以下のuse~記述を忘れないようにする! use JD\Cloudder\Facades\Cloudder;3.投稿内容一覧表示画面
albums/index.blade.php
画像が保存される際は、画像そのものではなく、画像のurlが保存されるので下記のように記述する。
<img src="{{$album->img}}" alt="">CREATE機能完成!
画像削除機能/DELETE機能
削除ボタンを押したら、削除する投稿のidを持ってAlbumControllerのdestroyアクションを動かす。
// albums/index.blade.php <from action="{{route('albums.destroy', $album->id)}}" method="post"> {{ csrf_field() }} {{ method_field('DELETE') }} <button class="delete">削除</button> </form>
コントローラの設定(削除処理)
AlbumController.php destroyアクション
削除機能完成!最後に
実装後、画像投稿・削除をCloudinary上のMedia Libraryでも確認ができたら完成です!