tag:crieit.net,2005:https://crieit.net/users/sosoppiy/feed みみみみみの投稿 - Crieit Crieitでユーザーみみみみみによる最近の投稿 2021-11-29T16:12:33+09:00 https://crieit.net/users/sosoppiy/feed tag:crieit.net,2005:PublicArticle/17794 2021-11-29T16:12:33+09:00 2021-11-29T16:12:33+09:00 https://crieit.net/posts/home-url-get-template-directory-uri-get-stylesheet-directory-uri-WordPress home_url、get_template_directory_uri、get_stylesheet_directory_uriの違い【WordPress勉強備忘録】 <h2 id="home_url"><a href="#home_url">home_url</a></h2> <p>サイトのURL<br /> 例)https://example.com/</p> <h2 id="get_template_directory_uri"><a href="#get_template_directory_uri">get_template_directory_uri</a></h2> <p>親テーマディレクトリまでのURL<br /> 例)https://example.com/wp-content/themes/xxx/</p> <h2 id="get_stylesheet_directory_uri"><a href="#get_stylesheet_directory_uri">get_stylesheet_directory_uri</a></h2> <p>子テーマディレクトリまでのURL<br /> 例)https://example.com/wp-content/themes/xxx-child/</p> みみみみみ tag:crieit.net,2005:PublicArticle/17292 2021-05-27T12:11:46+09:00 2021-05-27T12:11:46+09:00 https://crieit.net/posts/XSS XSSについてちゃんと調べてみた <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>OWASP ZAPで脆弱性診断を行ったところ、<strong>クロス サイト スクリプティング(DOMベース)</strong> というのが出てしまいました。<br /> XSS自体はよく聞くので知っていましたが、「DOMベースって何?そもそもXSSのことちゃんと理解してないな?」<br /> と思い調べてみたので、まとめていきます。</p> <h1 id="XSSとは"><a href="#XSS%E3%81%A8%E3%81%AF">XSSとは</a></h1> <p>Webサイトの脆弱性を突き、攻撃者がそこに悪質なスクリプトを仕掛ける攻撃です。<br /> 画面を一時的に改ざんしてログイン情報を抜き取ったり、Cookieを盗み見たりなど、とにかく危険満載って感じです。</p> <p>XSSには以下の3パターンがあります。</p> <h2 id="反射型"><a href="#%E5%8F%8D%E5%B0%84%E5%9E%8B">反射型</a></h2> <p>フォーム入力などを行った次のページで発生するヤツです。<br /> <a target="_blank" rel="nofollow noopener" href="https://gihyo.jp/dev/serial/01/javascript-security/0002">こちら</a>の例を使用させていただきます。</p> <p>検索画面で、ユーザーが「HTML5」と入力すると、<br /> <code>http://example.jp/search?q=HTML5</code>というURLで検索結果が表示されるとします。</p> <p>検索結果画面では、よく「◯◯を検索しました。◯件見つかりました。」みたいなのがありますよね。<br /> その部分がHTMLで以下の様になっているとします。</p> <pre><code class="html">語句「<span class="keyword">HTML5</span>」を検索しました。20件の文書が見つかりました。 </code></pre> <p>ユーザーが入力した「HTML5」をそのまま<code>span</code>で囲んで出力している感じですね。</p> <p>これにもし、検索キーワードとして<code><script>alert(1)</script></code>なんてものを入力された場合</p> <pre><code class="html">語句「<span class="keyword"><script>alert(1)</script></span>」を検索しました。20件の文書が見つかりました。 </code></pre> <p>となってしまいます。</p> <p>本来文字列として表示されるべき部分が<code><script></code>要素になってしまい、<br /> ブラウザ上ではJavaScriptが動作してしまうことで、XSSが発生します。</p> <p>これを利用して、<code>alert(1)</code>なんて可愛いものではなくてもっとエグいものを仕込まれることで被害が起きるという仕組みですね。</p> <h2 id="蓄積型"><a href="#%E8%93%84%E7%A9%8D%E5%9E%8B">蓄積型</a></h2> <p>DBに保存されている情報を表示させるときに発生するヤツです。</p> <p>例えば掲示板サイトがあったとして、攻撃者が本文に</p> <pre><code class="html"><script>alert(1)</script> </code></pre> <p>と入力して投稿→DBに保存されたとします。</p> <p>他のユーザーが掲示板を開くとこの攻撃者からの投稿が表示され、<br /> JavaScriptが勝手に実行されてしまい、XSSが発生します。</p> <h2 id="DOMベース型 "><a href="#DOM%E3%83%99%E3%83%BC%E3%82%B9%E5%9E%8B%E3%80%80">DOMベース型 </a></h2> <p>JavaScriptがDOMを構築するときに発生するヤツです。<br /> 今回起きてたのはコレですね。<br /> <a target="_blank" rel="nofollow noopener" href="https://gihyo.jp/dev/serial/01/javascript-security/0006">こちら</a>の例を使用させていただきます。</p> <p>以下のようなコードがあるとします。</p> <pre><code class="javascript">div = document.getElementById("info"); div.innerHTML = location.hash.substring(1); </code></pre> <p><code>location.hash.substring(1)</code>でURLのハッシュ部分(#以降)を取得し、<br /> それを<code>id="info"</code>の<code>div</code>要素に入れることで、画面に表示させている処理です。</p> <p>URLが<code>http://example.jp/#title1</code>みたいなものなら問題ないですが、<br /> <code>http://example.jp/#<img src=1 onerror=alert(1)></code> のようなURLを開いた場合、<br /> <code><img src=1 onerror=alert(1)></code> がHTML内に展開され、JavaScriptが実行されることでXSSが発生します。</p> <h1 id="困ったことに全く心当たりがない"><a href="#%E5%9B%B0%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8%E3%81%AB%E5%85%A8%E3%81%8F%E5%BF%83%E5%BD%93%E3%81%9F%E3%82%8A%E3%81%8C%E3%81%AA%E3%81%84">困ったことに全く心当たりがない</a></h1> <p>今回起きた(診断された)DOMベースのXSSが何なのかはわかったけど、<br /> 自分のコードにおいて心当たりが全く無い!<br /> フロントエンドはVueで作成しているので、VueにおけるXSSについても調べる必要がありそうだなと。<br /> OWSP ZAPの誤検知の可能性もあるので、万が一明確な原因が見つかったら、またまとめておこうかなと思います。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://gihyo.jp/dev/serial/01/javascript-security/0002?page=1">第2回 Webセキュリティのおさらい その2 XSS:JavaScriptセキュリティの基礎知識|gihyo.jp … 技術評論社</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://gihyo.jp/dev/serial/01/javascript-security/0006">第6回 DOM-based XSS その1:JavaScriptセキュリティの基礎知識|gihyo.jp … 技術評論社</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.slideshare.net/tobaru_yuta/vuejs-xss">Vue.js で XSS</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/miya_zato/items/7ea57326c86a198fcf08">XSSと、XSSの種類について - Qiita</a></li> </ul> みみみみみ tag:crieit.net,2005:PublicArticle/17277 2021-05-25T16:54:10+09:00 2021-05-25T16:54:10+09:00 https://crieit.net/posts/OWASP-ZAP OWASP ZAPで脆弱性診断を行う際の、予備知識的なもの─ローカルプロキシの設定編 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>OWASP ZAPを使って脆弱性診断を行う際、色んなサイトを参考にしながら進めていますが<br /> よくわからない箇所もとりあえず「そういうものなんだなー」と深く考えず、書いてあるとおりに行っていました。</p> <p>今回はそこを「それってなんズラなんズラ?」とツッコみつつ、<br /> なんとなく、ざっくり、ゆる~く 見ていこうかなと思います。</p> <p>なお、手順は<a target="_blank" rel="nofollow noopener" href="https://qiita.com/aikasu/items/6bfd33967448136b93bc">こちら</a>に沿って進めていきますが、<br /> 触れるのは冒頭の「ローカルプロキシの設定」のみとなっています。</p> <h1 id="プロキシ"><a href="#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7">プロキシ</a></h1> <p>手順によるとまず最初に、</p> <blockquote> <p>OWASP ZAPをプロキシとして使用することで診断対象サイトへリクエストを送信し、そのレスポンスから脆弱性を診断します。</p> </blockquote> <p>とありますね。<br /> 私はまだ赤ちゃんなのでそもそもプロキシってなんやねんレベルです。プロ棋士??ひふみん????</p> <h2 id="プロキシはブラウザとサーバの仲介人的ポジション"><a href="#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%81%AF%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%A8%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E4%BB%B2%E4%BB%8B%E4%BA%BA%E7%9A%84%E3%83%9D%E3%82%B8%E3%82%B7%E3%83%A7%E3%83%B3">プロキシはブラウザとサーバの仲介人的ポジション</a></h2> <p>まずは<a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word1752.html">わわわIT用語辞典</a>さんを読んでみます。<br /> マジいつもお世話になってます。</p> <p>簡単説明をそのまま引用すると、</p> <blockquote> <p>ホームページを見るときに使うソフト(Webブラウザ)の身代わりになってホームページにアクセスしてくれるコンピュータ(サーバ)のこと</p> </blockquote> <p>らしい。ほほーう。</p> <p>以下、書いてあったことほぼそのままですが、</p> <h5><del>プロ棋士</del>プロキシが居ないとき</h5> <p><a href="https://crieit.now.sh/upload_images/5410c8c78b63e2daeba20552c322f97960ab648d2a215.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5410c8c78b63e2daeba20552c322f97960ab648d2a215.png?mw=700" alt="image" /></a></p> <p>ってなるところが、</p> <h5 id="プロキシが居るとき"><a href="#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%81%8C%E5%B1%85%E3%82%8B%E3%81%A8%E3%81%8D">プロキシが居るとき</a></h5> <p><a href="https://crieit.now.sh/upload_images/19eb7c013188633f8a300785fc00457f60ab6643b1d18.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/19eb7c013188633f8a300785fc00457f60ab6643b1d18.png?mw=700" alt="image" /></a></p> <p>こんな感じに間に挟まってくれる。</p> <h2 id="プロキシの何が良いの?"><a href="#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%81%AE%E4%BD%95%E3%81%8C%E8%89%AF%E3%81%84%E3%81%AE%EF%BC%9F">プロキシの何が良いの?</a></h2> <p>アクセス元を隠せる、レスポンスが早い、などありますが、今回の脆弱性診断に関係ありそうなのは<br /> サーバに送ったリクエスト内容を見たり変更したりすることが出来る ということですかね。<br /> (厳密には使わなくても出来るけど、より簡単に出来るってことかも)</p> <h2 id="なるほど。で、つまりは?"><a href="#%E3%81%AA%E3%82%8B%E3%81%BB%E3%81%A9%E3%80%82%E3%81%A7%E3%80%81%E3%81%A4%E3%81%BE%E3%82%8A%E3%81%AF%EF%BC%9F">なるほど。で、つまりは?</a></h2> <p>「OWASP ZAPをプロキシとして使用して、ブラウザさんとサーバくんの間に入ってもらおう。<br /> そして、プロキシちゃんを使ってリクエスト内容を変更してPOSTしまくることで、脆弱性を見つけていこうZE!」</p> <p>…めっちゃざっくりいうと、こういうことなんだろうなと、ひとまず理解。</p> <h1 id="次いってみよーーう"><a href="#%E6%AC%A1%E3%81%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%83%BC%E3%83%BC%E3%81%86">次いってみよーーう</a></h1> <p>よおし!プロキシちゃんのことが少しわかったことだし、設定に進むぞ!<br /> 手順によると…</p> <blockquote> <p>Address欄には「localhost」、ポート欄には任意のポート番号(他と競合しない番号)を入力</p> </blockquote> <p><a href="https://crieit.now.sh/upload_images/6aaea3e4da676ec504a2979c126fd92460ab7109ca9fd.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6aaea3e4da676ec504a2979c126fd92460ab7109ca9fd.jpg?mw=700" width="50%"></a></p> <h1 id="localhost(127.0.0.1)"><a href="#localhost%28127.0.0.1%29">localhost(127.0.0.1)</a></h1> <p>脆弱性診断とか関係なくよく見ますね。XAMPPでローカルサーバ立ち上げたときとか。<br /> けど説明しろって言われたら何なのかはわからないので調べてみます。</p> <h2 id="ズバリ、localhost=自分のPCのこと です!"><a href="#%E3%82%BA%E3%83%90%E3%83%AA%E3%80%81localhost%EF%BC%9D%E8%87%AA%E5%88%86%E3%81%AEPC%E3%81%AE%E3%81%93%E3%81%A8%E3%80%80%E3%81%A7%E3%81%99%EF%BC%81">ズバリ、localhost=自分のPCのこと です!</a></h2> <p>ってよく色んなところに書いてあるけどいまいちピンとこない。<br /> まずはIPアドレスについて理解していく必要がある!<br /> 頭が痛くなってきたぞぅ。</p> <h2 id="IPアドレス"><a href="#IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9">IPアドレス</a></h2> <p>「インターネット世界での住所」みたいによく説明されてますね。<br /> 前提として、すべてのwebサイトにはIPアドレスを持っています。<br /> 住所不定のホームレスwebサイトなんてものは存在しないわけですね。</p> <h3 id="じゃあURLってなんなのさ"><a href="#%E3%81%98%E3%82%83%E3%81%82URL%E3%81%A3%E3%81%A6%E3%81%AA%E3%82%93%E3%81%AA%E3%81%AE%E3%81%95">じゃあURLってなんなのさ</a></h3> <p>脆弱性診断をやろうとしてる人なら既にわかってるとは思いますけども、<br /> webサイトってIPアドレスで開くこともできちゃいますよね。<br /> まさに開発環境なんかは、<code>192.168.0.15</code>みたいにIPアドレスを入力して開いていたりするわけで。</p> <p>つっても普段はIPアドレスじゃなくて<code>https://www.google.com</code>っていうURLでwebページを開きますよね。<br /> <code>google.com</code>の部分が所謂<code>ドメイン</code>なのですが、このドメインはIPアドレスと一対一の関係にあります。</p> <ul> <li>IPアドレス→コンピュータさん向けのもの</li> <li>ドメイン →人間様向けのもの</li> </ul> <p>と言った感じです。</p> <p>ちなみに<code>www</code>の部分は<code>ホスト名</code>というらしい。</p> <h2 id="グローバルIPとプライベートIP"><a href="#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%ABIP%E3%81%A8%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88IP">グローバルIPとプライベートIP</a></h2> <p>IPアドレスには、さらにグローバルIPとプライベートIPの2つが存在するらしい。<br /> 更に頭が痛くなってきた!</p> <h3 id="グローバルIP"><a href="#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%ABIP">グローバルIP</a></h3> <p>全世界のネットワーク上における住所みたいなもので、重複しないIPアドレスのことです。<br /> 自分の家の住所とすぐお隣の人の住所が全く同じ、みたいなわけのわからんことになったら困りますよね。<br /> UberもAmazonも届かなそう。そんなイメージ。</p> <p>世の中に公開されているwebページのIPアドレスは、全部このグローバルIPです。<br /> そりゃそうですよね、Googleと同じIPが複数あったらカオスなことになります。</p> <h3 id="プライベートIP"><a href="#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88IP">プライベートIP</a></h3> <p>組織内のネットワーク(ローカルネットワーク?)内で使用できる、自分で勝手に決めてOKなIPアドレスのこと。<br /> 同じネットワークの中にいる人達だけに意味が伝わる、仲間内のみに通用する住所的な感じだと思います。</p> <p>マンションAに住んでいる人に、「これ1階のエントランスホールの管理人に渡しといて~」というのは通じますが、<br /> そのへんにいたオッさんに同じことを言っても「は?」って言われますよね。1階のエントランスホールって、どこの1階やねんと。</p> <p>そもそも、「1階のエントランスホール」っていうのはマンションAだけにあるものではないですよね。<br /> マンションBにもCにもあるかもしれません。</p> <p>でもマンションA内に「1階のエントランスホール」が複数あったらちょっと変ですよね。<br /> (エントランスが2つある構造とか、そういう話じゃないよ)<br /> マンションAの中に「202号室の佐藤さん」が複数あったらおかしい、の方がわかりやすいか。</p> <p>そんな感じの理屈で、プライベートIPは<br /> 同じネットワーク内で重複して使うことは出来ないけど、世界規模で見たら重複はOKです。</p> <h3 id="じゃあlocalhost(127.0.0.1)はどっち?"><a href="#%E3%81%98%E3%82%83%E3%81%82localhost%28127.0.0.1%29%E3%81%AF%E3%81%A9%E3%81%A3%E3%81%A1%EF%BC%9F">じゃあlocalhost(127.0.0.1)はどっち?</a></h3> <p>もうおわかりかと思いますが、プライベートIPです。<br /> プライベートIPなので、皆同じ127.0.0.1っていうIPアドレスで自分のPCにアクセスすることが出来るというわけです。</p> <h2 id="localhostにアクセスしてみる"><a href="#localhost%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">localhostにアクセスしてみる</a></h2> <p>試しに、何もしないままでブラウザからlocalhostにアクセスしてみます。(URL部分にlocalhostって入れる)<br /> <a href="https://crieit.now.sh/upload_images/615a5561b95c310f92932d9da840c00260ac62c271d4e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/615a5561b95c310f92932d9da840c00260ac62c271d4e.png?mw=700" alt="image" /></a><br /> 当然こうなります。</p> <p>localhostというのは自分のPCを指している、ただそれだけであって、<br /> 何もしていないのであればwebサーバでもDBサーバでもなんでも無いんですよね。</p> <p>ここで、Apacheを起動した状態でlocalhostにアクセスしてみます。</p> <p><a href="https://crieit.now.sh/upload_images/058f853c1a17847b976120b7a1ac913560ac63ce316c6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058f853c1a17847b976120b7a1ac913560ac63ce316c6.png?mw=700" alt="image" /></a></p> <p>XAMPPを入れてるので、お馴染みのこの初期画面が出てきました。<br /> (なので厳密には、「localhost/dashboard/」になるんですけど)</p> <p>Apacheを起動したことで、PCさんはwebサーバとして機能し始めました。<br /> もちろん、DBサーバとして機能させることも可能なわけです。</p> <h2 id="なるほど。で、つまりは?"><a href="#%E3%81%AA%E3%82%8B%E3%81%BB%E3%81%A9%E3%80%82%E3%81%A7%E3%80%81%E3%81%A4%E3%81%BE%E3%82%8A%E3%81%AF%EF%BC%9F">なるほど。で、つまりは?</a></h2> <p>ってことは、localhost(=自分のPC)を、プロキシサーバとして機能させることも出来るよね!!<br /> ということで、手順の</p> <blockquote> <p>Address欄には「localhost」</p> </blockquote> <p>は、「自分のPCをプロキシサーバちゃんとして間に挟んであげようね!」<br /> みたいな意味かな~?と。</p> <p>ふぅ~ここまで長かったぜ。</p> <h1 id="ポート番号"><a href="#%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7">ポート番号</a></h1> <p>お次は</p> <blockquote> <p>ポート欄には任意のポート番号(他と競合しない番号)を入力</p> </blockquote> <p>この部分です。<br /> こう考えると、自分何も知らねーんだな!<br /> 仕方ない、赤ちゃんだもの。<br /> 頑張って見ていきます。</p> <h2 id="まずポートとは"><a href="#%E3%81%BE%E3%81%9A%E3%83%9D%E3%83%BC%E3%83%88%E3%81%A8%E3%81%AF">まずポートとは</a></h2> <p>ネットワークからコンピュータ(サーバ)にデータを送受信するときのドアみたいなものです。</p> <p>インターネットさんは80番のドア、FTPは20番のドアですよー みたいに<br /> データによって既にどのドアを決まっているものもあれば、<br /> ここからここまでは自由に使っていいですよ~~ なドアもあります。</p> <p>80番、とか20番、っていう番号がポート番号です。</p> <h2 id="ウェルノウンポート"><a href="#%E3%82%A6%E3%82%A7%E3%83%AB%E3%83%8E%E3%82%A6%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88">ウェルノウンポート</a></h2> <p>ポート番号が0~1023までのポートのことで、基本誰が通るのか決められています。</p> <h2 id="登録済みポート"><a href="#%E7%99%BB%E9%8C%B2%E6%B8%88%E3%81%BF%E3%83%9D%E3%83%BC%E3%83%88">登録済みポート</a></h2> <p>ポート番号が1024~49512までのポートのことで、<br /> ウェルノウン程ではないけど、よく使うアプリなどに割り振られます。</p> <h2 id="ダイナミック/プライベートポート"><a href="#%E3%83%80%E3%82%A4%E3%83%8A%E3%83%9F%E3%83%83%E3%82%AF%2F%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%9D%E3%83%BC%E3%83%88">ダイナミック/プライベートポート</a></h2> <p>ポート番号が49513~65535までのポートのことで、基本的にこの間のポートが自由に使えるポートです。</p> <p>なので、</p> <blockquote> <p>ポート欄には任意のポート番号(他と競合しない番号)を入力</p> </blockquote> <p>ここには49513~65535のうち好きな番号を指定してあげればOKです。</p> <h1 id="一旦終わり"><a href="#%E4%B8%80%E6%97%A6%E7%B5%82%E3%82%8F%E3%82%8A">一旦終わり</a></h1> <p>モロ一番最初のところだけでも、だいぶ体力使いました…。<br /> 正直、ここの範囲は知らなくても脆弱性診断はできちゃいますけど、知ってて損する知識なんか無いよねってことでまとめてみました。<br /> まだ深く理解は出来てないので、ざっくりゆるーく、ですけど。<br /> 診断に関係なく、この業界にいる以上基礎中の基礎知識だったと思うので、これを期に勉強出来てよかったなと思います。</p> <p>余力があれば、次は脆弱性診断で実際に行われている攻撃なども調べられたらいいな!</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word1752.html">プロキシ (proxy)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.yoheim.net/blog.php?q=20160702#:~:text=%E6%9C%80%E5%BE%8C%E3%81%AB-,%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%81%A8%E3%81%AF,%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82">[フロントエンド] ローカルプロキシを用いて、本番サイトで開発/デバッグを行う - YoheiM .NET</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.atmarkit.co.jp/ait/articles/0710/26/news131.html">リクエストをいじれば脆弱性の仕組みが見えるのだ!:もいちどイチから! HTTP基礎訓練中(2)(1/3 ページ) - @IT</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://codor.co.jp/django/localhost">localhostについて詳しく解説【具体的に解説します】 - code for Django</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word1286.html">ドメイン名とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word11976.html">グローバルIPアドレスとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word11977.html">プライベートIPアドレスとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://kino-code.com/whta-is-port-number/#102449151">【3分解説】ポート番号ってなに? | キノコード</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://27bit.com/question-number.html">ポート番号は何番を使えばいいのか教えて下さい - ポート開放ナビ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wa3.i-3-i.info/word1774.html">ポートとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典</a></li> </ul> みみみみみ tag:crieit.net,2005:PublicArticle/17227 2021-05-21T16:23:01+09:00 2021-05-21T16:23:01+09:00 https://crieit.net/posts/php-Laravel-60a75fd51f5f0 php(Laravel)でエクセルのインポート機能付けるときに試したもの <h1 id="渡されたデータがエクセルだった"><a href="#%E6%B8%A1%E3%81%95%E3%82%8C%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8C%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB%E3%81%A0%E3%81%A3%E3%81%9F">渡されたデータがエクセルだった</a></h1> <p>「ほいっじゃあこれ取り込んでね」<br /> と渡されたのは、2~3万行のデータ(エクセル形式)だった。<br /> …えー!CSVじゃないんですかー!?!?CSVはやったことあるけど、エクセルは知らーん!!</p> <p>ということで、3つほどライブラリを試してようやく機能実装が出来たので、その時のメモです</p> <h1 id="Laravel Excel"><a href="#Laravel+Excel">Laravel Excel</a></h1> <p>URL:<a target="_blank" rel="nofollow noopener" href="https://laravel-excel.com">https://laravel-excel.com</a></p> <p>これはLaravelのライブラリ(パッケージ?)ですね。<br /> 後に紹介するPhpSpreadsheetを基に作られております。<br /> エクセルだけでなくcsvも扱えます。</p> <p>使い方も特別難しいわけでもなく、<br /> 公式ドキュメントを落ち着いて読んでいけば大抵は問題ないはずです。</p> <p>…がしかぁし!</p> <p>データ数が少なめのテストデータでは問題ありませんでしたが、<br /> いざ実際の2~3万件データで試したところメモリ不足で死に至りました。(チーン)</p> <p>php-fpmの設定弄ってみたり、<br /> toArrayがいけないのか?と思いonRowで1行ずつinsertしてみたり…。<br /> かなり色々試行錯誤してみましたが解決には至らず、ライブラリ使用自体を断念しました…。</p> <p>(もし解決法ご存知の方がいらっしゃいましたら、そっとご教示いただければ幸いに存じます)</p> <h1 id="PhpSpreadsheet"><a href="#PhpSpreadsheet">PhpSpreadsheet</a></h1> <p>URL:<a target="_blank" rel="nofollow noopener" href="https://phpspreadsheet.readthedocs.io/en/latest/">https://phpspreadsheet.readthedocs.io/en/latest/</a></p> <p>くそう、ならば元であるコイツで試してみるか!<br /> てな感じで、半ヤケクソでやってみました。<br /> なお、phpExcelというライブラリの後継版らしいです。</p> <p>結論、メモリ不足も解決せず、なんなら処理時間も増えて、解決には至りませんでした…。<br /> 使用感としては、シンプルで使いやすいなーとは思いました。<br /> また、laravel excelより使用率が高いので、参考にできる記事も多い(日本語記事も多い)という点は良かったです。</p> <h1 id="Spout"><a href="#Spout">Spout</a></h1> <p>URL:<a target="_blank" rel="nofollow noopener" href="https://opensource.box.com/spout/"> https://opensource.box.com/spout/</a></p> <h4><strong>救 世 主</strong></h4> <p>メモリ不足問題はこれで解決しました!!!<br /> 代わりにCPU使用率がギュイーンと上がりますが。</p> <p>ただこれ、マイナーなのかわかりませんがググってもほぼ出てきません。<br /> 出てきたとしても全部英語です。google翻訳がある世界に生まれてよかった。</p> <p>基本公式ドキュメントを頼りにやるしか無いので、赤ちゃんエンジニアにはちょっと厳しかったです…。<br /> やりたいことが至ってシンプルだったのでなんとかなりましたが。</p> <p>気力があれば、使い方のメモも別で書こうかと思います。来世までにはきっと。</p> <h1 id="なお後日"><a href="#%E3%81%AA%E3%81%8A%E5%BE%8C%E6%97%A5">なお後日</a></h1> <p>えらいひと「ちょっとフォーマット変えたので、再度送るで!これで取り込んでくれや! つCSVファイル」<br /> ワイ「いやCSVで出力できんのかい!!!!!!!!!!!」</p> <p>~完~</p> みみみみみ tag:crieit.net,2005:PublicArticle/17122 2021-05-14T12:59:20+09:00 2021-05-14T13:02:02+09:00 https://crieit.net/posts/200 ある日突然ロードアベレージが200を超えた <p>※サーバの知識が乏しい為、誤った情報を載せるわけにもいかないので<br /> 具体的な解決方までは記載してません。ポエム感覚です。</p> <h2 id="何が起きた"><a href="#%E4%BD%95%E3%81%8C%E8%B5%B7%E3%81%8D%E3%81%9F">何が起きた</a></h2> <p>ある日、自分が開発した社内チャットツールが504エラーで開けなくなりました。<br /> クッソ時間をかけてターミナルを開き、<code>top</code>で確認したところ<code>load average:86</code> となっていて爆笑しました。(笑っている場合ではない)<br /> その後、色々対処している最終に230くらいになりました。写真撮っておけば良かったな(白目)。</p> <h2 id="どうしてそうなった"><a href="#%E3%81%A9%E3%81%86%E3%81%97%E3%81%A6%E3%81%9D%E3%81%86%E3%81%AA%E3%81%A3%E3%81%9F">どうしてそうなった</a></h2> <p>他のツールから、かなりの数のメッセージが送られてきたのが原因でした。<br /> と言っても1分に100件~200件程度なので、めちゃくちゃ多いのか?と言われれば微妙なところです。</p> <h2 id="とりあえず復活させるぞ"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E5%BE%A9%E6%B4%BB%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9E">とりあえず復活させるぞ</a></h2> <p>実は以前にも同じことが起きたのですが、そのときはまだサーバの知識が今より乏しく、<br /> とりあえず早く復旧させなきゃという気持ちが先走って<code>reboot</code>してしまいました。<br /> もちろんこれで直ることもありますが、下手すると<code>reboot</code>してから1時間くらい立ち上がらないなんてこともあるので(経験者は語る)、<br /> むやみにやらないべきだと思います。</p> <h3 id="何が原因か突き止める"><a href="#%E4%BD%95%E3%81%8C%E5%8E%9F%E5%9B%A0%E3%81%8B%E7%AA%81%E3%81%8D%E6%AD%A2%E3%82%81%E3%82%8B">何が原因か突き止める</a></h3> <p>めちゃくちゃ重いときはターミナルを開くのも一苦労であることが多いですが、めげずに待ちましょう。<br /> で、私はとりあえず<code>top</code>でロードアベレージやメモリ、CPUを確認します。<br /> 入っているなら、<code>htop</code>の方が見やすいかも。</p> <p>その後はひらすらググります!!!<br /> 「ロードアベレージ 高い」「メモリ 解放されない」とか。<br /> もっと根本的に「504エラー 原因 突き止める」とか。</p> <p>あと、アプリ自体のlogも確認します。<br /> 今回の場合は、ログファイルが朝の時点で昨日より3倍のサイズだったり、<br /> メッセージ送信のAPIがめちゃくちゃ呼ばれていた形跡があったので、予測通りこれ原因だな…と確信しました。</p> <h3 id="原因の元をどうにかする"><a href="#%E5%8E%9F%E5%9B%A0%E3%81%AE%E5%85%83%E3%82%92%E3%81%A9%E3%81%86%E3%81%AB%E3%81%8B%E3%81%99%E3%82%8B">原因の元をどうにかする</a></h3> <p>とりあえずApacheの再起動を試みましたが、タイムアウトでエラーになり出来ませんでした。<br /> これはkillするしかないな…と思い、以下のように対処。</p> <pre><code class="bash"># Apacheのプロセスを確認 ps agx | grep httpd # とりあえず一番上に出てきたプロセスをkill sudo kill 34568 (※PID) # ロードアベレージが落ち着いてきたらApache再起動 sudo systemctl restart httpd </code></pre> <p>この処理が終わるまでも時間かかりますが、<br /> <code>kill</code>されてからは徐々にロードアベレージも減っていきました。<br /> Apacheを再起動し、なんとか復旧しました。</p> <h2 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h2> <p>根本的に、<br /> 「100件程度のメッセージで落ちないような設計にしろよ!」とか<br /> 「そもそも1分に100件送ってくんなよ!!」とか<br /> その辺りの問題はまだありますが、それはまた別の話として。</p> <p>以前よりはサーバダウンにも冷静に対処出来たんじゃないかなと思います。<br /> 今回は原因がわかっていたので良かったですが、また別の要因で再発したときにも慌てず対処したいなと思う所存でございます。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16397 2020-12-20T18:34:18+09:00 2020-12-20T18:34:18+09:00 https://crieit.net/posts/29d787280cd024b2a9aadb09721b0005 【シリアル値】エクセルファイルで、日付の項目に謎の数値が入っていて困惑した時 <h2 id="日付の項目が数値になってる"><a href="#%E6%97%A5%E4%BB%98%E3%81%AE%E9%A0%85%E7%9B%AE%E3%81%8C%E6%95%B0%E5%80%A4%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%82%8B">日付の項目が数値になってる</a></h2> <p><a href="https://crieit.now.sh/upload_images/8ada1a91858eac436fbd4379a2f2d7ca5fdf1473d8dee.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8ada1a91858eac436fbd4379a2f2d7ca5fdf1473d8dee.jpg?mw=700" alt="image" /></a></p> <p>なにこれ???</p> <h2 id="シリアル値っていうらしいよ"><a href="#%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E5%80%A4%E3%81%A3%E3%81%A6%E3%81%84%E3%81%86%E3%82%89%E3%81%97%E3%81%84%E3%82%88">シリアル値っていうらしいよ</a></h2> <p>1900年1月1日を「1」として、そこからの経過日数を数値化したものをシリアル値というらしい。<br /> <a href="https://crieit.now.sh/upload_images/1df330be3cccd5e514b821a3ca5071be5fdf18bf0253f.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1df330be3cccd5e514b821a3ca5071be5fdf18bf0253f.jpg?mw=700" alt="image" /></a></p> <h2 id="phpで日付型に変換"><a href="#php%E3%81%A7%E6%97%A5%E4%BB%98%E5%9E%8B%E3%81%AB%E5%A4%89%E6%8F%9B">phpで日付型に変換</a></h2> <p>エクセルをインポートしてDBに登録する際には日付で登録したいので、<br /> シリアル値から日付型に変換する。</p> <pre><code class="php">$date = date('Y年m月d日', ($serial - 25569) * 60 * 60 * 24); </code></pre> <p>参考:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/shy_azusa/items/c78bb79c3dc6ac0585bd">https://qiita.com/shy_azusa/items/c78bb79c3dc6ac0585bd</a></p> みみみみみ tag:crieit.net,2005:PublicArticle/16396 2020-12-20T17:53:51+09:00 2020-12-20T17:53:51+09:00 https://crieit.net/posts/laravel6-x-bootstrap laravel6.xでbootstrapを使う <h2 id="laravel6.x以降にbootstrapを入れる"><a href="#laravel6.x%E4%BB%A5%E9%99%8D%E3%81%ABbootstrap%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B">laravel6.x以降にbootstrapを入れる</a></h2> <p>laravel6.xからは、bootstrapがデフォルトで入っていないので、自分で入れてあげる必要があるらしい。<br /> 調べたところ、以下のコマンドを実行すれば良さそう。</p> <pre><code class="bash">composer require laravel/ui php artisan ui bootstrap npm install && npm run dev </code></pre> <p>これでうまく行けばおしまい。</p> <h2 id="しかし現実は甘くなかった"><a href="#%E3%81%97%E3%81%8B%E3%81%97%E7%8F%BE%E5%AE%9F%E3%81%AF%E7%94%98%E3%81%8F%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F">しかし現実は甘くなかった</a></h2> <p><del>案の定</del><code>composer require</code>の時点でエラーになった。</p> <pre><code class="bash">Using version ^2.0 for laravel/ui ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - Conclusion: remove laravel/framework v6.18.1 - Conclusion: don't install laravel/framework v6.18.1 - laravel/ui 2.x-dev requires illuminate/filesystem ^7.0 -> satisfiable by illuminate/filesystem[7.x-dev, v7.0.0, v7.0.1, v7.0.2, v7.0.3, v7.0.4, v7.0.5, v7.0.6, v7.0.7, v7.0.8, v7.1.0, v7.1.1] # 以下略 </code></pre> <p>要は、「 laravel/ui2.0はLaravel7じゃないといけないけど、君の環境はそれを満たしてないよ!」とのこと。</p> <p><a target="_blank" rel="nofollow noopener" href="https://packagist.org/packages/laravel/ui">https://packagist.org/packages/laravel/ui</a><br /> ↑によると、それぞれの対応バージョンは以下のようになっている。</p> <div class="table-responsive"><table> <thead> <tr> <th>Version</th> <th>Laravel Version</th> </tr> </thead> <tbody> <tr> <td>1.x</td> <td>5.8, 6.x</td> </tr> <tr> <td>2.x</td> <td>7.x</td> </tr> <tr> <td>3.x</td> <td>8.x</td> </tr> </tbody> </table></div> <p>つまり、laravel6.xで使うには2.xではなくて1.xを入れないといけない。<br /> というわけで、以下のようにバージョンを明記してインストールし直し。</p> <pre><code class="bash">composer require laravel/ui:1.3.0 </code></pre> <p>次に、<code>/var/www/html/vendor/laravel/ui/src/Presets/Bootstrap.php</code>の中のパスを以下の様に変更</p> <pre><code>copy(__DIR__.'/bootstrap-stubs/_variables.scss', resource_path('assets/sass/_variables.scss')); copy(__DIR__.'/bootstrap-stubs/app.scss', resource_path('assets/sass/app.scss')); copy(__DIR__.'/bootstrap-stubs/bootstrap.js', resource_path('assets/js/bootstrap.js')); </code></pre> <p>これで再度</p> <pre><code class="bash">php artisan ui bootstrap npm install && npm run dev </code></pre> <p>これで入った。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16226 2020-11-18T11:41:16+09:00 2020-11-19T13:59:08+09:00 https://crieit.net/posts/Vue-Draggable Vue.Draggable をスマホでも使う時のアレコレ <p>Vueでドラッグ&ドロップの何かしらを作ろうとした時に便利な<a target="_blank" rel="nofollow noopener" href="https://github.com/SortableJS/Vue.Draggable">Vue.Draggable</a>ですが、<br /> これまたスマホ対応している最中に困ったことがあったのでメモ。</p> <h2 id="困ったこと1:スクロールしようとするとドラッグ&ドロップされてしまう"><a href="#%E5%9B%B0%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8%EF%BC%91%EF%BC%9A%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%EF%BC%86%E3%83%89%E3%83%AD%E3%83%83%E3%83%97%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">困ったこと1:スクロールしようとするとドラッグ&ドロップされてしまう</a></h2> <p>特にオプションなどの設定をせずデフォルトのままやると、リスト内の要素全体がドラッグ&ドロップできてしまうので、<br /> スマホだとうまくスクロールができない。</p> <pre><code class="html"><div id="app"> <draggable tag="ul"> <li v-for="item, index in items" :key="item.id"> <span>{</span><span>{</span>item.name<span>}</span><span>}</span> </li> </draggable> </div> </code></pre> <pre><code class="javascript">new Vue({ el: "#app", components: { 'draggable': draggable, }, data: { items:[] }, created() { for (var i = 0; i <= 30; i++) { this.items.push({id: i+1, name: `リスト${i + 1}`}) } } }); </code></pre> <p><a href="https://crieit.now.sh/upload_images/fef09829d50da55327f090d7279500b25fb48b1bb6ebc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/fef09829d50da55327f090d7279500b25fb48b1bb6ebc.png?mw=700" alt="image" /></a></p> <h2 id="困ったこと2:要素の中のクリックイベントが動かない(Androidのみ?)"><a href="#%E5%9B%B0%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8%EF%BC%92%EF%BC%9A%E8%A6%81%E7%B4%A0%E3%81%AE%E4%B8%AD%E3%81%AE%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%8C%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%84%EF%BC%88Android%E3%81%AE%E3%81%BF%EF%BC%9F%EF%BC%89">困ったこと2:要素の中のクリックイベントが動かない(Androidのみ?)</a></h2> <p>例えば、<br /> <a href="https://crieit.now.sh/upload_images/ad0586aa1a4628d79b6cd4caa62361935fb48bb64e05a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ad0586aa1a4628d79b6cd4caa62361935fb48bb64e05a.png?mw=700" alt="image" /></a></p> <p>のように、削除ボタンをリストの中に入れて、<br /> ボタンクリックで削除処理が行われる…みたいなときに、<br /> ボタンをクリックしても何も起こらない。<br /> ※自分はAndroidのみで確認。PC、iosは動く</p> <h2 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h2> <p>2つとも同じ方法で対処。</p> <p>draggableタグにoptionsを設定して、<br /> ドラッグ&ドロップができる領域を指定してあげる。</p> <p>まずは以下のようにドラッグ&ドロップ可能にする要素を追加。<br /> 任意の名前でclassを付けておく。 今回は<code>class="handle"</code>とした。</p> <pre><code class="html"><div id="app"> <draggable tag="ul"> <li v-for="item, index in items" :key="item.id"> <!-- ↓追加 --> <span class="handle">●</span> <span>{</span><span>{</span>item.name<span>}</span><span>}</span> <button> 削除 </button> </li> </draggable> </div> </code></pre> <p><a href="https://crieit.now.sh/upload_images/5d2729a3176f2e2df0f3e56c859c01fa5fb48e1bf0315.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5d2729a3176f2e2df0f3e56c859c01fa5fb48e1bf0315.png?mw=700" alt="image" /></a><br /> この●をクリックしているときだけドラッグ&ドロップ出来るようにする。</p> <p>draggableのoptionsを以下のように設定</p> <pre><code class="html"><draggable tag="ul" :options="{handle: '.handle'}"> ... </draggable> </code></pre> <p>これで、.handle要素をクリックorタップしたときのみドラッグ&ドロップが可能になり、<br /> スマホでのスクロールやボタンのクリックも問題なく動くようになった。</p> <p>いちおうここまでのサンプルを置いておきます。<br /> <a target="_blank" rel="nofollow noopener" href="https://jsfiddle.net/mimimimimi/vx1ksm8c/8/">https://jsfiddle.net/mimimimimi/vx1ksm8c/8/</a></p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tobita0000/items/867d25e7287ddb5b9cc3">Vue.Draggableでドラッグ領域を指定する方法</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.programmersought.com/article/55644805280/">The click event bound to the drag element using vue-draggable is invalid on Android phones</a></p> <h3 id="どうでもいい余談"><a href="#%E3%81%A9%E3%81%86%E3%81%A7%E3%82%82%E3%81%84%E3%81%84%E4%BD%99%E8%AB%87">どうでもいい余談</a></h3> <p>解決した日に気づいたけど、Youtubeのプレイリストの中身の順番を変える時とかも、同じ様にアイコンをタップしないとドラッグできないようになっていた!<br /> こういう普段何気なく使っているところにヒントが隠されてたりするんだな~と思ったり…。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16210 2020-11-10T18:19:54+09:00 2020-11-10T18:22:30+09:00 https://crieit.net/posts/Apache-Laravel-Vue-js-Vuetify-web 【Apache Laravel Vue.js Vuetify】webアプリをスマホに対応させるためにやったこと <p>Apache+Laravel+Vue.js+Vuetify で作った社内ツールをスマホ対応したときに行った作業内容メモ。<br /> <del>ほんとにiosが嫌いになりそうだった</del></p> <p>対応ブラウザは、</p> <ul> <li>chrome(PC, Android, ios)</li> <li>safari(ios)</li> </ul> <h2 id="まずはiPhone、Androidのデバッグが出来るように準備する"><a href="#%E3%81%BE%E3%81%9A%E3%81%AFiPhone%E3%80%81Android%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%8C%E5%87%BA%E6%9D%A5%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B">まずはiPhone、Androidのデバッグが出来るように準備する</a></h2> <p>それぞれの端末を持っていれば、PCに繋いでデバッグができる!なんて素晴らしい。<br /> iosはiPhone以外にもiPad、iPod touch でも問題なし。<br /> それぞれ以下を参考に。</p> <p>Android:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/hojishi/items/12b726f8b02ef3d713e4">https://qiita.com/hojishi/items/12b726f8b02ef3d713e4</a><br /> ios:<a target="_blank" rel="nofollow noopener" href="https://webkatu.com/archives/ios-safari-debug-on-windows/">https://webkatu.com/archives/ios-safari-debug-on-windows/</a></p> <h2 id="Polyfillを入れる"><a href="#Polyfill%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B">Polyfillを入れる</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://v2.vuetifyjs.com/ja/getting-started/browser-support/">Vuetifyの公式ドキュメント</a>に則って入れればOK。</p> <pre><code class="bash">npm install babel-polyfill --save npm install @babel/preset-env --save </code></pre> <p>インストール後、<br /> <code>import Vue from 'vue'</code> とか<br /> <code>import vuetify from '@/plugins/vuetify</code><br /> を書いているファイルに、<br /> <code>import 'babel-polyfill'</code> を追加。<br /> (自分の場合は <code>/resources/assets/js/app.js</code>)</p> <p>ルートディレクトリの .babelrcに、</p> <pre><code> { "presets": ["@babel/preset-env"] } </code></pre> <h2 id="対応していないjsを地道に直す"><a href="#%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84js%E3%82%92%E5%9C%B0%E9%81%93%E3%81%AB%E7%9B%B4%E3%81%99">対応していないjsを地道に直す</a></h2> <p>特に問題なければ、↑を行えば画面は表示されるはず…と思っていたのだが、画面が真っ白だった。</p> <p>エラーを調べると、どうやら正規表現で後読みを使っているのが原因みたいだったので、該当箇所を修正。<br /> (safariは後読みに対応していない)</p> <p>※書いている最中に気づいたけど、それってつまりうまくPolyfillが使えていなかったのでは…??</p> <h2 id="「Error: Network Error POST 応答を解析できません」を直す"><a href="#%E3%80%8CError%3A+Network+Error%E3%80%80POST++%E5%BF%9C%E7%AD%94%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%8D%E3%82%92%E7%9B%B4%E3%81%99">「Error: Network Error POST 応答を解析できません」を直す</a></h2> <p>iosのみ起きる謎現象。これに2日かかった…<br /> 自分は、Apacheの設定を変更で直った。</p> <pre><code><Directory "/var/www/html/public"> AllowOverride All # Allow open access: Header unset Upgrade ←これを追加 </Directory> </code></pre> <p>とりあえずここまでで画面が開けるようになりました。<br /> 以降は細かい部分です。</p> <h2 id="スクロールを入れたくないのにスマホだと入ってしまう"><a href="#%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AB%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%A0%E3%81%A8%E5%85%A5%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">スクロールを入れたくないのにスマホだと入ってしまう</a></h2> <p>webアプリ全体にスクロールを入れたくない場合、bodyに<code>height:100%</code>とか入れればPCでは大丈夫だったりしたんですが、<br /> スマホだとどうにも謎のスクロールが入ってしまうので、以下のように対応。</p> <pre><code class="html"><html id="content">  … </code></pre> <p>※jsでhtmlのところにstyleを指定する方法がわからなかったのでid属性を無理やり、、、</p> <pre><code class="js">const windowHeight = window.innerHeight; // windowの高さを取得 // <html>の高さを、windowsの高さいっぱいに設定 document.getElementById("content").style.height = windowHeight + "px"; // bodyはheight:100% document.body.style.height = "100%"; // スクロールバー非表示 // スマホのときはbodyに、PCのときはhtmlにかけないと反映されないっぽいので分ける const isSP = /iPhone|iPod|iPad|Android/i.test(navigator.userAgent); if (isSP) { document.body.style.overflowY = "hidden"; } else { document.getElementById("content").style.overflowY = "hidden"; } </code></pre> <p>…無理矢理感半端ないけど、ひとまずこれでPCでもスマホでも画面いっぱいでコンテンツが収まるようになった。</p> <h2 id="iosだけ、キーボードのenterでボタンクリック判定されてしまう"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AEenter%E3%81%A7%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E5%88%A4%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">iosだけ、キーボードのenterでボタンクリック判定されてしまう</a></h2> <p>PCやAndroidでは大丈夫なのに、iosだけ起きる謎現象。<br /> 改行する度にボタンが押されて送信されるという、、、、</p> <p>※単純にv-formのsubmitイベントが発火してしまっている場合は、<a target="_blank" rel="nofollow noopener" href="https://riotz.works/articles/lopburny/2019/07/31/page-reload-issue-by-implicit-submission/">こちら</a>を参考に。</p> <p>根本的な原因はわからなかったため、<br /> 入力文字が空欄・改行のみの場合は、ボタンクリックで呼ばれる処理が走らないようにした。</p> <pre><code class="html"><textarea v-model="inputText"></textarea> <v-btn @click="submit()">送信</v-btn> </code></pre> <pre><code class="js"><br />data: () => ({ inputText: "", }), computed: { /** * 空文字判定 */ isTextEmpty() { return !this.inputText || !this.inputText.match(/\S/g); }, }, methods: { submit() { if (this.isTextEmpty) return; // 以下送信処理 } } </code></pre> <h2 id="iosだけファイルアップロードができない"><a href="#ios%E3%81%A0%E3%81%91%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">iosだけファイルアップロードができない</a></h2> <p>ファイル選択のダイアルボックスを開く→ファイルを選択→アップロード<br /> という流れのとき、iosだけダイアルボックスが開かないという謎現象。<br /> エラーも出ない…</p> <p>調べてみたら、どうやら<code>input.onchange</code>が動いていないようだった。</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = "file"; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; input.onchange = event => { var file = event.target.files[0]; resolve(file); }; input.click(); }); } </code></pre> <p>ios以外は↑でも動いたが、どうやらiosではちゃんと<code><input></code>要素をDOMに追加してあげないといけないらしい。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only">https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only</a></p> <p>というわけで、以下のように修正</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = 'file'; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; document.body.appendChild(input); // ←DOMに追加 input.onchange = event => { var file = event.target.files[0]; document.body.removeChild(input); // ←DOMから削除 resolve(file); }; input.click(); }); } </code></pre> <h2 id="iosだけ画像が縦に伸びる時"><a href="#ios%E3%81%A0%E3%81%91%E7%94%BB%E5%83%8F%E3%81%8C%E7%B8%A6%E3%81%AB%E4%BC%B8%E3%81%B3%E3%82%8B%E6%99%82">iosだけ画像が縦に伸びる時</a></h2> <p>これは別記事にもメモしてあるが、<br /> <code>display:flex;</code>を指定している箇所に、<code>align-items: flex-start;</code>を追記するだけ。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://nichiyogogo.com/image-looks-stretched/">https://nichiyogogo.com/image-looks-stretched/</a></p> <h2 id="iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81height%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E8%A6%81%E7%B4%A0%E5%86%85%E3%81%AE%E3%80%8Coverflow-y%3A+visible+scroll%3B%E3%80%8D%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84">iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない</a></h2> <p>これもiosの一部で起きる現象。<br /> safariのバージョンの問題かもしれない。</p> <p>ますは<a target="_blank" rel="nofollow noopener" href="https://shanabrian.com/web/html-css-js-technics/css-ios-safari-02.php">ここ</a>を参考に修正。<br /> 自分はこのときにも頑なに<code>overflow-y: visible scrol</code>と書き続けていたら直らず、<br /> 素直に <code>overflow-y:auto;</code> にするだけで解決…。</p> <h2 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h2> <p>ほとんどios対応ですね。<br /> Androidはグリッドをちゃんと設定して、表示崩れしないようにだけしてあげれば殆ど動きました。<br /> マジでiosとsafariが嫌いになりそうだった…。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16209 2020-11-10T17:49:58+09:00 2020-11-10T17:49:58+09:00 https://crieit.net/posts/js-5faa5436c3be5 【js】連想配列からインデックスを取得 <p>よく忘れるのでメモ。</p> <p>参考元:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/Test_test/items/7d532f445f2980e896d0">https://qiita.com/Test_test/items/7d532f445f2980e896d0</a></p> <pre><code class="javascript">const obj = [ { num: 0, name: 'AAA', age: '60'}, { num: 1, name: 'BBB', age: '20'}, { num: 2, name: 'CCC', age: '40'}, { num: 3, name: 'DDD', age: '50'}, ]; obj.findIndex(({name}) => name === 'DDD'); // 3 obj.findIndex(({age}) => age === '20'); // 1 </code></pre> <p><code>findindex</code>は、インデックスが見つからなかった場合は<code>-1</code>を返すため、<br /> 条件分岐をする時は注意。</p> <pre><code class="javascript">var index = obj.findIndex(({age}) => age === '22'); if (index === -1) { console.log("見つかりませんでした。"); } else { console.log(index); } </code></pre> みみみみみ tag:crieit.net,2005:PublicArticle/16153 2020-10-19T18:10:44+09:00 2020-10-19T18:10:44+09:00 https://crieit.net/posts/ios-5f8d581420de5 iosだけ画像が縦に伸びる時 <p>「display:flex;」を指定している箇所に、「align-items: flex-start;」を追記するだけ!!</p> <p><a target="_blank" rel="nofollow noopener" href="https://nichiyogogo.com/image-looks-stretched/">https://nichiyogogo.com/image-looks-stretched/</a></p> みみみみみ tag:crieit.net,2005:PublicArticle/16152 2020-10-19T18:06:59+09:00 2020-10-19T18:06:59+09:00 https://crieit.net/posts/Vuex 【Vuex】別モジュールのステート、メソッド呼び出し <pre><code class="js">const moduleA = { // ... actions: { testA(context) { // state console.log(context.rootState.moduleName.stateName) // mutation context.commit("moduleName/mutationName", "引数", {root: true}); // action context.dispatch("moduleName/actionName", "引数", {root: true}); } } </code></pre> みみみみみ tag:crieit.net,2005:PublicArticle/16151 2020-10-19T18:05:31+09:00 2020-10-19T18:05:31+09:00 https://crieit.net/posts/Laravel-Pusher-The-data-content-of-this-event-exceeds-the-allowed-maximum 【Laravel+Pusher】The data content of this event exceeds the allowed maximum のエラーが出た時 <p><a target="_blank" rel="nofollow noopener" href="https://pusher.com/docs/channels/server_api/http-api#publishing-events">https://pusher.com/docs/channels/server_api/http-api#publishing-events</a></p> <p>↑にも書いてあるが、<br /> The data content (POST body) of events must be smaller than 10kB.<br /> (イベントのデータコンテンツ(POST本文)は10kB未満である必要があります。)</p> <p>とのことなので、<br /> イベントに何でもかんでもぶち込むとエラーになるっぽい。</p> <h1 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h1> <pre><code class="php">$event = [ "eventType" => 1, "id" => 1, "content" => [...] // ←ここのサイズが大きかった ]; event(new PusherEvent($event)); </code></pre> <p>↑これをvueで受け取って、</p> <pre><code class="js">this.content = event.content </code></pre> <p>のようにしていたのを、</p> <pre><code class="php">$event = [ "eventType" => 1, "id" => 1, ]; event(new PusherEvent($event)); </code></pre> <p>イベントタイプとデータのidのみ渡すように修正</p> <pre><code class="js">async getContent(id) { // ajaxでデータ取得 }, ... ver content = await getContent(event.id); this.content = content </code></pre> <p>ajaxでデータを取得し、それを反映</p> <p>という風に直したら解決。</p> <p>もちろん仕様によってはある程度制御をしなければ、<br /> ログインしているユーザー人数だけgetContent()が呼ばれてまた別のエラーになるので、<br /> そこは適宜対応が必要。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16150 2020-10-19T17:59:58+09:00 2020-10-19T17:59:58+09:00 https://crieit.net/posts/MySQL-DISTINCT 【MySQL】DISTINCT──重複したデータを除外する <p><a target="_blank" rel="nofollow noopener" href="https://www.dbonline.jp/mysql/select/index13.html">https://www.dbonline.jp/mysql/select/index13.html</a></p> <p>DISTINCT を指定すると、取得するカラムの値が一致しているデータは除外してデータを取得することができる。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16149 2020-10-19T17:58:51+09:00 2020-10-19T17:58:51+09:00 https://crieit.net/posts/php-php7-foreach 【php】php7系では、ループは普通にforeachを使えば良い <p>OOMの原因調査をしていた時</p> <p><a target="_blank" rel="nofollow noopener" href="https://norm-nois.com/blog/archives/1774">foreachを使うとき、もうちょいメモリのことを気にして行こうぜ</a><br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/h13/items/a75fba76f435212a2eb3">[PHP]ループのメモリ使用量と処理速度を比較しました</a></p> <p>こんな記事を見つけた。</p> <p>なるほど、foreachは配列のコピーを作るからメモリを食ってしまうので、<br /> 何でもかんでもforeachを使えばいいってわけじゃないのか…。<br /> 使う時も、unsertとかを上手く使わないといけないのか…。</p> <p>と思ったのですが。<br /> どうやらコレは2010年辺り(php5系?)の話のようで、<br /> php7系ではそんなことないらしい。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/Mister_K/items/5bcee3fdb95ed34313e4">PHP7系におけるループのメモリ使用量と処理速度を比較</a></p> <p>実際、自分のコードでも軽く比較してみたけど、特に差は見られなかった。<br /> (ちゃんとは比較してないので数値は載せませんが。)<br /> というか、</p> <pre><code class="php">while(list($key, $val) = each($data)) { $results[] = $key * $val; } </code></pre> <p>↑コレに関しては「eachはもう使うんじゃねえ」などと怒られた。</p> <h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1> <p>今まで通りforeach使おう。<br /> そしてメモリ食ってるのは、foreachやforeachの使い方が悪いわけじゃない というのがわかった。</p> <h1 id="ただのぼやき"><a href="#%E3%81%9F%E3%81%A0%E3%81%AE%E3%81%BC%E3%82%84%E3%81%8D">ただのぼやき</a></h1> <p>「php foreach メモリ」とかで検索すると、<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/h13/items/a75fba76f435212a2eb3">[PHP]ループのメモリ使用量と処理速度を比較しました</a><br /> これが上位に出てくるんですよね。<br /> 多分こういうことって普通にあると思うので…参考にする前に、<br /> ・何年前の記事なのか<br /> ・バージョン<br /> くらいはちゃんと確認しないといかんな。</p> <p>と、改めて感じた。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16148 2020-10-19T17:56:16+09:00 2020-12-16T15:01:13+09:00 https://crieit.net/posts/php-Fatal-error-Out-of-memory-5f8d54b00e0fc 【php】Fatal error: Out of memory が出たときの、原因特定の準備 <p>社内ツール開発中、追加機能の実装が出来たので意気揚々と本番にデプロイした結果。</p> <pre><code>Fatal error: Out of memory </code></pre> <p>ウワァァァァ</p> <p>頭を抱えていたら、とりあえずの対処法と原因特定するための方法をパイセンに教えていただいたので記録。</p> <h1 id="①とりあえずphp.iniをいじる"><a href="#%E2%91%A0%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9Aphp.ini%E3%82%92%E3%81%84%E3%81%98%E3%82%8B">①とりあえずphp.iniをいじる</a></h1> <p>参考:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/day-1/items/a3f5491c7e5b1ed4ed9e">PHPのメモリの上限を変更する</a></p> <pre><code>;memory_limit = 256M ←翌朝、128から256に変更してみた memory_limit = 512M ←256でも同エラーになったので、更に上げてみた </code></pre> <p>128Mから256Mに引き上げたものの、<br /> 数時間後に同エラーが発生したため解決にはならず。<br /> おそらく意味はないと思われるが、512Mまで引き上げて様子見…</p> <p>(そもそもメモリ上限を上げただけでは根本的な解決にはならない。)</p> <h1 id="②原因だと思われるメソッドのメモリ使用量を計測する"><a href="#%E2%91%A1%E5%8E%9F%E5%9B%A0%E3%81%A0%E3%81%A8%E6%80%9D%E3%82%8F%E3%82%8C%E3%82%8B%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E3%83%A1%E3%83%A2%E3%83%AA%E4%BD%BF%E7%94%A8%E9%87%8F%E3%82%92%E8%A8%88%E6%B8%AC%E3%81%99%E3%82%8B">②原因だと思われるメソッドのメモリ使用量を計測する</a></h1> <p>参考:<a target="_blank" rel="nofollow noopener" href="http://kameryo.hatenablog.com/entry/2015/06/24/110559">php メモリ使用量測定メモ</a></p> <p><code>memory_get_usage()</code> で現在のメモリ使用量<br /> <code>memory_get_peak_usage()</code>  でメモリ使用量の最大値<br /> をそれぞれ取得できる。</p> <p>これを使って、実行前後のメモリ使用量をLogに吐き出すように仕込んでみた。</p> <pre><code class="php">public function hoge() { \Log::debug("first:".memory_get_usage() / (1024 * 1024)."MB\n"); // なにかの処理… \Log::debug("now:".memory_get_usage() / (1024 * 1024)."MB\n"); \Log::debug("peak:".memory_get_peak_usage() / (1024 * 1024)."MB\n"); } </code></pre> <p>※laravelを使っているので\Log::debug()で書いています。</p> <p>次エラーが発生した際に、メモリ使用量がとてつもないことになっている箇所があればおそらくそれが原因。<br /> そうでもなければ、別の場所が原因なので、仕込む場所を変えてみる</p> <p>…という風に原因特定していくらしい。<br /> ひとまずは、この状態でログとにらめっこしつつ原因特定を頑張るぞ。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16147 2020-10-19T17:52:20+09:00 2020-10-19T17:52:20+09:00 https://crieit.net/posts/php-usort 【php】連想配列を、指定した配列の順番で並び替える (usort) <p><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.usort.php">https://www.php.net/manual/ja/function.usort.php</a><br /> 配列を並び替える関数の一つで、自分で指定した条件通りに並び替えることができる</p> <pre><code class="php">function cmp($a, $b) { if ($a== $b) { return 0; } return ($a< $b) ? -1 : 1; } $array = [3, 2, 5, 6, 1]; usort($array , "cmp"); foreach ($array as $key => $value) { echo "$key: $value\n"; } </code></pre> <p>出力結果:</p> <pre><code>0: 1 1: 2 2: 3 3: 5 4: 6 </code></pre> <p>呼び出し方は、<br /> usort(配列, コールバック関数)</p> <p>コールバック関数の返り値を使って並び替えをする。</p> <div class="table-responsive"><table> <thead> <tr> <th>返り値</th> <th>処理</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>そのまま(並び替えない)</td> </tr> <tr> <td>-1</td> <td><code>$a</code>の順番を<code>$b</code>より繰り下げる</td> </tr> <tr> <td>1</td> <td><code>$a</code>の順番を<code>$b</code>より繰り上げる</td> </tr> </tbody> </table></div> <p>↑これを全部の組み合わせで実行し、最終的に昇順に並び替えられる</p> <h1 id="usortを使って、連想配列を任意の順番に並び替える"><a href="#usort%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%80%81%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E4%BB%BB%E6%84%8F%E3%81%AE%E9%A0%86%E7%95%AA%E3%81%AB%E4%B8%A6%E3%81%B3%E6%9B%BF%E3%81%88%E3%82%8B">usortを使って、連想配列を任意の順番に並び替える</a></h1> <p>teratailの方で見つけて感動したのでメモ。(メモと言うかもろコピペですみません)<br /> <a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/93290">https://teratail.com/questions/93290</a></p> <pre><code class="php">$sortID=[3, 5, 12, 23, 67]; $array = [ ['id'=>3,'name'=>"test1"], ['id'=>67,'name'=>"test2"], ['id'=>23,'name'=>"test3"], ['id'=>12,'name'=>"test4"], ['id'=>5,'name'=>"test5"], ]; usort($array, function($a, $b) use ($sortID){ return array_search($a["id"], $sortID) > array_search($b["id"], $sortID); }); print_r($array); </code></pre> <p>出力結果:</p> <pre><code>Array ( [0] => Array ( [id] => 3 [name] => test1 ) [1] => Array ( [id] => 5 [name] => test5 ) [2] => Array ( [id] => 12 [name] => test4 ) [3] => Array ( [id] => 23 [name] => test3 ) [4] => Array ( [id] => 67 [name] => test2 ) ) </code></pre> <p>おお~。<br /> $sortIDに同じ値がある場合はちょっと足さないといけないっぽいけど、<br /> これは意外と色んな場面で使えそう。</p> みみみみみ tag:crieit.net,2005:PublicArticle/16146 2020-10-19T17:50:23+09:00 2020-10-19T17:50:23+09:00 https://crieit.net/posts/Laravel-feature 【Laravel】feature テスト レスポンスのデバッグ <pre><code class="php">$response = $this->get('/'); $response->assertStatus(200) </code></pre> <p>みたいなテストをするとき、レスポンスの中身をみたい場面があった。</p> <pre><code class="php">$response->dumpHeaders(); $response->dumpSession(); $response->dump(); </code></pre> <p>これで取得できる!<br /> ちゃんとドキュメントにも書いてあった。<br /> <a target="_blank" rel="nofollow noopener" href="https://readouble.com/laravel/6.x/ja/http-tests.html">https://readouble.com/laravel/6.x/ja/http-tests.html</a></p> <p>もっと早く気付けたら良かった~~~</p> みみみみみ tag:crieit.net,2005:PublicArticle/16145 2020-10-19T17:47:24+09:00 2020-10-19T17:47:24+09:00 https://crieit.net/posts/js js ファイルをドラッグ&ドロップでアップロードするとき、フォルダは弾く <pre><code class="html"><!-- ここにドラッグ&ドロップ --> <div @dragover.prevent @dragleave.prevent @drop.prevent="onDrop($event)"></div> </code></pre> <pre><code class="javascript">function onDrop() { const items = event.dataTransfer.items; for (var item of items) { var entry = item.webkitGetAsEntry(); if (entry.isDirectory) { alert("フォルダはアップロードできません"); return; } } } </code></pre> みみみみみ tag:crieit.net,2005:PublicArticle/16144 2020-10-19T17:46:19+09:00 2020-10-19T17:46:19+09:00 https://crieit.net/posts/WHERE-id-1 WHERE id !=1 みたいな条件文を書く時に気をつけること <p>idに必ず数値が入っている場合は</p> <pre><code class="sql">SELECT * FROM table WHERE id !=1; </code></pre> <p>でidが1以外のデータすべて取れるけど、<br /> これだと<strong>id=NULLのデータは取れない</strong></p> <p>ので、</p> <pre><code class="sql">SELECT * FROM table WHERE id !=1 OR id IS NULL; </code></pre> <p>のように書けばidがNULLのデータも取得できる。</p> みみみみみ