- 投稿日:2020-02-22T23:48:42+09:00
Laravelで、フォームの入力内容をコントローラで取得する
流れ
入力フォームを含む"view"
→サーバ(自分自身)にPOST
→サーバがPOSTを受け、値を受け取るview
sample_form.blade.php<html> ... <form action='destination' method='post'> {{ csrf_field() }} <input id="hogehoge" name="sample_text"> <button type="submit">完了</button> </form> ... </html>form内のデータが連想配列としてPOSTされる。
inputのname属性がプロパティ名になる。route
web.php... Route::post('/destination', 'FugaController@testMethod'); ...POSTを受けるとControllerへ
Controller
FugaController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class FugaController extends Controller { public Function testMethod(Request $req) { /* $req = { sample_text: "入力内容" } */ $text = $req::get('sample_text'); // formのname属性で値を参照できる return view('welcome'); } }
- 投稿日:2020-02-22T20:12:39+09:00
Laravel 多対多関係で使っている中間テーブルの created_at, updated_at などのカラムで並べ替える
前提
users
とposts
がfavorites
を中間テーブルとして多対多の関係になっています。TL;DR
public function favorite_posts() { return $this ->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id') ->withPivot(['created_at', 'updated_at', 'id']) ->orderBy('pivot_updated_at', 'desc') ->orderBy('pivot_created_at', 'desc') ->orderBy('pivot_id', 'desc'); }簡単に説明
withPivot()
を使用することで中間テーブルのカラムを参照できます。
withPivot()
の引数にorderby()
に使用したいカラムを配列形式で指定します。
orderBy()
の第1引数には'pivot_' + カラム名の形式で指定します。確認
favorite_posts()の呼び出し元の前後に以下を追記し、実際に流れているSQLを確認します。
DB::enableQueryLog(); $user->favorite_posts; dd(DB::getQueryLog());array:1 [ 0 => array:3 [ "query" => "select `posts`.*, `favorites`.`user_id` as `pivot_user_id`, `favorites`.`post_id` as `pivot_post_id`, `favorites`.`created_at` as `pivot_created_at`, `favorites`.`updated_at` as `pivot_updated_at`, `favorites`.`id` as `pivot_id` from `posts` inner join `favorites` on `posts`.`id` = `favorites`.`post_id` where `favorites`.`user_id` = ? order by `pivot_updated_at` desc, `pivot_created_at` desc, `pivot_id` desc" "bindings" => array:1 [ 0 => 1 ] "time" => 0.37 ] ]中間テーブル
favorites
のupdated_at
、created_at
、id
でorderbyされているのが確認できました参考
https://readouble.com/laravel/5.8/ja/eloquent-relationships.html
https://stackoverflow.com/questions/26551078/how-to-order-by-pivot-table-data-in-laravels-eloquent-orm/50767168
- 投稿日:2020-02-22T17:08:14+09:00
Laravel環境構築
composerインストール
brew install composerPHPインストール
brew install php@7.4 echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
php -v
でなぜか7.1が返ってきたのでバージョン切替brew unlink php && brew link php@7.4 php -i | grep php.ini php -vこれで無事7.4がインストールされた
Laravelインストール
composer global require "laravel/installer" echo export PATH=\"$HOME/.composer/vendor/bin:\$PATH\" >> ~/.bash_profile source ~/.bash_profileプロジェクト作成
laravel new sampleLaravel起動
php artisan serve
- 投稿日:2020-02-22T15:36:20+09:00
Laravel/PHP で(会員登録・ログイン必要なし)画像共有SNSアプリ作りました
Laravel/PHP で(会員登録・ログイン必要なし)画像共有SNSアプリ作りました
はじめに
はじめまして
GAOGAOゲートというプログラミング合宿に参加しています。daijuです。
勉強の一環として、Laravel/PHP/JavaScriptで、非同期の画像共有SNSアプリをデプロイしました。
下記サービスURLです。詳細は後述しますが、下のURLにアクセスするだけで画像投稿できます。1枚だけでもよろしければ投稿お願いします!
https://newtreap.herokuapp.com/top?access_url=1525e4df64119a38Gname=SAMPLE
なぜ作ったのか?
もともと、昔の友達と会ったときに思い出の写真を探し出すのが難しいという不満を持っていました。
例えば、ラインだとチャットメインなのでいらない写真も混ざっていて目的の写真が見つからない!といったことありませんか?そこで、イベント毎や仲の良い人たちでグループを立てて、画像のみ投稿して思い出を残せるアプリが作りたい(ラインの画像版みたいな感じ)と思ったのがきっかけです。
しかし、
・作成していく中で会員登録・ログインめんどくさくね?
・知らない人が開発したwebアプリに個人情報預けるのこわくね?
・結局ラインのアルバム・Googleフォト使えば良くね?
となったわけです。
ということで軌道修正して登録一切必要なしの画像共有SNSアプリを作成しました!
グループ作成時に発行されるURLを共有さえすれば画像を投稿できます。簡単です。5秒です。ソースコードは以下にあります。プルリク受け付けています。未熟な部分多いので是非お願いします。機能はもちろん、デザインも!
https://github.com/daiju81/treap/branches使用技術
- Laravel6
- PHP 7.3.11
- JavaScript/ajax
バックエンド(一部抜粋)
public function add(Request $request) { $image = new Image(); $image->post_id = $post->id; $image_path[] = $image_name[$i]->getRealPath(); $image_file_name[] = $image_name[$i]->getClientOriginalName(); Cloudder::upload($image_path[$i], $image_file_name[$i]); $publicId[$i] = Cloudder::getPublicId(); $logoUrl = Cloudder::show($publicId[$i], [ 'width' => 400, 'height' => 400 ]); $logoUrl = str_replace('http', 'https', $logoUrl); $image->name = $logoUrl; $image->save(); } $group_posts_images[] = Image::where('post_id', $post->id)->get(); return redirect(route('top', [ 'access_url' => $access_url, ])); } }ここが核となる画像共有のプログラムですが、requestで画像情報を受け取りCloudinaryに保存しています。
フロントエンド(一部抜粋)
<div class="card-header"></div> <div class="card-body chat-card"> <div id="comment-data"></div> </div>for (var i = 0; i < data.comments.length; i++) { for(var a = 0; a < data.comments[i].length; a++) { var html = ` <div class="media comment-visible" style="width: 100%;"> <div class="media-body comment-body"> <div class="row"> <span class="comment-body-time" id="created_at">${data.comments[i][a].created_at}</span> </div> <img style="max-width: 90%;" src="${data.comments[i][a].name}" class="comment-body-content" id="comment"> </div> </div> $("#comment-data").prepend(html); } }jsで5秒ごとに情報を受け取り更新しています。jsの知識はまだ疎いので説明が全然できません。すみません。
使い方
グループ作成し、発行されたURLをLINE等のSNSで共有するだけ!
これだけで画像を投稿できます。
まずはサンプルグループを作成したのでそこで画像投稿を試してみてください!以下URLから入れます!
https://newtreap.herokuapp.com/top?access_url=1525e4df64119a38Gname=SAMPLE
これからの展望
これからさらにアプリをブラッシュアップしていきます!
現在ハッシュタグをつけたTwitter投稿がイベント・フェス等の公式サイトや会場ビジョンで流れることがありますがこれに代わるサービスとして運用していきたいです。
プルリク受け付けているので以下から是非!
Branches · daiju81/treap · GitHubまとめ
最初想定していたコンセプトとは少しずれましたが、ログインを削ることで少しでもユーザーが感じる壁は取り除けたかなと思っています。
これで終わりではなくどんどん改善していきます。
URL共有するだけで画像を投稿できるのでぜひ1枚だけでも投稿していただけると嬉しいです。参考サイト(こちらを参考に作成しました。ありがとうございます)
- 投稿日:2020-02-22T15:09:28+09:00
[Laravel]データベースを操作したい時のメモ?
Laravelでデータベースを操作したい時のメモ
データを挿入する
route.phpRoute::get('/insert', function() { DB::insert('insert into posts(title, content) value(?, ?)', ['PHP with Laravel', 'Laravel is the best thing...']); });データを取り出す
route.phpRoute::get('/read', function() { $results = DB::select('select * from posts where id = ?', [1]); return $results; }データの更新
route.phpRoute::get('/update', function() { $update = DB::update('update posts set title = "update title" where id = ?', [1]); return $update; });データの削除
route.phpRoute::get('/delete', function() { $delete = DB::delete('delete from posts where id = ?', [1]); return $delete; }Eloquent ORMデータの操作
データベーステーブルを操作するめに関連するモデルを作成する
php artisan make:model モデル名(Post)
モデル作成時にデータベースマイグレーションも作成する場合には-mオプションをつける
php artisan make:model Post --migration
orphp artisan make:model Post --m
Post.phpclass Post extends Model { protected $table = 'posts'; //テーブル名 //テーブルを指定しない場合はクラス名を複数形の「スネークケース」にしたものがテーブルとして使用される。 protected $primaryKey = 'post_id'; //テーブルのキーをオーバーライド。指定しない場合はidが想定される }Eloquentでデータを取得する
route.phpuse App\Post; Route::get('/read', function() { $posts = Post::all(); //全て取得 $post = Post::find(1)->get(); //id[1]を取得 }特定のデータを更新する
routs.phpRoute::get('basicinsert', function() { $post = Post::find(2); //id(2)を書き換え $post->title = "NEW 2" $post->content = "content 2" $post->save(); });データの作成
routes.phpRoute::get('/create', function() { Post::create([ 'title' => 'create title', 'content' => 'crate content' ]); }); //モデルで$fillabeでカラムを指定しないとエラーになるデータのアップデート
routes.phpRoute::get('/update', function(){ Post::where('id', 2)->where('is_admin', 0) ->update(['title' => 'update title', 'content' => 'update content' ]); });データの削除
route.phpRoute::get('/delete', function() { $post = Post::find(2); $post->delete();データの削除(2)
route.phpRoute::get('/delete', function() { Post::destroy(2); //直接idを指定して削除 Post::destroy([4, 5]); //複数id指定して削除データの削除(ソフトデリート/論理削除)
データ復元可能なゴミ箱に入ってる状態にするソフトデリート。この場合モデルからソフトデリートされてもデータベースのレコードからデータは削除されない。代わりにそのモデルにdeleted_at属性がセットされてデータベースへ書き戻される。
モデルの設定
Post.phpnamespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; //追加 class Post extends Model { use SoftDeletes; protected $dates = ['deleted_at']; //削除された日付をタイムスタンプとして扱う protected $fillable = [ 'title', 'contetn' ]; }カラムを追加したいテーブルを作成する
php artisan make:migration add_deleted_at_column_to_posts_tables --table=posts
作成されたマイグレーションファイルの設定
public function up() { Schema::table('posts', function (Blueprint $table) { $table->softDeletes(); //追加 }; } public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropColumn('deleted_at'); //ロールバックする場合に備えてドロップを設定 }; }テーブルにカラムを追加
php artisan migrate
テーブルに
deleted_at
カラムがnullで設定される
Post::find(1)->delete();
Postテーブルのid:1を削除
データはテーブルに残ったままだが、deleted_at
カラムに削除された日時が入るソフトデリートされたデータの取得
ソフトデリートされた要素はクエリの結果から除外されます。しかし、ソフトデリートされた要素を含めたい場合は、クエリに
withTrashed
メソッドを使用する。$post = Post::withTrashed()->where('id', 1)->get();ソフトデリートされた要素飲みを取得したいとき
$post = Post::onlyTrashed()->where('vote', 0)->get(); // ソフトデリートされたvoteカラムが0の要素を取得ソフトデリートされた要素はゴミ箱に入った状態なので復元することもできる。
その場合は、restore
メソッドを使用する。$post = Post::withTrashed()->where('vote', 0)->restore(); // ソフトデリートされたvoteカラムが0の要素を復元ソフトデリートされた要素を完全に削除する。
この場合はテーブルから要素も完全に削除されます。$post = Post::withTrashed()->where('id', 1)->forceDelete(); // ソフトデリートされたid:1の要素を完全に削除する参考サイト
- 投稿日:2020-02-22T13:36:19+09:00
【Laravel7リリース】Laravel 7 Release Notes 日本語訳
Laravel 7 Release Notes
Laravel Airlock
AirlockはSPAやモバイルアプリなどシンプル、トークンAPIを提供する機能的な認証システムです。Airlockはアプリケーションのユーザアカウントに複数のAPIトークンを生成することも可能にしました。これらのトークンはそれぞれの機能やスコップごとに機能します。
- 詳細はAirlockのドキュメントへ
Custom Eloquent Casts
Laravel自体は豊富なキャストタイプを持っていますが、あたなはよく自らのキャストタイプを定義したいこともあるでしょうか。Laravel 7は
CastsAttributes
インターフェイスを実装するクラスを定義すれば、できるようになりました。このクラスは必ず
get
とset
メソードを持ち、get
はデータベースの生のデータをキャスト値に変換します。一方、set
はキャスト値をデータベースの生のデータに変換します。例えば、json
キャストタイプを作ってみましょう。class Json implements CastsAttributes { /** * Cast the given value. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return array */ public function get($model, $key, $value, $attributes) { return json_decode($value, true); } /** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param array $value * @param array $attributes * @return string */ public function set($model, $key, $value, $attributes) { return json_encode($value); } }カスタマイズキャストタイプを定義したら、モデルに使うことができます。
<?php namespace App; use App\Casts\Json; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'options' => Json::class, ]; }
- 詳細はEloquentのドキュメント
Blade Component Tags & Improvements
簡単に言うと、Bladeコンポネートはそれに対応しているクラスを持ち、それぞれのデータを受け入れることが可能になりました。全ての定義されたパブリックプロパーティーとメソードのコンポネートクラスは自動的にコンポネートビューに利用できます。コンポネート中のHTMLの属性は
$attribute
と言うattributeインスタンスが自動的に追加されます。
例えば、App\View\Components\Alert
はこのように定義され<?php namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component { /** * The alert type. * * @var string */ public $type; /** * Create the component instance. * * @param string $type * @return void */ public function __construct($type) { $this->type = $type; } /** * Get the class for the given alert type. * * @return string */ public function classForType() { return $this->type == 'danger' ? 'alert-danger' : 'alert-warning'; } /** * Get the view / contents that represent the component. * * @return \Illuminate\View\View|string */ public function render() { return view('components.alert'); } }次は、コンポネートのBladeテンプレートを定義し、
<!-- /resources/views/components/alert.blade.php --> <div class="alert {{ $classForType() }}" {{ $attributes }}> {{ $heading }} {{ $slot }} </div>コンポネートタグを使い、下のBladeにレンダリングされます。
<x-alert type="error" class="mb-4"> <x-slot name="heading"> Alert content... </x-slot> Default slot content... </x-alert>この例はただBlade component機能の中の一部だけで、Laravel 7は他の匿名、インラインビューコンポーネントなどたくさんの機能を改造しました。
- 詳細はfull Blade component documentation のドキュメント
HTTP Client
今までLaravelは
Guzzle HTTP client
を使用し、HTTPリクエストなどのサービスを提供しています。Laravel 7はGuzzle
一番よく使われる機能の部分を抜粋し、より使いやすいため、Guzzle
のラッパーのHTTP client
を作りました。例えば、JSONデータのPost
リクエストは以下のようにuse Illuminate\Support\Facades\Http; $response = Http::withHeaders([ 'X-First' => 'foo' 'X-Second' => 'bar' ])->post('http://test.com/users', [ 'name' => 'Taylor', ]); return $response['id'];更に、この
HTTP client
は素晴らしい、人間にわかりやすいテスト機能も搭載Http::fake([ // Stub a JSON response for GitHub endpoints... 'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']), // Stub a string response for Google endpoints... 'google.com/*' => Http::response('Hello World', 200, ['Headers']), // Stub a series of responses for Facebook endpoints... 'facebook.com/*' => Http::sequence() ->push('Hello World', 200) ->push(['foo' => 'bar'], 200) ->pushStatus(404), ]);
- 詳細はHTTP clientのドキュメント
Fluent String Operations
Laravelの
Illuminate\Support\Str
クラスはもう馴染みな存在になっているでしょう。たくさんの文字列の操作に役に立つメソードがありますよね。Laravel 7はこれらのメソードに基づいて、オブジェクト指向、スムーズな文字列操作のライブラリを作成しました。Str::of
メソードを使って、Illuminate\Support\Stringable
インスタンスを使用します。たくさんのメソードはメソードチェンで文字列を操作return (string) Str::of(' Laravel Framework 6.x ') ->trim() ->replace('6.x', '7.x') ->slug();
- 詳細はオブジェクト指向、スムーズな文字列操作のドキュメント
Route Model Binding Improvements
Key Customization
Eloquentモデルのデータは
id
以外のコラムを使いたいことがあるでしょうか。Laravel 7はルートパラメータにコラムを指定することを可能にRoute::get('api/posts/{post:slug}', function (App\Post $post) { return $post; });Automatic Scoping
1つのルートに多数のEloquentモデルをバンドする時に、2つ目パラメータは1つ目のパラメータに属するスコップしたい時はあるでしょう。例えば、ある特定のユーザのブログポストの場合とか
use App\Post; use App\User; Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post; });Laravel 7はこのようにparentモデル側に定義されるコラム名をネストパラメータとして分析します。上の例では、
User
モデルにposts
コラムが定義されると想定し、Post
モデルデータの取得に利用します。
- 詳細はroute model bindingのドキュメント
Multiple Mail Drivers
Laravel 7は1つのアプリに多数の"mailers"ドライバをサポートすることも可能にしました。各mailerドライバは
option
やtransport
を持つことや、特定のメールサービスで特定のメッセージを送信することが可能です。例えば、Postmark
にトランザクションのメールを、他の大部分のメールはAmazon SES
に設定します。デフォルトは
mailer
メソードを使えば特定のメールドライバを指定できます。Mail::mailer('postmark') ->to($request->user()) ->send(new OrderShipped($order));Route Caching Speed Improvements
Laravel 7は新たなメソードを利用し、
route:cache
コマンドでコンパイル済みのルートキャッシュのマーチングを行っています。大規模なアプリ(800ルート以上)にて"Hello World"のベンチマークは、毎秒2倍以上のリクエストスピードに改善されました。自らの対応はいりません。CORS Support
Laravel 7自体はBarry vd. HeuvelさんのCORSパッケージのCross-Origin Resource Sharing (CORS)
OPTIONS
のリクエストとレスポンスをサポートします。新たなcors
設定ファイルはLaravelアプリに存在するようになります。
- 詳細はCORSのドキュメント
Query Time Casts
テーブルから生のデータをセレクトするなど、クエリ実行時にキャストを使いたい時はあるでしょう。例えば、下のクエリ
use App\Post; use App\User; $users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->get();
last_posted_at
の結果は文字列になります。もしクエリ実行時はdate
キャストに変換できれば便利ですね。そのため、Laravel 7にwithCasts
が誕生しました。$users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->withCasts([ 'last_posted_at' => 'date' ])->get();MySQL 8+ Database Queue Improvements
前回のLaravelリリースにて、
database
queueはdeadlocksにより、商用には不十分だと考えられます。Laravel 7はMYSQL8+を使用し、データベースバックエンドqueueを改善します。FOR UPDATE SKIP LOCKED
clauseと他のSQL改善を使い、database
稼働のqueueは大負荷の商用にも対応できます。Artisan
test
Command
phpunit
コマンドの追加として、test
Artisan コマンドでもテスト実行できます。このコマンドにより、美しいコンソルUXや豊富なテスト情報が提供されます。更に、テストは初めての通らなかったテストに止まります。php artisan test
ちょいお試し!
vi tests/Unit/ExampleTest.php確かに
phpunit
よりわかりやすくなってるけど??
大量なテストがあれば、どうなるだろうかな??元々
phpunit
に渡せるパラメータはArtisantest
コマンドにも渡せます。php artisan test --group=featureMarkdown Mail Template Improvements
デフォルトのMarkdownメールテンプレートは、Tailwind CSS カラーパレットをベースにし、更にモダンなデザインにします。もちろん、このテンプレートは自由にカスタマイズするは可能です。
- 詳細は Markdown mailのドキュメント
Stub Customization
Artisan
make
コマンドはcontrollers, jobs, migrations, testsなど様々なクラスを生成することに使われます。これらのクラスは'stub'ファイルを使用し、インプットの値を参照し、作られます。ただし、これらのクラスの構造を少し編集してmake
コマンドを使いたい事があるでしょう。Laravel 7はstub:publish
を使用したら、よく使われるstubをカスタマイズすることも可能です。php artisan stub:publishpublished
stubs
フォルダはLaravelのルーツフォルダに、これらのファイルの全ての編集はmake
コマンドに反映されます。
便利そうな機能いっぱい?
- 投稿日:2020-02-22T10:49:42+09:00
☀Ponanza(ポナンザ)の作成者さんが作ったお天気のアレを真似たひとり用。
Ponanza(ポナンザ)の作成者さんが作ったお天気のアレを真似たひとり使用?ものです。下記のものを作りました。開発者の場合、自分で作りたい衝動にかられると思います。まんまと駆られて作りました…なので考え方をお裾分けです。今までQiitaで公開したソースコードも必要になりますので、リンクを貼っときます。そしてメインのソースコードは下記になります(Twitterのoauthライブラリを呼び出しが必要になります。 )。
※個人の開発者様用なので位置情報は引っ張って来てません、天気の都道府県を変更されるか、Twitterの位置情報を使用し天気のAPIへ投げるなりしてください(本家はIP情報から位置情報を特定しようとしているようです)。乱暴な説明ですが駆け出しのプログラマーじゃない限りできると思います。
天気のソースコードはこちら=> https://qiita.com/taoka_toshiaki/items/6818486d3e1429f050cf
月の満ち欠けのソースコードはこちら=> https://qiita.com/taoka_toshiaki/items/0b9792ebe1ce1854e355本家はこちら
https://note.com/issei_y/n/ne128a0cf27ca
<?php require_once ("vendor/autoload.php"); require_once ("moon.php"); require_once ("tenki.php"); use Abraham\TwitterOAuth\TwitterOAuth; $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET); $user_data=$connection->get("users/show",["screen_name"=>$user_screen_name]); $name = $user_data->name; date_default_timezone_set('Asia/Tokyo'); $icons = moon::$icon + tenki::$icon + array("@"=>"@"); $year = date("Y"); $mon = (int)date("m"); $day = (int)date("d"); $H = (int)date("H"); if($H>=6 and $H<=17){ tenki::main(); tenki::$url = "https://api.openweathermap.org/data/2.5/weather?id=".tenki::$ken->kochi["id"]."&appid=".tenki::$appid; tenki::api(); $chg = tenki::$icon[str_replace("n","d",tenki::$response->weather[0]["icon"])]; }else{ moon::main($year,$mon,$day); $chg = moon::icon(); } foreach($icons as $key=>$val){ if(preg_match("/$val/",$name)){ $hit = $val; } } $name = str_replace("$hit",$chg,$name); $connection->post("account/update_profile", ["name" =>$name]);
- 投稿日:2020-02-22T10:25:37+09:00
URLの引数をバリデーションに使いたい(Laravel)
結論
任意のRequestクラスに以下の関数を追加する。
/** * 更新、削除時に渡されるルート引数を Request Parametersに含める。 * ただし、すでにキーが存在している場合は上書きしない。 * @return array */ public function validationData() { $params = $this->all(); $route_params = $this->route()->parameters(); return $params + $route_params; }なんで作ろうと思ったか?
APIを作っていて、更新処理を書いている時にふと思った。
public function update(ProjectUpdateRequest $request, $id) { $project = Project::find($id); // もしデータが取得できなかったら 失敗のレスポンス if (empty($project)) return response()->json(['result' => 'failed']); $project->fill($request->all()); $project->update(); return response()->json($project); }せっかくバリデーション専用のクラスあるのに、ここでパラメータをチェックするの違和感ある。
どうにかしてRequestクラスでできないだろうか。Requestクラス内でルートパラメータ取得
紆余曲折あったが、パラメータを取得する関数を発見したのでそれを使用。
$this->route()->parameters()/project/{id} だったら ['id' => xxx]の形で取得できる。
Rulesでバリデーションできるようにする
Requestクラスの rules()でチェックされるデータは validationData()で取得しているので、オーバーライドしてルートパラメーターを含めるようにする。
ただし、ルートパラメータと同じ値があったときに上書きするのは望ましくないので、array_mergeは使わずに配列をマージすることにした。$params = $this->all(); $route_params = $this->route()->parameters(); return $params + $route_params;結果
rules()で、ルートパラメータを使ってバリデーションを行えた。
とっても満足した。
効率や生産性、拡張性は見なかったことにする。
- 投稿日:2020-02-22T10:15:23+09:00
Ubuntu 18.04にNginx、PHP 7.4、MySQL 5.7をインストールする
目的
ローカル環境で開発していたLaravelのプロジェクトをVPSに乗せるための準備です。
OSバージョン
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"Nginxのインストール
$ sudo apt update $ sudo apt install nginxインストールが完了して、ブラウザ上からホスト名でアクセスすると以下のページが表示されると思います。
セキュリティ設定
ufwによるファイアウォール設定
Ubuntu 18.04ではファイアウォールパッケージとして
ufw
(Uncomplicated Firewall)がインストールされています。
SSH(22)とHTTP(80)、HTTPS(443)のNginxへの接続を許可します。$ sudo ufw allow 'Nginx HTTP' $ sudo ufw allow 'Nginx HTTPS' $ sudo ufw enable
ufw
コマンドに関しては下記の記事が大変参考になりました。
ufw
コマンドの使い方 https://qiita.com/hana_shin/items/a630871dce209cff04f3fail2banでアクセス制限設定
ufw
と一緒にサーバへの攻撃をモニターして、保護してくれるfail2ban
も導入します。
こちらはインストールして、サービスを起動するだけでOKです。$ sudo apt install fail2ban $ sudo service fail2ban startNginxの設定
nginx.conf
Nginxの設定ファイルである
nginx.conf
を修正します。$ sudo vim /etc/nginx/nginx.conf
user
をwww-dataからsshのログインユーザに変更しますserver_token
のコメントアウトを外します- 必要があれば
client_max_body_size
を追加します
これはnginxがPOSTの最大サイズを設定するための項目です(デフォルトは1MB)fastcgi_params
NginxでPHPを動かすためには
fastcgi_params
も修正します。
fastcgi_params
を開いて、末尾に下記を追加します。$ sudo vim /etc/nginx/fastcgi_params ↓追加します fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; ↑追加します追加したら構文チェックのために下記を実行します
問題なければNginxを再起動します$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo service nginx restartPHP 7.4 のインストール
Ubuntu18.04でPHP 7.4をインストールするには
ondrej/php
レポジトリを追加する必要があります$ sudo apt install software-properties-common $ sudo add-apt-repository ppa:ondrej/php追加できたら一度リポジトリ一覧を更新し、モジュールと一緒にPHP 7.4をインストールします
$ sudo apt update $ sudo apt install php7.4-fpm php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip unzip -yphp 7.4およびモジュールが正しくインストールされているか下記コマンドで確認します
$ php -v $ php-fpm7.4 -v $ php -mwww.confを開いて、userとgroupを`www-data`からsshのログインユーザに変更します
$ sudo vim /etc/php/7.4/fpm/pool.d/www.conf user = username group = username listen.owner = username listen.group = username変更できたらphp-fpmの構文チェック、再起動を行います
$ sudo php-fpm7.4 -t $ sudo service php7.4-fpm restartNginxでPHPを実行する
sites-available/default
sites-available/default
を開いて、下記のように修正します。indexにindex.phpを追加します
index index.php index.html index.htm index.nginx-debian.html;location ~ .php$ {の記述があれば閉じ括弧も含めてコメントアウトを外します
なければ追加してくださいlocation ~ \.php$ { }括弧内に# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;のような記述があれば以下のように書き換えてコメントアウトを外します
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;最後に括弧内に
include fastcgi_params;
を追加します設定例
index index.php index.html index.htm index.nginx-debian.html; ...略... location ~ \.php$ { include snippets/fastcgi-php.conf; # With php-fpm (or other unix sockets): fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # With php-cgi (or other tcp sockets): # fastcgi_pass 127.0.0.1:9000; include fastcgi_params; }/var/www/htmlに
index.php
を作成します。<?php phpinfo();ここまでできたらnginxを再起動させてブラウザ上からホスト名でアクセスします。
$ sudo nginx -t $ sudo service nginx restart親の顔より見た(?)画面が表示されましたね!
MySQL 5.7 のインストール
aptコマンドでインストールします。
$ sudo apt install mysql-server次のコマンドでMySQLのセキュリティ設定を行います。
$ sudo mysql_secure_installation設定方法は下記URLが参考になります。
https://weblabo.oscasierra.net/mysql-57-init-setup/rootパスワードが設定できたらDBとユーザを作成します。
※'DATABASE_NAME'、'YOUR_NAME'、'YOUR_PASSWORD'には任意の値を適宜書き換えてください$ mysql -u root -p mysql> CREATE DATABASE 'DATABASE_NAME'; mysql> CREATE USER 'YOUR_NAME'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD'; mysql> GRANT ALL PRIVILEGES ON DATABASE_NAME.* TO 'your_name'@'localhost';作成できたら 設定したユーザとパスワードでMySQLサーバにアクセスできるか確認しましょう。
mysql> exit; $ mysql -u 'YOUR_NAME' -p最後に、index.phpを以下のように変更し、PHPでMySQL接続確認を行います。
<?php define('DB_HOST', 'localhost'); define('DB_USER', 'YOUR_NAME'); define('DB_PASSWORD', 'YOUR_PASSWORD'); define('DB_NAME', 'DATABASE_NAME'); // エラー表示設定:通知系以外全て表示 error_reporting(E_ALL & ~E_NOTICE); try { $dbh = new PDO('mysql:'.DB_NAME.';'.DB_HOST, DB_USER, DB_PASSWORD); print('接続しました。'); } catch(PDOException $e){ print('ERROR:'.$e->getMessage()); exit; }以下の画面が表示されたら、ミドルウェアのセットアップ完了です。お疲れ様でした
参考ページ:
https://www.cloudbooklet.com/install-php-7-4-on-ubuntu/
https://stackoverflow.com/questions/25591040/nginx-serves-php-files-as-downloads-instead-of-executing-them
https://teratail.com/questions/137445
- 投稿日:2020-02-22T09:25:01+09:00
?月の満ち欠けPHPライブラリを書きました。ちょっと適当なアイコンで表示。
月の満ち欠けPHPライブラリを書きました、ご自由にお使いください。
ちょっと適当なアイコンで表示。
もっと正確なアイコンを取り入れたい方はご自身でご自由に変更ください。
尚、先人の知恵やネット住民達の知恵を借り出来ました、ありがとうございます。<?php //date_default_timezone_set('Asia/Tokyo'); class moon{ static public $icon = array( "0"=>'?',//朔 "1"=>'?',//朔 "2"=>'?',//朔 "3"=>'?',//三日月 "4"=>'?',//三日月 "5"=>'?',//三日月 "6"=>'?',//三日月 "7"=>'?',//上弦の月', "8"=>'?',//上弦の月', "9"=>'?',//上弦の月', "10"=>'?',//上弦の月', "11"=>'?',//上弦の月', "12"=>'?',//十三夜月 "13"=>'?',//十三夜月 "14"=>'?',//十三夜月 "15"=>"?",//望月 "16"=>"?",//望月 "17"=>"?",//望月 "18"=>"?",//望月 "19"=>"?",//寝待月 "20"=>"?",//寝待月 "21"=>"?",//寝待月 "22"=>"?",//寝待月 "23"=>'?',//下弦の月 "24"=>'?',//下弦の月 "25"=>'?',//下弦の月 "26"=>"?",//二十六夜月 "27"=>"?",//二十六夜月 "28"=>"?",//二十六夜月 "29"=>"?"//二十六夜月 ); static public $res = "0"; static public $moon_gregorian = array(0,2,0,2,2,4,5,6,7,8,9,10); public function main($year=2012,$mon=12,$day=12) { static::$res = ((($year-11)%19)*11 + static::$moon_gregorian[$mon-1]+$day)%30; } public function icon(){ return static::$icon[static::$res]; } }呼び出しはこんな感じで。
moon::main($year,$mon,$day); $ret = moon::icon();