- 投稿日:2019-07-09T23:34:43+09:00
[PHP]ヘッダーの上に隙間が空く問題
はじめに
PHPファイルでヘッダーをつくっていて、上に隙間が空いたので解消方法を探った。
わかったこと
❶ キャッシュが溜まっている可能性
❷ phpのinclude(['hoge']);関数が影響を及ぼしてる可能性
❸ 単純にcssでtop: 0;をあててみるメモ
環境
- PHPファイルにHTMLとCSSを使用している。
解消方法の検証
❶ キャッシュが溜まっている可能性
キャッシュを一週間分消したが効果なし
❷ phpの
include(['hoge']);関数が影響を及ぼしてる可能性文字種類を
UTF-8からUTF-8Nに変更することで解消できるとのことだったが効果なし❸ 単純にcssで
top: 0;をあててみる隙間が解消されて解決に至った。
気づき
- 単純にcssで消すことができた。
include(['hoge'])が影響を及ぼしていたのは間違いないようだった。参考サイト
https://okwave.jp/qa/q8630179.html
http://kagan.hatenablog.com/entry/2014/08/09/190812
- 投稿日:2019-07-09T22:25:54+09:00
【PHP7.4】PHP7.4では変数に型指定できる & 菱形継承っぽいものができる
PHPのすごい開発者Nikita Popovが書いたTyped Properties and more: What's coming in PHP 7.4?というスライドを見ていたらなにやら面白かったので、適当に紹介してみる。
変数の型指定
PHP7.4ではプロパティに型指定できるようになりましたが、実はプロパティではない只の変数にも型指定することができます。
class Dummy{ public int $id = 42; } $dummy = new Dummy(); $id = & $dummy->id; $id = 10; // OK $id = 'not an id'; // Uncaught TypeErrorええ…
なんかもう普通に
int $id = 42とか書けるようにしたほうがいい気もしないでもないですが、構文解析とかの都合で難しいのでしょう。なんにせよ、これで変数の型指定もできるようになってしまいました。
このまま書くと非常にもったり感がありますが、きっと簡単に使えるライブラリが出てくることでしょう。菱形継承
似たような方法でプロパティの菱形継承っぽいこと(交差型)も可能です。
class A{} class B extends A{ public ?Traversable $a; } class C extends A{ public ?Countable $a; } $b = new B(); $c = new C(); $a =& $b->a; $a =& $c->a; $a = new RecursiveArrayIterator (); // OK $a = new MultipleIterator(); // Uncaught TypeError: Cannot assign MultipleIteratorRecursiveArrayIteratorはTraversableとCountableをimplementsしているので代入可能ですが、MultipleIteratorはCountableをimplementsしていないので代入不可能です。
ということで菱形継承が可能になりました。どんなときに役立つのか、よくわかりませんが。
親クラスには書けない
上記は親クラスに何も書かれていなかったので、本来の菱形継承ではありません。
親クラスでプロパティの型を指定した場合、子クラスでその制限を変更することはできません。
すなわち、以下のコードは残念ながら動きません。動かないclass A{ public Traversable $a; } class B extends A{ public OuterIterator $a; // Fatal error: Type of B::$a must be Traversable }メソッドの型宣言は子クラスで狭めることができますが、プロパティはPHP7.4α1の時点では狭めることができません。
メソッドと動作を合わせるのであればこの書き方も許容されるべきですが、はたして修正されるでしょうか?
だめなままなのかな?これが許可されるのであれば、以下のように自然な?形の菱形継承も可能になります。
動かないclass A{ public ?Iterator $a; } class B extends A{ public ?OuterIterator $a; } class C extends A{ public ?RecursiveIterator $a; } $b = new B(); $c = new C(); $a =& $b->a; $a =& $c->a; $a = new RecursiveArrayIterator(); // OK $a = new MultipleIterator(); // Uncaught TypeError: Cannot assign MultipleIterator書けるようになったからといってどうするのかわかりませんが。
ジェネリクス
スライドを見ていたら、意外な構文が出てきました。
似非ジェネリクスではなく、本物のジェネリクスの導入を考えているみたいです。
まだ動かないinterface Event{} class SpecificEvent implements Event{} interface EventHandler<E: Event>{ public function handle(E $e); } class SpecificEventHandler implements EventHandler<SpecificEvent>{ public function handle(SpecificEvent $e){} }RFCもありませんし(Generic Types and Functionsは構文が異なる)、まだ思いつき段階といったところでしょうが、このひとNikitaですからね。
PHP8でジェネリクスが導入されていた、なんてことになったとしても驚きはないですね。感想
変数の型指定は有用ですね。
定義方法さえ簡単になれば、あとパフォーマンスが極端に落ちるなどの問題がなければ、普通に使ってもよさそうです。
ただPHPの場合、stringを返す組み込み関数が普通にfalseを返してきたりするので、全てを置き換えるのはちょっと辛そうです。菱形継承はそもそも役に立つ場面を知らないのでなんとも言えません。
ジェネリクスはどうなんですかね、PHPでそこまで必要なんですかね。
確かに配列要素の型を限定したいことは頻繁にありますが、しかし、あらゆるオブジェクトに型指定が欲しいとまではあまり思ったことがないですね。
今でもArrayAccessやらを使えば一応できますしね。
- 投稿日:2019-07-09T21:53:09+09:00
なんちゃってオンラインターミナル
なんちゃってオンラインターミナル
プロジェクトによってはFTP接続しかできないといった環境にたまに参画することもあります。
修正の影響範囲調査、バージョン情報などちょっとしたこともファイルのダウンロードやサーバの管理をしている会社への問い合わせなど時間の無駄を排除すべく最低限のことができるオンラインターミナルを記載します。webconsole.php<?php $command = ""; $commandResult = ""; if (isset($_POST['command']) && $_POST['command'] != "") { $command = $_POST['command']; $result = shell_exec($command); if ($result != null) { $commandResult = $result; } else { $commandResult = "実行結果はありません。。。"; } } $html = <<< EOM <!doctype html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>オンラインたーみなる</title> <script> </script> </head> <body> <header> <h1>オンラインたーみなる</h1> </header> <div> <form action="webconsole.php" method="post"> <input type="text" id="command" name="command" required size="10" value="{$command}" placeholder="コマンドを入力してください。"> <button type="submit" value="ボタン">ボタンの内容</button> </form> <div> <pre>{$commandResult}</pre> </div> </div> <footer> <address>Copyright(C) Dsuke,Allright Reserved.</address> </footer> </body> </html> EOM; echo $html;このソースだけでも事足りますが多少はデザインはしておきたいところです。
→
少しやる気を出してデザインした結果が以下です。
webconsole.php<?php $command = ""; $commandResult = ""; if (isset($_POST['command']) && $_POST['command'] != "") { $command = $_POST['command']; $result = shell_exec($command); if ($result != null) { $commandResult = $result; } else { $commandResult = "実行結果はありません。。。"; } $commandResult = "<div class='box'><pre>{$commandResult}</pre></div>"; } $html = <<< EOM <!doctype html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>オンラインたーみなる</title> <style type="text/css"> <!-- #header { position:relative; margin:0 10px; padding:10px 10px 10px 30px; font:bold 22px/1.2 Arial, Helvetica, sans-serif; color:#666; text-align: center; background:#ccc; border-top:#ccc solid 1px; border-right:#999 solid 1px; border-bottom:#999 solid 1px; border-left:#ccc solid 1px; text-shadow:1px 1px 0 rgba(255,255,255,1); box-shadow: 0 0 0 1px rgba(255,255,255,0.5) inset; background-image: -webkit-gradient(linear, left top, left bottom, from( rgba(220, 220, 220, 1.0)), color-stop(0.25, rgba(240, 240, 240, 1.0)), color-stop(0.30, rgba(235, 235, 235, 1.0)), color-stop(0.36, rgba(240, 240, 240, 1.0)), color-stop(0.50, rgba(235, 235, 235, 1.0)), color-stop(0.80, rgba(215, 215, 215, 1.0)), to( rgba(210, 210, 210, 1.0)) ); background-image: -webkit-linear-gradient(top, rgba(220, 220, 220, 1.0), rgba(240, 240, 240, 1.0) 25%, rgba(235, 235, 235, 1.0) 30%, rgba(240, 240, 240, 1.0) 36%, rgba(235, 235, 235, 1.0) 50%, rgba(215, 215, 215, 1.0) 80%, rgba(210, 210, 210, 1.0) ); background-image: -moz-linear-gradient(top, rgba(220, 220, 220, 1.0), rgba(240, 240, 240, 1.0) 25%, rgba(235, 235, 235, 1.0) 30%, rgba(240, 240, 240, 1.0) 36%, rgba(235, 235, 235, 1.0) 50%, rgba(215, 215, 215, 1.0) 80%, rgba(210, 210, 210, 1.0) ); background-image: -o-linear-gradient(top, rgba(220, 220, 220, 1.0), rgba(240, 240, 240, 1.0) 25%, rgba(235, 235, 235, 1.0) 30%, rgba(240, 240, 240, 1.0) 36%, rgba(235, 235, 235, 1.0) 50%, rgba(215, 215, 215, 1.0) 80%, rgba(210, 210, 210, 1.0) ); background-image: linear-gradient(to bottom, rgba(220, 220, 220, 1.0), rgba(240, 240, 240, 1.0) 25%, rgba(235, 235, 235, 1.0) 30%, rgba(240, 240, 240, 1.0) 36%, rgba(235, 235, 235, 1.0) 50%, rgba(215, 215, 215, 1.0) 80%, rgba(210, 210, 210, 1.0) ); } #header:before { content:" "; position:absolute; top:0; left:15px; width:0; height:100%; border-left:#ccc solid 1px; } #header:after { content:" "; position:absolute; top:0; left:16px; width:0; height:100%; border-right:#eee solid 1px; } .cmd_input { position: relative; width: 90%; margin: 40px 3%; } .cmd_input input[type='text'] { font: 15px/24px sans-serif; box-sizing: border-box; width: 100%; letter-spacing: 1px; padding-left: 1em; color: #ffffff; background-color: #000000; } .cmd_input input[type='text']:focus { outline: none; } .effect { padding: 7px 14px; transition: 0.4s; border: 1px solid #000000; background: transparent; color: #ffffff; background-color: #000000; } .effect ~ .focus_line:before, .effect ~ .focus_line:after { position: absolute; top: -1px; left: 50%; width: 0; height: 2px; content: ''; transition: 0.4s; background-color: #00ff00; } .effect ~ .focus_line:after { top: auto; bottom: 0; } .effect ~ .focus_line i:before, .effect ~ .focus_line i:after { position: absolute; top: 50%; left: 0; width: 2px; height: 0; content: ''; transition: 0.6s; background-color: #00ff00; } .effect ~ .focus_line i:after { right: 0; left: auto; } .effect:focus ~ .focus_line:before, .effect:focus ~ .focus_line:after, .cmd_input.ef ~ .focus_line:before, .cmd_input.ef ~ .focus_line:after { left: 0; width: 100%; transition: 0.4s; } .effect:focus ~ .focus_line i:before, .effect:focus ~ .focus_line i:after, .cmd_input.ef ~ .focus_line i:before, .cmd_input.ef ~ .focus_line i:after { top: -1px; height: 100%; transition: 0.6s; } .effect ~ label { position: absolute; z-index: -1; top: 10px; left:30px; width: 100%; transition: 0.3s; letter-spacing: 0.5px; color: #00ff00; } .effect:focus ~ label, .cmd_input.ef ~ label { font-size: 18px; top: -20px; left: 0; transition: 0.3s; color: #000000; } button.button { font-size: 1.0em; font-weight: bold; padding: 5px 15px; background-color: #c0c0c0; color: #191970; border: 2px solid #000000; } button.button:hover { background-color: #000000; color: #00ff00; } .box { padding: 8px 19px; margin: 2em 0; color: #2c2c2f; background: #cde4ff; border-top: solid 5px #00ff00; border-bottom: solid 5px #00ff00; background-color: #000000; } .box pre { margin: 0; padding: 0; color: #ffffff; } footer { font-size: 80%; width: 99%; text-align: center; padding-top: 10px; padding-bottom: 10px; background-color: #313131; position: absolute; bottom: 0; } footer address { color: #ffffff; letter-spacing: 5px; font-style: normal; } --> </style> </head> <body> <header> <h1 id="header">オンラインたーみなる</h1> </header> <form action="webconsole.php" method="post"> <div class="cmd_input"> <input class="effect" type="text" id="command" name="command" value="{$command}" placeholder=""> <label>コマンドを入力してください。</label> <span class="focus_line"><i></i></span> </div> <center><button class="button" type="submit" value="実行">実行</button></center> </form> {$commandResult} <footer> <address>Copyright(C) Dsuke,Allright Reserved.</address> </footer> </body> </html> EOM; echo $html;見れるレベルにはなったかと思います。(だれかデザインしてくれ)
最後に
・バリデーションなど行っていないため各自実装してください
・適当に流用してください
・いい感じのデザイン求む(ください)
- 投稿日:2019-07-09T21:16:51+09:00
Carbonを使って投稿経過時間を表示する(Laravel)
About Carbon
Carbonについての説明は下記の記事に詳しく書かれています。
PHPで日付時刻処理を書くならCarbonを使うべき
phpの便利な日付、時刻オブジェクト Carbon を使用する。平成、令和などの和暦を表示させる
全217件!Carbonで時間操作する実例概要
過去に作ったモジュールについて記事を書いてます。
instgramなどの投稿に、投稿から「〇〇分前」などと表示される時間経過の部分を作ります。
画像の「9分前」、「1秒前」の部分のことです。
コード
bladeテンプレートの投稿コンテンツにこれを書くだけでできます。
index.blade.php<?php //時間の差分を求める $postedAt = new \Carbon\Carbon($message->created_at); $now = \Carbon\Carbon::now(); $secondsSincePosted = $postedAt->diffInSeconds($now); if($secondsSincePosted > 59){ $minutesSincePosted = $postedAt->diffInMinutes($now); if($minutesSincePosted > 59){ $hoursSincePosted = $postedAt->diffInHours($now); if($hoursSincePosted > 23){ $daysSincePosted = $postedAt->diffInDays($now); if($daysSincePosted > 6){ $yearsSincePosted = $postedAt->diffInYears($now); if($yearsSincePosted > 0){ echo $postedAt->format("Y年n月j日"); }else{ echo $postedAt->format("n月j日"); } }else{ echo $daysSincePosted.'日前'; } }else{ echo $hoursSincePosted.'時間前'; } }else{ echo $minutesSincePosted.'分前'; } }else{ echo $secondsSincePosted.'秒前'; } ?>まとめ
Carbonはいいぞ。
Githubにも上げてます。
jdkfx/posted-date
- 投稿日:2019-07-09T18:51:25+09:00
PHP Parse error: syntax error, unexpected T_VARIABLE in
単純な記号ミス、打ち間違えなどによるエラー。
今回はコメントアウトの//が抜けてたため、指定行の一つ手前の行が原因で
エラーが発生した模様
- 投稿日:2019-07-09T16:59:09+09:00
Laravel キーワード検索 複数
はじめに
Laravelアプリにて、複数条件の検索機能を実装しました!
文字とカテゴリーの2つで検索出来る仕様です!始め(修正前)はコントローラー/モデルで下記のように、条件毎でメソッドを分け記述していました。(メソッド名は気にせず)
QuestionsController.php(修正前)class QuestionsController extends Controller { private $question; private $category; public function __construct(Question $question, Category $category) { $this->question = $question; $this->category = $category; } public function index(Request $request) { //カテゴリー一覧を表示するため、カテゴリーモデルでデータを連想配列で取得するメソッド $categoryNames = $this->category->カテゴリー名取得メソッド(); $keyword = $request->input('キーワード'); $categoryId = $request->input('カテゴリー'); if (isset($keyword) && isset($categoryId)) { $questions = $this->question->なんちゃらメソッド1($keyword, $categoryId); } elseif (isset($keyword)) { $questions = $this->question->なんちゃらメソッド2($keyword); } elseif (isset($categoryId)) { $questions = $this->question->なんちゃらメソッド3($categoryId); } else { $questions = $this->question->all(); } return view('question.index', compact(['questions', 'categoryNames'])); } }モデル
questiion.php(修正前)class Question extends Model { public function なんちゃらメソッド1($keyword, $categoryId) { return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%') ->where('category_id', '=', $categoryId) ->get(); } public function なんちゃらメソッド2($keyword) { return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%')->get(); } public function なんちゃらメソッド3($categoryId) { return $this->with(['紐づくデータ'])->where('category_id', '=', $categoryId)->get(); } }今回は条件が2つなので上記の記述量で収まっていますが、検索条件が増えた場合、メソッドと条件分岐をその都度書き足す必要が出てきます。
めんどくさいですし、コントローラがファットになってしまいます。複数条件での検索を探す中で、クロージャやorWhereなど色々出てきましたが、わからず。。
最終的に下記の記述に書き直しました!QuestionsController.php(修正後)class QuestionsController extends Controller { <--- 略 ---> public function index(Request $request) { $categoryNames = $this->category->カテゴリー名取得メソッド(); $questions = $this->question->なんちゃらメソッド($request); return view('question.index', compact(['questions', 'categoryNames'])); } }モデル
Question.php(修正後)class Question extends Model { public function なんちゃらメソッド($request) { $keyword = $request->input('キーワード'); $categoryId = $request->input('カテゴリー'); $query = $this->with(['紐づくデータ', '紐づくデータ']); if (isset($keyword)) { $query->where('title', 'LIKE', '%' . $keyword . '%'); } if (isset($categoryId)) { $query->where('category_id', '=', $categoryId); } return $query->get(); } }inputでの値の抽出もモデルに記述し、なるべくコントローラーのコードを減らしました!
eagerロードで紐づく値を取得したものを$query変数に代入し、条件が入力されていればその条件にあったSQLの処理が走ります!このように書けば、メソッド毎に処理を追うこともなくなり、条件が増えた場合の追加が楽、可読性向上などのメリットがあると思います!
改善点あればご教示お願い致します!
- 投稿日:2019-07-09T16:59:09+09:00
Laravel 検索機能 複数条件
はじめに
Laravelアプリにて、複数条件の検索機能を実装しました!
文字とカテゴリーの2つで検索出来る仕様です!始め(修正前)はコントローラー/モデルで下記のように、条件毎でメソッドを分け記述していました。(メソッド名は気にせず)
QuestionsController.php(修正前)class QuestionsController extends Controller { private $question; private $category; public function __construct(Question $question, Category $category) { $this->question = $question; $this->category = $category; } public function index(Request $request) { //カテゴリー一覧を表示するため、カテゴリーモデルでデータを連想配列で取得するメソッド $categoryNames = $this->category->カテゴリー名取得メソッド(); $keyword = $request->input('キーワード'); $categoryId = $request->input('カテゴリー'); if (isset($keyword) && isset($categoryId)) { $questions = $this->question->なんちゃらメソッド1($keyword, $categoryId); } elseif (isset($keyword)) { $questions = $this->question->なんちゃらメソッド2($keyword); } elseif (isset($categoryId)) { $questions = $this->question->なんちゃらメソッド3($categoryId); } else { $questions = $this->question->all(); } return view('question.index', compact(['questions', 'categoryNames'])); } }モデル
questiion.php(修正前)class Question extends Model { public function なんちゃらメソッド1($keyword, $categoryId) { return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%') ->where('category_id', '=', $categoryId) ->get(); } public function なんちゃらメソッド2($keyword) { return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%')->get(); } public function なんちゃらメソッド3($categoryId) { return $this->with(['紐づくデータ'])->where('category_id', '=', $categoryId)->get(); } }今回は条件が2つなので上記の記述量で収まっていますが、検索条件が増えた場合、メソッドと条件分岐をその都度書き足す必要が出てきます。
めんどくさいですし、コントローラがファットになってしまいます。複数条件での検索を探す中で、クロージャやorWhereなど色々出てきましたが、わからず。。
最終的に下記の記述に書き直しました!QuestionsController.php(修正後)class QuestionsController extends Controller { <--- 略 ---> public function index(Request $request) { $categoryNames = $this->category->カテゴリー名取得メソッド(); $questions = $this->question->なんちゃらメソッド($request); return view('question.index', compact(['questions', 'categoryNames'])); } }モデル
Question.php(修正後)class Question extends Model { public function なんちゃらメソッド($request) { $keyword = $request->input('キーワード'); $categoryId = $request->input('カテゴリー'); $query = $this->with(['紐づくデータ', '紐づくデータ']); if (isset($keyword)) { $query->where('title', 'LIKE', '%' . $keyword . '%'); } if (isset($categoryId)) { $query->where('category_id', '=', $categoryId); } return $query->get(); } }inputでの値の抽出もモデルに記述し、なるべくコントローラーのコードを減らしました!
eagerロードで紐づく値を取得したものを$query変数に代入し、条件が入力されていればその条件にあったSQLの処理が走ります!このように書けば、メソッド毎に処理を追うこともなくなり、条件が増えた場合の追加が楽、可読性向上などのメリットがあると思います!
改善点あればご教示お願い致します!
- 投稿日:2019-07-09T16:42:43+09:00
Smartyでエスケープしてかつ”nl”を改行する
探したけど、これがなかった。
{$project_name|escape|nl2br}PS:今更感あるかも?
- 投稿日:2019-07-09T16:29:36+09:00
採番したUniqueIdをHtmlに含めてはいけない
採番したUniqueIdをHtmlに含めてはいけない
先日レガシーシステムでトラブルにぶつかったので。
TL;DR
- Safariなど一部のブラウザはキャッシュがやたら強いので、採番した一意IDをHTML上の要素として渡すと過去に採番したものを持ってきてしまう可能性がある
- クエリパラメータでキャッシュの利用を抑制したり、jsで取得するなどcacheに影響されない工夫が必要
遭遇した事象
phpを利用した申し込みシステムにおいて、毎回新規に採番されるはずのtokenが重複した場合にのみ発生するエラーがたまに発生していました。
tokenはランダム32桁の文字列+生成時刻のエポックミリ秒のため、重複することはほぼあり得ません。tokenの出所
token自体は申し込み画面に入るタイミングでサーバーサイドで採番され、
Html上のhiddenなinputとしてブラウザ側に渡されていました。
ヘッダにno cacheはついているので、基本的に毎回新たに採番されます。戻るボタンではない
当初は戻るボタン関連の問題かと思ったのですが、
ログに出てきたエラー時のtokenの日付を見る限り、採番後数日経ってからエラーが発生したケースもありました。
単純に申し込み後に戻ってもう一度押してしまったわけではなさそうです。ブラウザに依存している
基本的に問題が発生しているのはiphoneのSafari。
ただし、常に発生しているわけではない。原因
iphoneのsafariで2回目の申し込みをした場合、
1回目の申し込みのキャッシュが残っており同一番号で重複申請してしまっていた。iphoneのSafariのcache機構はやたらと強力で、
Headerにちょっとno cacheを加えたくらいではcacheから読み込んでくるようです。参考:
https://www.ituki-yu2.net/entry/iPhone_no_cache対応
レガシーシステムで仕様が不明確だったので、一旦遷移時にクエリパラメータを付けて無理やりキャッシュを利用しないように対応しました。
ただ、本来はキャッシュされる可能性のある部分を使って一意識別子を渡すこと自体を本来は避けるべきです。
- 投稿日:2019-07-09T16:20:10+09:00
Vagrantのphpを7.2にあげる
前提
VCCW + Vagrant
ubuntu16.04.1
PHP 7.0 (多分デフォルトではPHP7.0が走っているはず)手順
(1)Vagrant 起動
$ vagrant up $ vagrant ssh(2)リポジトリのインストール
$ sudo apt install software-properties-common $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update(3)PHP7.2&主要モジュールをインストール
$ sudo apt-get install php7.2 php7.2-fpm php7.2-mysql php7.2-mbstring php7.2-zip php7.2-xml libapache2-mod-php7.2(4)確認
$ php -v vagrant@maedag:~$ php -v PHP 7.2.18-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: May 3 2019 09:23:41) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.18-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend TechnologiesPHP7.2になっている。
! 注意
ただしソフト側で実行されるPHPが切り替わっていないことが多い(下記スクショ)。
(5)上記の場合、下記コマンドを実行
$ sudo apt install libapache2-mod-php7.2 #Apacheのphpモジュール 使いたいバージョンに適宜書き換えて $ sudo a2dismod php7.0 #Apacheの旧phpモジュールのバージョンをdisable $ sudo a2enmod php7.2 #Apacheの新phpモジュールのバージョンをenable $ sudo service apache2 restart #apache再起動(6)完了を確認!
- 投稿日:2019-07-09T15:10:09+09:00
AmazonLinux2でLaravelの開発環境構築
AWSでLaravelの開発環境を構築して行きたいと思います。
前提条件として、
すでにAWSでアカウントは作成済みとしています。
また、簡単なWEBアプリケーションは作成したことがある方を対象としていますEC2の起動
まずは、AWSのコンソールからEC2を起動します。
「インスタンスの作成」をクリックすると、Amazon マシンイメージ(AMI)の選択画面になるので、Amazon Linux 2 AMI (HVM),SSD Volume Type を「選択」します。次にインスタンスタイプの選択画面になるので、好きなインスタンスタイプを選択します。t2.microが無料利用枠の対象なので、利用できる方はこちらのタイプが良いかと思います。
私は開発環境での利用なので、今回 t3.nano を選択しました。インスタンスの詳細の設定については、基本的には自由に設定できますが、よくわからなければ一旦全てデフォルトのままでも問題ないかと思います。
私は、そこまで頻繁に利用しない開発環境ということもあるので、スポットインスタンスのリクエストにチェックを入れて、費用を安く抑えています。スポットインスタンスは、費用を安く抑えられる反面、連続稼働を保証していないので、本番環境ではお勧めできませんので注意ください。ストレージの追加も任意ですが、ルートの8GiBのみで進みます。
セキュリティグループの設定は、一旦最小限のセキュリティグループを作成します。
タイプ プロトコル ポート範囲 ソース SSH TCP 22 マイIP (ご自身の接続IP) HTTP TCP 80 カスタム 0.0.0.0/0,::/0 ターミナルへのログインのために、SSHのポートをご自身のIPで設定。
HTTPは、どこからでも閲覧可能なように設定。自分しか確認できないようにしたい場合は、HTTPのソースについてもマイIPを設定してください。最後に、ログイン用のキーを生成して終了です。
EC2の初期設定
EC2が起動したら、ec2-userとしてログインしてみましょう。
作成したキーを .ssh/ 以下に配置しておきます。ssh ec2-user@ec2-**-**-**-***.ap-northeast-1.compute.amazonaws.com -i ./.ssh/(秘密キー)Laravelをセットアップする前に、ざっとEC2の設定を行います。
とりあえず、パッケージを最新に更新
$ sudo yum update -yec2-userのままでも良いですが、実際に利用するユーザーを作成
ユーザー名をいつも利用しているユーザー名を利用してください。説明では munakata として進めます。$ sudo su - # useradd munakata # passwd munakata # usermod -G wheel munakatamunakata に sudo権限を付与します。
# visudoroot以下に追加
visudo## Allow root to run any commands anywhere root ALL=(ALL) ALL munakata ALL=(ALL) ALLmunakataのホームディレクトリ(/home/munakata) 以下の
.ssh/authorized_keys に公開鍵をセット。すでにご自身の公開鍵はお持ちかと思いますが、まだない方は作成してください。
SSHキー等で検索すれば、いくつか情報が出てくるかと思います。一応、権限を記載しておきます。
権限 パス 700 ~/.ssh 600 ~/.ssh/authorized_keys これで、munakataユーザーでログインする準備は完了です。
一度ログアウトして、実際に新しいユーザーでログインしてみましょう。ssh munakata@ec2-**-**-**-***.ap-northeast-1.compute.amazonaws.com -i ./.ssh/(munakataの秘密キー)ローカライズ設定を行います。
タイムゾーンを日本時間にセット
/etc/sysconfig/clock$sudo vim /etc/sysconfig/clock ZONE="Asia/Tokyo" UTC=false反映には再起動が必要なので、とりあえず日本時間にセット
$ sudo cp /usr/share/zoneinfo/Japan /etc/localtime日本語設定
/etc/sysconfig/i18n$ sudo vim /etc/sysconfig/i18n LANG=ja_JP.UTF-8ここまでで、ざっとEC2の初期設定が完了です。
必要なパッケージのインストール
ここからは、AmazonLinux2でLaravelを構築するために必要なパッケージをインストールしていきます。
なるべく特殊なことはせず、ある程度AWSで用意された標準的なもので構築したいと思います。WEBサーバーとして、apache2.4 、PHPのバージョンは、PHP7.3 を使用します。
いきなりですが、AmazonLinux2で、yumを利用してPHPをインストールするとPHP5になってしまいます。
AmazonLinuxでは、yum install php72 でPHP7.2をインストールできたのですが、AmazonLinux2には用意されていません。
その代わりに、Extra Library が用意されているようです。
Extra Library は、amazon-linux-extras で利用可能です。php7.3をインストールしてみます。
$ sudo amazon-linux-extras php7.3一緒に必要なパッケージもインストールされます
php-cli.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3 php-common.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3 php-fpm.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3 php-json.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3 php-mysqlnd.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3 php-pdo.x86_64 7.3.6-1.amzn2.0.1 @amzn2extra-php7.3確認してみましょう。
$ php -vamazon-linux-extras でパッケージをインストールすると、拡張モジュールに関しては、yumを使って適切なパッケージをインストールしてくれるようになります。便利ですね!
実際にインストール可能な拡張モジュールを確認してみましょう。
$ sudo yum list php* | grep php7.3必要な拡張モジュールをインストールしていきます。必要に応じて各自検討ください。
php-xmlは、Laravelインストール時に、phpunitのインストールに必要になるようなので、事前にインストールしておきましょう。$sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml次に、apache2.4をインストールします。
AmazonLinuxの場合は、2.4系を入れる場合は、 httpd24 でしたが、AmazonLinux2の場合は、httpd で、2.4系になるようです。
$ sudo yum install httpd起動します。
$ sudo systemctl start httpdコンソール上には何も出力されないので、実際に動いているか確認します。
下記のコマンドで、active (running) とか表示されているはずです。$ sudo systemctl status httpd実際にWEBブラウザから確認してみます。
起動したEC2に、パブリックDNSが割り振られているかと思うので、そのURLで確認すると、Apacche2.4のTestPageが表示されるかと思います。
IPv4 パブリックIPでも確認可能です。
ElasticIPを紐付けた方は、そちらのIP、もしくはRoute53で設定したドメインで確認してください。
PHPの設定
この時点で、Laravelのインストール自体は可能なのですが、PHP、Apacheの細かい設定もしていきましょう。
PHPの設定は、 /etc/php.ini で行います。設定した値を確認できるように、phpinfoの表示ページを作成しておきましょう。
設定内容は、各自調整してください。
私がよく変更する箇所は、この辺です。php.ini# HTTPヘッダにPHPのバージョンを記載しない(一応セキュリティ的にOffにしておいたほうが良い) # expose_php = On expose_php = Off # メモリ上限を引き上げる(結構デフォルトのメモリは少なめなので増やしておくことが多い) # memory_limit = 128M memory_limit = 256M # POST送信の許容サイズを引き上げる # post_max_size = 8M post_max_size = 16M # アップロードファイルの許容サイズを引き上げる(スマホの写真のサイズが大きくなっているので、2Mだとほぼ画像投稿できないので増やす) # upload_max_filesize = 2M upload_max_filesize = 16M # timezoneの設定 # date.timezone = date.timezone = Asia/Tokyo設定を反映します。
モジュール版のPHPの場合、通常httpdを再起動すると、php.iniの内容が反映されるのですが、AmazonLinux2で、PHP7.3とhttpd2.4を構築した場合、デフォルトでSever APIが FPM/FastCGI となるため、httpdでは、php.iniの設定が反映されず、php-fpmの再起動が必要となります。
php-fpmについて詳しく知りたい方は、「php-fpm」等のキーワードでお調べください。
$ sudo systemctl restart php-fpmLaravelインストール
DocumentRootにLaravelを配置することも可能なのですが、開発環境として構築するので、今回はVirtualHostの機能を利用して、ホームディレクトリに、htmlディレクトリを作成して、その配下にLaravelプロジェクトを配置します。
まずは、Composerをインストール
curl -sS https://getcomposer.org/installer | phpcomposer.phar がダウンロードされるので、composer のコマンドで実行できるように、PATHが通っている場所へ移動させます。
sudo mv composer.phar /usr/local/bin/composerこれで composer が利用できるようになったので、Laravelをインストールします。
$ cd ~/html/ $ composer create-project --prefer-dist laravel/laravel blogこれで、blogというLaravelプロジェクトが構築されます。
ただし、今回利用している t3.nano などのインスタンスタイプだと、メモリが足らずにインストールの途中に下記のエラーが出てしまいます。mmap() failed: [12] Cannot allocate memoryそこで、ハードディスクにswap領域を作成して、メモリ不足を補います。
最初に、現状確認
$ free total used free shared buff/cache available Mem: 470512 145504 118000 104 207008 290656とりあえず、1G程度用意すればLaravelのインストールは可能なのでswapを作成します。
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=1024 $ sudo chmod 600 /swapfile $ sudo mkswap /swapfile $ sudo swapon /swapfile再度、freeコマンドでSwapが追加されていれば、OKです。
$ free total used free shared buff/cache available Mem: 470512 145504 118000 104 207008 290656 Swap: 1048572 27904 1020668これで、やっと準備が整ったので、再度
$ composer create-project --prefer-dist laravel/laravel blogあとは、Laravelのドキュメントに記載がある通りに設定をしていきます。
$ cd ~/html/blog $ composer update $ chmod -R 777 bootstrap/cache $ chmod -R 777 storage $ php artisan key:generate基本的には、設定ファイルは、.envになりますが、開発環境専用にする場合は、下記のようにリネームします。
$ mv .env .env.developmentApache VirtualHost 設定
最後に、ApacheのVirtualHost設定を行います。
Virtual Hostの記述は、自動で設定が読み込まれる /etc/httpd/conf.d 配下にファイルを作成して記述します。
ファイル名は任意ですが、vhost.confで作成します。$ sudo su - # cd /etc/httpd/conf.d # vim vhost.conf一旦必要な記述を記載しますが、Virtual Hostの詳しい記述方法については、他で調べてみてください。
アクセス予定のドメインは、blog.munakata.net を仮定しています。適宜変更ください。vhost.conf<VirtualHost *:80> DocumentRoot /home/munakata/html/blog/public ServerName blog.munakata.net ServerAlias blog.munakata.net <Directory "/home/munakata/html/blog/public"> #.htaccessを利用可能にする AllowOverride All # Laravelで利用する環境変数を development に設定 SetEnv APP_ENV development #アクセス許可 Require all granted </Directory> </VirtualHost>httpd再起動
$ sudo systemctl restart httpdRoute53で、設定したドメインを紐付けるか、ご自身のマシンのhostsを設定して、ブラウザでアクセスしてみてください。
Laravelのトップページが表示されていれば、一旦完了です。
- 投稿日:2019-07-09T14:57:29+09:00
Vueをマウントできなくて奮闘
プログラミング歴3か月くらいの初心者です、自分のメモ用。
bladeファイル内になどを記載して、コンポーネントを挿入しても
app.js:38008 [Vue warn]: Failed to mount component: template or render function not defined. found in ---> <コンポーネント名> <Root>上記のエラーが発生する。
app.jsにもしっかり記載している。
Vue.component('my-component', require('./components/MyComponent.vue'));いろいろな記事を見て、webpack.config.jsに追記だの devコマンドを実行したかだのいろいろ対処法が
書かれていたがどれでも解決できないところ以下の記事を見つけた。どうやら app.jsで
Vue.component('my-component', require('./components/MyComponent.vue').default);最後に.defaultを追記するだけでした。(意味は知らない)
- 投稿日:2019-07-09T09:40:26+09:00
php-master-changes 2019-07-08
今日は exif の修正、argon2i(d) のパスワードハッシュを必要な場合 sodium から使うようにする修正、ビルドシステムのリファクタリング、ZEND_ASSIGN_DIM_OP の記述修正、com_dotnet の TsHashTable 関連の race 修正、INPUT_SESSION と INPUT_REQUEST の削除、libmagic のパッチ更新、_JIT のデバッグ用ディスアセンブラが FreeBSD / NetBSD で PHP バイナリの ELF シンボルを読む際の処理修正、base_convert() 等の基数変換関数へ無効な文字列を渡した際に deprecation notice を吐くようにする修正、スローパスで EG(exception) のチェックを遅延させるようにする修正、Mac 用のテスト修正、ドキュメントの更新、ReflectionReference::getRefcount() を実装する修正があった!
2019-07-08
smalyshev: Simplify expression and remove the possibility of div by 0
- https://github.com/php/php-src/commit/57e7c3aac100f7ceb992a9a554b76235713f9a83
- [7.4~]
- ext/exif で、処理を単純化し 0 除算の可能性があったのを修正
sgolemon: Provide argon2i(d) password hashing from sodium when needed
- https://github.com/php/php-src/commit/0ba1db7a4ab035e00dcb3089ef45820054c5a1cf
- [7.4~]
- argon2i(d) のパスワードハッシュを必要な場合 sodium から使うよう修正
- PHP RFC: Provide argon2i(d) implementations for password_hash() from ext/sodium の実装
petk: Remove some unused variables
- https://github.com/php/php-src/commit/5ba69ab3addf17b0b854a20148f92e25b3790ef7
- [7.4~]
- ビルドシステムで、不要な変数を削除
dstogov: Fixed opcode description
- https://github.com/php/php-src/commit/1305d9c0d26c167c4cb0abcd78a5c804ad96a292
- [7.4~]
- ZEND_ASSIGN_DIM_OP の OP2 のタイプを修正
- UNUSED のオペランドを何らかの形で利用する際の区別に THIS とか NEXT とか CLASS_FETCH とかを雰囲気で付けてるように見える、が、どんな時にどれ使うのかがイマイチ分からず(CLASS_FETCH は op.num をクラスフェッチで使うんだなというのは見てて分かる)
- たぶん zend_hash_next_index_insert() につながる配列への auto_increment 使った要素追加とかそういう系に使われることの記述なのかな、という気はしている
petk: Simplify PHP_CHECK_PDO_INCLUDES calls
- https://github.com/php/php-src/commit/a39ea91753c5d131ff802ee394ee23ce2f37d7f4
- [7.4~]
- ビルドシステムで、PHP_CHECK_PDO_INCLUDES の呼び出しを単純化
- PHP_CHECK_PDO_INCLUDES がないバージョンの phpize との後方互換用の記述があった
cmb69: Fix TsHashTable related race conditions
- https://github.com/php/php-src/commit/98b6330ab45732dcb16bb714d66ca1d987531406
- [7.4~]
- ext/com_dotnet で、TsHashTable 関連の race を修正
- TsHashTable 使っても要素の finding と updating 被るの安全じゃねえよ!というので tsrm_mutex 自前で使って保護する実装にしたもよう
cmb69: Implement FR #77230: Support custom CFLAGS and LDFLAGS from environment
- https://github.com/php/php-src/commit/338e1b245d8c234ffbd5407bf3f6c05a9e1b3cb3
- [7.4~]
- ビルドシステムで、Windows 版の configure で CFLAGS と LDFLAGS を環境変数から取れるよう修正
nikic: Remove INPUT_SESSION and INPUT_REQUEST
- https://github.com/php/php-src/commit/0904dd3dc2bae8508f58f99c71e0d1d79fb91d38
- ext/filter で、filter_input() の INPUT_SESSION と INPUT_REQUEST がぶっちゃけ実装されてなかったので(警告吐くだけだったので)削除
petk: Update libmagic patch
- https://github.com/php/php-src/commit/f002761e08b928f17b16fb7bf7885294f4128415
- ext/fileinfo で、libmagic のパッチを upstream に追従して更新
devnexen: JIT: Reading php binary symbols list on FreeBSD
- https://github.com/php/php-src/commit/5e1368814265871695ffb35ceb927cd1bae06a25
- [7.4~]
- ext/opcache/jit で、デバッグ用ディスアセンブラが FreeBSD / NetBSD で PHP バイナリの ELF シンボルを読む際の処理を修正
petk: Remove C89 checks for signal.h and strerror
- https://github.com/php/php-src/commit/550c2aa89b97b07582773f22b9a52466d8584ab8
- [7.4~]
- ビルドシステムで、C89 で標準化されている signal.h と strerror のチェックを削除
exussum12: Deprecate passing invalid character to base_convert etc
- https://github.com/php/php-src/commit/d90cdbd9df42c3d012af23a64fb3062f0af60efa
- base_convert() 等の基数変換関数へ無効な文字列を渡した際に deprecation notice を吐くよう修正
- PHP RFC: base_convert changes の実装
nikic: Remove redundant variable declaration
- https://github.com/php/php-src/commit/3ee570ae0d8fff340fea207ee49a694ae5b0a7f9
- [7.4~]
- ext/opcache/jit で、先の修正の不要な変数宣言の削除
dstogov: Delay EG(exception) check on slow path
- https://github.com/php/php-src/commit/9a833438d184bcc7198c609117b27a321f20d22c
- [7.4~]
- スローパスで EG(exception) のチェックを遅延させるよう修正
nikic: Make busy wait busier
- https://github.com/php/php-src/commit/392398bfe63b43288a0fbd301491b564eb24dfe9
- [7.4~]
- タイムアウトのテストが Mac でこけるのでビジーループを足して様子見
petk: Refactor genif.sh
- https://github.com/php/php-src/commit/900de30b0f40a254e19082d3e2b696d58e338b43
- [7.4~]
- genif.sh のリファクタリング
- genif で Generate internal functions file、って分かるかそんなもん
petk: Remove APACHE symbol
- https://github.com/php/php-src/commit/4b864c2ebbee11739a52b20a59aff8bdf9a38801
- [7.4~]
- ビルドシステムで、大昔に使われていたシンボル APACHE の削除
petk: Catch up with recent changes [ci skip]
- https://github.com/php/php-src/commit/0f0c6c617f3a91e9b10bc0107226b7cedfd7d44f
- [7.4~]
- UPGRADING と NEWS の更新
nikic: Add ReflectionReference::getRefcount()
- https://github.com/php/php-src/commit/428cfdd1810b17f0064b7691276f0eb92dc963b6
- [7.4~]
- ext/reflection で、ReflectionReference::getRefcount() の実装
- 経緯は #78263








