家庭教師をやってみて
2020/02/05 2020/02/05実は少し前から未経験の方の家庭教師をしていました こんにちは。Nonです。 今回は10月くらいから始めていたプログラミングの家庭教師についてお話しようと思います。 ハマりがちなところ? 配列と連想配列 以外と思うかもしれませんが、配列がわかっても連想配列がわからないことが多いです。 それに絡んでループなど入ってくると、さらにわからなくなるようです。 個人的には、ループと箱の関係はわかりやすくて参照やポインタなどのほうがよっぽどわかりにくいと思うのですが、なんででしょうかね? 数人持って数人ともそうだったので、僕の教え方の問題かもしれません。もう少し掘り下げる必要があるかと思います。 物事の考え方、論理的思考 これは個人で大きく違うと思いました。 できる人は言わずとも(プログラミングは完璧でなくても)完璧に近い構造で課題をこなします。 これが苦手な人は、プログラミングができていても構造がおかしい、みたいな課題を提出してきます。 気づいたのはユースケースを思い浮かべているかどうかだと感じました。 例えば、ただ商品の合計金額を算出する問題でも、現実では明細や小計、税額など色々な数字が登場し、その結果、合計が算出されると思います。 レシートなど見てもそうですよね。 これを頭で想像しながら組んだプログラムと、ただ合計金額を算出するだけのプログラムとでは、構造が天と地ほど違いました。 前者で組んだ生徒さんは一つ一つの計算と商品の小計を出す処理が独立していて、それらを全て加算した結果が合計という構造。 後者で組んでしまった生徒さんはひたすら四則演算で頑張ってしまったという構造 今では後者の生徒も構造化を理解できているので、問題ありませんが、学校を卒業した今でも、パッと思いつける人はいないように感じました。 やっぱりプログラミングに対するスタイルというかタイプは存在する デザイン重視 機能重視 今の所出会った生徒はこの2つのタイプが多かったです。 HTMLやCSSなどフロントが向いてるとか(今回で言えば)PHPなど裏の機能に向いてるとか言う話では無く、モチベーションがどう上がるかという話 どちらの生徒も、やはり定期的にプログラミングをやっていると飽きが来てしまうのですが、そのモチベを回復すべく結構工夫しました。 その試行錯誤の結果、わかったことです。 フロント、いわゆる見た目をきれいに整える(機能はまだ無い)手伝いをしてあげて、きれいな画面を見せるとモチベーションが上がる人 バック、いわゆる実際に動くよう(デザインはまだ無い)手伝いをしてあげて、機能を見せるとモチベーションが上がる人 がいました。もしかしたらプログラミングに対する考えというか、求めるものが結構違うのではと思うきっかけになりました。 アプリを作りたいと言うのは便利なアプリを作りたいのか、美しいアプリを作りたいのかとかいう話になりそうです。(自分でもまだ噛み砕いていない) コツ やっぱり先生から熱意を見せることは大事だと思いました。 僕は何かを伝えるとき、結構声に抑揚がついたり、声が大きくなったりします。僕的には(起怒っている風に見えないかな?)とか思っているのですが、以外とそうでもなく、「おとなしい人でも」しっかり聞いて頑張ろうとしていることがわかりました。 できるだけ自由に 最初は冒頭に言ったような課題を用意していたのですが、モチベーションが下がっていくのは目に見えてわかりましたので、自由な課題を用意して、アドバイスを出していくようにしたらうまくいくようになりました。 最後に 今回は未経験の方にプログラミングを教えるときのコツのようなものに関して書いてみましたが、僕も初めて半年くらいなものですので、当てにならないかもしれません。 皆さんの力になれれば嬉しいです。 また更新するかもしれません。 その時はよしなに .
昨年の振り返りと本年の目標
2020/01/01 2020/01/01昨年の振り返りと本年の目標 こんにちは。Nonです。 少し遅れてしまいましたが、去年の振り返りと、本年の目標を書いていこうと思います。 2019年はどんな年だったか? 職場 実は2018年に転職をしておりまして、前職がそれはもうレガシーな環境での開発でした。 Gitサーバー 存在しているが、「全く」使用されていない状態 つまりフォルダバージョン管理 サクラエディタでの開発 VSCodeの存在を知らない人が多数 フレームワークの使い方を知らない MVCすら怪しい 途中から僕一人での保守運用 開発業務がほとんどできずドメインについて知っているのが僕一人 ちょっと愚痴っぽくなってしまいましたが、ほとんどあっていると思います。 2019年になる間際に転職をしまして、現職となります。 現職では首都圏のエンジニア事情より少し遅れてる感は否めませんが、前職よりかなり進んだ環境になったと思います。 それに伴いかなり広い範囲で勉強になりました。 GitLab Git管理手法 CI/CD 自分以外が書いたMVC設計 チケットを用いた業務管理 設計などは個人で勉強していたので、特にという感じでしたがコード管理と業務管理は参考になるところが多いと思います。 個人活動 大きく変わったのはこれでしょうね。 新卒の頃から色々自分で作成していましたが、サーバーを借りて公開し始めたのはちょうど去年の今頃です。 クソアプリですが、 旧:non's Labo トドTask ツーマッチ 今年の抱負メーカー などなど色々作成しました。 特に今年の抱負メーカーはちょうど去年の1月1日にリリースしたものでした。 こちらその時のQiitaの記事です。 この子達を開発するにあたってLaravelに手を出して、色々勉強しながら開発していました。 最初はどちらかというとLaravelやDDD、クリーンアーキテクチャを勉強するためにアプリを作ってた感がありましたが、2019年後半になってくるとアプリのために開発するようになっていました。 そう言えば家庭教師はじめました 友人からプログラミングを教えてほしいとのことなので、かなりの格安で毎週家庭教師をしています。 後輩以外にプログラミングを教える機会がなかったので、うまく行っているか不安でしょうがないです。 これはまた詳しく別の記事にしたいですね。 2020年の目標 目標というか方針ですね。 なにか1つのアプリをじっくりと開発する 今までは何か一つ作ってポーンって出したりして、リリース後は放置みたいなずさんなアプリ開発だったので、きっちりバージョンごとに区切り、ピリオドをつけるようにしていきたいと思います。 とはいえ個人開発であることに変わりはないので、ツーマッチのように規模が大きすぎて無謀な挑戦にならないようにはしたいです。 自作アプリを紹介するHP作成 構想としてあるのが、一昔(平成時代)に流行った、自作アプリを一覧にしてそこからDLやリンクで使用してもらうという、あのページを作成してnons Laboに埋め込みたいです。 うまく作成すればそのままポートフォリオになりますし、共同開発者を募るページも作成したいですね。 ということは 現在作成中のあるアプリ これに一番注力したい nons Laboの管理 アプリまとめページ 技術記事更新(Qiita含め) 会社で使用されるであろうLuncher 会社で使用される予定で、一人で結構大きめのアプリをつくったので、なにかにまとめて記事にしたいと思います。 これを2020年に落ち着かせるのが目標でしょうか。 その他私生活に関すること 貯金 ホントは去年頑張るよていだったのですが、全く達成されず😂 バイクやキャンプ用具を買っていたらお金が全く貯まりませんでしたw この辺我慢するようにはしていませんが、ちょっとしたカフェ台や食費が結構かかっているので、その辺の管理をちゃんとできるようにしないといけませんね。 おしゃれに気を使う 流石にいい年齢になりましたので、そろそろ身につけるものに気を使おうと思いますw 寝間着同然の格好で外歩き回ったりする人間なので僕😱 ここに書いたこと以外は我慢しない これが意外に重要かもしれません。気楽に行きましょう! 最後に こんなものでしょうか。 怠けグセがあるので、どれか忘れそうですが、気を引き締めて行きたいと思います。 ブログのネタにしたいものをたくさんあるので頑張って記事にしていきます! その時はよしなに。 .
Laravelの404ページやその他の例外ページの作成方法
2019/07/15 2019/12/27Laravelの404ページやその他の例外ページの作成方法 こんにちは。Nonです。 今回は備忘録としてLaravelでの404ページなどのカスタマイズ方法について書いていきたいと思います。 ページ用のbladeを作成する 普通にbladeとして作成します。 下記の例ではh1タグのみにしていますが、CSSなどを利用してページを装飾することをおすすめします。 copied.<h1>404 Not Found. このページは存在しません。</h1> <a href="/" class="btn btn-primary">TOPへ戻る</a> 404というか例外時の処理 Laravelはroutesに無い時NotFoundHttpExceptionをスローします。 このスローの結果、最終的に/app/Exceptions/Handler.phpのrenderメソッドへ処理が移ります。 また、自分のアプリケーションで独自の例外を作成している場合もアプリケーション層でキャッチしていない場合、ここへ処理が来ます。 copied./** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { return parent::render($request, $exception); } ここのrenderメソッドを編集します。 ページがないときの例外 copied./** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { if ($exception instanceof NotFoundHttpException) { return view('pages.errors.404'); } return parent::render($request, $exception); } サーバーエラーが発生したときの例外 他の例外時、例えばサーバーエラーを示す500エラーなどの場合は、独自の例外や、Laravelの例外すべてを拾いたいので、このようにするのがいいかもしれません。 copied./** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { if ($exception instanceof NotFoundHttpException) { return view('pages.errors.404'); } // 一番最後に書くことを推奨 if ($exception instanceof Throwable) { return view('pages.errors.500'); } return parent::render($request, $exception); } ログインに失敗した時や、権限のエラーのときの例外 ログイン時は401 Unauthorizedで、権限エラーは403 Forbiddenです。 しかし、このエラーをここで拾うのはちょっとおかしいかもしれません。 このメソッドはアプリケーションが想定していない入力をされた時に発生する例外をまとめるべきです。 ログインエラーや、アプリケーション権限の例外は想定できる例外ですので、ControllerやMiddlewareレベルでtry-catchを使用するべきです。 例えばログインが必要な機能ページの例外はLoggedInMiddlewareなどを作成して自身のログインチェック時にスローされる例外をキャッチしてエラーページをレンダリングするほうが、/app/Exceptions/Handler.phpのコードを汚さなくてすみます。 copied./** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { try { // ログインチェック } catch (UnauthorizedHttpException $e) { // 認証のエラーページやリダイレクト処理 } return $next($request); } ちなみにLaravelの標準で付属している認証システムを利用している場合は、すでにRedirectIfAuthenticatedが実装されているので、不要です。 アプリケーションの権限などの場合はログインと同様にRoleMiddlewareなどを作成し、権限が関係するルーティングにこのミドルウェアを適用し、try-catchを使います。 copied./** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { try { // 権限チェック } catch (RoleException $e) { // 権限のエラーページやリダイレクト処理 } return $next($request); } (adsbygoogle = window.adsbygoogle || []).push({}); APIのときとかは? LaravelのRequestクラスにはexpectsJsonメソッドが実装されているので、これを利用してAPIでコールされているかどうかを確認しましょう。(APIがXMLとかの場合は他の関数を用意して利用しましょう) copied./** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { if ($exception instanceof NotFoundHttpException) { if ($request->expectsJson()) { response()->json([ 'message' => 'Not Found.', ]); } return view('pages.errors.404'); } // 一番最後に書くことを推奨 if ($exception instanceof Throwable) { if ($request->expectsJson()) { response()->json([ 'message' => 'Server Error.', ]); } return view('pages.errors.500'); } return parent::render($request, $exception); } 基本的に/app/Exceptions/Handler.phpはあまり利用しないようにしたほうがいいかも ここに例外がスローされる時はアプリケーション上本当に拾えない例外か、よっぽどの想定外(PHP構文エラーや実装時のバグとか)を拾うためのメソッドです。 なので、アプリケーション上で開発時に想定できる例外はキチンと他の層でキャッチしたほうが可読性が上がります。 最後に 今回は備忘録とエラーハンドリングの整理がてらまとめてみました。 最初は404エラーについてにまとめようと思っていましたが、結局それはエラーハンドリングをどのような構造で作成するかということでしたので、他の例外についてもまとめてみました。 正常時の設計も大事で、こちらばかりに注目が行きがちですが、エラーハンドリングをしっかりすることもとても重要です。例外を自分の想定どおりにハンドリングできていないと、運用のときどこでエラーが起きたとかを拾いづらくなってとても困ります。 一度適当な記事を書いてしまったので、リライトしました。 これからもLaravelを利用したアプリの設計について思うところがあれば記事を更新したいと思います。 その時はよしなに。 .
CakePHP3でShellでメール送信できなかった話
2019/12/17 2019/12/18CakePHP3でShellでメール送信するときに気をつけること こんにちは。Nonです。 今回は僕がCakePHP3でメール送信する際にハマったときのことを書こうと思います。 ちょっと重ための処理をシェルで実行した後、メール送信する処理を作った話。 ハマる前に少しだけ前提知識を書くと、ちょっと重ための処理が合ったのですが、これをユーザーに待たせるのは避けたく、バックグラウンド(シェル)で実行して、その完了通知をメールで通知しようという処理があったのです。 そのときに、メールが送信できない現象が発生しました。 Gsuiteのrelayを使用していますので、他の人はこの現象発生しないかも? 結論 config/app.phpのEmail設定にclientは指定しておいたほうが吉。 copied.'EmailTransport' => [ 'default' => [ 'className' => 'Smtp', // The following keys are used in SMTP transports 'host' => 'smtp-relay.gmail.com', 'port' => 587, 'timeout' => 30, // ここNULLは避ける↓ // 'client' => null, // ここドメインを指定↓ 'client' => 'example.com' 'tls' => true, ], ], 何故か? /vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php copied.protected function _connect() { $this->_generateSocket(); if (!$this->_socket->connect()) { throw new SocketException('Unable to connect to SMTP server.'); } $this->_smtpSend(null, '220'); $config = $this->_config; if (isset($config['client'])) { $host = $config['client']; } elseif ($httpHost = env('HTTP_HOST')) { // ここ$config['client']がNULLだったら設定されたドメイン list($host) = explode(':', $httpHost); } else { $host = 'localhost'; } ... } clientが存在しなければ環境変数HTTP_HOSTがclient、それ以外ならlocalhostとして設定され、接続されます。 このときの環境変数HTTP_HOSTですが、諸事情により自分で設定した違うドメイン(購入していないローカルPCだけのドメイン)でした。 さらに本番環境でShellを実行すると、環境変数が強制的にLocalになってしまう始末。。。(皆さんはちゃんとプログラムで制御してください。) まぁlocalhost.test.comで接続なんて許されませんよねw それに仮にlocalhostで接続したとして、Gmailがlocalhostでの接続を許してくれるのでしょうか? これは検証する必要があるかもしれません。 最後に 今回は短めでしたが、CakePHP3のソースを追わないとわからない内容だったと思います。 皆さんの力になれれば嬉しいです。 ところで copied.'client' => 'example.com' で設定してもうまくいくのでしょうか?私の修正後のコードはセキュリティの観点からお見せすることはできませんが、購入したサーバーに接続できるhostでした。 仮にここにlocalhost.test.comを入れた送信できないのでしょうかね?(まぁできないと思う。) 最近ちょっとした処理でフレームワークの処理を追うことになったので、こういったニッチな解決法を発見したら、今後も記事にしていきたいと思います。 その時はよしなに。 .
さくらのレンタルサーバーのPHPをモジュールモードにしたらアホみたいに早くなった話
2019/12/13 2019/12/13さくらのレンタルサーバーのPHPをモジュールモードにしたらアホみたいに早くなった話 こんにちは。Nonです。 今回は僕の大事なクソアプリ'sが稼働している本番環境のレンタルサーバーについてお話したいと思います。 本番環境がレンタルサーバーってどうなの? 僕はかなりアリだと思っています。 というのも僕の考えるアプリって複雑な機能を必要としないアプリですし、基本的にPHPが動作すれば問題ありません。DBも使用できますし。(じゃないとWordPress動かない) また、セキュリティも問題ないと思っています。レンタルサーバーだろうがVPSだろうがIDとPASSをしっかり守ること、知っていても簡単にログイン出来ないようすること、やることは対して変わりません。IP制限とかもできるサービスもありますね。 そもそも大半のHPはレンタルサーバーで稼働しているサイトが多いと思いますしね。 メリット 安い。月額500円くらいで100GB使えます。ファイルサーバーやメールサーバーとしても使用できます。 メールの設定などすでに実装されているものを作成する必要がない。 デメリット 環境の選択肢が有限。使用できる言語が限られたりする。 マシンパワーに依存してしまう。 僕の作ったクソアプリはユーザー数少ないのでまだパワー不足に陥ったことはありませんので、なんとも言えませんが、有名サイトや有名HPがレンタルサーバーで動いているのを考えると、ある程度のパワーも持っているのではないでしょうか? herokuなどのサービスやAWSばかりに注目が行っていますがレンタルサーバーという選択肢は結構アリだと思っています。 PHPのCGIモードとモジュールモード モード説明 モジュールモードApacheの拡張機能でPHPを直接実行するモード CGIモードCGIプログラムを別途実行するモード さくらのレンタルサーバーの公式HPでは ※自社調べ。スタンダードでCGIモード(PHP5.6)とPHPモジュールモード(PHP7.1)を比較。WordPress4.9.5を使用し、同一の負荷をかけた状態でWordPressページのソース表示リクエストの処理時間を計測しました。結果、CGIモード8.2秒、PHPモジュールモード0.5秒の処理時間となりました。 >なお計測値は参考となり、すべての環境で同様に表示速度が改善されるわけではなく、お客さまが運営するウェブサイトの構成などにより変化が見られない場合もございます。 とあります。 CGIモード(PHP5.6)とPHPモジュールモード(PHP7.1)で、PHPのバージョンに差異があるのは気になりますが、それを踏まえてもかなり早くなっていることがわかります。 最大16倍に高速化するそうです。 僕のクソアプリもかなり早くなった感あってうれしい このnon'Laboも表示までかなり早くなったと思います。 まだ胸張って「良いアプリだ!」といえるアプリは作っていないので、他の例は挙げていませんが、現在新しいアイデアをアプリ化しているのでそのアプリでも体験してみてください! その時はよしなに。 .
CakePHP3.0でCSRF対策済みのアクションテストを行う
2019/11/28 2019/12/12CakePHP「3.0」で「CSRF」のコントローラー「テスト」を行う こんにちはNonです。 今回はあるプロダクトの開発に出くわしたちょっとした内容の課題を解決する手法についてお話しようと思います。 かなりニッチな需要となりますので、お役に立てるかわかりませんが参考になれば嬉しいです。 はじめに 環境は CakePHP「3.0」 です。CakePHP「3.1」以降ではCSRF対策のテスト手法は確率されているので、この記事の対象者はCakePHP3.0のユーザーということになります。 結論 CakePHP3.0では copied./** * Test sample method */ public function testSample() { // sample-tokenの部分は任意の値で大丈夫です。 $this->cookie('csrfToken', 'sample-token'); $url = Router::url(['controller' => 'Sample', 'action' => 'sample']); $data = [ 'sample' => 'サンプル', '_csrfToken' => 'sample-token' ]; $this->post($url, $data); } sample-tokenの部分は任意の値で大丈夫です。 CakePHP3.1以降では copied./** * Test sample method */ public function testSample() { $this->enableCsrfToken(); $this->enableSecurityToken(); $url = Router::url(['controller' => 'Sample', 'action' => 'sample']); $data = [ 'sample' => 'サンプル', ]; $this->post($url, $data); } 事例 とあるプロダクトの開発中、こんな出来事に遭遇しました。 あれ?このプロダクトCSRF対策されてないやん…… このプロダクトは簡素なもので、最近引き継いだばかり、プロトタイプと言っていいほどの機能にしか持っていないので、当時の作成者は面倒臭くてCSRF対策を忘れていたのでしょう。 よっしゃ、CakePHP3だしCSRF対策楽勝やろ!やったろ! 軽い気持ちで実装しました。 問題 CSRF対策は導入できたけどPHPUnit通らなくなってもうた…… CakePHP3の更新HPのCSRFアクションのテストの項目では…… CsrfComponent や SecurityComponent で保護されたアクションのテスト SecurityComponent または CsrfComponent のいずれかで保護されたアクションをテストする場合、 テストがトークンのミスマッチで失敗しないように自動トークン生成を有効にすることができます。 copied.public function testAdd() { $this->enableCsrfToken(); $this->enableSecurityToken(); $this->post('/posts/add', ['title' => 'Exciting news!']); } また、トークンを使用するテストで debug を有効にすることは重要です。SecurityComponent が 「デバッグ用トークンがデバッグ以外の環境で使われている」と考えてしまうのを防ぐためです。 requireSecure() のような他のメソッドでテストした時は、適切な環境変数をセットするために configRequest() を利用できます。 copied.// SSL 接続を装います。 $this->configRequest([ 'environment' => ['HTTPS' => 'on'] ]); バージョン 3.1.2 で追加: enableCsrfToken() と enableSecurityToken() メソッドは 3.1.2 で追加されました。 あれ?あかんやん そら通らんわ。Cakeのソース追ってもenableCsrfToken()もenableSecurityToken()も通りで無いわけや…… 解決 でもよく考えて見ると、CSRFってトークン送信してそのトークンが合ってるだけで良い訳で、しかもPHPUnitでのリクエストが送信されれば良い(CSRF対策のテストがしたいわけではない)ので、普通にトークン送信すれば良いんじゃない? ということで、やってみました。 CakePHP3の仕様では、HTML側に埋め込まれるCSRFトークンは copied.<input type="hidden" name="_csrfToken" value="43b804c28f3bd305a513c7c8ba1f1ce61e5ac6a9"> こんな感じなので、PHPUnitでリクエストするときは copied.$this->post($url, [ '_csrfToken' => '43b804c28f3bd305a513c7c8ba1f1ce61e5ac6a9', ]) という形式になっていれば、OK。 この送信したトークンをサーバー側のクッキーと比較するはずなので、同様にPHPUnitでは copied.$this->_cookie('csrfToken', '43b804c28f3bd305a513c7c8ba1f1ce61e5ac6a9'); こう。 ということで最終的に下記のようなテストコードに。 copied./** * Test sample method */ public function testSample() { // sample-tokenの部分は任意の値で大丈夫です。 $this->cookie('csrfToken', 'sample-token'); $url = Router::url(['controller' => 'Sample', 'action' => 'sample']); $data = [ 'sample' => 'サンプル', '_csrfToken' => 'sample-token' ]; $this->post($url, $data); } 結果 無事成功しました。 余談 CakePHP3.1.2以降では…… copied./** * Test sample method */ public function testSample() { $this->enableCsrfToken(); $this->enableSecurityToken(); $url = Router::url(['controller' => 'Sample', 'action' => 'sample']); $data = [ 'sample' => 'サンプル', ]; $this->post($url, $data); } これでOKです。 設定するの面倒なので、CakePHPのバージョンあげますか…… 最後に フレームワーク独特の課題にぶつかりまして、少し楽しかったです。 実はもうCakePHP3のバージョンアップソースは完成しているので、またテスト内容をリライトしなければならないのですが、CakePHP3.0特有の課題を見つけることができてよかったと思います。 地味な内容になってしまいましたが、今後もニッチな内容のものを見つけましたら記事にしていこうと思います。 その時はよしなに。 . おまけ https://labo.nozomi.bike 僕の個人ブログです。(Laravel + Vue)で自作。 こっちにしかない記事も多数ありますので、よかったら見てやってください。
VSCodeセットアップ方法
2019/11/29 2019/12/05この前少し設定について聞かれたのでメモ 前提 VSCodeのプラグインは自由に設定可能なので、この内容は参考までにお願いします。 PHPを利用を前提としています。 Homebrewのインストール Composerのインストール お手軽版 僕のVSCode設定をそのままダウンロードすることができます。 https://gist.github.com/Nozomi-Hosaka/73330eef313f4a4fb4c2a71f6bd0012c サイドメニューのExtensionsからSettings SyncをVSCodeにインストールしてください。 command + Shift + p を押してください。 コマンド欄にSyncと入力してください。 Sync: 設定をダウンロード or Sync: Download Settingsという項目があるので、それを選択してください。 下図のような画面になりましたら、Download Public Gistをクリックしてください。 https://gist.github.com/Nozomi-Hosaka/73330eef313f4a4fb4c2a71f6bd0012c のID部分である73330eef313f4a4fb4c2a71f6bd0012cを入力してください。 インストールが成功すれば完了です。 GitHubのアカウントを求められた場合は作成するか、アカウントを持っている場合はログインしてください。 1から設定版 PHPの開発に必要最低限必要なものをリストにします。 Extensionsから検索してインストールしてください。 (要)PHP IntelliSense コードの補完などしてくれます。 settings.json copied.{ "php.validate.executablePath": "/usr/bin/php", } (要)PHP Debug xdebugを利用したデバッグツールです。 参考 https://qiita.com/non_z250/items/96fd7779bdf2bbae26f5#%E3%82%82%E3%81%A3%E3%81%A8%E4%BE%BF%E5%88%A9%E3%81%AB%E3%81%97%E3%82%88%E3%81%86%E3%83%96%E3%83%AC%E3%83%BC%E3%82%AF%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88 (要)PHP Extension Pack PHP IntelliSenseとPHP Debugの拡張パックです。 (要)PHP Intelephense コードの補完などしてくれます。 phpcsをインストールしない場合はこれをフォーマッターとして登録します。 settings.json copied.{ "[php]": { "editor.defaultFormatter": "bmewburn.vscode-intelephense-client" }, } (要)PHP DocBlocker PHP Doc の規則に従ったブロックコメントを自動補完してくれます。 (要)GitLens コード上でGitのコマンドをGUIで実行することができます。 (要)Docker コード上でGitのコマンドをGUIで実行することができます。 (要)Docker Explorer コード上でGitのコマンドをGUIで実行することができます。 phpcs 設定がめんどくさいので時間に制限がある場合は無視して可。 PHP のコーディング規約のチェックをしてくれます。 https://qiita.com/AkiraTameto/items/6f4aa8debd18024cf634 @PSR2を採用しているので、Qiita記事の通りに設定でOKです。 composerをインストールしていない場合、homebrewでインストールしてください。 設定例 settings.json copied.{ "phpcs.standard": "PSR2", "phpcs.executablePath": "/Users/nozomihosaka/.composer/vendor/bin/phpcs", } php cs fixer 設定がめんどくさいので時間に制限がある場合は無視して可。 php cs fixerを利用して、PHPのコーディング規約をチェックして、自動的に修正してくれます。 phpcsをインストールしている場合、phpcsをアンインストールしてください。 Code Spell Checker スペルなどのタイポを検出してくれます。
Smaregi Tech Talk #1
2019/10/25 2019/10/25スマレジがホストで勉強会を開催した話 こんにちは。Nonです。 プロフィールにもある通りですが、私は株式会社スマレジでサーバーサイドエンジニアをしています。 この株式会社スマレジで初の勉強会を開催しました。 テーマはWEBAPIでした。 今回はちょっとビジネス寄り スマレジAPI 一発目は弊社の今西さんがスマレジAPIについて説明しました。 スマレジの無料契約から使用できるので、よければ使ってくださいね。 スマレジ・デベロッパーズ - スマレジとコラボしませんか? スマレジの次期バージョン「スマレジ4.0」がリリースされます。「スマレジ4.0」では、開発パートナーが参加することができるスマレジプラットフォームを構築。スマレジのAPIを活用したアプリを販売できるス... LTVを最大化させるスマレジ×Zoho CRM連携術 カイト合同会社CEO&Co−founder 藤川勝廣さんのスマレジとZoho CRMの連携についてでした。 Zoho CRMというのを初めて知ったので、詳しい内容まではわかりませんでしたが、これとスマレジを両方導入することで、店舗を1から10まで開設できるそう。 Zoho CRMに無いものがスマレジにはあるそうです。 Poewr BIからリアルタイム・ダイレクトにスマレジAPIデータをクエリしてビジュアライズする方法 CData Software Japan合同会社 エンジニア 杉本 和也さん のPoewr BIについてのお話でした。 スマレジAPIのレスポンス結果をより使いやすいように纏めていただいているようです。 Power BIにインストール出来る形で配布するそうで、とても楽しみです。 実務でつまずくREST API こちらが僕の発表した内容です。 内容はスマレジAPIと全く関係無い上に、ビジネス寄りではなくテック系のお話だったので、不安たっぷりでした。 内容は以前記事にしておりますので、ご覧ください。 https://labo.nozomi.bike/article/26 最後に 発表ってやっぱり難しいなぁと思いました😇 喋ってる内容もちゃんと筋が通ってるか不安になってしまいましたね。 でも自分の意見をアウトプットしてそれにレスポンスをいただけるだけで嬉しいものです。 また機会があれば参加したいですね。 そのときはよしなに。 .
RESTful APIを実用的に使うためにはどうすればいいだろうか?
2019/10/11 2019/10/16RESTful APIを実用的に使うためにはどうすればいいだろうか? こんにちは。のんです。 実は 【大阪・本町】smaregi tech talk #1 【Web API】 にLT枠で登壇することになりまして、このために再度REST APIについて纏めていました。 何番煎じかわかりませんが、お付き合いください。 スライドはこちら Smaregi Tech Talk #1 REST API 実務でつまずくREST API ちょっと絵文字が崩れてるけど許してください🙇 GoogleSlidesを使ったのですが、うまいこと行く方法があれば教えて下さい REST APIは実務で使うとちょっと悩むところがある WEB APIをRESTで設計するとめちゃくちゃ簡単に設計と作成することができますが、 いざ作成してみると、「こういうときどうすればええねん」みたいなときが多くなります。 今回はそういったちょっと考えちゃうところの解決案を提示していこうかなと思います。 よくある簡単なやつ めちゃくちゃ簡単ですね。 強いて挙げるとすれば、バルク参照でしょうか。 個人開発などの小規模アプリでは1個の参照で十分という場合が多いです。 多くても10個とかなので、それでも何回かリクエスト飛ばして対応することも多いでしょう。 しかし業務アプリのAPIとなると数千の参照を一発で解決したいという要望は結構多いです。(少なくとも僕の周りでは) そこでapi/products/{:id}で対応するのではなく、api/products/{:id},{:id},{:id}・・・で対応するバルク参照があります。 結構思いつく方も多そうなので、スライドでは言及していませんが、一応実務的な内容なので、挙げておきます。 このとき注意したいのはmysqlなどで一括取得するときのIN句には限界があるところや、レスポンスの容量が大きすぎないよう調整をかけるところでしょうか。 実際には・・・ 想像するように実際には中間テーブルや関連テーブルが腐るほどつながっているテーブルが多いですよね。 しかも、その関連は更新がある度に判定・更新をしなければならない仕様が多いので、RESTでリソースにアクセスする際に中のコードで嫌な設計になってしまいがちかもしれません。 自作アプリでも簡単な内容ですが、似たようなことがありました 僕が作成している個人開発のアプリ トドTask でもAPI作成時に似たようなことがありました。 タスクとノートをそれぞれ独立させて作成できる機能があったのですが、タスクのメモ代わりとしてノートに書くというユースケースがありましたので、タスクとノートを紐付けて管理する機能を新規追加していたときのことです。 タスク追加のAPIでノートも一緒に登録して、紐付けしたいと僕は思いました。 でも単純な考え方をすると copied.api/tasks api/notes api/tasks_notes の3つのエンドポイントを用意して登録処理をしなければならないと考えてしまいました。 まぁでもそうではありませんよね。 解決策① テーブル=リソースではない DBに用意されているテーブルそのものがリソースとは限らない点に気づきました。 MVCにおけるModelのように、複数のテーブル情報を組み合わせて、1つのリソースと考え、エンドポイントを1つにまとめることができます。 こうすることで、 copied.api/todo に対して copied.{ "task": "新しいアプリを作る", "note": "LINE Bot を使いたい", "status": "1", } というリクエストボディを送信することでtaskとnoteを登録・更新することができます。 解決策② 煩わしいAPIにしない 解決策①は纏めてしまうという考え方ですが、こちらは連結させてしまうという考えです。 よくありそうなレスポンスが、成功時に成功メッセージだけを送信して終了するみたいなエンドポイントがありますが、そういったものは控えたほうがいいでしょう。 間違いではありませんが、API使用者側がこのレスポンスを使用して次のアクションにつなげにくいです。 登録成功時には、そのリソースに関わる現在の情報を返してあげれば、その情報を使って次のアクションをお越しやすいです。 こういう風な情報をキャッチボールするとよりAPIを使用しやすくなり、ユーザーのためにナリやすいですね。 今回の場合はidを流用してnote_idとして使いまわします。 リクエストを2回送信することになりますが、シンプルな実装になりそうです。 まぁでも解決策①のほうがスマートで良いですね WEB APIでサービスを起動したい REST APIなのでエンドポイントは名詞ですよね。 でも昨今台頭してきている機械学習APIなどはどう考えてもリソース(つまり名詞)ではなくサービス(つまり動詞)です。 こういうときREST APIだとエンドポイントに悩みます。 解決策 RESTにこだわりすぎない 例えば検索サービスなどをAPIにするときはこうなってしまいそうで怖いですね。 copied.api/search copied.{ "users": { "name": "Z250" }, "tasks": { "name": "Z250" }, "notes": { "name": "Z250" } } このようなjsonではなんかRESTっぽくないしイケてない。 そういうときはこうしてみてはいかがでしょうか? REST APIの目的はAPI使用者にわかりやすいエンドポイントを作成することです。 RESTにこだわりすぎてわけわからんエンドポイントを作成してしまっては本末転倒なので、注意しましょう。 当たり前ですが、エラー処理 当たり前ですが、エラー処理はHTTPステータスコードを使用しましょう。 「当たり前やんけ」と思った方、そうは思っても実際にエラーコードをボディに書いてしまったことは無いでしょうか? 大規模になるほど、エラーも独自仕様になりやすくなってしまいます。 心を鬼にして、デファクトスタンダードを進みましょう。 よく使うHTTPステータスコードです。 エラーメッセージは最低限を返すようにしましょう。 エラーメッセージはAPI使用者が任意に変更したいはずですから。 最後に フロント言語の台頭でAPIは更に重要に 機械学習・統計のネタにされやすくなる 食べログ 天気予報 図書館 リソースではなくサービスの提供もできる この辺は抑えておきたいですね。 Googleなんかは機械学習用のデータAPIや、機械学習行った結果を返すサービスAPIなども用意しています。 APIが当たり前の時代がやってきました。 皆さんが作るアプリにはWEB APIが実装されているでしょうか? 僕のアプリも絶賛開発中です。 もし僕のAPIを利用するときはよしなに。 .
TANAXのツアーシェルケース2(MFK250)をZ250に取り付け
2019/10/09 2019/10/09TANAXのツアーシェルケース2(MFK250)をZ250に取り付けてみました! こんにちは。Nonです。 今回は久しぶりに技術記事ではなく、どちらかといえばレビューになります🏍 これ、買いました。 Amazon.co.jp: タナックス(TANAX) バイク用サイドバッグ MOTOFIZZ ツアーシェルケース2 (カーボン柄) 容量40ℓ(片側20ℓ) MFK-250 : スポーツ&アウトドア TANAXツアーシェルケース2(MFK250) 本体サイズ : (H)300×(W)420×(D)220mm(片側) 容量 :20L(片側) 最大収納重量 :2.5kg(片側) 材質 :ポリカーボネート+1680D ポリエステル 内容 :バッグ本体×2、インナーポーチ×2、イージーベース×1、固定ベルト×4、セフティーベルト×1、取扱説明書×1 では早速Z250の実際の装着感を見てみましょう こんな感じ うーんやっぱりZかっこいいですわ🏍 思ったより前に装着するイメージですね。 色はカーボンというよりもメタリックグレー 写真の感じで伝わるかと思いますが、カーボン柄というよりも光沢のあるシルバーに近いです。メカメカしいのが好きな方にはぴったりかも。 色はこれしかわかりません。 装着具合 良好😁 結構ぴったり張り付く感じでくっついています。 この写真からわかるようにマフラーへの干渉もありません!! 結構タンデムシート上が水平に伸びる感じなので、少し大きめのツーリングバッグがドンっと乗りますね。 ナンバープレートの荷掛けフックあれば嬉しいかも 荷掛けフックがあれば、シェルを固定する箇所に困らなくていいかもしれません。 もしなくても近くに固定する場所がありますが、輪っか状になってると安心できます。 ウインカーにはギリギリで干渉していないです。 ここは工夫次第でしょうか。 積載量は申し分無し 成人男性(チビ)の肘の長さくらいです。 中に入っている袋はキャンプ用の椅子です。 よくあるやつ!! それがすっぽりちょうどですね。 走行感 意識しなくてもいつもどおりの走行ができました。 しかしスポーツ走行は控えたほうがいいでしょう。 あとすり抜けが癖になってる人はバッグがあたってしまうかもしれません。 ノーマルのミラー幅とトントンくらいの幅を取ります。 また、降りるときに足を引っ掛けない様に注意!(僕は立ちゴケしそうになりました😂) 最後に これでかなりのロングツーリングを楽しめしそうです。 キャンプ道具を揃えている最中なので、来年の夏は長期休暇どこかでとってキャンプツーリング行きたいですね!! なにか他に知りたい内容があればコメントにでも書いて下さい 来週あたりはPWA、特にServiceWorkerらへんの記事を書けたらなと思っております。 そのときはよしなに。 .