20210607のPHPに関する記事は13件です。

Laravel user()とuserの違い 動的プロパティ リレーションメソッド

概要 他のテーブルとリレーションを結ぶuser( )などのリレーションメソッド。 user( )と使う場面と単にuserとして使う場面もある。 なんとなくで使っていたがここらでスッキリさせておくために、今回は この2つの違いについて自分なりにまとめておく。 リレーションメソッド User.php <?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * ユーザーの全ポストの取得 */ public function posts() { return $this->hasMany('App\Post'); } } [表題ではuserで書いたが書きにくかったのでpostで書いてます] これはUserモデルとposts()という1対多のリレーションメソッドですね。 あるユーザーの持つPostを取得したいときは以下のようなコードになるでしょう。 idが1のUserの全Postを取得 $user = App\User::find(1); $posts = $user->posts; さてこの$postsに入っているのはなんでしょうか? posts()で定義しているのに$user->postsと( )がついていません。 この$postsに入っているのはPostモデルのインスタンスのコレクションです。 posts()の中身はこうでした。 return $this->hasMany('App\Post') ですので$this->hasMany('App\Post')を返していることは確実です。 では、この$this->hasMany('App\Post')がコレクションを返しているのか? そうではなくてこれはHasMany オブジェクトというものを返しています。 $user->postsここで動的プロパティというものを呼び出しているんですね。 動的プロパティ プロパティってのは何かの性質、特徴を表すものですから。 それが動的ってことはなんらかの原因によって性質が変わるものってことでしょうか? 調べたところ インスタンスのプロパティには attributes と呼ばれる各レコードのカラムの値の他に、relations というものもあって、その中身には定義したリレーションメソッド名を key、リレーションメソッドの制約に従って取得したリレーション先のモデルインスタンスのコレクションを value とした連想配列が入っているそうです。 ここのrelations 内の値は定義されたリレーションメソッドやリレーション先のテーブル内容によって動的に変わるので、動的プロパティと呼ばれているということですね!なるほど! ()がつくと? 先ほどの動的プロパティを使わずに有効な全 Post を取得するコードを書いてみましょう。 $user = App\User::find(1); $posts = $user->posts()->where('active', 1)->get(); ここではposts()としてからwhereで一致するものを探してからget()で取得しています。 こちらの$user->posts()の時点では、return $this->hasMany('App\Post')の結果の HasMany オブジェクトが返ってきています。 HasMany オブジェクトを考えるために、 HasMany の基底クラスである HasOneOrMany の実装を見てみましょう。 *略 public function create(array $attributes = []) { return tap($this->related->newInstance($attributes), function ($instance) { $this->setForeignAttributesForCreate($instance); $instance->save(); }); } $this->relatedにPostモデルの仮のインスタンスが入っていて、newInstance($attributes)で意味のあるモデルインスタンスを生成しています。 そしてsetForeignAttributesForCreate()で外部キーがセットされてそのままそのモデルをsaveしているんですね。 なので今回の場合は$user->posts() で user_id が埋められた状態になっててそれをwhereで一致したものをget()しているということです。 2つの違い だったら記述の少ない動的プロパティだけで良いじゃんってことになりますが、HasMany オブジェクトなどの Eloquent リレーションオブジェクトはクエリビルダとしても動作するという大きな特徴があります。 クエリビルダは Laravel で SQL の記法を書きやすくするもので、where('active', 1)といった記法をメソッドチェーン的に繋げられます。 コレクションが返ってくる動的プロパティではそのまま繋げられないが、Eloquent リレーションオブジェクトであればそのまま繋げて制約を追加することが可能ということですね。 反対に、動的プロパティは「遅延ロード」されるという性質を持っています。 遅延ロードとは、アクセスされたときにだけリレーションのデータをロードするというもので、このため、あらかじめアクセスしておいて EagerLoadができるのです。 まとめ 1.posts()などの()がつくものはリレーションメソッド postsは動的プロパティである。 2.動的プロパティpostsでUserモデルのコレクションが返ってきている。 **3.リレーションメソッドposts()の時点では結びつけているもの(今回だとuser_id--テーブル書くの省略していますが笑--)が返ってきてそれをクエリビルダでメソッドチェーン的につなげられる!。 ということになるかと思います! しかしこれ頻出すると思うのですが記事がかなり少ない。。。 慣れたら感覚で使いこなせるのかな? 何かありましたらコメントお願いします!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Eloquentって何ってなったからまとめてみた

Eloquentとは Eloquent ORMとはLaravelで実装されているデーターベース操作のための機能。 すべてのEloquentモデルは Illumination\Database\Eloquent\Modelを継承する。 そもそもORMとは ORM・・・Object-relational mapping オブジェクト関係マッピング(英: Object-relational mapping、O/RM、ORM)とは、データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。 オブジェクト関連マッピングとも呼ぶ。 Wikipediaより オブジェクト指向プログラミングとRDBとの考え方の違いを変換してつないでくれるもの。 考え方の違いを「インピーダンス・ミスマッチ」  という 本来RDBからの値はオブジェクト指向プログラミングとは互換性がないがそれを変換して使いやすくしてくれることになる。 とりあえず自分がわかる範囲でまとめました…。 Laravelにおけるデータベース操作 ①Eloquent ORM ②クエリビルダ Eloquentを使用するにはuseするモデル名を宣言する必要がある。 クエリビルダを使用する場合には加えてDBファザードをuse宣言する必要がある。 本題 使用するサンプル Flight.php <?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { // } テーブルの定義 Flight.php <?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { /** * モデルと関連しているテーブル * * @var string */ protected $table = 'my_flights'; } 主キー 主キーはidカラムであると想定している。 これをオーバーライドするにはprotectedのprimaryKeyプロパティを定義する。 タイムスタンプ データベース上にあるcreated_atカラムとupdated_atカラムを自動的に更新する。 自動的に更新してほしくない場合は$timestampsをfalseにする。 タイムスタンプのフォーマットをカスタマイズするなら$dataFormatプロパティを設定する。 タイムスタンプを保存するカラム名をカスタマイズする必要があるなら、モデルにCREATED_ATとUPDATED_AT定数を設定する。 データベース接続 デフォルトでは.envに定義されているデータベースに接続されるが、それと異なる接続をしたいときは$connectionプロパティを使用する。 デフォルト属性値 あるモデルの属性にデフォルト値を指定したい場合は、$attributesプロバティを定義する。 モデルの取得 各Eloquentモデルは対応するデータベースへ接続できたときクエリビルダとして使用できる。 コレクション 複数の結果を取得するallやgetはIlluminate\Database\Eloquent\Collectionインスタンスを返す。 多次元配列で返されるため、アロー演算子ではプロパティの取得ができない。 単レコードの取得 単一レコードで取得した場合はModelオブジェクトで値を返す。 アロー演算子で中身のプロパティの取得ができる。 主キーで指定したモデル取得:find $flight = App\Flight::find(1); クエリ条件にマッチした最初のモデル取得:first $flight = App\Flight::where('active', 1)->first(); クエリ条件にマッチした最初のモデル取得の短縮記法:firstWhere $flight = App\Flight::firstWhere('active', 1); fillableとguardedの違い 両方とも入力値を反映したくないときに使う。 fillble →  指定したカラムのみ値が入力される。 guarded → 指定したカラムには値が入力されない。 おわりに だいぶ駆け足でまとめたのでだいぶ中身が薄っぺらくなってしまいましたが、いままで何となく使っていたものが ここまで奥深いとは思いませんでした。(正直何も疑問に思わずに手を動かしていた) これをきっかけにまた詳しく学んでいきたいと感じました! 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP8.1】PHPで交差型が使えるようになる

交差型は何かって一言で言うと型のANDです。 PHP8.0で型のORことUNION型が導入されましたが、これに続いてPHP8.1で交差型が導入されることになりました。 これでPHPでも型パズルマウント取れるようになりますね。 ということで以下はPure intersection typesの紹介です。 PHP RFC: Pure intersection types Introduction 交差型とは、型がひとつの制約ではなく、複数の制約を同時に満たすことを必要とする型です。 交差型は、現在のところ言語ネイティブには対応していません。 かわりにphpdocアノテーションを使用したり、型付きプロパティを濫用したりしています。 class Test { private ?Traversable $traversable = null; private ?Countable $countable = null; /** @var Traversable&Countable */ private $both = null; public function __construct($countableIterator) { $this->traversable =& $this->both; $this->countable =& $this->both; $this->both = $countableIterator; } } 交差型をPHP本体でサポートすることにより、型情報を関数のシグネチャに記述することが可能となり、多くの利点が生まれます。 ・型が実際に強制されるため、誤りを早期に発見できる。 ・型が古くなったり、エッジケースを見逃したりする可能性が低くなる。 ・型は継承時にチェックされ、リスコフの置換原則が適用される。 ・Reflectionから交差型を使用可能。 ・構文はphpdocよりシンプルになる。 Motivation 複数のインターフェイスを継承した新しいインターフェイスを作成することで、交差型を疑似再現することは可能です。 そのような例として内蔵のSeekableIteratorが存在します。 これはIteratorインターフェイスを継承してseek()メソッドを追加したものです。 ところで新たにCountできるイテレータがほしいと思った場合、新たなインターフェイスを作成する必要があります。 interface CountableIterator extends Iterator, Countable {} たしかにこれは動作します。 さて、それではcountできてシークもできるイテレータがほしくなったときはどうすればよいでしょう。 interface SeekableCountableIterator extends CountableIterator, SeekableIterator {} このように、新しい要求があるたびに、全ての可能な組み合わせを考慮しながら次々と新しいインターフェイスを作成していかなければなりません。 交差型はこれらの問題を解決します。 Proposal 現在型を書くことのできる全ての位置において、T1&T2&...という構文で交差型をサポートします。 class A { private Traversable&Countable $countableIterator; public function setIterator(Traversable&Countable $countableIterator): void { $this->countableIterator = $countableIterator; } public function getIterator(): Traversable&Countable { return $this->countableIterator; } } 交差型とUNION型の混在、A&B|Cのような構文は、このRFCではサポートしません。 Supported types 交差型においてサポートされているのは、クラスタイプの型、すなわちインターフェイスとクラスです。 プリミティブ型の交差型は、たとえばint&stringのように、ほぼ全ての場合において値の無い型になるため対応しません。 またmixed型は、mixed&TはただのT型であり、意味がないので対応されません。 iterable疑似型の交差型は、iterable&TはTraversable&Tと同じであるため、対応する必要がありません。 iterable&T = (array|Traversable)&T = (array&T) | (Traversable&T) = Traversable&T callable型の交差型は意味があることもあります(例:string&callable)が、あまり賢明な使用法とは言えないでしょう。 parent・self・staticの交差型は技術的には可能ですが、親クラスが反するような奇妙な制限を子クラスに課したり、あるいは単に冗長なだけになってしまいます。 従って、これらの型を使った交差型は設計的に問題である可能性が高いため、禁止されます。 Duplicate and redundant types クラスの読み込みを行わずに検出できる冗長な交差型は、コンパイル時にエラーになります。 A&B&Aのような同じクラスの交差型は禁止されます。 ただし、これは型が最小であることを保証はしません。 例として、BクラスがAクラスを継承していた場合のA&BはBですが、これは許可されます。 function foo(): A&A {} // 禁止 use A as B; function foo(): A&B {} // 禁止 パース時にわかる class_alias('X', 'Y'); function foo(): X&Y {} // 許可 実行時までわからない Type grammar パーサーがリファレンス渡しの&と交差型の&を区別できるように、レキサーは&の後に可変変数が続くか否かによって異なるトークンを生成するようになります。 結果として、型の文法は以下のようになります。 type_expr: type | '?' type | union_type | intersection_type ; intersection_type: type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type | intersection_type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type ; Variance 交差型は、既に継承や型チェックで使われている標準的なルールに従います。 ・返り値の型は共変です。 ・引数の型は反変です。 ・プロパティの型は不変です。 交差型とサブタイプの相互作用により、ふたつのルールが追加されます。 ・全てのB_iに対してAがB_iのサブタイプである場合、AはB_1&...&B_nのサブタイプです。 ・BのサブタイプA_iが存在する場合、A_1&...&A_nはBのサブタイプです。 どのような型が許され、何が許されないのか、以下にいくつかの例を挙げます。 Property types プロパティの型は不変です。 すなわち継承前後で同じでなければなりません。 しかし、同じ型を複数の方法で表現することが可能です。 交差型はこの表現の幅を広げます。 たとえばA&BとB&Aは同じ型です。 以下はより複雑な例です。 class A {} class B extends A {} class Test { public A&B $prop; } class Test2 extends Test { public B $prop; } この例では、交差型A&Bは実質的にBであり等しくなるため、この構文は有効です。 Adding and removing intersection types 返り値への交差型の追加、および引数からの交差型の削除は合法です。 class A {} interface X {} class Test { public function param1(A $param) {} public function param2(A&X $param) {} public function return1(): A&X {} public function return2(): A {} } class Test2 extends Test { public function param1(A&X $param) {} // NG public function param2(A $param) {} // 有効 public function return1(): A {} // NG public function return2(): A&X {} // 有効 } Variance of individual intersection members 同様に、返り値の交差型の制限を狭めること、および引数の交差型の制限を広げることも有効です。 class A {} class B extends A {} interface X {} class Test { public function param1(B&X $param) {} public function param2(A&X $param) {} public function return1(): A&X {} public function return2(): B&X {} } class Test2 extends Test { public function param1(A&X $param) {} // 有効 public function param2(B&X $param) {} // NG public function return1(): B&X {} // 有効 public function return2(): A&X {} // NG } もちろん、交差型の追加、削除と制限の拡縮を組み合わせることも可能です。 Variance of intersection type to concrete class type 交差型の主な用途は、複数のインターフェイスを確実に実装することなので、交差型の全てのインターフェイスを継承している具象クラスおよびインターフェイスはサブタイプとみなされます。 interface X {} interface Y {} class TestOne implements X, Y {} interface A { public function foo(): X&Y; } interface B extends A { public function foo(): TestOne; } また具象クラスおよびインターフェイスのUNION型は、UNION型の各メンバーが交差型の全てのインターフェイスを実装している場合にのみ可能です。 class TestTwo implements X, Y {} interface C extends A { public function foo(X&Y $param): TestOne|TestTwo; } Coercive typing mode プリミティブ型は交差型に対応していないため、暗黙の型変換についての考慮は不要です。 Property types and references 交差型プロパティのリファレンスについては、型付きプロパティのRFCのセマンティクスに従います。 interface X {} interface Y {} interface Z {} class A implements X, Y, Z {} class B implements X, Y {} class Test { public X&Y $y; public X&Z $z; } $test = new Test; $r = new A; $test->y =& $r; $test->z =& $r; // Reference set: { $r, $test->y, $test->z } // Types: { A, X&Y, X&Z } $r = new B; // TypeError: Cannot assign B to reference held by property Test::$z of type X&Z Reflection 交差型に対応するリフレクションクラスReflectionIntersectionTypeが追加されます。 class ReflectionIntersectionType extends ReflectionType { /** @return ReflectionType[] */ public function getTypes(); /* Inherited from ReflectionType */ /** @return bool */ public function allowsNull(); /* Inherited from ReflectionType */ /** @return string */ public function __toString(); } getTypes()は、交差型の要素であるReflectionTypeクラスの配列を返します。 元の型宣言と順番が異なる可能性があり、また等価である別の型になる可能性があります。 たとえばX&Yが["Y", "X"]の順番になる可能性もあります。 Reflection APIが保証するのは、論理的に同じものであるということです。 __toString()メソッドは、型宣言を有効なコード表現として返します。 元の型宣言と必ずしも同じではありません。 // 配列の順番は逆転する可能性があります。 function test(): A&B {} $rt = (new ReflectionFunction('test'))->getReturnType(); var_dump(get_class($rt)); // "ReflectionIntersectionType" var_dump($rt->allowsNull()); // false var_dump($rt->getTypes()); // [ReflectionType("A"), ReflectionType("B")] var_dump((string) $rt); // "A&B" function test2(): A&B&C {} $rt = (new ReflectionFunction('test2'))->getReturnType(); var_dump(get_class($rt)); // "ReflectionIntersectionType" var_dump($rt->allowsNull()); // false var_dump($rt->getTypes()); // [ReflectionType("A"), ReflectionType("B"), ReflectionType("C")] var_dump((string) $rt); // "A&B&C" Backward Incompatible Changes このRFCには、後方互換性のない変更はありません。 ただしReflectionTypeを利用しているコードは、交差型に関する処理を追加する必要があります。 Proposed PHP Version PHP8.1。 Future Scope この項目は今後の展望であり、このRFCには含まれていません。 Composite types (i.e. mixing union and intersection types) グループ化しないA&B|Cのような複合型のサポート。 Reflectionなど多くの考慮事項があり、特に継承時のルールやチェックが困難になります。 また、明示的にグループ化すべきだという意見もあります。 Type Aliases 型がどんどん複雑になっていく中で、型宣言の再利用を可能にすることに価値があるかもしれません。 その一般的な方法は2種類が考えられます。 ひとつめはエイリアスです。 use Traversable&Countable as CountableIterator; function foo(CountableIterator $x) {} この場合、CountableIteratorはローカルにのみ現れる型で、コンパイル時に元のTraversable&Countableに解決されます。 もうひとつは型宣言の定義です。 namespace Foo; type CountableIterator = Traversable&Countable; // どこからでも\Foo\CountableIteratorを使える これらをサポートした場合、複合型がサポートされているかのように型を書くことが可能になるため、注意が必要です。 Proposed Voting Choices 投票期間は2021/06/03から2021/06/17で、受理には投票の2/3の賛成が必要です。 2021/06/07時点では賛成15反対2の賛成多数であり、このまま順調にいけば受理されます。 Patches and Tests プルリクエスト: https://github.com/php/php-src/pull/6799 感想 ここまできたのならもう型宣言もくれ。 と言いたいのですが本文にもあるように、一見普通の型宣言に見えて実は非対応ですって文が作れてしまうので、現状そのままでの導入は難しそうです。 type C = A|B; function X(C&D){} type E = string; function X(E&F){} このあたりについてはPHP8.2とかその後あたりできっとどうにかしてくれるでしょう。 ということでPHPはUNION型と交差型を手に入れ、並み居る言語の中でもトップクラスに高度な型操作が可能になります。 PHPには型が無いなんて言ってる連中は時代に取り残されているだけなので、みんなはぱりぱり型を使ったコードを書いていきましょう。 VSCodeなど統合開発環境を使っていれば、C#並みに型を追跡してしてくれたりするのでリーディングもリファクタリングもとっても楽になります。 まあPHPの場合、型宣言を全部取っ払っちゃったりしても動作するのがいいところであり悪いところであるわけですが。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel 作成されているroute情報の一覧を出力する

目的 laravelにて作成されているroute情報の一覧を出力するコマンドを紹介する 方法 アプリ名ディレクトリで下記コマンドを実行して作成されているroute情報を出力する。 $ php artisan route:list
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

プロジェクト演習 webサーバ側 (環境構築)

インストール php pi@raspberry:~ $ sudo apt install php php php-cli php-curl pi@raspberry:~ $ sudo a2enmod userdir pi@raspberry:~ $ sudo systemctl restart apache2 MariaDB pi@raspberry:~ $ sudo apt-get install mariadb-server-10.0 python pi@raspberry:~ $ pip install mysql-connector-python pi@raspberry:~ $ pip install mysqlclient ソースコード pi@raspberry:~ $ cd /var/www/html pi@raspberry:/var/www/html $ git clone https://github.com/kawanishi291/proen pi@raspberry:/var/www/html $ cd ~ pi@raspberry:~ $ git clone https://github.com/kawanishi291/proen2021 初回準備 pi@raspberry:~ $ cd ./proen2021 pi@raspberry:~/proen2021 $ chmod 777 setup.sh pi@raspberry:~/proen2021 $ ./setup.sh 実行 pi@raspberry:~/proen2021 $ ./RS232C_raspberry_pi
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

プロジェクト型演習 webサーバ側 (環境構築)

準備 RaspberryPiのPythonのデフォルトは2系なので、シンボリックを3系に変更 pi@raspberrypi:~ $ python --version Python 2.7.16 pi@raspberrypi:~ $ cd /usr/bin pi@raspberrypi:/usr/bin $ sudo unlink python pi@raspberrypi:/usr/bin $ sudo ln -s python3 python pi@raspberrypi:/usr/bin $ cd ~ pi@raspberrypi:~ $ python --version Python 3.7.3 インストール php pi@raspberry:~ $ sudo apt install php php php-cli php-curl pi@raspberry:~ $ sudo a2enmod userdir pi@raspberry:~ $ sudo systemctl restart apache2 MariaDB pi@raspberry:~ $ sudo apt-get install mariadb-server-10.0 python pi@raspberry:~ $ pip install mysql-connector-python pi@raspberry:~ $ pip install mysqlclient ソースコード 全ソースはGitHubのリポジトリにアップしているのでcloneする pi@raspberry:~ $ cd /var/www/html pi@raspberry:/var/www/html $ git clone https://github.com/kawanishi291/proen pi@raspberry:/var/www/html $ cd ~ pi@raspberry:~ $ git clone https://github.com/kawanishi291/proen2021 初回準備 DBのユーザ登録やテーブル作成、初期データインサートなどを行うシェルスクリプトを実行 pi@raspberry:~ $ cd ./proen2021 pi@raspberry:~/proen2021 $ chmod 777 setup.sh pi@raspberry:~/proen2021 $ ./setup.sh Enter password: raspberry 初期セットアップ実行開始 DBユーザ作成完了 DBテーブル作成完了 テキストファイル作成完了 ファイル権限変更完了 Cコンパイル完了 この画面表示ならおけ。 TOPページの確認 実行 RaspberryPi側 pi@raspberry:~/proen2021 $ ./RS232C_raspberry_pi fb = 3 em board側 rs232c.mtpjをCS+で実行 結果 pi@raspberry:~/proen2021 $ ./RS232C_raspberry_pi fb = 3 s 0 0 2 , 0 0 1 , 0 0 0 , 0 3 9 True 現在の日付時刻のデータが増えていれば成功 参考 Raspberry Pi Python3系に変更する方法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フレームワークなし、PHPでURLルーティングする

フレームワークを使わずに以下のルーティングを使って自作したサイトたち 自作SNS https://test.nieru.net/ ユーザーページサンプル https://test.nieru.net/admin https://test.nieru.net/nieru (利用者募集しております。) 無料レンタル掲示板サイト https://nieru.net/ 掲示板活用サンプル - https://nieru.net/sample - https://nieru.net/vip - https://nieru.net/atbs フレームワークなし、PHPでURLルーティングする フレームワーク使わないルーティングはこれでいいよねって思ったので書いてみる フォルダ構成 ルート ┣ index.php ┣ .htaccess ┗ show   ┗ main.html .htaccess <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] </IfModule> 5行目の RewriteRule ^(.*)$ index.php/$1 [L]が重要 これを記載すればとりあえずどんなURLでも最初のindex.phpにアクセスさせる・・・らしい。 違ったらごめんなさい。 index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); ?> これで現在のURLのディレクトリを配列で取得出来る。 https://example.com/test/hello/bayにアクセスしている場合 $pathの中は Array ( [0] => [1] => test [2] => hello [3] => bay ) となっている。 show/main.html こちらはコンテンツです。 ブラウザに表示する文字を書きます。 ではURLがhttps://example.com/contentsの時、show/main.htmlを表示させてみる。 コードを追加 index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); switch($path[1]) { case "contents": include "show/main.html"; break; } ?> https://example.com/contentsにアクセスすると こちらはコンテンツです。と表示されます。 $path[1]がcontentsなら、つまりURLのディレクトリの1番目がcontentsならshow/main.htmlをincludeします。 なのでhttps://example.com/contents/helloでもshow/main.htmlがincludeされブラウザにこちらはコンテンツです。と表示されます。 https://example.com/contents/helloの場合表示させない index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); switch($path[2]) { default: exit(); } switch($path[1]) { case "contents": include "show/main.html"; break; } ?> 上記の場合はURLのディレクトリが2階層以上の場合exit()により処理が止まります。 if($path[1] === "contents") {}などでいろいろ条件分岐出来ると思います。 おまけ ルートのindex.phpで動かしてるのでshow/main.htmlに書いたPHPのコードも動きます。 フレームワークを使わずに以下のルーティングを使って自作したサイトたち 自作SNS https://test.nieru.net/ ユーザーページサンプル https://test.nieru.net/admin https://test.nieru.net/nieru (利用者募集しております。) 無料レンタル掲示板サイト https://nieru.net/ 掲示板活用サンプル - https://nieru.net/sample - https://nieru.net/vip - https://nieru.net/atbs
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フレームワークなし、.htaccessとPHPでURLルーティングする

フレームワークを使わずに以下のルーティングを使って自作したサイトたち 自作SNS https://test.nieru.net/ ユーザーページサンプル https://test.nieru.net/admin https://test.nieru.net/nieru (利用者募集しております。) 無料レンタル掲示板サイト https://nieru.net/ 掲示板活用サンプル - https://nieru.net/sample - https://nieru.net/vip - https://nieru.net/atbs フレームワークなし、.htaccessとPHPでURLルーティングする フレームワーク使わないルーティングはこれでいいよねって思ったので書いてみる フォルダ構成 ルート ┣ index.php ┣ .htaccess ┗ show   ┗ main.html .htaccess <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] </IfModule> 5行目の RewriteRule ^(.*)$ index.php/$1 [L]が重要 これを記載すればとりあえずどんなURLでも最初のindex.phpにアクセスさせる・・・らしい。 違ったらごめんなさい。 index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); ?> これで現在のURLのディレクトリを配列で取得出来る。 https://example.com/test/hello/bayにアクセスしている場合 $pathの中は Array ( [0] => [1] => test [2] => hello [3] => bay ) となっている。 show/main.html こちらはコンテンツです。 ブラウザに表示する文字を書きます。 ではURLがhttps://example.com/contentsの時、show/main.htmlを表示させてみる。 コードを追加 index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); switch($path[1]) { case "contents": include "show/main.html"; break; } ?> https://example.com/contentsにアクセスすると こちらはコンテンツです。と表示されます。 $path[1]がcontentsなら、つまりURLのディレクトリの1番目がcontentsならshow/main.htmlをincludeします。 なのでhttps://example.com/contents/helloでもshow/main.htmlがincludeされブラウザにこちらはコンテンツです。と表示されます。 https://example.com/contents/helloの場合表示させない index.php <?php $path = explode("/",$_SERVER["PATH_INFO"]); switch($path[2]) { default: exit(); } switch($path[1]) { case "contents": include "show/main.html"; break; } ?> 上記の場合はURLのディレクトリが2階層以上の場合exit()により処理が止まります。 if($path[1] === "contents") {}などでいろいろ条件分岐出来ると思います。 おまけ ルートのindex.phpで動かしてるのでshow/main.htmlに書いたPHPのコードも動きます。 フレームワークを使わずに以下のルーティングを使って自作したサイトたち 自作SNS https://test.nieru.net/ ユーザーページサンプル https://test.nieru.net/admin https://test.nieru.net/nieru (利用者募集しております。) 無料レンタル掲示板サイト https://nieru.net/ 掲示板活用サンプル - https://nieru.net/sample - https://nieru.net/vip - https://nieru.net/atbs
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LINE MessageAPIで作った天気予報アプリをAWSでデプロイしてみた!

以前作成したアプリのデプロイに関する記事です。 無料で使いたいのでherokuへデプロイしましたが、Flex Messageが届きませんでした。 ということでお金がかかりますが、AWSにデプロイすることにします。 アプリ作成までの記事はこちらです。 それではAWSへのデプロイをやっていきましょう! 今回のアプリはDBを使っていませんが、もしかしたら使うこともあると思うので一応RDSも使います。 ハンズオン 1. AWSへログイン 2. 東京リージョンになっていることを確認 3. VPCを作成(IP:10.0.0.0/21) ■ルート コンソールで「VPC」と検索→左ペイン内の「VPC」を選択→「VPCを作成」を選択 4. サブネットを作成(IP:10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24, 10.0.3.0/24) ■ルート コンソールで「VPC」と検索→左ペイン内の「サブネット」を選択→「サブネットを作成」を選択 Public Subnetを作成(IP:10.0.0.0/24, 10.0.1.0/24) Laravelで使うサブネットを作成します。 Private Subnetを作成(IP:10.0.2.0/24, 10.0.3.0/24) RDS(MySQL)で使うサブネットを作成します。 5. Publicサブネットをインターネットに接続するためにInternet Gatewayを作成しアタッチする ■ルート コンソールで「VPC」と検索→左ペイン内の「インターネットゲートウェイ」を選択→「インターネットゲートウェイの作成」を選択 6. EC2がインターネット接続するためにルートテーブルを作成 ■ルート コンソールで「VPC」と検索→左ペイン内の「サブネット」を選択→「Laravel-Pub-1」を選択→「ルートテーブル」を選択→「ルート」へ移動→「ルートを編集」を選択 7. Publicサブネット内にEC2を構築 ■ルート コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスを起動」を選択 ■ステップの流れ ①Amazon Linux 2 AMI (HVM), SSD Volume Typeを選択 ②t2.microを選択 ③インスタンスの詳細の設定の、ネットワーク, サブネット, 自動割り当てパブリックIPを変更 ④ストレージはそのままでOK ⑤キーをNameで追加(値は任意でOK) ⑥セキュリティーグループを変更 EC2は、HTTP通信でリクエスト、レスポンスを行うためHTTPを許可します。 ⑦キーペアの作成 私は事前に作成しているキーペアがあるのでそちらを使います。 このキーペアはdesktopにでも保存しておきましょう。 以前書いたEC2の記事です。 基本的な内容になっているのでEC2ってなんやねんって方は見てもらえると! 8. EC2のIPアドレスを固定するためにElastic IPを導入する IPアドレスを固定する理由としては、インスタンスを再起動しても同じIPアドレスに固定しておきたいためです。 通常、インスタンスを再起動するとIPアドレスが変わってしまいます。 それでは再起動する度にSSH接続の設定を変えないといけないため、IPアドレスを固定します。 ちなみに、Elastic IPは関連づけを行わなければ費用が発生します。 その点はご注意ください。 ■ルート コンソールで「EC2」と検索→左ペイン内の「Elastic IP」を選択→「Elastic IPアドレスの割り当て」を選択 作成できたら次は関連づけを行います。 9. SSH接続でログイン ターミナルを開きましょう。 ターミナル // ①キーペアがあるところへ移動 $ cd desktop // ②キーペア発見 $ ls -l Keypair.pem -rw-r--r--@ 1 ryo staff 1704 5 1 14:38 Keypair.pem // ③権限を400に変更 $ chmod 400 Keypair.pem // ④SSH接続 $ ssh -i Keypair.pem ec2-user@(パブリックIPアドレス) __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| これでEC2にログインできました。 それでは動作するために必要なものをまとめてみましょう。 パッケージのアップデート PHP7.4のインストール PHPの拡張機能のインストール Composerのインストール GitHubからソースコードをクローン vendorのインストール Laravelの初期設定 環境設定ファイルの準備 アプリ固有のキーを発行 ディレクトリの権限変更 nginxのインストール nginxの起動と再起動 ドキュメントルートなどのnginx設定 結構やることは多いですがそんなに難しくないので頑張りましょう! パッケージのアップデート まずはパッケージのアップデートを以下のコマンドで行います。 ターミナル $ sudo yum update -y PHP7.4のインストール php7.4やnginxのインストールには、Amazon Linuxで提供しているamazon-linux-extrasというコマンドを使用します。 amazon-linux-extrasとはあらかじめAWSでインストールされているソフトウェアを起動させることで簡単に利用できるシステムです。 さっそく以下のコマンドを入力してみましょう。 ターミナル // amazon-linux-extras $ amazon-linux-extras 0 ansible2 available \ [ =2.4.2 =2.4.6 =2.8 =stable ] 2 httpd_modules available [ =1.0 =stable ] 3 memcached1.5 available \ [ =1.5.1 =1.5.16 =1.5.17 ] 5 postgresql9.6 available \ [ =9.6.6 =9.6.8 =stable ] 6 postgresql10 available [ =10 =stable ] 9 R3.4 available [ =3.4.3 =stable ] 10 rust1 available \ [ =1.22.1 =1.26.0 =1.26.1 =1.27.2 =1.31.0 =1.38.0 =stable ] 11 vim available [ =8.0 =stable ] 15 php7.2 available \ [ =7.2.0 =7.2.4 =7.2.5 =7.2.8 =7.2.11 =7.2.13 =7.2.14 =7.2.16 =7.2.17 =7.2.19 =7.2.21 =7.2.22 =7.2.23 =7.2.24 =7.2.26 =stable ] 17 lamp-mariadb10.2-php7.2 available \ [ =10.2.10_7.2.0 =10.2.10_7.2.4 =10.2.10_7.2.5 =10.2.10_7.2.8 =10.2.10_7.2.11 =10.2.10_7.2.13 =10.2.10_7.2.14 =10.2.10_7.2.16 =10.2.10_7.2.17 =10.2.10_7.2.19 =10.2.10_7.2.22 =10.2.10_7.2.23 =10.2.10_7.2.24 =stable ] 18 libreoffice available \ [ =5.0.6.2_15 =5.3.6.1 =stable ] 19 gimp available [ =2.8.22 ] 20 docker=latest enabled \ [ =17.12.1 =18.03.1 =18.06.1 =18.09.9 =stable ] 21 mate-desktop1.x available \ [ =1.19.0 =1.20.0 =stable ] 22 GraphicsMagick1.3 available \ [ =1.3.29 =1.3.32 =1.3.34 =stable ] 23 tomcat8.5 available \ [ =8.5.31 =8.5.32 =8.5.38 =8.5.40 =8.5.42 =8.5.50 =stable ] 24 epel available [ =7.11 =stable ] 25 testing available [ =1.0 =stable ] 26 ecs available [ =stable ] 27 corretto8 available \ [ =1.8.0_192 =1.8.0_202 =1.8.0_212 =1.8.0_222 =1.8.0_232 =1.8.0_242 =stable ] 28 firecracker available [ =0.11 =stable ] 29 golang1.11 available \ [ =1.11.3 =1.11.11 =1.11.13 =stable ] 30 squid4 available [ =4 =stable ] 31 php7.3 available \ [ =7.3.2 =7.3.3 =7.3.4 =7.3.6 =7.3.8 =7.3.9 =7.3.10 =7.3.11 =7.3.13 =stable ] 32 lustre2.10 available \ [ =2.10.5 =2.10.8 =stable ] 33 java-openjdk11 available [ =11 =stable ] 34 lynis available [ =stable ] 35 kernel-ng available [ =stable ] 36 BCC available [ =0.x =stable ] 37 mono available [ =5.x =stable ] 38 nginx1 available [ =stable ] 39 ruby2.6 available [ =2.6 =stable ] 40 mock available [ =stable ] 41 postgresql11 available [ =11 =stable ] 42 php7.4 available [ =stable ] 43 livepatch available [ =stable ] 44 python3.8 available [ =stable ] 45 haproxy2 available [ =stable ] 46 collectd available [ =stable ] 47 aws-nitro-enclaves-cli available [ =stable ] 48 R4 available [ =stable ] 49 kernel-5.4 available [ =stable ] 50 selinux-ng available [ =stable ] 51 php8.0 available [ =stable ] 52 tomcat9 available [ =stable ] 53 unbound1.13 available [ =stable ] 54 mariadb10.5 available [ =stable ] 55 kernel-5.10 available [ =stable ] 56 redis6 available [ =stable ] 現時点では合計56個のパッケージとそのバージョンが表示されています。 では、amazon-linux-extrasを利用したPHPのインストールをしましょう。 ターミナル // PHP7.4のインストール $ sudo amazon-linux-extras install -y php7.4 // バージョンを確認(OKです) $ php -v PHP 7.4.19 (cli) (built: May 13 2021 22:36:40) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies PHPの拡張機能のインストール Laravelのインストール時やプロジェクト作成時にこれらの拡張機能がないとうまくいきません。 ターミナル $ sudo yum install -y php-mbstring php-dom php-zip composerのインストール PHPのパッケージマネージャーであるcomposerをインストールしていきましょう。 curlコマンドはインターネット上のファイルを取得するコマンドで、ダウンロードしたcomposerのインストーラーをphpで実行するコマンドになります。 どこでもcomposerコマンドを使えるようにパスを通しましょう。 mvコマンドを使って、/usr/bin/に移動させることにより、どのディレクトリからでもcomposerコマンドを使えるようになります。 ターミナル // Composerのインストール $ curl -sS https://getcomposer.org/installer | php // Composerがどこでも使えるようにパスを通す $ sudo mv composer.phar /usr/bin/composer // バージョンを確認(OKです) $ composer -v ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 2.1.1 2021-06-04 08:46:46 GitHubからソースコードをクローン ターミナル // GitHubからソースコードをクローンをする準備 // ディレクトリを作成して移動する $ sudo mkdir /var/www $ cd /var/www // アクセス権限を変更 $ sudo chmod 777 . // gitをインストール $ sudo yum install -y git // GitHubからソースコードをクローン $ git clone https://github.com/ssk9597/LINE-Weather.git // アクセス権限を変更して誰でも書き込みできないようにする sudo chmod 0755 . vendorのインストール GitHubからクローンしてもvendorディレクトリは付属してきません。 その理由としてはそもそもvendorはフレームワークの根幹機能がまとまったディレクトリになります。 そのため、バージョンが同じであれば同じ内容になります。 しかも容量が大きいためGitHubにアップロードするのは非効率です。 JavaScriptなどでいうと、node_modulesと一緒です。 vendorはLaravelを利用する環境で、composerを使って個別にダウンロードする必要があります。 ターミナル // ディレクトリに移動する $ cd LINE-Weather $ cd src // vendorのインストール $ composer install Laravelの初期設定 ターミナル // 環境設定ファイルの準備 $ cp .env.example .env // アプリ固有のキーを発行 $ php artisan key:generate // ディレクトリの権限変更 $ chmod 0777 -R storage $ chmod 0777 -R bootstrap nginxのインストール nginxはapacheと似た機能を提供するWebサーバーです。 主な違いとしては駆動方式です。 apacheはユーザーからのアクセスの度にプロセスを立ち上げる駆動方式に対して、nginxはプロセスは増えずループによってユーザーからのアクセスを捌く方式です。 そのため、nginxの方がメモリ効率良く、近年においてはnginxのシェアが高まってきています。 ターミナル // nginxをインストール $ sudo amazon-linux-extras install -y nginx1 // バージョンを確認(OKです) $ nginx -v nginx version: nginx/1.20.0 // nginxが再起動後も自動的に動くようにする $ sudo systemctl enable nginx // nginxをスタート状態に sudo service nginx start nginxを起動したら、EC2のIPアドレスにブラウザからアクセスしてみましょう。 以下のようなnginxの初期画面が表示されていれば、正常に動作しています。 ドキュメントルートなどのnginx設定 ターミナル $ sudo vi /etc/nginx/nginx.conf etc/nginx/nginx.conf server { listen 80; listen [::]:80; server_name _; # ==========ここを編集する========== root /var/www/LINE-Weather/src/public; # ==========ここを編集する========== # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; # ==========ここを編集する========== location / { try_files $uri $uri/ /index.php?$query_string; } # ==========ここを編集する========== error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } ここまで編集できましたら、nginxを再起動します。 ターミナル $ sudo service nginx restart 10. AMIの作成 今回は冗長化されたウェブサービスを作るので上記と同じ内容のEC2インスタンスを作る必要があります。 しかし、またゼロからポチポチするのもめんどくさいので、上記で作ったEC2インスタンスからコピーしましょう。 その仕組みをAMIと言います。 作成した001-LINE-Weatherを停止してAMIを作成します。 ■ルート コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスの状態」から停止を選択 コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「アクション」から「イメージを作成」を選択 11. 作成したAMIを使ってインスタンスを作成 12. EC2のIPアドレスを固定するためにElastic IPを導入する 新しく作成したEC2インスタンスの002-LINE-WeatherにElastic IPを導入しましょう。 上記でやったことを繰り返すだけなので省略します。 13. PrivateサブネットにRDSを構築 AWSのサービスであるRDSを利用してMySQLを立ち上げLaravelと連携できるようにします。 以前書いたRDSの記事です。 サブネットグループの作成 RDSには、エンドポイント通信という機能があります。 もし通信障害などが発生して、親のRDSが使えなくなった時子のRDSに接続してくれる機能です。 つまり、このことから異なるAZにサブネットがないとRDSは使えません。 ということで複数のサブネットにまたがる形でRDSは構築されるので、 サブネットグループというものが必要になります。 ■ルート コンソールで「RDS」と検索→左ペイン内の「サブネットグループ」を選択→「DB サブネットグループを作成」を選択 DBの作成 ■ルート コンソールで「RDS」と検索→左ペイン内の「データベース」を選択→「データベースの作成」を選択 追記する部分のみスクショしました。 セキュリティグループを修正 ■ルート コンソールで「VPC」と検索→左ペイン内の「セキュリティグループ」を選択→「RDS-SG-1」を選択 DBは重要な情報が入っているため誰でも彼でもアクセスできると困ります。 なので、PublicサブネットのEC2(セキュリティグループ→EC2-LINE-Weather-SG)からしか触れないように修正します。 LaravelのDB接続設定 EC2(Laravel)からRDSに接続するための設定を行っていきます。 EC2は2台あるので、両方ともに同じ設定をする必要があります。 2台ともSSH接続を行ってください。 ターミナル // SSH接続 $ ssh -i Keypair.pem ec2-user@(パブリックIP) // .envファイルを編集 $ vi /var/www/LINE-Weather/src/.env /var/www/LINE-Weather/src/.env DB_CONNECTION=mysql DB_HOST=line-weather.cjsmw2zqsiga.ap-northeast-1.rds.amazonaws.com DB_PORT=3306 DB_DATABASE=line_weather DB_USERNAME=admin DB_PASSWORD=password // LINE LINE_CHANNEL_SECRET=??? LINE_CHANNEL_ACCESS_TOKEN=??? // OpenWeatherAPI WEATHER_API=??? ターミナル // 移動 $ cd /var/www/LINE-Weather/src // migrate $ php artisan migrate 14. ロードバランサーを導入 ロードバランサーは、負荷のバランスを取る装置です。 例えばWebサーバーに負荷がかかりやすいアプリケーションの場合、複数のサーバーに負荷を振り分けます。 これを冗長化と言います。 今回も2台のEC2を使っており冗長化しております。 ロードバランサーの主な機能としては3つです。 ①ELBにはDNSのアクセスポイントが付与されます。 つまり、アクセスポイントを1つにして負荷を分散させることができます。 ②ヘルスチェック機能がある 異常なインスタンスを発見したら通信をキャンセルしてくれます。 ③ELBに証明書を付与することでSSL通信の終端になってくれる HTTPS通信を復号する処理を担当してくれます。 つまり、internet gatewayの段階ではHTTPSだが、サブネット内ではHTTP通信となります。 以前書いたELBの記事です。 ELBに関して詳しく知りたい方はどうぞ。 ■ルート コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「ロードバランサーの作成」を選択 15. EC2のセキュリティグループのアクセス許可をロードバランサーからに変更する ■ルート コンソールで「EC2」と検索→左ペイン内の「セキュリティグループ」を選択→「EC2-LINE-Weather-SG」を選択 16. Freenomでドメインを購入する Freenomは1年間ドメインを無料で使えます。 なのでこちらでドメインを購入しましょう! どうやればいいかわからない方は以下の記事がわかりやすいので以下の記事を参考にしてみてください。 今回私は、line-weather-fashion.tkというドメインを取得しました。 17. Route53と独自ドメインの紐付け ■ルート コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「ホストゾーンの作成」を選択 作成が正常に完了すると、NSレコードと呼ばれる値が割り振られます。 この値をFreenomの方に書き写していきます。 以前書いたS3とRoute 53の記事です。 S3とRoute 53に関して詳しく知りたい方はどうぞ。 18. ドメインとロードバランサーを紐付ける ■ルート コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「line-weather-fashion.tk」を選択→「レコードを作成」を選択 これでロードバランサーとline-weather-fashion.tkは結びつきました。 成功ですね! 19. ロードバランサーでリスナーを追加する AWS Certificate Manager(ACM) で証明書を取得します。 現状http通信でしかアプリケーションを利用できない状態です。 近年は常時SSL化(常に暗号化したデータをユーザーとサーバーでやりとり)が推奨されていて、 Google Chromeではhttp通信のままだと保護されていない通信と出てしまいます。 ■ルート コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LINE-Weathe-LB」を選択→「リスナーの追加」を選択 「新しいACM証明書をリクエスト」で発行を行います。 Route 53でレコードの作成を行います。 ありましたね! 証明書の検証に時間がかかるので成功になるまで待ちましょう。 成功に変わったら、次はリスナーの追加に戻ってSSL証明書を取得しましょう。 20. セキュリティグループの修正でHTTPSへのリダイレクト設定 ■ルート コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LB-LINE-Weather-SG」を選択→「セキュリティグループ」を選択 最後にロードバランサーのリスナーをHTTPSのみにしましょう。 終わりに HTTPSでアクセスできました。 だが...動かぬ Flex MessageってどれくらいCPUとメモリ食うんでしょうね。。 t2.microからバランスの取れたCPUとバランスの取れたメモリ数のM系に変えて検証してみます。 このアプリに、M系はお財布痛すぎるので、最終的にはFlex Messageをやめて無料で運用できるHerokuにしようと思います。 こんな未完成なハンズオン記事はねーだろと思いますが、「一応デプロイはできたぞ」という記事でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelしくじり先生その1『(型宣言を)「ガチガチにやらなきゃモチモチにならない」と言ったな。あれはやり過ぎ注意だ。』

久々にQiita投稿します。 前提 Laravel Valetで開発環境を構築しています(Docker不使用) Laravel 8.41.0 PHP 8.0.5 Nginx 1.19.10 macOS Big Sur 11.4 リクエストしたらテキストをレスポンスボディとして返すAPIを作っています 「どうして」となったコード HogeController.php <?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class HogeController extends Controller { public function fuga(Request $request): string { return response('OK')->header('Content-Type', 'text/plain'); } } と書いたらレスポンスが下記のようになりました。 bash % curl https://example.test/api/hoge/fuga HTTP/1.1 200 OK OK どうしてHTTPヘッダーもレスポンスに混じっているんですかねぇ? これが正解 HogeController.php <?php namespace App\Http\Controllers\Api; use Illuminate\Http\Response; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class HogeController extends Controller { public function fuga(Request $request): Response { return response('OK')->header('Content-Type', 'text/plain'); } } Illuminate\Http\Response を戻り値の型宣言にしたら bash % curl https://example.test/api/hoge/fuga OK 期待通りstringだけのレスポンスが返ってきました? 結局 「stringを返すからstringで型宣言だな!」という短絡的な思い込みは良くないですね。 最後に マサカリ大歓迎です。 よろしければ、LGTMボタンを押して行ってくださいね? 見出しの出典
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Php】Sessionの学習ノート(1)

初めに Sessionについて学習した内容のoutput用記事です。 ※内容に間違いなどがある場合はご指摘をよろしくお願いします。 ※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。 Sessionとは クライアントとサーバー間の通信において、クライアントがサーバーに接続してサーバーから離れるまでのことを指す。 session_start() phpにおいてsessionを管理するため、新たにsessionをスタートする、または既存のsessionを続けるメソッド。sessionを開始すると管理するためのIDが発行される。それと同時にスーパグローバル変数$_SESSIONが生成され全てのsessionデータが連想配列という形で保存される。 <?php session_start(); ?> $_SESSION session_start()メソッドで生成されるスーパーグロバル変数。sessionの情報が連想配列という形で保存される。 $_SESSION['bgcolor'] = 'yellow'; $_SESSION['animal'] = 'dog'; $_SESSION['time'] = time(); echo $_SESSION['bgcolor']; echo '<br>'; echo $_SESSION['animal']; echo '<br>'; echo $_SESSION['time']; $_SESSIONに保存されているデータは以下の通り。 isset() 変数がセットされているか否かをチェックする関数。セットされているとtrue、されていないかnullである場合はfalseを返す。 var_dump(isset($_SESSION['bgcolor'])); //bool(true) unset() 指定した変数のセットを解除する関数。 unset($_SESSION['bgcolor']); echo $_SESSION['bgcolor']; bgcolorがunsetされ、定義されていないと表示される。 参考サイト https://www.php.net/manual/ja/session.examples.basic.php https://www.php.net/manual/ja/reserved.variables.session.php https://www.php.net/manual/ja/function.isset.php https://www.php.net/manual/ja/function.unset.php https://e-words.jp/w/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3.html https://www.ntt.com/bizon/glossary/j-s/session.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

演習型ITリテラシー学習アプリを作りました。

こんにちは。 私は今までに複数のアプリを作ってきたのですが、使って貰ったのは家族や知人の狭い範囲でした。 今回は、思い切って公開するので、ぜひご一読お願いできればと思います! なにを作ったのか 一言で言うならば、タイトルにもあるように、演習型ITリテラシー学習アプリです。 アプリの構想はProgateを元にしていて、実際にアプリを操作して、事例に触れながらITリテラシーを「楽しく」学んで貰えることを目指しています。 リリースしたばかりなので、レッスンはまだ「フィッシング詐欺」だけなのですが、これからアップデートできればと思います。 なぜ作ったのか 昨今でもないですが、日本はITリテラシーが低いとよく耳にします。 佐川急便やAmazonなどを装ったメールが届くことはいろいろなところで目に、耳にしますが、本物かどうかわからないという人もちらほら見ます。 そういった人に向けて、是非役に立てればいいなと思って開発しました。 私自身もさほど高い方ではない気がしているので、自分の勉強も兼ねています。 アプリの中身 ・アプリランディングページ ・レッスンスライド ・レッスン ・現在動作が不安定で、読み込みに時間が掛かる場合があります。恐縮ですが、気長にお待ちいただけると幸いです。。。 使い方 Lesson1である「フィッシング詐欺」は、会員登録をしなくても受講していただけます。 「まずはここから始めてみましょう」にある、フィッシング詐欺をクリックすると、Lesson1が始まります。 その後は案内に沿って進めていただければ大丈夫です。 会員登録は、通常の登録とGoogleでのログインができます。 退会処理もできますので、不要と思えばページの下部から「退会手続き」を選択し、処理を進めてください。 開発に当たっての詳細 使用技術 ・PHP, Laravel ・Vue.js ・Docker ・AWS 大変だった部分 大変だったのは、認証機能の理解です。 当アプリは、ログインにメール認証を行っています。 Email Verificationを使いましたが、元から用意されてある分見えない部分があって理解に時間がかかりました。 現在のアプリの状態は、ログインしていようがしていまいが、使える機能に違いがないので、メール認証を完了していなくともログインはできる状態です。 今後は、基本的にこの仕組みは変えずに、より詳細な機能を利用する際は、verifiedのミドルウェアを通すようにして、認証して貰ってから機能を使う仕組みにして行こうと思います。 記事をご覧いただいた方へお願い 是非アプリを使っていただいて、感想や修正依頼、アイデアやその他様々なご意見のフィードバックをいただけたら非常に嬉しいです。 その際は、この記事に直接、もしくは以下に送っていただければと思います。 GitHub アプリ公式TwitterのDM よろしくお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PhpStormに入れておくと作業が爆速になるプラグイン一覧

はじめに Jetbrains社のIDEを好んで使っています。その中でも最近愛用しているのがPhpStormです。 PhpStormは機能が豊富ですが、プラグインを入れると機能を大幅に拡張することができます。 この記事が新しいプラグインの発見のきっかけになれば幸いです。 対象者 PhpStormを使っている人 プラグイン開発者がPhpStormだけでなくVSCodeなど、他のIDEでもプラグインを公開している場合があります。 プラグイン名でVSCodeのプラグイン検索をかけてみると存在の有無が見つけやすいです。 動作確認環境 PhpStorm 2021.1 下位のバージョンでも動作するプラグインが見つかる場合がありますがPhpStormはライセンスさえあれば無料で最新版にできるので、常に最新にしておくことをオススメします。 プラグインの導入方法 PhpStormを起動します メニューのファイル→設定を開きます プラグイン項目を選択し、検索枠に探したいプラグインの名前を入力します 表示されたプラグインをインストールし、ウィンドウ右下のOKをクリックしIDEを再起動します オススメしたいプラグイン一覧(2021年度版) 日本語化 Japanese Language Pack / 日本語言語パック PhpStormはインストールした時は海外製のツールという特徴上、すべて英語表記になっています。 このプラグインを導入するとIDEを日本語化することができます。 以前までは外部のライブラリを導入することで日本語化ができていましたが、現在は公式としてプラグインが提供されるようになりましたので、こちらを利用することをオススメします。 Laravel関連 Laravel 機能 configやViewなど、Laravel独自の機能に関するコードジャンプや補完機能が追加されます。 使い方 インストール後、ファイル->設定->PHP項目のLaravel欄にある項目にチェックを入れることでプラグインが有効化されます。 なお、このプラグインをより活用するためには以下のライブラリをプロジェクトに追加する必要があります。 Laravel Idea(有料) 1つ目で紹介したプラグインのさらに上位版のようなプラグインです。 有料というだけあってLaravelにまつわるあらゆる補完がIDEで効くようになります。 Laravel Query LaravelのQueryBuilderの補完が効くようになります。 Laravel Make Integration Laravelでは、php artisan make xxx というコマンドでひな型を作ることができますが、そのひな型作成をファイル作成メニューに追加することができます。 .​env files support envファイルの入力を補完してくれるようになります。 Collector LaravelのCollectionに関する補完をサポートしてくれるようになります。 Symfony Support LaravelはSymfonyがベースとなっているため、このプラグインを入れておくことで補完することができるようになります。 コードの整形、指定変換 CamelCase 機能 変数名やメソッド名などをケバブケース、スネークケース、パスカルケース、キャメルケース、スネークケース、スペースケースを簡単に切り替えることができるようになります。 メニューの編集内にToggleCamelCaseという項目が追加されているので、それを選択することで変換できるようになります。 毎回メニューを開いていては時間がかかるので、ショートカットを覚えて使うのが便利です。 設定変更 String Manipulation 文字列をソートしたり、整形させたり、変換する機能を追加することができます。 プラグインを導入すると、文字列を右クリックした際に表示されるメニューに「String Manipulation」という項目が追加されるようになります。 予測変換 deep-assoc-completion 連想配列のキーを予測変換してくれる機能を追加することができます。 deep-js-completion deep-assoc-completionのjs版です。 Tabnine AI Autocomplete AIがコーディングを学習し、予測変換をしてくれる機能を追加することができます。 私自身はまだあまり使いこなせていませんが、いまもっとも熱いプラグインとして注目しています。 Custom Postfix Templates 独自の後置テンプレートを定義することができるようになります。 また、コミュニティで共有されている何百もの有用な後置テンプレートが付属しているためプラグインを入れるだけで補完機能を向上させることができます。 PHP Advanced AutoComplete 組み込みのPHP関数およびメソッドの自動補完をサポートしてくれるようになります。 PHP Annotations PhpDocの補完をサポートしてくれるようになります。 PHPUnit Enhancement PhpUnitに補完機能を追加することができるようになります。 コードの品質向上(インスペクション系) SonarLint インスペクションを追加することができます。 品質の低いコードがあった場合、指摘してくれるようになります。 このプラグインを導入するとIDE下部にSonerLintという項目が追加され、レビューを通すことができるようになります。 Php Inspections ​(EA Extended)​​ インスペクションを追加することができます。 品質の低いコードがあった場合、指摘してくれるようになります。 Php Inspections ​(EA Ultimate) ※有料 EA Extendedの上位版です。無料版に比べてさらに多くのチェックをしてくれるようになります。 操作性向上 CodeGlance IDEにミニマップを表示することができるようになります。 Rainbow Brackets カッコの対応関係を色付きで分かりやすくしてくれるようになります。 HighlightBracketPair カーソルがある箇所を囲んでいるカッコをハイライト表示してくれるようになります。 Key Promoter X 手動で行った操作について、ショートカットがあることを提示してくれます。 ショートカットを覚えるきっかけを与えてくれます。 外部サイトや別ツールで行っていたものをIDE内で完結できるようにする Json Parser IDEにJsonのパース機能を追加することができます。 Translation IDEで翻訳ができるようになります。 海外のコードのコメントを読む時などに大変重宝します。 Codic Support 日本語を打ち込むとプログラムの変数名やメソッド名に適する英語を提案してくれるようになります。 RegexpTester IDEに正規表現のチェック機能を追加することができます。 その他機能追加 PlantUML integration IDEでUMLを表示する機能を追加することができます。 IDEでER図を編集する際にとしても重宝します。 Redis(有料) GUIとしてRedisの中の値を確認することができるようになります。 BashSupport Pro(有料) Bashおよびシェルスクリプト編集の時に補完機能を追加することができます。 Save Actions コードの保存時に「インポートの最適化」「コードの再フォーマット」「コードの再配置」などの操作を自動で行われるようにすることができます。 なお、詳細な設定はファイル->設定->その他の設定->Save Actionsから行うことができます。 GitToolBox 該当コードの編集者やコミットメッセージなどをIDE上に表示することができるようになります。 Live Edit ライブコーディングができるようになります。 PhpStormが重いときの対処法 [ファイル]→[キャッシュの破棄]を行うことで軽くすることができます。 それでも依然として改善されない場合は、PhpStormに割り当てるメモリを増設することで改善される場合があります。 ライセンスについて JetBrainsのライセンスは個人ライセンスであっても仕事との両立が可能です 業務だとライセンスがなくて使えないといった問題もないので(社内ライセンスがある場合も多い)、個人としてもライセンス持っておいた方が何かと便利です。 ライセンス料金は継続して課金すると年々お安くなります。 学生ライセンス 学生さんであれば無料で使うことも可能です。 日本語ドキュメント 公式サイト 日本国内代理店 公式サイトで購入ができますが、何らかの理由により日本国内の代理店でないと購入が難しい場合はこちらがオススメです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む