- 投稿日:2019-12-11T22:23:52+09:00
ボタンクリックでランダムでペンギンの画像が出るページを作る その2
概要・目次はこちら
ベースづくり
整理のために、ひとまず必要なページなどを書き出してみます。
いわゆるサイトマップ。index.html
⇃(ボタンクリックで遷移)
result.php(ランダムでペンギンの画像表示)サイトマップ作るほどでもないのでこれで
Javascriptとか組み合わせればページ遷移せずに(index.html内で)画像表示までできるんだろうけど、とりあえずシンプルにこの形で…
コーディング
サイトマップが出来たらページデザイン、
デザインが出来たらコーディングしていきます。
(複雑なものだとワイヤー作ったほうがいいと思います…)ひとまずphp無しに作りますが、作りながらどこを動的に処理したいか考えつつコーディングします。
画像、画像のalt、画像のタイトル、説明文が変わっていくな~~とか思いながらコーディングしますphpを実装する
ベースが出来たら、phpで動きを実装していきます。
<body> <div class="wrap"> <header class="header">Qiita</header> <article class="main"> <h1 class="main-ttl">Random Penguin</h1> <p class="main-img"><img src="img/01.jpg" alt="タイトル01"></p> <p class="main-img-ttl">タイトル01</p> <p class="main-img-caption">説明文01</p> </article> <footer class="footer">© 2019 Random Penguin</footer> </div> </body>
main-img
、main-img-ttl
、main-img-caption
の部分をまとめて変えたいので、配列でセットを作ります。画像・タイトル・説明文を設定する
<?php $set = array( array( //[0] 'title' => 'タイトル01', 'img' => '01', 'caption' => '説明文01' ), array( //[1] 'title' => 'タイトル02', 'img' => '02', 'caption' => '説明文02' ), array( //[2] 'title' => 'タイトル03', 'img' => '03', 'caption' => '説明文03' ), ); echo 'タイトル:'.$set[0]['title'].'<br>'; echo '画像:'.$set[0]['img'].'<br>'; echo '説明文:'.$set[0]['caption']; ?> //実行結果 タイトル:タイトル01 画像:01 説明:キャプション01
$set[0]
の数字を変えればその中にセットしたtitleなどが表示されます。ランダムな数字を発生させる
rand関数を使います。
//0~2の数字からランダムな数字を$randomに入れる $random = rand(0, count($set)-1); //$set[0~2]を$resultに入れる $result = $set[$random];
rand(0, 2)
でもいいけど、$set
の中身が増えても対応させていきたいので、$set
の中身をcountで数えて-1します。
あとは$result['title']
などで表示させるだけ。htmlに組み込む
<?php $set = array( array( //[0] 'title' => 'タイトル01', 'img' => '01', 'caption' => '説明文01' ), array( //[1] 'title' => 'タイトル02', 'img' => '02', 'caption' => '説明文02' ), array( //[2] 'title' => 'タイトル03', 'img' => '03', 'caption' => '説明文03' ), ); $random = rand(0, count($set)-1); $result = $set[$random]; ?> <body> <div class="wrap"> <header class="header">Qiita</header> <article class="main"> <h1 class="main-ttl">Random Penguin</h1> <p class="main-img"><?php echo '<img src="img/'.$result['img'].'.jpg" alt="'.$result['title'].'">' ;?></p> <p class="main-img-ttl"><?php echo $result['title']; ?></p> <p class="main-img-caption"><?php echo $result['caption']; ?></p> </article> <footer class="footer">© 2019 Random Penguin</footer> </div> </body>結果ページで更新かけるとまたランダムに変わってしまったり、いろいろ改善すべき点はあるけども、
やりたいことはなんとなくできたのでオッケーとします。
- 投稿日:2019-12-11T21:33:45+09:00
Web x PHP TechCafe12月イベントレポート
PHP × Web Tech Cafe
『Web×PHP TechCafe』は、WebやPHPに関わるITエンジニアがスキルアップのために開発や勉強、LTをするコミュニティです。オフィスをスキルアップの場としてご提供します。
connpassのページはこちら
今回は PHP × Web Tech Cafe 12月の内容をまとめてお伝えします!!
今回のテーマ
PHP7.4の新機能をRFCを見ながら「何が嬉しいのか、どういう時に使うのか」などを参加者同士でお話しする。(パート2)
RFC
https://wiki.php.net/rfc#php_74
Migration
https://www.php.net/manual/en/migration74.php
前回の模様
https://qiita.com/Y-Kanoh/items/c6a5b2cd8ff18753c3f7
今日のディスカッション対象
Arrow functions
- アロー関数
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.arrow-functions
- https://wiki.php.net/rfc/arrow_functions_v2
場内意見
- 利用シーンとしては見た目がきれいになるという利点しかない
- JavaScriptでは2016年から利用されている書き方なので見た目としてよく見かけるコード体系になった
- シンプルになったように思う反面、明示的にUSEを書いた方がわかりやすいんじゃないか
- 外側のスコープの値を使いたい場合はわかりずらいような気がする
- アロー関数はユーザ一覧の配列から別の属性の値を持つユーザだけを突き合わせていく処理では使えると思う
- Javaなどではコールバックを使うことが多いので、他の言語の当たり前を取り入れていくのはいいかなと思う
Preload
- プリロード
- https://wiki.php.net/rfc/preload
- https://qiita.com/niisan-tokyo/items/ec4c918715d5ec754721
- 参考: PHP: OPcache - Manual
場内意見
- サーバを起動したときにOPEコードをキャッシュする
- 修正していたと思ったらキャッシュされていなかった等
- 再起動してたらうまくいくと思っていたらうまくいかなかったなど、慣れるまでは原因の切り分けが難しい
- 考慮ポイントが増えてしまうんじゃ?
- DBのキャッシュなどでも問題になりやすいのでトラブルの原因を増やしてしまいそう
- 変化に対応しづらそう
- JavaエンジニアとしてはPHPはファイルを差し替えるだけで動くから楽にできていいと思ってたがキャッシュ前提になるとPHPである意味とは・・・?
- 手軽さも残しつつケースバイケースで使えるようになれればいいかも
- 立ち上げに時間がかかりそう
- そこの影響を知りたい
- 必要な時だけ作っていらなくなったら捨てる、というシステムだと足を引っ張りそう
- 賛成多数の機能なのでこの機能を待っていた人は多いのではないか
- PHP8でJITが実装されたらもっと早くなりそう
Limited return type covariance and argument type contravariance
- 共変戻り値と反変パラメータ
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.type-variance
- https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
場内意見
- 継承しているクラスのオーバーライドしているメソッドで戻り値の型を変えることができる
- 反対する人がいないから可決されたんじゃないか
- 他の言語でできることをPHPでもできるようにするというモチベーションで追加された機能なんじゃないか
mb_str_split
- str_splitのマルチバイト対応版
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.mbstring
- https://wiki.php.net/rfc/mb_str_split
場内意見
- マルチバイト文字を特定の文字数で区切って配列に出力できる
- ファイル操作などで使えそうか
- そもそもデータを加工して登録していることの方が多いと思うので正直いらない
Allow exceptions from __toString
- __toStringが例外を投げられるようになった
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.tostring-exceptions
- https://wiki.php.net/rfc/tostring_exceptions
場内意見
- __toString内でExceptionを発生させることができる
- これまでできなかった理由はかなり複雑な背景があったそうな
- __toStringはログを出力する際によく使う
Unpacking inside arrays
- 配列内で別の配列をアンパックできるようになる
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.unpack-inside-array
- https://wiki.php.net/rfc/spread_operator_for_array
場内意見
- 配列の途中に配列を連結させることができる
- 人間にやさしい書き方になる
- CSVなど最初にヘッダ情報を書き、データを連結させるなどの方法で使えそう
- 投稿日:2019-12-11T21:33:45+09:00
Web x PHP TechCafe 2杯目 「PHP7.4の新機能を追う」
PHP × Web Tech Cafe
『Web×PHP TechCafe』は、WebやPHPに関わるITエンジニアがスキルアップのために開発や勉強、LTをするコミュニティです。オフィスをスキルアップの場としてご提供します。
connpassのページはこちら
今回は PHP × Web Tech Cafe 12月の内容をまとめてお伝えします!!
今回のテーマ
PHP7.4の新機能をRFCを見ながら「何が嬉しいのか、どういう時に使うのか」などを参加者同士でお話しする。(パート2)
RFC
https://wiki.php.net/rfc#php_74
Migration
https://www.php.net/manual/en/migration74.php
前回の模様
https://qiita.com/Y-Kanoh/items/c6a5b2cd8ff18753c3f7
今日のディスカッション対象
Arrow functions
- アロー関数
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.arrow-functions
- https://wiki.php.net/rfc/arrow_functions_v2
場内意見
- 利用シーンとしては見た目がきれいになるという利点しかない
- JavaScriptでは2016年から利用されている書き方なので見た目としてよく見かけるコード体系になった
- シンプルになったように思う反面、明示的にUSEを書いた方がわかりやすいんじゃないか
- 外側のスコープの値を使いたい場合はわかりずらいような気がする
- アロー関数はユーザ一覧の配列から別の属性の値を持つユーザだけを突き合わせていく処理では使えると思う
- Javaなどではコールバックを使うことが多いので、他の言語の当たり前を取り入れていくのはいいかなと思う
Preload
- プリロード
- https://wiki.php.net/rfc/preload
- https://qiita.com/niisan-tokyo/items/ec4c918715d5ec754721
- 参考: PHP: OPcache - Manual
場内意見
- サーバを起動したときにOPEコードをキャッシュする
- 修正していたと思ったらキャッシュされていなかった等
- 再起動してたらうまくいくと思っていたらうまくいかなかったなど、慣れるまでは原因の切り分けが難しい
- 考慮ポイントが増えてしまうんじゃ?
- DBのキャッシュなどでも問題になりやすいのでトラブルの原因を増やしてしまいそう
- 変化に対応しづらそう
- JavaエンジニアとしてはPHPはファイルを差し替えるだけで動くから楽にできていいと思ってたがキャッシュ前提になるとPHPである意味とは・・・?
- 手軽さも残しつつケースバイケースで使えるようになれればいいかも
- 立ち上げに時間がかかりそう
- そこの影響を知りたい
- 必要な時だけ作っていらなくなったら捨てる、というシステムだと足を引っ張りそう
- 賛成多数の機能なのでこの機能を待っていた人は多いのではないか
- PHP8でJITが実装されたらもっと早くなりそう
Limited return type covariance and argument type contravariance
- 共変戻り値と反変パラメータ
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.type-variance
- https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
場内意見
- 継承しているクラスのオーバーライドしているメソッドで戻り値の型を変えることができる
- 反対する人がいないから可決されたんじゃないか
- 他の言語でできることをPHPでもできるようにするというモチベーションで追加された機能なんじゃないか
mb_str_split
- str_splitのマルチバイト対応版
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.mbstring
- https://wiki.php.net/rfc/mb_str_split
場内意見
- マルチバイト文字を特定の文字数で区切って配列に出力できる
- ファイル操作などで使えそうか
- そもそもデータを加工して登録していることの方が多いと思うので正直いらない
Allow exceptions from __toString
- __toStringが例外を投げられるようになった
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.tostring-exceptions
- https://wiki.php.net/rfc/tostring_exceptions
場内意見
- __toString内でExceptionを発生させることができる
- これまでできなかった理由はかなり複雑な背景があったそうな
- __toStringはログを出力する際によく使う
Unpacking inside arrays
- 配列内で別の配列をアンパックできるようになる
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.unpack-inside-array
- https://wiki.php.net/rfc/spread_operator_for_array
場内意見
- 配列の途中に配列を連結させることができる
- 人間にやさしい書き方になる
- CSVなど最初にヘッダ情報を書き、データを連結させるなどの方法で使えそう
- 投稿日:2019-12-11T21:33:45+09:00
PHP7.4の新機能を'もっと'追う【Web x PHP TechCafe 2杯目】
PHP × Web Tech Cafe
『Web×PHP TechCafe』は、WebやPHPに関わるITエンジニアがスキルアップのために開発や勉強、LTをするコミュニティです。オフィスをスキルアップの場としてご提供します。
connpassのページはこちら
今回は PHP × Web Tech Cafe 12月の内容をまとめてお伝えします!!
今回のテーマ
PHP7.4の新機能をRFCを見ながら「何が嬉しいのか、どういう時に使うのか」などを参加者同士でお話しする。(パート2)
RFC
https://wiki.php.net/rfc#php_74
Migration
https://www.php.net/manual/en/migration74.php
前回の模様
https://qiita.com/Y-Kanoh/items/c6a5b2cd8ff18753c3f7
今日のディスカッション対象
Arrow functions
- アロー関数
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.arrow-functions
- https://wiki.php.net/rfc/arrow_functions_v2
場内意見
- 利用シーンとしては見た目がきれいになるという利点しかなさそう
- JavaScriptでは2016年から利用されている書き方なので見た目としてよく見かけるコード体系になった
- シンプルになったように思う反面、明示的にUSEを書いた方がわかりやすいんじゃないか
- 外側のスコープの値を使いたい場合はわかりずらいような気がする
- アロー関数はユーザ一覧の配列から別の属性の値を持つユーザだけを突き合わせていく処理では使えると思う
- JavaScriptではコールバックを使うことが多いので、他の言語の当たり前を取り入れていくのはいいかなと思う
Preload
- プリロード
- https://wiki.php.net/rfc/preload
- https://qiita.com/niisan-tokyo/items/ec4c918715d5ec754721
- 参考: PHP: OPcache - Manual
場内意見
- サーバを起動したときにopcodeをキャッシュする
- 修正していたと思ったらキャッシュされていなかった等ありそう
- 再起動してたらうまくいくと思っていたらうまくいかなかったなど、慣れるまでは原因の切り分けが難しい
- 考慮ポイントが増えてしまうんじゃ?
- DBのキャッシュなどでも問題になりやすいのでトラブルの原因を増やしてしまいそう
- 変化に対応しづらそう
- JavaエンジニアとしてはPHPはファイルを差し替えるだけで動くから楽にできていいと思ってたがキャッシュ前提になるとPHPである意味とは・・・?
- 手軽さも残しつつケースバイケースで使えるようになれればいいかも
- 立ち上げに時間がかかりそう
- そこの影響を知りたい
- 必要な時だけ作っていらなくなったら捨てる、というシステムだと足を引っ張りそう
- 賛成多数の機能なのでこの機能を待っていた人は多いのではないか
- PHP8でJITが実装されたらもっと早くなりそう
Limited return type covariance and argument type contravariance
- 共変戻り値と反変パラメータ
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.type-variance
- https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
場内意見
- 継承しているクラスのオーバーライドしているメソッドで戻り値の型を変えることができる
- 反対する人がいないから可決されたんじゃないか
- 他の言語でできることをPHPでもできるようにするというモチベーションで追加された機能なんじゃないか
mb_str_split
- str_splitのマルチバイト対応版
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.mbstring
- https://wiki.php.net/rfc/mb_str_split
場内意見
- マルチバイト文字を特定の文字数で区切って配列に出力できる
- ファイル操作などで使えそうか
- そもそも分割したいというシーンに出くわさないような仕様的にしているケースが多いと思うので正直いらないかも
Allow exceptions from __toString
- __toStringが例外を投げられるようになった
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.tostring-exceptions
- https://wiki.php.net/rfc/tostring_exceptions
場内意見
- __toString内でExceptionを発生させることができる
- これまでできなかった理由はかなり複雑な背景があったそうな
- __toStringはログを出力する際によく使う
Unpacking inside arrays
- 配列内で別の配列をアンパックできるようになる
- https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.unpack-inside-array
- https://wiki.php.net/rfc/spread_operator_for_array
場内意見
- 配列の途中に配列を連結させることができる
- 人間にやさしい書き方になる
- CSVなど最初にヘッダ情報を書き、データを連結させるなどの方法で使えそう
- 投稿日:2019-12-11T20:09:19+09:00
PHPカンファレンスレポート:オニギリペイのセキュリティ事故に学ぶ安全なサービスの構築法
前提
PHPカンファレンスに参加してきたので、
セッションを聞いた感想というかレポート記事になります。
その他の記事は ここにあります。この記事はオニギリペイのセキュリティ事故に学ぶ安全なサービスの構築法について記載します。
このセッションの概要
オニギリペイという架空のバーコード決済サービスのセキュリティ事故事例から、
安全なサービスの構築法をお話しいただきました。オニギリペイで発生した試練
1.21%キャンペーンで景品表示法違反に引っかかった
2.ログインIDを発番したが、不正ログインが多発した
3.二段階認証を強制したのに不正ログインが止まらない
4.ヘルプデスクへのパスワード再発行で変更後のパスワードを電話口で伝えてしまった
5.開発ベンダーがパスワードを平文で設置していた
6.iOS版にAndroidの情報が含まれていたため、App storeから削除された
7.OSコマンドインジェクションで不正アクセスされた
8.WAFを導入した結果SSRF脆弱性が発生していた※各詳細はスライドがありますので以下からご確認ください。
オニギリペイのセキュリティ事故に学ぶ安全なサービスの構築法各プロセスでの検討内容とインシデント例
プロセス 検討内容 インシデント例 サービス企画 法律、各種ガイドライン、業界慣行への準拠 試練1 プラットフォーム設計 プラットフォーム固有の問題 試練8 業務設計 業務上の脆弱性 試練4 機能仕様 機能上の脆弱性、デベロッパー規約 試練2、試練6 実装設計 実装設計上の脆弱性 試練3、試練5 プログラミング プログラミング上の脆弱性 試練7 自分はWebアプリケーションの運用・保守をメインで行っているため、
サービス企画や業務設計の部分でのインシデント例はあまり考えたことがなかったです。
ただ、新規サービスに携わりたいと考えてもいるため、
上記のことも考慮する必要があるのだと気付かされました。とはいえ、何を考えればいいのかがわからないのですが、
以下の書籍が参考になるとのことでした。リスクアセスメントの方法
リスクアセスメントについてWikiより。
リスクアセスメント(英: Risk assessment)とは、リスク特定、リスク分析、リスク評価を網羅するプロセス全体を指す [1] [2] [3] [4] [5] 。
リスク特定 (risk identification) - リスクを発見し、認識し、記述するプロセス
リスク分析 (risk analysis) - リスクの特質を理解し、リスクレベルを決定するプロセス
リスク評価 (risk evaluation) - リスク(とその大きさ)が受容可能か(許容可能か)を決定するためにリスク分析の結果をリスク基準と比較するプロセス徳丸さんいわく上記の方法論について以下の方法論があるとのこと。
1.ベースラインアプローチ
既存の標準や基準を元にベースライン(自組織の対策基準)を策定し、チェックしていく。
徳丸本を基準にするなど。
2.非形式的アプローチ
コンサルタントまたは組織や担当者の経験、判断により実施
3.詳細リスク分析
情報試算に対し「資産価値」「脅威」「脆弱性」「セキュリティ要件」を識別し、リスクを評価
4.組み合わせアプローチ
上記いずれか複数のアプローチを併用する。また、その他の具体的な方法としては、
概要レベルの業務フローチャートを記載し、各箇所に「ツッコミ」を入れていく。
その「ツッコミ」をもとに業務レベルの脅威分析表としてまとめるなど。発注がセキュリティを左右する
インシデント例でいう実装設計にあたりますが、
ベンダーを選定する際は発注がセキュリティを左右します。
RFP(提案仕様書)がシステムの大枠・概略予算となるため、RFPの段階ではセキュリティが明確になっている必要があります。
また、発注者が提案書の内容に関与できるのはRFPだけでもあります。例えば脆弱性に関しては、
○○などと記載するのではなく、
別紙で一覧を設けるといった方法を取る必要がある。分析を具体的にすすめるには?
IPAのIot開発におけるセキュリティ設計の手引がよくまとまっているので、
参考になる。
Iot開発におけるセキュリティ設計の手引おわり
抽象論だけではなく、
具体的な方法論にまで落とし込まれていて大変わかりやすかったです。改めてセキュリティ周りに関しては考慮すべきことが膨大すぎるなと思うのですが、
そう考えるのは自分だけでなく、
ある程度体系的にまとめられたものもあるので、
そういったものを参考に進めるのが一旦はいいのかなと感じました。ベースラインだけですべてをまかなえるわけはないので、
自分でも知識をつけることは重要ですね。
徳丸本読み切れてないけど、
徳丸試験(Webセキュリティ試験)受けるのもありですね。
- 投稿日:2019-12-11T19:09:12+09:00
PHPカンファレンスレポート:PHPerのためのテストコード入門
前提
PHPカンファレンスに参加してきたので、
セッションを聞いた感想というかレポート記事になります。
その他の記事は ここにあります。この記事はPHPerのためのテストコード入門について記載します。
はじめに
テストコードの具体的な導入方法などではなく、
そもそもなんでテストコードって必要なんだっけと言った
そもそもの話をしていただきました。テストの目的
そもそものテストの目的です。
・品質を可視化すること
・ソフトウェアのどの品質を高めるか、判断するための材料を提供すること
の2つ。品質を可視化すること
品質という言葉はあいまいで見えずらい。
品質が守られているかどうかをテストを持って可視化することができます。ただし、ソフトウェアテストだけでは品質を高められない。
品質を高めるためにはバグの修正が必要だからです。
そのため、あくまで品質の保証です。ソフトウェアのどの品質を高めるか、判断するための材料を提供すること
バグの発見数とバグの内容から、次に品質を高めるべき箇所を判断したり、
リリース判定においてバグの発見数からをリリース可否の判断を行うなど。テストコードの目的
品質と開発スピードを両立することです。
テストの7原則
ソフトウェアテストには7つの原則があります。
1.テストは「欠陥がある」ことしか示せない
2.全数テストは不可能
3.初期テスト
4.欠陥の偏在
5.殺虫剤のパラドックス
6.テストは条件次第
7.「バグゼロ」の落とし穴上記のうち、
初期テストにもあるとおり、
バグは早期発見できればできるほど影響範囲が少なくなります。
リリース後であれば、関係部門への連絡・緊急リリース・恒久対応といった対応が必要となりますが、
同じミスが単体テスト時に発見できれば、コードを1行直すだけで済むかもしれません。
上記を考慮し、テスト工程を前倒すことをシフトレフトといいます。では、シフトレフトはテストコードというだけで実現可能なのかという点で、
手動テストとテストコードを比較してみます。手動テストとテストコード
手動 テストコード タイミング 実装が終わったタイミングでみんなでテスト コマンド一発で終わるので、手動テストよりも早いタイミングで実行できる 正確さ ヒューマンエラーが起きる可能性 コードさえあっていれば何度実行しても同じ結果が実行できる 比べるまでもないですが、
バグの修正工数を減らしながら確実にテストを行うことができる。
よって品質と開発スピードを両立することが可能。ただし、テストコードでは導入・メンテナンスコストが発生するので、
必ずしもテストコードが圧勝というわけではない。(手動テストでしかチェックできないテストもある)様々なテストコードを知る
ユニットテスト
1つの関数やメソッドに対して、
I/Oを通して使用通りの挙動をしているか検証する。
※PHPUnitなどを使用テストコードを使って、
入力値とそれに伴う出力値が期待値と比べてどうなのかをテストすることになります。結合、統合テスト
featureテスト、APIテスト。
特定のリクエストを投げて、レスポンスされた内容が正しいかどうかを検証する。
※PHPUnitなどを使用UIテスト
E2Eテスト。
ブラウザ上でclassやidを指定して自動操作をし、期待通りの動作をしているか検証する。
※PHPUnitやPHP-WebDriver、Seleniumなどユニットテストに近いほうが、
テストをしている範囲が狭く、原因の特定もしやすい。
そのため、できる限りユニットテストでカバーしていくことが合理的である。
どのテストをどれくらい書くかはテストピラミッドを参考にすべし。おわり
テストコードを書いたことがないため、
学習コストから敬遠気味でしたが、
品質の可視化というのはまったくもってそのとおりだなと感じました。プルリク前に本当に大丈夫だよなーとか何度も確認して、
結局どっかがミスってるとかの無駄な時間を削減できると考えて重い腰を上げる必要がありそうです。
また、まずは人が書いたコードでテストをやってみるというところから初めて、
エラーが出たらなぜ出たのかということから学んでいこうと思います。
- 投稿日:2019-12-11T19:03:07+09:00
Webサービス(CtoC)集客・マネタイズ成功させたければこれを実装しろ
はじめまして。加藤です。
本業はインフラエンジニアですが、技術書典で技術系同人誌を頒布したりWebサービスを個人開発したりしています。さて、突然ですが、あなたはWebサービスを個人開発して公開していますか。
そして「せっかく開発したのに誰も利用してくれない」「マネタイズ(収益化)したいが上手くいかない」といった悩みを抱えていないでしょうか。
PythonやRuby、PHPなどの言語やそれらのフレームワークを使ってWebサービスを個人開発し、Firebaseなどで公開する人たちは年々増えており、彼らと話す機会も多いので、そういった声をよく聞きます。
私はそれを聞くたびに心の中で「そりゃ当たり前だ!あんなクソサービス誰も使わないわ。」と叫んでいます。
脳内妄想をこじらせた技術オタクがゴミを生む
私を含めて、Webサービスを個人開発している人たちの大多数がしている会話は「○○の言語と△△のフレームワークを使って開発しました~~」とか「Firebaseを使って~~」「フロントエンドは□□で~~」みたいにどんな技術を用いて開発したかを語るものばかりです。
「お前ら、マネタイズがしたいんだよね?マーケティングの話とかしないの?」
「素晴らしいサービス(自称)だから黙っていれば利用者が増えてスケールすると思ってない?」
「口ではマネタイズに困っているとか言いながら、そのための行動も勉強もしてないじゃん。」と感じるようになって、私は自然と彼らと距離を置くようになりました。
自戒を込めて言うと、世の中には業務改善に役立った素晴らしいサービス(この伝票開発アプリとか)やマシュマロ(質問箱)のように多く人が利用したサービスもありますが、大多数は技術者が「面白いサービスを思いついた。こりゃ流行るぞ!」とか「この人たちはきっとこれに悩んでいるから、こういったサービスなら課題解決できるに違いない」と自分の脳内妄想を実現させた結果生みだしたゴミなので過疎って終了するわけです。
「金稼ぎ」や「欲求充足」ができる仕組みを実装しろ
では、どうしたら利用者が増えるサービス開発ができて、その結果マネタイズが成功するのか。
これを研究してきた私がたどり着いたのが、利用者が「金稼ぎ」と「欲求充足」ができる機能を実装したサービスを作れでした。
その証拠にYoutuberが雨後の筍のように増えていますし、ニコ生主等が続々とVTuberに転生してYouTubeやMirrativ等で配信していますし、小説家になろうでは書籍化を目指して多くの作家が小説公開していて、絵師や同人漫画家がTwitterやPixivでイラスト・マンガを投稿して、いまだ多くのブロガーが無料ブログやWordPressで記事を投稿しています。
みんな本音を言えば「(広告収入・投げ銭・書籍化・マンガ化等で)大金を稼ぎたい」し「承認欲求を満たしたい」から、それらのサービスを使ってせっせと活動しているんです。
※好きでやっている勢もいるでしょうが、なぜ1円にもならないのにPVや再生数が伸びなくてもクソリプやアンチコメが来ても作品・動画の投稿が続けられるかといったら、ここに集約されます。そして、それらの実装のために参考になるWebサービスが無料小説投稿サイトです。
詳細は後述しますが、収益還元の仕組みや作家・ユーザー相互の交流機能により「金稼ぎ」と「欲求充足」がどちらもできるからですね。
あなたが手っ取り早く集客やマネタイズに成功するWebサービスが作りたいのなら「大金がほしい」「注目されたい、ちやほやされたい、モテたい」といった人間が普遍的に持つ欲を(法律に抵触しない範囲で)利用者が満たせるものを開発してはいかがでしょうか。
※あなた自身が欲望に忠実になり闇落ちすると、悪質アフィリエイターやSEOを悪用したWELQ中の人のような存在になるので、健全な精神状態と倫理観は維持しましょう。
金稼ぎとは
ここでは投稿した作品に対する収益還元や作家への投げ銭が得られるサービスを紹介します。
これ以外にも、自分の小説やイラストを販売できるBOOTHのようなサービス、Youtubeのスーパーチャット・メンバーシップやFANBOXのようなクリエイター支援や投げ銭のサービスでもお金が稼げますので、サービス設計の参考にしてはいかがでしょうか。
Webサービス運営者は単発の課金であれ月額課金であれ自分の金もうけ(いかに無課金勢に課金させるか)第一で会議でも金や数字(KPIなど)の話しかしない人種なくせに、やれ「カスタマーエクスペリエンス」だとか「カスタマーサクセス」だとかぬかしおるのであほかと思います。
「利用者に収益を還元する」とか「生み出した作品の対価が得られる仕組みを提供する」とか、利用者にメリットがある仕組みの構築(+その結果としてのマネタイズ)ができてはじめてカスタマーについて語る資格があるのではないでしょうか。
広告収益の分配
作品のPVや閲覧人数などに応じて広告収益が分配される仕組みです。
Peing(質問箱)開発者のSeseriさんが作った小説投稿サイト「scraiv」がこの仕組みを導入しています。
他にもアルファポリス、カクヨム、ノベルバなどが同じ仕組みを導入していますね。広告収入の分配といっても、作家の作品内にある広告リンクがGoogleアドセンスのようにクリックされたり、アフィリエイトのように商品が購入されたりすることで分配されるわけではありません。
それぞれのサービスで広告収益分配の基準は異なりますが、純粋に作品が読まれるほど収益が増える仕組みとなっています。
予約投稿を課金で先読み
読者が課金することで、作家が予約投稿した最新話を公開日前に読める仕組みを導入し、課金額の40%を作家に還元しています。
※最新話を無料で読みたいときは公開日まで待てばOK。
これを導入しているのは待ラノだけですね。
利用者による投げ銭
Youtubeのスーパーチャットのように、作者に対して読者が投げ銭を行える仕組みです。
投げ銭機能はノベルアッププラスやマグネットマクロリンク、カクヨムなどが実装しています。
コンテストの開催
優秀な作品は賞金がもらえたり書籍化したりといった特典があるWebコンテストをサイト内で開催し、作家がそれに応募できるようにする仕組みです。
カクヨムやアルファポリス、エブリスタなどがWebコンテストを定期的に開催しています。
欲求充足とは
ここからはマズローの欲求5段階説を用いて説明します。
詳しく知りたい方はfelletさんの下記記事をご覧ください。
マズローの欲求5段階説を図付きで解説!各段階に合わせたサービスも紹介そして「金稼ぎ」で説明した仕組みは小説投稿サイトでいう作家向けのものですが、欲求充足に関しては作家と読者双方の欲求(承認欲求とか作家・読者と繋がりたい欲求とかコミュニティに所属したい欲求など)を満たす仕組みとなっています。
そうしないと、金と欲を満たしたい作家しかおらず読者がいないという地獄のようなサービス(どれだけ作品投稿しようがPVもブックマークも感想も増えない)と化してしまうからです。
社会的欲求を満たす
集団への帰属や愛情を求める欲求です。
コミュニティへの所属や人とのつながりなどが得られることで満たされます。これを満たす機能として、ノベルデイズのコラボノベル(他のユーザーと共同で作品を作る)機能やエブリスタのコミュニティ機能などが挙げられます。
また、ハーメルンには「捜索掲示板」という機能があり、自分が探している作品について質問すると他の利用者が返信で教えてくれるので、そこで作品について盛り上がることができます。
承認欲求を満たす
他人から尊敬されたい、認められたい、賞賛されたいという欲求です。
具体的には作品を読まれたい、読者に応援されたいなどです。マグネットマクロリンクでは読者が作品を読んだり、作家が創作活動をすることによって自動的に「磁界」というポイントが貯まります。
作家は自分が獲得した磁界(ポイント)と読者からプレゼントされた磁界(ポイント)を消費することで、サイト内で自分の作品を宣伝することができます。ノベルアッププラスでは、ログインするともらえるポイントを作家にプレゼントしたり、感想コメントや感想スタンプを送るなどで作家・作品を応援する仕組みがあります。
また、豊富なランキングやピックアップがあり、自分の作品が露出する機会が多いことも重要です。
例えばノベルアッププラスには新着作品・注目作品・読者のオススメ作品などのピックアップがありますし、ハーメルンには総合・短編・オリジナル(作品)・二次創作・R18など複数のランキングがあります。カクヨムでは特集(カクヨム公式レビュアーが選んだ作品を紹介する記事)や各ジャンルの作品のピックアップが公開されており、多くの作品に日があたりやすくなっています。
自己実現欲求を満たす
自分の可能性を追求し、技術や能力の向上に努めて作家としての自分の理想像を実現したいという欲求です。
ツギクルには「人工知能を用いた文章解析システム」があり、AIが客観的に作品の分析をしてくれます。
また、ノベルアッププラスでは小説を投稿する、小説を読む、感想を書き込むなどにより自分のアカウントのレベルや称号がアップしていきます。
一番の悪手は「運営が多数の利用者を置き去りにして全力で金儲けしだすこと」
今回ご紹介した方法が正解ではありません。
多くの利用者を獲得する方法が他にもありますし、そこを研究していただけたらと思います。
ただし、「絶対にWebサービス運営者がやってはならない悪手」が存在します。
それは一部の利用者のみ優遇するや運営の商品・広告を推しすぎることです。
一部の利用者のみ優遇するとは、小説投稿サイトで例えると「PVが稼げる作家の作品バナーをトップページの目立つ場所に掲載したり、書籍化のバックアップや(公式ブログ等で)販促支援を行う」「運営を通じてお仕事がもらえる」「PVが稼げる作家との打ち合わせと称して高級なご飯を奢る」などの運営が不自然なまでに特定利用者を推していたり癒着している状況を指します。
※実際に小説投稿サイト運営がこれらを行っていると言うわけではありません。運営の商品・広告を推しすぎるとは、小説投稿サイトで例えると「トップページなどが書籍の広告などで溢れかえっていて利用者が使いづらい」状況です。
※アルファポリスがこの傾向にあります。利用者が報われる仕組み、飽きさせない仕組みを作れ
報われる仕組みとは
また、悪手というよりは過疎らないためにやっておいた方がベターなのが「利用者が注目される機会をなるべく平等に与える」「利用者の努力が報われる」サービス設計をする事です。
小説投稿サイトで例えると、既存のランキング(PVやブックマークに基づくもの)だけでなく、活動歴が浅い作家のみのランキングや細かくジャンルわけしたランキングを用意したり、活動歴が長い作家の作品やニッチなジャンルでPVは高くないものの濃いファンがついている作品等を運営がピックアップして紹介するなどです。
ぶっちゃけると、小説投稿サイトもYoutubeもはてなブログも、何らかのコンテンツを投稿するプラットフォームのランキングっていうのは
ランキング上位勢がランキングにのることによってさらにPVやブクマを稼いでランキングにのり続けているのが現状です
そしてそんな状況で並み居る古参上位勢を押しのけてランキング上位に食い込めるのは「強力な個性や才能の持ち主」か「元々大多数のファンを抱えている人間(芸能人や他の小説サイトで固定ファンを抱えた作家など)」か「箱推しされている事務所に所属したり動画再生数や配信の同時接続人数が稼げる人とコラボする(VTuberのにじさんじやホロライブなど)」くらいです。
※お金や互助会の力で何とかしようとする人もいますが、それは多くのサービスで利用規約違反になるので割愛。
きっと、商業出版を果たしたつよつよ作家や自称有識者の読者は「ランキング出来ない人間の努力が足りないからだ。才能がないからだ。」と言うでしょう。
登録者10万人越えのYoutuber・VTuberもオンラインサロンを開いちゃうようなはてなブロガーも「そうだそうだ」と賛同するでしょう。※その格差があるからこそアフィリエイトの情報商材やサロン、コンサル、事務所(○○ネットワークとか)に金を払う人が出てくるわけです。
それは利用者目線で言えば正しい事なのかもしれませんが、Webサービスの運営側としては、努力(作品のコンセプトを工夫する、毎日投稿する、コメント返しするなど)を続けてもランキング入りできず離脱する作家が増えて過疎化するリスクのケアを考えなければいけません。
あなたのWebサービスが世界でオンリーワンのものでないのなら、作家たちは競合他社の類似サービスに移っていくからです。
飽きさせない仕組みとは
そして、代わり映えしない作品(所謂なろう系の異世界転生ものとか)や作家で埋め尽くされたランキングに飽きて離脱する読者もケアしないと、作家と同様に競合他社の類似サービスに移っていかれます。
これへのケアも報われる仕組みと同じく、既存のものとは違うランキングの創設やピックアップで作品を掘り起こす仕組みが必要となります。
- 投稿日:2019-12-11T18:42:36+09:00
PHPで配列に要素を追加する方法に関するメモ ($hoge[] = ...; の挙動)
コード
<?php $hoge[] = "a"; $hoge[] = "b"; $hoge[] = "c"; var_dump($hoge); ?>出力結果
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" }配列用の変数に配列じゃないものを代入するという変な書き方に見える。PHPの配列の実体は連想配列で
$hoge[] = ...;
はキー名を省略した形と見えるから、その点から見れば自然な文法かな。
- 投稿日:2019-12-11T17:21:07+09:00
PHPでslackにメッセージを送ってみる
通知をまとめたいと思った
バックグラウンドで動いているPHPの実行通知がメールだったり、ツールの管理画面だったりといろんなところに散らばっているので、どっか簡単に見れるところにまとめたい考えた。
slackを使っているのでそのチャンネルに送れば手軽にチェックできるのでは?と思いやってみた。準備するもの
php
curl
slackのチャンネル
php内でcurlが動作さえすればphpのバージョンは問わず。実装してみる
①slack appを検索する
slack内でappから「Incoming Webhook」を検索する。
「appディレクトリで確認する」ボタンを押してアプリのページに移動。
②「Incoming Webhook」を追加する
チャンネルを選択して「Incoming Webhookインテグレーションの追加」ボタンを押す。
③「Incoming Webhook」の設定ページ
アプリ登録後、投稿用のurlやサンプルが表示されます。
基本このサンプルに沿って実装するだけで簡単にできました。
④PHPを書く
1.まずは一番簡単な形で送信してみる。
設定画面に表示されたWebhook URLにPOSTリクエストでpayloadパラメーターをJSON形式で送信すればよいらしい。$url = 「設定画面に表示されたWebhook URL」 $message = [ "channel" => "#チャンネル名", "text" => "これはテストです", ]; $ch = curl_init(); $options = [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'payload' => json_encode($message) ]) ]; curl_setopt_array($ch, $options); curl_exec($ch); curl_close($ch);3.少し凝ってみる
デフォルトIncoming Webhookからのユーザー名や画像のなどの変更も可能。$message = [ 'channel' => '#チャンネル名', 'username' => 'System', 'icon_emoji' => ':eyes:', 'text' => 'これはテストです', ];4..もっと凝ってみる
attachmentsを追加してその下に配列としてメッセージ添付ファイルを設定することができる。$message = [ 'channel' => '#チャンネル名', 'username' => 'System', 'text' => 'これはテストです', 'attachments' => [ [ 'text' => '結果OK', 'color' => 'good', 'fields' => [ [ 'title' => 'xxxx', 'value' => 'xxxx01', ], [ 'title' => 'xxxx', 'value' => 'xxxx02', ] ] ], [ 'text' => '要チェック', 'color' => 'warning', 'fields' => [ [ 'title' => 'xxxx', 'value' => 'xxxx03', ], ] ], [ 'text' => '結果NG', 'color' => 'danger', 'fields' => [ [ 'title' => 'xxxx', 'value' => 'xxxx04', ] ] ] ] ];使ってみた感想
Incoming Webhookのページが親切。
attachmentsを使用することで引用の色を変えたり、複数の値をリストで送れるので通知にはもってこいだとおもう。
- 投稿日:2019-12-11T16:13:10+09:00
PHPカンファレンスレポート:MVCにおける「モデル」とはなにか
前提
PHPカンファレンスに参加してきたので、
トークを聞いた感想というかレポート記事になります。
その他の記事は ここにあります。MVCにおける「モデル」とはなにか
個人的には聞いていて最も面白かったのがこれです。
内容としてはかなり難しく、聞いていてかなり疲れたのですが、、、具体的にこういうものがモデルだよって話というよりは、
かなり抽象度の高い哲学的な話にも聞こえてきたので、すごく面白かったです。話の展開としては、
・ドメインモデルは個人を束縛する
・メンタルモデルは個人が世界に抱く内面的なモデル
・パーソナルコンピュータは社会と個人の関係を変えようとした
という前提があったうえで、
MVCモデルに対する説明がなされます。
前提部分から順を追ってレポートしてまいります。ドメインモデルは個人を束縛する
ドメイン駆動開発などを聞いたことがない人は、ドメインと聞くとURLの話?となりそうですが、
ここでは異なる文脈となります。
天重さんのセッションの中では「問題領域(ドメイン)= ビジネス/目的 」という言葉で説明されています。そもそもソフトウェア開発をする目的は何かしらの問題/課題を解決するためにあります。
この解決したい問題/課題そのものがドメインであり、
問題/課題を解決する手段/システムをドメインモデルといいます。例えば、天重さんが例題でも仰られていた飲食店でいうと、
・顧客が食べたいものを出す
・利益を上げる
といったことが目的であり、・料理を出す
・顧客から注文を取る
・注文伝票による情報伝達
といったことが手段となります。そういう意味ではドメインモデル(手段)が個人の行動を決める(束縛する)というのは、
非常に理解できる内容かと思います。メンタルモデルは個人が世界に抱く内面的なモデル
メンタルモデル(英: mental model)とは、頭の中にある「ああなったらこうなる」といった「行動のイメージ」を表現したものである[1]。
これも言わんとする事はなんとなくわかります。
ボールペンをかちっとしたら芯が出てくるとか、
ペットボトルのキャップを左回りでひねったら蓋があくとか、
説明なしにイメージできるようなものだと解釈できます。このような適切なメンタルモデルを構成するためには、
・可視性
・よい概念モデル
・よい対応付け
・フィードバック
が重要となります。
日常の生活のなかで、ボールペンをかちっとすると芯が出てくるというイメージを持ちながら、
実際にボールペンを触ってみるとそうなる(フィードバック)や、
押したら別のところが出るという対応付けなどなどが該当するのかなと思います。一方で、
コンピュータに目を向けると、
何をやっているかがわかりにくいので、間接的なものであり、
メンタルモデルを構築するのが難しいものです。
特に非エンジニアなどであればあるボタンを押すとよくわからないけど、
結果が出力されるといったケースは往々にしてあります。(非エンジニア時代の懐古)そのため、コンピュータに必要なのは、コンピュータを操作しているのではなく、
コンピュータを通して行っている作業そのものに取り組んでいるとユーザーに感じさせることです。
そういった錯覚のことをユーザーイリュージョンといいます。天重さんの例としても出ておりましたが、
よいユーザーイリュージョンが発揮されているソフトウェアの1つにEXCELがあります。
A1+A2の結果がC1 に出力されるといった可視性や、
その場でエラーが変えるフィードバックといった部分が適切であり、
コンピュータを操作しているというよりは表計算をしているという
作業そのものに集中することができます。パーソナルコンピュータは社会と個人の関係を変えようとした。
1984年のマッキントッシュのCMが代表するように、
パーソナルコンピュータは社会から個人を解放することを目的として作られているとのことでした。
また、それを達成するためにはコンピュータにコントロールされるのではなく、
自分たちが制御可能な言語で作られている必要があります。MVCについて
ここまでで以下の点を記載してきました。(発表から抜粋)
・ドメインモデルは情報システムがもつモデル
社会的システムとして個人を束縛する。
・メンタルモデルは個人が世界に抱く内面的なモデル。
メンタルモデルを形成するためには良い道具が必要、特にコンピュータにあってはユーザーイリュージョンが重要。
・パーソナルコンピュータは社会と個人の関係を変えようとした。
自分の力でシステムを書き換えられることが重要だった。
そのためにはコンピュータの言語を個人が理解できなければならない。上記の前提の上MVCとはの話に移ります。
基本的なエコシステムの中では、
各個人がパーソナルコンピューターを通して、
何かしらの情報システム(ドメインモデル)にアクセスをします。
情報システムが掴みずらければAmazonなどのソフトウェアサービスを思い浮かべてください。
各個人のパーソナルコンピュータからAmazonにアクセスしているイメージです。ここで問題となるのは、
この情報システムと個人の間にギャップが生じている点です。
例えば、Amazonが(情報システム)が使いづらいなど。。これは先程のメンタルモデルが形成されていない状態であり、
メンタルモデルが形成されていなければ、
情報システム(ドメインモデル)が持つ本来の目的である
問題/課題を解決する手段/システムものとしての役割を果たせていません。そうならないように、
メンタルモデルを形成してあげる必要がありますが、
そのためには各個人が操作可能なようにツールとモデリング言語を導入する必要があります。
このツールはMVCモデルにおけるViewとControllerにあたります。仕事の対象がそこに見えていて、
それに対して行えるアクションが見えていて、
その結果の状態が常に見えるようになっていれば、
ユーザーはその道具を使ってできること、
その道具の役割を自ら発見し、妥当性を感じながら仕事を組み立てることができます。
そのような仕事は楽しいものです。つまり、ツール(View,Controller)を通して、
ユーザーがドメイン(目的)の情報を直接操作しているように感じさせることが、
MVCモデルとしては重要となります。おわりに
天重さんから最後の一言は、
「そのデザインは、いったい誰に力を与えるものなのか」
でした。私自身もエンジニアとして働き始めるまえから、
特に組織においては人の行動は仕組みで決まるなーとうっすらと考えていたので、
今回のセッションを聞いて、
より具体的な方法に近づいたのかなと思いました。考えられていないMVCでは個人のメンタルモデルとの乖離が発生し、
ユーザーは提供者の思惑とは異なる動きをするようになると思いますし、
それを防ぐためにはユーザーのメンタルモデルを考慮し、
メンタルモデル通りにモデルを動かせるようにツール(View,Controller)を設計する必要があると
現時点では感じました。とはいえ自分の知識量ではさらに深い話へと持っていけないというのも事実であるので、
ドメイン駆動開発など少し学んでみようかなーという気になりました。参考
- 投稿日:2019-12-11T14:43:11+09:00
【初心者】phpで動作するプログラムをPythonで書くとどうなりますか?
phpでLINE botを作成しました。チャットに入力された文字がデバッグとして該当txtに入力されるだけの仕組みです。
これをPythonで代替して作る場合のコードが分からず困っています。
以下はphpで実際に動作したコードになります。
<?php
//(1)ログファイルの指定
define('DEBUG','../debug.txt');//(2)リクエストの取得
$input=file_get_contents('php://input');//(3)ログファイルの出力
file_put_contents(DEBUG,$input):これをPythonで代替するとどのようなコードになりますでしょうか?初歩的な事と理解出来ますが恥を承知でご教示頂ければと思います。
requestsを使うんだろうなぁ…というあたりまではつけれるのですが…何卒よろしくお願いします。
- 投稿日:2019-12-11T14:18:22+09:00
PHPメモ: foreachでオブジェクトの配列を回したい時
シンプルなオブジェクト配列
// 動物クラス class Animal { private string $name; // 名前 public function __construct($name) { $this->name = $name; } public function getName() : string { return $this->name; } } // インスタンス化し、配列に格納 $animals[] = new Animal('cat'); $animals[] = new Animal('dog'); $animals[] = new Animal('tanuki'); // 全ての動物の名前を出力する関数 function echoAnimalNames(array $animals) { foreach ($animals as $animal) { echo $animal->getName(), PHP_EOL; } var_dump($animals); } // 実行 echoAnimalNames($animals); // cat // dog // tanuki // array(3) { // [0]=> // object(Animal)#1 (1) { // ["name":"Animal":private]=> // string(3) "cat" // } // [1]=> // object(Animal)#2 (1) { // ["name":"Animal":private]=> // string(3) "dog" // } // [2]=> // object(Animal)#3 (1) { // ["name":"Animal":private]=> // string(6) "tanuki" // } // }シンプルなオブジェクト配列の問題点
- 型の保証がない
- 配列にインスタンスを追加する時にコードの方で型を保証しても、関数の引数には単なる配列として渡すことになるので型宣言できない
- IDEも判別してくれないので自動補完が使えない
オブジェクト(疑似)配列クラス
// 動物オブジェクト疑似配列クラス ⭐ class AnimalArray { // 動的にプロパティを追加するマジックメソッド public function __set(string $name, Animal $animal) { $this->$name = $animal; } } class Animal { private string $name; public function __construct($name) { $this->name = $name; } public function getName() : string { return $this->name; } } // インスタンス化し、疑似配列オブジェクトに格納 $animals = new AnimalArray(); // ⭐ $animals->cat = new Animal('cat'); // ⭐ $animals->dog = new Animal('dog'); // ⭐ $animals->tanuki = new Animal('tanuki'); // ⭐ function echoAnimalNames(AnimalArray $animals) { foreach ($animals as $animal) { echo $animal->getName(), PHP_EOL; } var_dump($animals); } echoAnimalNames($animals); // cat // dog // tanuki // object(AnimalArray)#1 (3) { // ["cat"]=> // object(Animal)#2 (1) { // ["name":"Animal":private]=> // string(3) "cat" // } // ["dog"]=> // object(Animal)#3 (1) { // ["name":"Animal":private]=> // string(3) "dog" // } // ["tanuki"]=> // object(Animal)#4 (1) { // ["name":"Animal":private]=> // string(6) "tanuki" // } // }良い点
- 型が(疑似)配列の内部で保証されている
- 関数の引数にも(疑似)配列クラスを型宣言して渡せる
微妙な点
- 全ての配列要素にプロパティ名を設定する必要があるのが面倒
- プロパティ名に数字は使えないので、
for
文では回せないと思われforeach
の中で使われるvalue
の型はIDEには相変わらず判別できないので、自動補完は使えないままどうにか自動補完させたかった
class AnimalArray { public function __set(string $name, Animal $animal) { $this->$name = $animal; } } class Animal { private string $name; public function __construct($name) { $this->name = $name; } public function getName() : string { return $this->name; } } $animals = new AnimalArray(); $animals->cat = new Animal('cat'); $animals->dog = new Animal('dog'); $animals->tanuki = new Animal('tanuki'); function echoAnimalNames(AnimalArray $animals) { // Animal型を引数とする無名関数を宣言 ⭐ $name = function (Animal $animal) { return $animal->getName(); }; foreach ($animals as $animal) { echo $name($animal), PHP_EOL; } var_dump($animals); } echoAnimalNames($animals);
- ちょっと無理やりですよね‥‥‥良い方法があったら知りたいです
- 投稿日:2019-12-11T13:20:51+09:00
【VScode】設定と拡張機能でPHP開発用に便利なやつ
環境
windows 10
Visual Stadio Code 1.40.2内容
社内開発用と自宅開発用のVScodeを同期する方法とかあるのかな?
とりあえず方法を知らないので自分の環境を晒して自力で同じ状態にするSettings
File→Preferences→Settings→右上のOpen Settings(JSON)をクリック
settings.json{ "editor.fontSize": 11, "editor.renderWhitespace": "boundary", "php.validate.executablePath": "C:\\php-7.3.11\\php.exe", "php.validate.run": "onType", "workbench.iconTheme": "material-icon-theme", "window.zoomLevel": 0, "diffEditor.ignoreTrimWhitespace": false, "editor.suggestSelection": "first", "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue", "workbench.startupEditor": "newUntitledFile", "terminal.integrated.fontFamily": "monospace", "editor.cursorBlinking": "smooth", "editor.fontFamily": "'Fira Code','Meiryo UI'", "editor.fontLigatures": true, "terminal.integrated.rendererType": "dom", "files.eol": "\n", "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "php.suggest.basic": false }↑の説明.json"editor.fontSize": 11, "editor.renderWhitespace": "boundary", "php.validate.executablePath": "C:\\php-7.3.11\\php.exe", "php.validate.run": "onType", "workbench.iconTheme": "material-icon-theme", "window.zoomLevel": 0, "diffEditor.ignoreTrimWhitespace": false, "editor.suggestSelection": "first", "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue", "workbench.startupEditor": "newUntitledFile", "terminal.integrated.fontFamily": "monospace", "editor.cursorBlinking": "smooth", // プログラミング用フォント「Fira Code」を設定 "editor.fontFamily": "'Fira Code','Meiryo UI'", // 合字(リガチャ)を有効化 "editor.fontLigatures": true, "terminal.integrated.rendererType": "dom", "files.eol": "\n", "files.trimTrailingWhitespace": true, // 保存時にファイル最終行に空白行を付加 "files.insertFinalNewline": true, // VSCodeデフォルトのサジェストを無効化(説明が衝突するため) "php.suggest.basic": falseExtensions
Bracket Pair Colorizer 2
https://github.com/CoenraadS/Bracket-Pair-Colorizer-2
()や[]や{}を色分けして直感的にわかりやすくしてくれる
これが入っているとかっこ関連のsyntax errorが視認できる
Bracket Pair Colorizerの動作改良版code-eol
https://github.com/sohamkamani/code-eol
改行コードがlfなら「↓」、crlfなら「↲」で表示されるようになる
ソースの改行コード統一はマナーPHP DocBlocker
https://github.com/neild3r/vscode-php-docblocker
「/**」入力で追記されるアノテーションの記述を補助してくれる
タイプヒンティングや返り値指定も自動で書いてくれるPHP Intelephens
- 投稿日:2019-12-11T12:41:26+09:00
xampp/mamp/cyberdockサーバー各種 起動方法(mac)
【dotinstall cyberdock】
※cdコマンドでホームに戻り、開きたいフォルダに移動その後下記コマンド実行
$ cd /Users/ユーザー名/ (cd移動省略) $pwd /Users/ユーザー名/MyVagrant/MyCentos $vagrant up $vagrant ssh [vagrant@localhost ~]$ [vagrant@localhost ~]$ ls //開きたいフォルダの確認 centos6 php_lessons todo_app_php [vagrant@localhost ~]$ cd todo_app_php //開きたいファイルのフォルダへ移動 [vagrant@localhost todo_app_php]$ ip a (省略) pfifo_fast state UP qlen 1000 link/ether 08:00:27:91:bf:ad brd ff:ff:ff:ff:ff:ff inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1 inet6 fe80::a00:27ff:fe91:bfad/64 scope link (省略) [vagrant@localhost php_lessons]$ php -S 192.168.33.10:8000 URLで下記入力で上記ファイルのindex.phpが開かれる。 http://192.168.33.10:8000
【mamp】
1.MANPを起動2.mac内のアプリケーション内からhtdocsを開きアクセスしたいフォルダまで移動してアドレス入力
http://localhost:8888/todo_app_php/index.phpmampファイルのhtdocsの中のプロジェクトファイル指定でアクセス可能となる。
【xampp】
1.maneger-osxを起動2.アプリケーション→xampp→htdocs→アクセスしたいフォルダまで移動してアドレス入力
例:http://localhost/todo_app_php/index.php
- 投稿日:2019-12-11T11:29:44+09:00
PHP - 配列を変数に変換する
メモ
配列のキーの変数名に配列の値を入れる
test.php<?php $arr = [ 'id' => 1, 'name' => 'ほげほげ', 'age' => 25, ]; foreach ($arr as $key => $val) { $$key = $val; } var_dump($id); // int(1) var_dump($name); // string(12) "ほげほげ" var_dump($age); // int(25)
isset
等で値が入ってるか調べること可変変数 - Manual - PHP
https://www.php.net/manual/ja/language.variables.variable.php
- 投稿日:2019-12-11T11:29:44+09:00
PHP - 配列のキーの変数名に配列の値を入れる
メモ
配列のキーの変数名に配列の値を入れる
test.php<?php $arr = [ 'id' => 1, 'name' => 'ほげほげ', 'age' => 25, ]; foreach ($arr as $key => $val) { $$key = $val; } var_dump($id); // int(1) var_dump($name); // string(12) "ほげほげ" var_dump($age); // int(25)
isset
等で値が入ってるか調べること可変変数 - Manual - PHP
https://www.php.net/manual/ja/language.variables.variable.php
- 投稿日:2019-12-11T10:13:32+09:00
カバレッジエラーの対策[404編]
まえがき
株式会AncarのWebエンジニアをしている、keiと申します。
「株式会Ancar ~Advent Calendar 2019~」 11日目を担当させていただきます。弊社は安心・安全な移動体験を届けるをモットーに
中古車の個人間売買をオンラインで行うサービス
全国の中古車からお買い得な車を検索・比較できるサービス を展開しております。当記事では、GoogleSearchConsoleにサイトマップを登録後、発生したカバレッジエラーに対しての対応について共有させていただきます。
おしながき
- カバレッジエラーの現状把握
- 404の調査結果
- カバレッジエラー対策
- その1
- その2
- 最終結果
カバレッジエラーの現状把握
上記サービスは、50万以上の車両詳細ページがあります。しかし、どんなにユーザーに役立つページを持っていたとしても、クローラーがページを見つけられなかったら、検索結果に表示されません。
ということで、より多くのページを検索結果に表示させたいと思い、サイトマップをGoogleSearchConsoleで登録しました。送信したサイトマップの一部
ステータスが成功になり送信できました
が、、、喜んでるのも束の間
最大で251ページも404が見つかってしまいました
エラーがたくさん見つかってしまったので、次になぜクローラーが251ページも404を返してしまったのかを調査していきました。404の調査結果
サーバーのアクセスログとDBを調査したところ、2019年の第41週において、中古車情報取得コマンドの実行中にデータの欠損が起きていたことが判明しました
そのため、第42週のデータがcreateされる前に
クローラーが欠損した出品ページにアクセスしエラーを吐いた。
中古車情報取得コマンドにおいて、41週目のデータ欠損が起こった一例+---- +------+--------------+----------------------+---------------------+ | uid | week | car_make_id | created_at | updated_at | | +-----+------+--------------+ ---------------------+---------------------+ | 1 | 40 | 7 | 2019-09-30 16:44:03 | 2019-09-30 22:25:10 | +-----+------+--------------+----------------------+---------------------+ 1 row in set, 1 warning (0.00 sec)+---- +------+--------------+----------------------+---------------------+ | uid | week | car_make_id | created_at | updated_at | | +-----+------+--------------+ ---------------------+---------------------+ | 1 | 42 | 7 | 2019-10-08 17:30:03 | 2019-10-08 21:55:10 | +-----+------+--------------+----------------------+---------------------+ 1 row in set, 1 warning (0.00 sec)しかし、たとえ中古車取得コマンドで欠損が起こらなくても、
前の週にあった出品が今週なくなった
という場合に同様のエラーが起こる可能性がある。
したがって、前週にあって今週には存在しない出品について、今週のサイトマップをSearch Consoleが読み込むまでの間はクローラーが存在しない出品ページにアクセスするという状況を作り出してはならない。カバレッジエラー対策その1
対応策として行ったことは、前の週にあった出品が今週なくなった場合、掲載終了ページを作成することで404のレスポンスコードを返さないようにする方法である。
実際に作成したページ
カバレッジエラー修正リクエスト後
GoogleSearchConsoleを見てみると、あれ?増えているではありませんか。。
カバレッジエラー対策その2
ということで、第2弾修正を行っていくことにしました。
エラー再調査
クローラーがサイトを訪れたタイミングとデータが作られた時間の比較
+---- +------+--------------+----------------------+---------------------+ | uid | week | car_make_id | created_at | updated_at | | +-----+------+--------------+ ---------------------+---------------------+ | 4 | 41 | 5 | 2019-10-07 05:53:03 | 2019-10-07 12:43:15 | +-----+------+--------------+----------------------+---------------------+ 1 row in set, 1 warning (0.00 sec)+---- +------+--------------+----------------------+---------------------+ | uid | week | car_make_id | created_at | updated_at | | +-----+------+--------------+ ---------------------+---------------------+ | 4 | 45 | 5 | 2019-11-05 06:55:03 | 2019-11-06 07:25:10 | +-----+------+--------------+----------------------+---------------------+ 1 row in set, 1 warning (0.00 sec)上記時刻を見てみると、クローラーが2019/11/04に対して、DBのcreateした時刻は2019/11/05である。
今回の場合は、41週目の次にデータが出来たのは45週目でした。そのため、前週のデータが有り、かつ今週のデータが無い場合は掲載終了ページを表示するようにしていたが、先週だけのステータスだけだと今回みたいに過去にデータがあった場合、クローラーがきた時に404を返してしまうということが新たに判明した。
対策として、先週だけのステータスだけではなく、データが過去1週でも有り、かつ今週のデータが無い場合は掲載終了ページを表示するようにしました。
最終結果
カバレッジエラー対策その2後、再度Googleにクロールをリクエストすると、251ページもあったエラーが49ページまで減りました
残りの49ページはクロールが来るのを待っているという状況なので、404のカバレッジエラー が0件になる日もそう遠くはありません!!
- 投稿日:2019-12-11T08:42:57+09:00
LINE WORKS(と色々)用いて文化祭用のシステムを作った話。
今回したことが学校のHPに掲載されていました↓
https://www.anan-nct.ac.jp/notifications/10973/
前置き(文化祭2週間前の部活)
先輩「LINE WORKSの人と協力して文化祭の落とし物管理システムを作るやで」
開発メンバー「ほう」
先輩「LINE WORKSの人来てくれるから色々教わってな」
開発メンバー「それはいいですね」
先輩「先輩ら他で忙しいから開発メンバーは3年主体でやってな」
開発メンバー「ん??」
先輩「製作期間文化祭までな」
開発メンバー「???」
というやり取りがあり、このプロジェクトが始まった。開発メンバー
- Microsoft Flow担当
- Naoki Takahashi
Twitter→@NaokiPadT480- サーバー担当フレンズ
- プロ(グラミング見習い中のアラ)イさん.php
Twitter→@raspberry_craft- 掲示板ページUI担当
- K-Mano
Twitter→@ClockOjisan
Github→K-Manoメンターとしてワークスモバイルジャパンの方がついてくれた。
したこと
- LINE WORKSのBot作成
- MS FlowのBot APIを使用したフローの作成 →Botに投げられた文をサーバーにPOST →Botに投げられた写真のIDをサーバーにPOST →使い方ガイドの送信
- サーバー上にPOSTされた文字列の処理 →PHPを用いて文字列と写真IDを取得しデータベースに登録 →写真は即座にダウンロード
- DBの情報をPHPを埋め込んだHTMLファイルで表示
なぜMS Flowが挟まれているか
実は運用に使うサーバーが自己署名証明書を使っており、LINE WORKSの仕様では使えないことが判明。
納期が短く、正常に動作させるために時間を使いたいことからサーバー側は特にいじらず間にMS Flowを挟むことで解決した。
MS Flowの構成は以下のようになった。LINE WORKSのBotを作る
といってもこれは特別なことは特にせず、Botが受け取ったメッセージをサーバーにMS Flow経由で送るようにした
(トークンの期限切れに気づかず、2日ほど潰れたが...)サーバー処理方法について考える
サーバー担当は過去に作ったシステムを流用して開発しようとしたが
- SQLインジェクション対策がされていない
- PHPを初めて触った頃の設計で無駄が多すぎる
- なにより汚すぎる
といった理由で新規開発となった。
今回のサーバーでは以下の点を重視した
- 動作ログを残す
- 処理をモジュール化する
ある意味当たり前のことだが、これは過去に出来ていなかったため苦労したことを反映した結果となる。
落とし物情報の判別方法
時間がなかったために、送信するメッセージの先頭に番号をつけて
- 落とし物の名前
- 落とし物を見つけた場所
- 落とし物の特徴
を判別した。
また、画像はJSONの情報から判別し、取得したそして出来たのがこれ
開発にはPHP 7.3が使われた。選んだ理由は一番慣れている言語かつ、既にサーバーに実行環境が整っていたというものである。
メッセージ受信用プログラム
メッセージ受信用プログラム<?php require_once("/var/www/lib/Tools.php"); require_once("/var/www/Config/SQL_login.php"); require_once("/var/www/lib/SQL.php"); require_once("/var/www/Config/Server_config.php"); require_once("/var/www/Config/Server_Proxy_Config.php"); $json=json_decode((file_get_contents(('php://input'),true))); $type=$json->content->type; //メッセージイベントのタイプ判別 error_log("type:$type"); switch($type){ case "text" : $cmd=mb_substr(($json->content->text),0,1); //コマンド文字の切り出し error_log("cmd:".$cmd); switch($cmd) { case "1": line_message("name",$json,$cmd,$dbh); break; case "2": line_message("place",$json,$cmd,$dbh); break; case "3": line_message("feature",$json,$cmd,$dbh); default : echo "Invalid command"; } break; case "image" : $fileName=str_replace('/','',sha1($resourceID)); $count=0; $res=false; $accountID=$json->source->accountId; $time=$json->createdTime; $resourceID=$json->content->resourceId; $header_json=array( 'http'=>array( 'method' => 'GET', 'header' => "consumerKey:******\r\n" . "authorization: ******\r\n" . "x-works-apiid: *****\r\n" . "x-works-resource-id:$resourceID\r\n" ) ); $context = stream_context_create($header_json); do{ if($proxy_set){ $res=file_get_contents($line_image_url, false, stream_context_create([ 'http' => [ 'method' => 'GET', 'request_fulluri' => true, // プロキシ通す場合は必須 'proxy' => $proxy_url, ] ])); error_log(print_r($http_response_header)); }else{ $res=file_get_contents($line_image_url, false, $context); error_log(print_r($http_response_header)); } $count++; }while(($res==false&& $count>3)); if($res!=false){ if($proxy_set){ LogSQL(000,"Success ($resourceID) ,Line Picture Get Proxy Enable","Line_get","0",$dbh); }else{ LogSQL(000,"Success ($resourceID) ,Line Picture Get Proxy Disable","Line_get","0",$dbh); } if(file_put_contents("/var/www/html/image/$fileName.png",$res)){ LogSQL(000,"Success ($resourceID) ,Picture Write","Line_get","0",$dbh); $line_get_sql="UPDATE Lost_Article SET `picture`=:Data WHERE `RoomID`=:RoomID ORDER BY id DESC limit 1"; $line_get_prepare=$dbh->prepare($line_get_sql); $line_get_prepare->bindValue(':Data',$fileName,PDO::PARAM_STR); $line_get_prepare->bindValue(':RoomID',$accountID,PDO::PARAM_STR); if($line_get_prepare->execute()){ LogSQL(000,"Success Picture Data Update","line_get",0,$dbh); }else{ LogSQL(005,"Failed Picutre Data Update","line_get",2,$dbh); } }else{ LogSQL(001,"Failed ($resourceID) ,Picture Write","Line_get","2",$dbh); } }else{ if($proxy_set){ LogSQL(001,"Failed ($resourceID) ,Line Picture Get Proxy Enable","Line_get","2",$dbh); }else{ LogSQL(001,"Failed ($resourceID) ,Line Picture Get Proxy Disable","Line_get","2",$dbh); } } }Webページに表示されるのはこんな感じ(ページのリソース:50MB(ほぼフォント))(1分毎に再読み込み有り)
感想
Naoki Takahashi ↓
納期が短く死にかけたが、見える部分の見た目は良くなったので良かった。
APIを初めて触ったが、仕組みを理解できた。プロイさん ↓
やはり慣れたPHPは手っ取り早く開発するには使いやすいと改めて実感すると同時に、サーバーへの負荷を考えてほしいと半分キレそうになったK-Mano ↓
普通のWebページを作るだけだったがその分見た目に凝る時間もできた。
- 投稿日:2019-12-11T08:28:13+09:00
C++とPHPとMySQLの連携を試してみた
タイトルの通り、C++とPHPとMySQLを用いてデータのやり取りをやってみたのでメモ。
使用したもの
ツール
・VisualStudio2017
・Xampp
ライブラリ
・Boost (通信するために使用)
・Json11 (JSONを解析するために使用)やりたいこと
流れとしては、
①C++ → ②PHP → ③MySQL → ④PHP → ⑤C++ の順でデータをやり取りしたい。
取りあえず、今回は2つの値を足し算した結果を取得することを目標とする。① 足し算したい2つの値を入力し、GET方式で送る。
② 足し算を行い、MySQLに計算結果を送る。
③ 結果を保存する。
④ 今までの計算結果を受け取り、JSON形式で送る。
④ JSON形式で計算結果を受け取り、それらを表示する。コード
main.cpp#include <iostream> #include <iomanip> #include <boost/asio.hpp> #include <boost/algorithm/string.hpp> #include <vector> #include "json11.hpp" using namespace std; namespace asio = boost::asio; namespace ip = asio::ip; using namespace json11; int main() { //足し算する値の入力 int value1, value2; cout << "value1を入力 : "; cin >> value1; cout << "value2を入力 : "; cin >> value2; cout << '\n'; //リクエストに対するレスポンス string allRes = ""; //通信を開始 try { asio::io_service io_service; //TCPソケットを作成する ip::tcp::socket sock(io_service); //名前解決(ホスト名からIPアドレスに変換)する ip::tcp::resolver resolver(io_service); ip::tcp::resolver::query query("127.0.0.1", "http"); //ホスト情報を設定する ip::tcp::endpoint endpoint(*resolver.resolve(query)); //ソケットへ接続 sock.connect(endpoint); //メッセージを送信 asio::streambuf request; ostream request_ostream(&request); string getRequest = "GET add.php?value1=" + to_string(value1) + "&value2=" + to_string(value2) + " HTTP/1.0\r\n\r\n"; request_ostream << getRequest; asio::write(sock, request); //メッセージを受信 asio::streambuf response; boost::system::error_code error; while (asio::read(sock, response, asio::transfer_at_least(1), error)) { //streambufからstringに変換 string tmp = asio::buffer_cast<const char *>(response.data()); allRes += tmp.substr(0, response.size()); } } catch (exception& e) { cout << e.what() << '\n'; return 1; } //二重改行で区切る(レスポンスボディを取得するため) vector<string> res; res = boost::split(res, allRes, boost::is_any_of("\r\n\r\n")); //stringからJsonに変換 string err; const Json jsonData = Json::parse(res[res.size() - 1], err); cout << jsonData.dump() << "\n\n"; //各値を取得 auto jsonArray = jsonData.array_items(); cout << " id value1 value2 ans" << endl; for (auto &item : jsonArray) { cout << setw(6) << right << item["id"].string_value() << " "; cout << setw(6) << right << item["value1"].string_value() << " "; cout << setw(6) << right << item["value2"].string_value() << " "; cout << setw(6) << right << item["ans"].string_value() << '\n'; } return 0; }MySQLに「calc_db」というデータベースを作り、テーブル名を「result」とした。
カラムは、「id」「value1」「value2」「ans」の4つである。
これにより、挿入された順番、入力した値、二つの値の足し算の結果がDBに保存される。add.php<?php //計算する値を入力 $isInput = TRUE; if(isset($_GET['value1'])){ $value1 = intval($_GET['value1']); } else { $isInput = FALSE; } if(isset($_GET['value2'])){ $value2 = intval($_GET['value2']); } else { $isInput = FALSE; } //DBの設定 $mysql = mysqli_connect('localhost', 'root', '') or die(mysqli_error($mysql)); mysqli_select_db($mysql, 'calc_db'); mysqli_query($mysql, 'SET NAMES UTF8'); //入力があるならデータをDBに追加 if($isInput){ //結果を計算 $ans = $value1 + $value2; //DBにデータを挿入 $insert = sprintf('INSERT INTO result SET value1=%d,value2=%d,ans=%d', mysqli_real_escape_string($mysql, $value1), mysqli_real_escape_string($mysql, $value2), mysqli_real_escape_string($mysql, $ans) ); mysqli_query($mysql, $insert) or die(mysqli_error($mysql)); } //DBからデータを取得 $request = sprintf('SELECT * FROM result'); $result = mysqli_query($mysql, $request) or die(mysqli_error($mysql)); $ansList = array(); while($row = mysqli_fetch_assoc($result)){ $ansList[] = array( 'id'=>$row['id'], 'value1'=>$row['value1'], 'value2'=>$row['value2'], 'ans'=>$row['ans'] ); } //jsonで出力 $jsonData = json_encode($ansList); header("Content-Type: application/json; charset=utf-8"); echo $jsonData; ?>出力結果
value1に「1」、value2に「2」を入力した。
足し算をした結果、ansが「3」となっていることが分かる。value1を入力 : 1 value2を入力 : 2 [{"ans": "3", "id": "1", "value1": "1", "value2": "2"}] id value1 value2 ans 1 1 2 3次に、value1に「2」、value2に「3」を入力した。
ansは「5」となり、表にはこれまでの計算結果が表示されている。value1を入力 : 2 value2を入力 : 3 [{"ans": "3", "id": "1", "value1": "1", "value2": "2"}, {"ans": "5", "id": "2", "value1": "2", "value2": "3"}] id value1 value2 ans 1 1 2 3 2 2 3 5まとめ
C++からPHP、PHPからMySQLへの連携は簡単ながら行うことができた。
GET形式をPOST形式にしたり、同期通信を非同期通信にするなどまだやることはある。
また、コードに関してももっと良い書き方があると思う。
今度はこれを応用して何か作りたい。参考にしたサイト
・ネットワーク - TCP
・Boost.AsioでHTTP通信
・C++11でjsonを扱う方法。json11
・C++11でjson扱うならdropbox/json11がよさそうなど。
- 投稿日:2019-12-11T04:23:09+09:00
Moodle 3.8 マニュアル - Unix 又は Linux における cron
Unix 又は Linux における cron
Unix と Linux ではほ cron プログラムを構築し、それはほとんどすべてのシステム上で標準です。あなたは web サーバユーザのために、'crontab' (cron コマンドを保持しているテーブル)にコマンドを追加することが要求されます。
Moodle の cron プロセスを呼び出すために使うことができる方法には 2つの異なるものがあります。
注:示しているコマンドは機能させるために crontab に追加される必要があります(もうすぐ記述します)。しかしながら、あなたは、コマンドライン上でそれらが動作するかどうか、まず走らせることができます(そうすべきです)。
内容
1 方法 1:コマンドライン(cli)による cron
2 方法 2:web ベースの cron
3 Unix/Linux で crontab を使用する
4 関連項目1 方法 1:コマンドライン(cli)による cron
あなたに選択肢があるのなら、これが Moodle cron を走らせるのにもっともよい方法となります。
PHP も直接コマンドラインからプログラムを実行できます。あなたのシステムはこれをするようにセットアップする必要があります。特に 'CLI' バージョンがインストールされていることが必要です。PHP がインストールされているほとんどのシステムでは、デフォルトでこれがあるでしょう。PHP CLI バージョンがインストールされているならこれが cron を立ち上げる推奨する方法となります。正しいコマンドラインは以下のようになるでしょう。/usr/bin/php /path/to/moodle/admin/cli/cron.php(必要に応じ、moodle と php への正しいパスに置き換えてください。)
うまく動作するかどうか、以下を単にタイプするだけでよいです。PHP へのパスが定かではないならば、以下をタイプしてください。which phpこつ:何か問題があるのなら、PHP ページを見てください。特に、CLI PHP コマンドのためには相応しい設定がないかもしれない php.ini の代わりを推測してください。
2 方法 2:web ベースの cron
注:web ベースの cron スクリプトを使用するためには、まず、この方法が許可されているかどうか Cron設定 をチェックしなければいけません。
このアイディアは、次の web ページを呼ぶこと(あなたは、これをブラウザから為すことができます)です。
http://url.of.your/moodle/admin/cron.php
A command line (text based) browser is needed to run this on the server. Possibilities are as follows (OSX, for example, only ships with curl)...
コマンドライン(テキストベースの)ブラウザがこのサーバ上で走る必要があります。可能性としては、次のものがあります(例えば OSX では、curl だけが同梱されています)。/usr/bin/wget -q -O /dev/null/ http://url.of.your/moodle/admin/cron.php(アウトプットは表示されません。テストするには -O /dev/null/ を削除してください)
... あるいは ...
/usr/bin/curl http://url.of.your/moodle/admin/cron.php -o /dev/null/ -silent(アウトプットは表示されません。テストするには -O /dev/null/ を削除してください)
3 Unix/Linux で crontab を使用する
あなたが Moodle cron を呼び出す適切なコマンドを選択(そしてテストして!)したら、定期的に走るようにスケジュールされるよう web ユーザの 'crontab' のスケジュールに追加されるべきです。'crontab' は、ユーザの cron コマンドを含んでいるファイルであるとともに、それを編集するために使用される(コマンドラインの)プログラム名でもあります。(root で)次のコマンドを、'www-data' から正しいユーザに置き換えて(たとえば、CentOS なら 'apache'、Debian/Ubuntu なら 'www-data' に-Google に聞いてください!)使用してください。
crontab -u www-data -e
This will bring up an editor window (the first time it may ask you which editor to use). Add the command onto the end of the file in this way (it may be empty or it may have some instructional comments):
*/1 * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php >/dev/null
The first five entries specify the times, followed by the command, to run. This says to run the command every minute which is normally ok. On a hosted system you may get complaints if you do not run it a lot less often (e.g. to run every two hours use '0 */2 * * *' for the first five entries). If you want to use the wget/curl version, the first five entries remain the same - just change the command part.
4 関連項目
A basic crontab tutorial
Online version of the man page
Predicting Cron job's run timeカテゴリ:インストール
- 投稿日:2019-12-11T01:19:21+09:00
PHP7.4の新機能を追う/PHPの謎仕様/ソースコード共有サービス/PHPの歴史【Web x PHP TechCafe 1杯目】
PHP × Web Tech Cafe
『Web×PHP TechCafe』は、WebやPHPに関わるITエンジニアがスキルアップのために開発や勉強、LTをするコミュニティです。オフィスをスキルアップの場としてご提供します。
今回は PHP × Web Tech Cafe 11月の内容をまとめてお伝えします!!
Lightning Talks
参加者の方にLTを行っていただきました!
- Javaエンジニアが怖いと思うPHPの仕様
- ソースコード共有サービス emoscode (エモすこ)
- The World of PHP
Javaエンジニアが怖いと思うPHPの仕様
by soachr さん
Java を3年半使っていたsoachrさんから見た、PHPの不思議なところを紹介いただきました。
PHP初学者のあるあるがたくさん含まれていました。
- ifの中で代入する場合の挙動 → Javaならエラーなので違和感あり
- 空文字をifの条件に入れる → 型がないので普通に実行できてしまう
- 第二引数がない関数 → エラーにならない
→ PHPは ゆるふわ!!
ソースコード共有サービス emoscode (エモすこ)
by ともたこ さん
ともたこさんが作成したソース共有サービス「エモすこ」を紹介いただきました!
テーマは 「エモいコードにすこを加える」だそうです!
- ソースコード共有サービス
- ソースコード上にコメントを貼り付けられる
- SNSでのシェアも可能
技術要素
- フレームワーク:bottle-breaker
- フロント:JS→TypeScript
- ホスティング:Heroku
- etc...
今後の展望
- 現在はコードのアップロードのみ → 編集、削除ができるようにしたい!
- 誤解するようなUIを修正
The World of PHP
by @kawanamiyuu さん
PHPとは
- さまざまな目的で使える
- 特にWebで使える
- 十分早い
- 実用的
PHPは何の略?
→ PHP: Hypertext PreprocessorPHPの歴史
- 1995年に誕生(このときは personal Home Page tool の略だった)
- レガシーとモダン(5.2と5.3で変わる)
- 名前空間の導入
- 自動読み込み
- Composer(依存管理ツール)
- 型定義
PHPのいいところ
- 十分に高速
- webサイトを構築するのに最も使われている言語である
- よく知ってるサービスで使用されている
- 公式マニュアルが充実
- Hello world が異常に簡単
- コミュニティも活発
まとめ 〜PHPとは〜
Rasmus Lerdorf の言葉
- PHPは歯ブラシ : 日常で使うあくまで便利な道具である
- PHPは話し言葉のように進化してきた : 新しい言葉が追加され、古い言葉は使われなくなっていく
ディスカッション議事録
今回は、もくもく学習だけでなく、PHPについてのテーマに基づいたディスカッションを行いました!
今回のテーマ
- PHP7.4の新機能をRFCを見ながら「何が嬉しいのか、どういう時に使うのか」などを参加者同士でお話しする。
RFC
https://wiki.php.net/rfc#php_74
Migration
https://www.php.net/manual/en/migration74.php
今日のディスカッション対象
Typed Properties
- プロパティ型指定
- https://wiki.php.net/rfc/typed_properties_v2
- ディスカッション内容
クラスのプロパティに型を指定できる。
- 違う型を指定しようとするとエラー
- モードで使えるかどうかを指定できる
- クラスも指定できる → オブジェクト指向の実装がやりやすい
- 新しいコードから使用していく
- 型指定があるプロパティとないものの混在も可能
- NULL許容演算子でNULLを許すかどうか制御できるのが嬉しい
- コードを読むときに見当がつけやすくなる
- 変数名の$~~Strが無くせる!
- ジェネリクスがあったらいいのに...
- RFCはあった: PHP: rfc:generics
- 連想配列の型指定も欲しい
Foreign Function Interface
- FFI
- https://wiki.php.net/rfc/ffi
- ディスカッション内容
PHPから他の言語を呼び出せます。
- 24 vs 15 で可決された
- そもそものRFCのあり方のディスカッションにもなった
- 他の言語でも同様のことはできるので世の中の流れ的には納得感ある
- 文字列で書く仕様はいかがなものか…
- 記述内容をコンパイルして利用する
- コンパイル済みの実行ファイル置いておけばいいのでは?
- 使いようによってはコンパイルした結果をキャッシュすることができる
- PHPの拡張機能を使うことを想定している?
- 速度改善が目的?
- すでに存在するCのコードを生かすため?
参考
Null Coalescing Assignment Operator
- NULL合体演算子
ディスカッション内容
Nullかどうかを確認する演算子をさらに省略系にする
- 書くのは楽になる
- 読みにくくはならないか?
- 短いことは読みやすいことである?
??
を見たときにコードの意図はすぐ理解できる- リクエストパラメータのデフォルト値設定とかに使いやすそう
- シングルトンパターンのインスタンス存在判定に使えそう
PHPの亜種たちはどこいった??
P++とは?
もっとPHPを厳密化して使いましょうといった言語。
話題になったが提案だけで移行動きがない参考: P++: 銀河に平和をもたらすための奇策と決着 - Qiita
Hack
Facebookが作成していたPHPを拡張して使おうとしていたもの。
Arrow functions
- 投稿日:2019-12-11T01:19:21+09:00
Web x PHP TechCafe11月イベントレポート
PHP × Web Tech Cafe
『Web×PHP TechCafe』は、WebやPHPに関わるITエンジニアがスキルアップのために開発や勉強、LTをするコミュニティです。オフィスをスキルアップの場としてご提供します。
今回は PHP × Web Tech Cafe 11月の内容をまとめてお伝えします!!
Lightning Talks
参加者の方にLTを行っていただきました!
Javaエンジニアが怖いと思うPHPの仕様
by soachr さん
Java を3年半使っていたsoachrさんから見た、PHPの不思議なところを紹介いただきました。
PHP初学者のあるあるがたくさん含まれていました。
- ifの中で代入する場合の挙動 → Javaならエラーなので違和感あり
- 空文字をifの条件に入れる → 型がないので普通に実行できてしまう
- 第二引数がない関数 → エラーにならない
→ PHPは ゆるふわ!!
ソースコード共有サービス emoscode (エモすこ)
by ともたこ さん
ともたこさんが作成したソース共有サービス「エモすこ」を紹介いただきました!
テーマは 「エモいコードにすこを加える」だそうです!
- ソースコード共有サービス
- ソースコード上にコメントを貼り付けられる
- SNSでのシェアも可能
技術要素
- フレームワーク:bottle-breaker
- フロント:JS→TypeScript
- ホスティング:Heroku
- etc...
今後の展望
- 現在はコードのアップロードのみ → 編集、削除ができるようにしたい!
- 誤解するようなUIを修正
The World of PHP
by @kawanamiyuu さん
PHPとは
- さまざまな目的で使える
- 特にWebで使える
- 十分早い
- 実用的
PHPは何の略?
→ PHP: Hypertext PreprocessorPHPの歴史
- 1995年に誕生(このときは personal Home Page tool の略だった)
- レガシーとモダン(5.2と5.3で変わる)
- 名前空間の導入
- 自動読み込み
- Composer(依存管理ツール)
- 型定義
PHPのいいところ
- 十分に高速
- webサイトを構築するのに最も使われている言語である
- よく知ってるサービスで使用されている
- 公式マニュアルが充実
- Hello world が異常に簡単
- コミュニティも活発
まとめ 〜PHPとは〜
Rasmus Lerdorf の言葉
- PHPは歯ブラシ : 日常で使うあくまで便利な道具である
- PHPは話し言葉のように進化してきた : 新しい言葉が追加され、古い言葉は使われなくなっていく
ディスカッション議事録
今回は、もくもく学習だけでなく、PHPについてのテーマに基づいたディスカッションを行いました!
今回のテーマ
- PHP7.4の新機能をRFCを見ながら「何が嬉しいのか、どういう時に使うのか」などを参加者同士でお話しする。
RFC
https://wiki.php.net/rfc#php_74
Migration
https://www.php.net/manual/en/migration74.php
今日のディスカッション対象
Typed Properties
- プロパティ型指定
- https://wiki.php.net/rfc/typed_properties_v2
- ディスカッション内容
クラスのプロパティに型を指定できる。
- 違う型を指定しようとするとエラー
- モードで使えるかどうかを指定できる
- クラスも指定できる → オブジェクト指向の実装がやりやすい
- 新しいコードから使用していく
- 型指定があるプロパティとないものの混在も可能
- NULL許容演算子でNULLを許すかどうか制御できるのが嬉しい
- コードを読むときに見当がつけやすくなる
- 変数名の$~~Strが無くせる!
- ジェネリクスがあったらいいのに...
- RFCはあった: PHP: rfc:generics
- 連想配列の型指定も欲しい
Foreign Function Interface
- FFI
- https://wiki.php.net/rfc/ffi
- ディスカッション内容
PHPから他の言語を呼び出せます。
- 24 vs 15 で可決された
- そもそものRFCのあり方のディスカッションにもなった
- 他の言語でも同様のことはできるので世の中の流れ的には納得感ある
- 文字列で書く仕様はいかがなものか…
- 記述内容をコンパイルして利用する
- コンパイル済みの実行ファイル置いておけばいいのでは?
- 使いようによってはコンパイルした結果をキャッシュすることができる
- PHPの拡張機能を使うことを想定している?
- 速度改善が目的?
- すでに存在するCのコードを生かすため?
参考
Null Coalescing Assignment Operator
- NULL合体演算子
ディスカッション内容
Nullかどうかを確認する演算子をさらに省略系にする
- 書くのは楽になる
- 読みにくくはならないか?
- 短いことは読みやすいことである?
??
を見たときにコードの意図はすぐ理解できる- リクエストパラメータのデフォルト値設定とかに使いやすそう
- シングルトンパターンのインスタンス存在判定に使えそう
PHPの亜種たちはどこいった??
P++とは?
もっとPHPを厳密化して使いましょうといった言語。
話題になったが提案だけで移行動きがない参考: P++: 銀河に平和をもたらすための奇策と決着 - Qiita
Hack
Facebookが作成していたPHPを拡張して使おうとしていたもの。
Arrow functions