/// BANGBOO BLOG ///

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

March 8, 2016

Cache

■画像のキャッシュ
ページは新しいが、画像は古いキャッシュを参照している理由
影響因子:ブラウザキャッシュ>プロキシ>ファイアウォール>ロードバランサ>htaccessのようなサーバ設定
基本的な考え方:キャッシュはPHPページ等でのディレクティブで制御されるが、特に画像等はプロキシではキャッシュ期間が優先される場合がある(ブラウザ更新ボタンでスキップできるが、、)

1)ページ遷移時は、キャッシュがありExpire等が効いている場合は、完全にローカルキャッシュだけを使ってそもそもリクエストを送っていません。
(ちなみに、ページを進んで(ブラウザの戻る機能で)戻ったときは大元のHTMLを含めてキャッシュが使われたりします。)
2)リロードは大元のHTMLを受け取ったら、そのページ内のリソースについてレスポンスヘッダを確認しに行っています。その結果304 Not Modifiedが帰ってきて、実際にはキャッシュを使います。
3)スーパーリロードCtrl+F5(Ctrl+更新ボタン)はキャッシュに関係なく、すべてのリソースを取得しなおしています。
リロードをしても表示されない時ブラウザのキャッシュ削除するといいのは、この辺りが上手く行っていないからだと言える

どういうリクエスト/レスポンスの流れ?(304はトラフィックは減るが比較でサーバリソースを食う場合もある)
1)ブラウザのキャッシュ :Expire/max-ageのあるとき?、あるいはブラウザキャッシュ削除
2)ブラウザ→プロキシのキャッシュ :Cache refreshでの間隔で処理、あるいはブラウザ更新ボタン
3)ブラウザ→プロキシ→サーバで304 not modefied(ブラウザ/プロキシのキャッシュが使用される)

http://www.atmarkit.co.jp/ait/articles/0305/10/news002.html
http://blog.redbox.ne.jp/http-header-tuning.html

HTTPヘッダ(htttpヘッダはプログラムで制御できる)
 Pragma
 •Cache-Control(汎用)-no-cache, max_ageディレクティブなど
 •Age(レスポンス)
 •Date(汎用)
 •Expires(エンティティ)
 •Last-Modified(エンティティ)
 •If-Modified-Since(リクエスト)
 •If-Unmodified-Since(リクエスト)
 •ETag(レスポンス)
 •If-Match(リクエスト)
 •If-None-Match(リクエスト)
 •Range(リクエスト)
 •If-Range(リクエスト)
 ブラウザに一切キャッシュさせたくない場合Cache-Control "no-cache" この辺りの動作は環境に依存する
 ブラウザにキャッシュさせるが変更ないか都度確認Cache-Control "max-age=0" or Expires "Mon, 26 Jul 1997 05:00:00 GMT"
 ブラウザにキャッシュさせ都度確認はそれほど必要ないCache-Control "max-age=秒数" or Expires "Mon, 26 Jul 2020 05:00:00 GMT"
 Cache-Control: private webサーバから返されるコンテンツがただ一人のユーザのためのもので複数のユーザが共有されるキャッシュに記録されるべきではない
 Cache-Control: must-revalidate キャッシュに記録されているコンテンツが現在も有効であるか否かをWebサーバに必ず問い合わせよ
metaタグ
 <meta http-equiv="Pragma" content="no-cache">
 <meta http-equiv="Cache-Control" content="no-cache">
 <meta http-equiv="Expires" content="0">キャッシュの有効期限,0=キャッシュさせない
 no-store:キャッシュするな→ Webサーバから返却されるコンテンツをキャッシュするな
 no-cache:キャッシュしても良いが、確認してから使え→ キャッシュは使用しても良いが現在でも有効か否か確認した上で使用しろ
 no-cacheがキャッシュを使用しない設定に思えるが実際には、no-storeがキャッシュをさせない設定。大体の場合ではno-cacheでOK
シリアルの変数を付ける
 <img src="http://aaa/v.gif?27" />
 <link type="text/css" rel="stylesheet" href="styles.css?20130420-1100">
.htaccess
 <Files ~ ".(gif|jpe?g|png|ico|js|gz|otf|ttf|eot|woff)$">
   Header set Cache-Control "max-age=2592000"
 </Files>
プロキシサーバ
  基本はどれだけの期間キャッシュを保つかのCache refresh設定、他はhttpヘッダのディレクティブで制御されると考える
  Cache Refresh 設定 HTTPドキュメントの場合(4-8時間、5min、20%等複合)の更新間隔を保つ、ブラウザ更新ボタンで取得も可能だし
  20%の意味は、1週間前の10080前にできた場合これを1440/10080=14.2%となってまだ新しいとみなす
  Last-Modified 要素を 0.1 に設定した場合、最後の変更が 10 日前に行われたドキュメントのケースだとプロキシはこの要素の意味を、ドキュメントが 1 日 (10 * 0.1 = 1) の間変更されない、と解釈します。その場合、ドキュメントのチェックが 1 日以内に実行されている場合、プロキシはキャッシュからドキュメントを返します
  使用されたキャッシュの回数
  キャッシュの容量
  Internet Cache Protocol (ICP) はキャッシュ(プロキシ)間の対話を可能で履歴を共有
  (Sun Java System Web Proxy Server) https://docs.oracle.com/cd/E19636-01/819-3160/agcache.html
 http://trafficserver.readthedocs.io/ja/latest/admin-guide/configuration/cache-basics.en.html
 (Squid) http://d.hatena.ne.jp/takami_hiroki/20101006/p1
 (Vanish) http://www.kumoyanet.com/420/

Posted by funa : 08:06 PM | Web | Comment (0) | Trackback (0)


March 8, 2016

Detected as bad site by virus company

アクセスが遮断される場合ダメサイトとして登録されている可能性がある

Nortonでの確認:
https://safeweb.norton.com/report/show?url=bangboo.com

トレンドマイクロで確認:
http://global.sitesafety.trendmicro.com/

McAfeeでの確認:
http://www.siteadvisor.com/

Nortonに異議を申し立てるには
1.     Nortonのアカウントを作成
2.     該当Webサイトを登録
3.     Webサイトのオーナーを証明する作業を行う
(ページにNorton用タグを埋め込む、またはNorton専用HTMLファイルをRootに配置)
4.     異議申請
https://safeweb.norton.com/help/site_owners

Posted by funa : 01:07 AM | Web | Comment (0) | Trackback (0)


February 27, 2016

Takoyaki Design

@千成屋 200円/6個。プロダクトデザイン、なんでも同じか

■101デザインメソッド

5 Human factors:
ユーザを観察して、物理的、認知的、社会的、文化的、感情的の要素を調べる

POEMS:
ユーザを観察して、People, Objects, Environment, Messages, Servicesに分け、システムとしてコンテクストを捉える


■The art of Innovation, Ideo
Hot Teamを作る
顧客になって学ぶ(理解 > 観察 > 視覚化 >レビュー/評価)
ブレインストーミング
 焦点を明確に
 遊び心、身体を使う、基礎スキルをやらせる
 テーマを外向きのアイデアを募りイノベーション
  (Xシェアを上げるには→○外出先でネット接続を時短するには)
プロトタイプ
 製品をS字改良、製品は成長する(macマウス、トラックボール、ワイン蓋)
 白紙から考える、No They:自身でやる、イノベーションは目的志向
 アフォーダンス、全然違うものを作る、そしてマーケで売る(イリュージョン)
旅に出てリサーチ、アイデアが重要
よく観察する

ファミレスは注文時間が22時を超えると深夜料金10%掛かるよ

Posted by funa : 09:25 PM | Column | Comment (0) | Trackback (0)


February 14, 2016

Google API

Google Analyticsを使った機能が動いていない。APIの使い方が変わったのか新しい方法があるようだ。なおGoogleMapも部分カットされていたし、互換性も糞もない、Holy moly、Holy crap、Holy shit。

1)Google Developer Console https://console.developers.google.com/start
 アカウントを取得、APIの許可、サービスアカウント作成、OAuthのキーを生成
2)Google Anal https://www.google.com/analytics/
 閲覧権限(サービスアカウントのメールをユーザ管理で付与)
3)Google APIs Client Library https://developers.google.com/api-client-library/
 ダウンロード https://github.com/google/google-api-php-client

https://developers.google.com/youtube/v3/guides/moving_to_oauth?hl=ja
http://log.noiretaya.com/141
https://remotestance.com/blog/2592/

Posted by funa : 01:03 AM | Web | Comment (0) | Trackback (0)


January 8, 2016

OSS License

https://thinkit.co.jp/story/2014/02/03/4804
https://qiita.com/0xfffffff7/items/efbb65521d7708f2db7d
http://webnonotes.com/web/license/

/// GNU General Public License(GPL)ライセンス
https://emgr.jp/to-use-gpl/
https://www.mirucon.com/2018/04/10/all-about-gpl/
 伝搬性が強く、ソフトウェアAにおいて一部でもGPLソフトウェアBを使用した場合にはAはBの二次的著作物でありAもGPLにしなければなりません
 Linuxカーネル利用はGPLが伝播しない等あるが複雑で危険、商用使用可だが組み込まない方が良い

/// BSDライセンス
http://easylabo.com/2015/04/rapid-prototyping/9050/
http://neareal.net/index.php?IT%2FLicense%2FBSDLicense
https://www.wdic.org/w/TECH/4%E6%9D%A1%E9%A0%85BSD%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9
 もともと4条項の条件、一つずつ削られて4つ、3つ、2つとなり現在3種類
 BSD-2-ClauseはMITライセンスと内容がほぼ同じと言える

/// MITライセンス
https://wisdommingle.com/mit-license/
 無料で自由につかうことができる(制限がほんのすこししかない)
 条件は、「著作権表示」と「MITライセンスの全文 or そのURL」を記載
https://www.catch.jp/oss-license/2018/11/14/use_mit_license/
 サンプルコードを元に、複製して変更して結合して、頒布/サブライセンス/販売したり等もOK
 「ライセンス文書に記載の著作権表示」と「本許諾表示」をソフトウェアのすべての複製または重要な部分に記載する
 作者または著作権者はソフトウェアに関してなんら責任を負わない
https://www.catch.jp/oss-license/2013/09/27/mit_license/
 組み込む場合はライブラリとして、著作権表示とMITランセンス項をそのままで、が良い

/// CC License(クリエイティブ・コモンズ・ライセンス)
http://webnonotes.com/web/flickr/#cc
 非営利のみ、改変禁止、クレジットを表示、該当作もCCLに

ライセンスのタイプ 主なOSSライセンス 特徴
コピーレフト型 GNU General Public License(GPL)
Affero General Public License Version 3(AGPL)
Sleepycat License
The TMate Open Source License
ライセンステキストの添付が必要
改変した(コピー&ペーストも含む)ソースコードの開示
組み合わせて利用した場合、対応する部分のソースコードの開示
準コピーレフト型 GNU Lesser General Public License(LGPL)
Mozilla Public Licens(MPL)
ライセンステキストの添付が必要
改変した(コピー&ペーストも含む)ソースコードの開示

非コピーレフト型

BSD 2-clause License
BSD 3-clause License
BSD 4-clause License
Apache License 1.1
Apache License 2.0 MIT License
ライセンステキストの添付が必要
ソースコードを変更したとしても、ソースコードを開示する必要はない

https://thinkit.co.jp/story/2014/02/03/4804?page=0%2C2

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


January 7, 2016

Bash

https://qiita.com/Ping/items/57fd75465dfada76e633
https://qiita.com/Riliumph/items/97d9f0ae2eb2d7aae587

bash xxx.sh で実行、拡張子.sh(cmdと拡張子だがあっているのか?)

代入する際は頭に$を付けず=を用いる、参照時には頭に$をつける
文字列連結は演算子不要でつなげて書くだけ

ダブルクォートで囲った中で変数があれば展開される
シングルクォートで囲った内容はただの文字列
バッククォートで囲った内容はコマンドとして認識、$()も可、入れ子も可
エスケープは\、改行の前にも入れるとバッチファイルで改行ができる
 RMFILE=mysql.`date -v -"$KEEPDAY"d +%y%m%d`.gz
 rm -f $RMFILE

/dev/nullはぬるぽ空ファイル、コメントアウトは#
myscript.sh >/dev/null 2>&1    # 標準出力と標準エラー出力を破棄する
somecommand 2>/dev/null        # エラー出力だけ破棄する
cat /dev/null > myfile.txt     # サイズ0のファイルを作る
cp /dev/null > myfile.log      # 既存のファイルのサイズを0にする

出力のリダイレクト(0: 標準入力)
1>(上書き)と 1>>(追記)、1 は標準出力を意味するファイル記述子、1はデフォルトで省略可能
コマンドのエラー(標準エラー出力)は、同様に 2> と 2>>
2>&1 は標準エラー出力を標準出力にマージ、あるいはコマンド後に流す
1>&2 は標準出力を標準エラー出力にマージ、あるいはコマンド後に流す

< file 標準入力先をfileに変更
> file 標準出力先をfileに変更する。fileがすでに存在していた場合上書き
>> file 標準出力先をfileに変更する。fileがすでに存在していた場合追加

command 1>log.txt 2>errlog.txt 別々のファイルに保存する
command 2>&1 >a.log コマンドラインから実行していれば標準出力はファイルに、標準エラー出力は画面に出力
command >a.log 2>&1 標準出力と標準エラー出力の両方をファイルに出力

特殊変数$? 直前のコマンドの終了コードが$?に代入される。0(ゼロ)の場合は正常終了
 if [ $? != 0 -o ! -e $DBDUMP_FILE ]; then

ifの条件式内でのオプション、というか演算子らしい
-oはORをあらわす
-d ディレクトリなら真
-f 普通のファイルなら真
-e 存在するなら真
-w 書き込み可能なら真
! 否定
https://qiita.com/egawa_kun/items/196cd354c0d8e4e0fefc
 何のコマンドに対するオプションかで意味が変わるので個別に要調査

dateコマンドに+をつけてフォーマット指定 date "+%Y%m%d-%H%M%S"

MySQLダンプのスクリプト例の記事
https://www.bangboo.com/cms/blog/page_153.html

Posted by funa : 10:41 PM | Web | Comment (0) | Trackback (0)


January 6, 2016

Regular expression

■正規表現
最長一致
 一番長いものにマッチするので意図しないものが置換されがち
 ABC (c) & DEF (c)でABC (c)にマッチさせたいとき、
 ABC.*)の代わりにABC[^)]*がベターとかそういうこと

.* 繰り返し
.+ 1文字以上
[a-zA-ZO-9][a-zA-ZO-9] 英数2文字 → A1等
[a-zA-ZO-9]+\.jpg JPGファイル

\$100 \でエスケープ → $100
\\100 エスケープをエスケープ → \100

^ 行頭 ^# → #から始まる
[^]  否定 [^a-z] → aからz以外
$ 行末 jpg$ → jpgで終わる行
. 任意の1文字 ... → 3文字
* 直前文字の0回以上の繰り返し a* → aとか とかaaaaとか
  シェル)0文字以上の任意の文字 *.pdf → pdfファイル
? 直前文字の1文字か0文字 all? → allかal
  シェル)任意の1文字 ??? → 3文字
+ 直前文字1回以上の繰り返し a+ → aとかaaaaとか
- 範囲(文字コード上の) [0-2] → 0か1か2
[] いずれか1文字 [012] → 0か1か2
| いずれかの文字 slee|ap → sleeかap(前後文字をまとめて判断)
() まとまり sle(e|a)p → sleepかsleap
\< 単語の先頭境界 \<no → nothingやnobody等
\> 単語の末尾境界 \<no\> → noのみ
{min, max} 繰り返し回数の範囲 e{2,5} → eeやeeeeeやbeepやdeep等
  シェル)リスト展開 e{2,5} → e2とe5
\b 空文字
\d 数字1文字 [0-9]
\D 数字1文字以外 [^0-9]
\s 空白文字(改ページ、改行、タブを含む)[ \f\n\r\t]
\S \s以外
\w アルファベット数字 [a-zA-ZO-9]
\W アルファベット数字以外 [^a-zA-ZO-9]

■-の範囲は文字コード上
なのでEBCDICコード(IBMEBCDICカナ)の[A-Z]は$}を含む、[A-IJ-RS-Z]が正しい
なのでposixのブラケットが安全[[:alnum:]]

■サンプルは検索すると早いが
https://murashun.jp/blog/20190215-01.html#chapter-3

■デバッガー
https://www.debuggex.com/

■Winのワイルドカード
? 1文
* 1文字以上

■オラクルSQL
% NULLを除く0文字以上の任意の文字列にマッチ
_ 任意の1文字にマッチ

■本(正規表現の達人)を見よ
シェルのメタキャラクタを使う(リストを見やすく)
シェルのメタキャラクタを使う(ファイル名を補完)
コマンドの検索パターンとして使う(条件検索)
メールアドレスを抽出する
メールアドレスを抽出する(もっと厳密に)
メールアドレスを抽出する(Perlで)
コメン卜行・空行を削除する
マッチした文字列を抽出する(Perlで)
コメント行・空行を削除する(厳密に)
コメント行・空行を削除する(Perlで)
コメン卜行・空行を削除する(Cのソースコードから)
改行コードを変燥する(Win⇔UNIX⇔Mac)
電話番号をチェックする(簡易版)
時刻を条件にロクファイルをチェックする
HTMLファイルから見出しを抽出する
HTMLファイルから見出しを抽出する(さらに加工)
HTMLファイルの記述を修正する
郵便番号のチェック(Webフォームで)
英小文字からなる文字列にマッチする正規表現は?
西暦の年月日を「年/月/日」の形式で表す正規表現は?
‘daemon'と‘demon'の両方にマッチする正規表現は?
タブで区切られた2つの項目を入れ替え、カンマ区切りにするには?
メールボックスファイルからメールアドレスを抽出するには?
メールアドレスのユーザ名を厳密にチェックするには?
メールアドレスのドメイン名を厳密にチェックするには?
Perlで変数に格納されている文字列と正規表現がマッチするかとごうかテストするには?
JavaScriptで、変数に格納されている文字列と正規表現がマッチするかどうかテストするには?
シェルスクリプトからコメント行空行を削除するには?
正規表現にマッチした文字列から必要な部分だけ抽出するには?
余分なスペスを取り除くには
Cのソースコードからコメント行空行を削除するには?
複数行にまたがったコメントを取り除くには?
正規表現を使って改行コードを変換するには?
電話番号をチェックするには?
時刻をチェックするには?
郵便番号をチェックするには?
HTMLの見出しタグに困まれたデータを取り出すには?
HTMLファイルの記述をまとめて修正するには?
sedで前方参照を使うには?
大文字小文字の区別を無視するには?
sedでパタンの区切り文字「/」を変更するには?
Perlでパタンの区切り文字「/」を変更するには?
ファイル名がある範囲の文字で、終わっているファイルを表示するには?
長いファイル名を入力する手聞を省くには?
「.」「..」を含み、「.」からはじまるファイル名のファイルを表示するには?
「.」「..」は含まずに、「.」からはじまるファイル名のファイルを表示するには
多量の画面出力に対して、ページ単位でスクロールを止めるには?
画面出力をファイルに保存するには?
編集前と編集後のデータを比較するには?
元のファイルからどれくらいデータが抽出されたか調べるには?
データをソー卜するには?
重複するデータをlつにまとめるには?
findコマンドの検索条件にメタキャラクタを使うには?
入力行の指定した文字位置から指定したフィルドを切り出すには?
egrepコマンドで、検索条件にマッチした行円以外"を表示するには?
viで複数ファイルを編集するには?
viの検索パタンに正規表現を使うには?
trコマンドで空行を削除するには?
viで、改行コードを変換するには?
trコマンドで改行コードを変換するには?

■改行コード
\n(LF):Unix系OS全般、Mac OS X
\r\n(CR+LF):Windows系OS
\r(CR):古いMac OS(9以前)

Posted by funa : 01:27 AM | Web | Comment (0) | Trackback (0)


January 5, 2016

Javascript

varを省略した場合は関数内での宣言であってもグローバル変数(window.と同じ)
関数外のvarはグローバル変数
関数内のvarのみローカル変数(だが、関数の中に関数を作るとスコープチェーンによって、内側のローカル変数から順に探していくので、関数の外からは見えないが関数の内からはアクセスされる恐れはある)

関数を変数の様に書ける(無名関数)、スコープチェーンやレンダリングが関係している(後述)
//関数式による定義、JSは全てobjでありobjを受け取ってその中のメソッドを使う、New不要のケース
create_row = function(){
  var tbody = document.getElementById("input_tbody");
  var new_row = tbody.insertRow(num_row+1);
  var cell1 = new_row.insertCell(0);
  var copy = function(cell,tb,arg){
    cell.innerHTML = tb.rows[num_row].cells[arg].innerHTML;
  }
  return {tbody: tbody, cell1: cell1, copy: copy};
};
copy_cell = function(obj_create_row){
  obj_create_row.copy(obj_create_row.cell1, obj_create_row.tbody, 0);
};
//ここからフロー
num_row = 1;
setTimeout(function(){
  console.log('setTimeOut');
  obj_cr = create_row();
  copy_cell(obj_cr);
  num_row++;
}, 2000);
//ここからHTML
<table border=1>
<thead><tr><th>Items</th><th>Expenditure</th></tr></thead>
<tbody id="input_tbody"><tr><th>Pen</th><td>3,000</td></tr>
<tr><th>Eraser</th><td>1,000</td></tr></tbody>
</table>

ココから改めて追記する形でJavascriptの学び直し
///基礎文法
http://gifnksm.hatenablog.jp/entry/20100131/1264934942
一番下にリンク集がある、コメントも仕様が分かり参考になる
https://language-and-engineering.hatenablog.jp/entry/20100111/p1

///オブジェクト
https://www.wakuwakubank.com/posts/464-javascript-array-object-pattern/
オブジェクトは連想配列ようである、なおJSには配列[]/オブジェクト{}/JSON[{"":""},{"":""}]を使う
var obj = {a: 1, b: 2};

for - in は連想配列に使う(for in は配列にはダメ)
for - of は列挙可能なオブジェクト(配列等)に使う
for (var i in obj) {
  alert(obj[i]);
}
for each (var v in obj) {
  alert(v);
}
オブジェクトにはメソッドも付与しカプセル化可
var man = {
  time: 0,
  gettime: function() { this.time = new Date(); },
  hello: function() { alert(this.time + 'hello!'); },
};
man.gettime();
man.hello();

///インスタンス化
ファンクションでクラスを宣言(←古い。Classが実装される前の話)
https://so-zou.jp/web-app/tech/programming/javascript/grammar/function/class/
function Image() {
    this.width  = 0;
    this.height = 0;
    this.src    = '';
}
実はそれにはプロトタイプもあるので足せる(蛇足になるのでリンク等を参照)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
Image.prototype.type     = 'image object';
Image.prototype.width    = null;
Image.prototype.height   = null;
Image.prototype.src      = null;
Image.prototype.resizeTo = function(aNewWidth, aNewHeight) {
    this.width  = aNewWidth;
    this.height = aNewHeight;
};
まとめて下記の書き方もできる
Image.prototype = {
    type     : 'image object',
    width    : null,
    height   : null,
    src      : null,
    resizeTo : function(aNewWidth, aNewHeight) { alert(aNewWidth + aNewHeight); }
};
newでコンストラクタでのインスタンス化する
var img = new Image();
img.resizeTo(30, 40);

///無名関数、匿名関数、クロージャ、関数式
https://www.sejuku.net/blog/25026
クロージャとは関数とその関数が定義された状態をセットにした特殊なオブジェクト
var メソッド名的変数 = function(引数) { /*処理*/ } あるいは他メソッド(function(引数) { /*処理*/ });等で直使用
 メリットとして
 極力グローバルの変数や関数を使わなくて済む
 余計な関数名や変数名を考えなくても済む
 無名関数は式が実行されるときにFunctionオブジェクトが生成される
  無名関数は定義より前では呼び出せない(定義した所で呼び出すので混同がなく安全と考えられる)
   Javascriptは同名をオーバーライドする
  旧来の関数宣言は定義より前に実行が書かれていても呼べる
   どの関数が使われるか注意が必要(便利だが大規模では危険と考える場合も)
手続き型ではこうだが、
<html>
<head>
<script type="text/javascript">
function button1Click(){
 alert(1);
}
function windowOnload(){
 var button1 = document.getElementById("button1");
 button1.onclick = button1Click;
}
</script>
</head>
<body onload="windowOnload()">
<form name="foo">
<input type="button" id="button1" value="1">
</form>
</body>
↓無名関数ではこう
<script type="text/javascript">
window.onload = function(){
 document.getElementById("button1").onclick = function(){
  alert(1);
 };
};
</script>

//下記は無名関数を変数に入れているので実行自体はされない
実行結果を入れている分けではない、なお実際は変数名が関数名だが
var hello = function(){alert("Hello");};
//これなら実行される、ほかにも即時関数の書き方がある
setTimeout(function(){ alert("Aloha"); },1000);

///即時関数
functionから始まる関数定義そのものを()でくくって(arg)を付けて即実行できる
普通()だが関数式と評価されればいいので、!でも同じ、+-でもOK
(function(){ /*処理*/ })();
<script>
 var sum = (function(a,b){
  var result = a + b;
  return result;
 })(1,2);
 alert(sum);
!function(a,b){
 let result = a + b;
 alert(result);
}(3,4);
+function(a,b){
 let result = a + b;
 alert(result);
}(5,6);
</script>

///上記重複だがclassが導入されたES6より前の書き方(Classがないver)
https://www.yunabe.jp/docs/javascript_class_in_google.html
関数には関数式(無名関数)と関数宣言の2通り
 関数宣言は旧来のfunction name(){}の方法
 下記例が関数式
//関数式でのクラス、これはnewが必要だった
var Person = function(name, age) {
  this.name = name;
  this.age = age;
};
var alice = new Person("Alice", 7);
console.log(alice.name); // Alice
//これならnewは不要
var Person = function() {
  return { name: "alice", age: 7 };
};
var alice = Person();
console.log(alice.name); // Alice

//オブジェクトでの継承、オブジェクトではnewが不要
var sayHelloShared = function() {
  console.log("Hello, I'm " + this.name);
};
var alice = {
  sayHello: sayHelloShared,
  name: "Alice"
};
var bob = {
  sayHello: sayHelloShared,
  name: "Bob",
  child: alice
};
alice.sayHello(); // Hello, I'm Alice
bob.sayHello(); // Hello, I'm Bob
bob.child.sayHello(); // Hello, I'm Alice

//new必要?
エラーがでなければ不要といえるのでは、、、
newするとコンストラクタで明示的初期化がされインスタンスも作られるが、、、
Javascriptは全てがオブジェクトであり、newを要不要は仕様でなく使い方の範疇のようで、それゆえ、functionでクラス化したり、メソッドを定義したり、無名関数だったりできる、、、newもエラーがでなければ不要かと

//扱い注意
thisが指す対象が、objが参照で別実態だったり、タグ要素であったりで注意が必要
 console.logに出して確認するといいかも
メソッド内で使われている this が指すものは呼び出され方によって変わる
obj.hoge(); の形で呼び出された場合thisはobjになり
hoge();の形で呼び出された場合はthisは window (グローバルオブジェクト) になります
https://so-zou.jp/web-app/tech/programming/javascript/grammar/function/class/
別実態
 var Person = function(a, b) {
   return { name: a, age: b };
 };
 var alice = new Person('Alice', 7);
 var takahashi = new Person('Takahashi', 6);
 takahashi = alice;
 console.log(takahashi.name); //Alice

///ECMAScript 6 (ES6) でクラスの構文が追加
クラス構文にはクラス宣言とクラス式という 2 つの定義方法
クラス宣言の方法
class Teki{
  constructor(name, hp){
    this.name = name;
    this.hp = hp;
  }
  attack(){
    console.log(`${this.name}の攻撃!`);
  }
}
class Dragon extends Teki{
  hello(){
    console.log(`${this.name}のHPは${this.hp}です。`)
  }
}
var boss = new Dragon('どらごん', 3000);
boss.attack(); // どらごんの攻撃!
boss.hello();  // どらごんのHPは3000で
こちらがクラス式
var Foo = class {
  hello(){
    console.log("Hi!");
  }
};
var obj = new Foo();
obj.hello();

///可変変数(変数名に変数を使いたいとき)はevalで変数を含んで実行する
var new_div = eval('document.querySelector(\'#item' + settings.num_item + '\')');
eval('window.item' + settings.num_item + ' = new classItem;');
 エスケープは円マーク
 indow.a とwindow.を付けるとグローバルになる(関数の中からグローバル変数を作る等)
 
//タグ要素を取得、cssセレクタで指定
document.querySelector('#main .posts h1'); //最初の一つを取得
document.querySelectorAll('a'); //すべて取得

///実行の順番
https://kde.hateblo.jp/entry/2017/05/20/212928
https://www.javadrive.jp/javascript/ini/index2.html
ブラウザはスクリプトが記述されたHTMLファイルを順に解析しながらブラウザに表示。その途中に<script>要素が現れるとHTMLの解析を一時中断し、そのスクリプトが実行されるのを待ちます。そしてスクリプトの実行が終了すると続きからHTMLを実行していきます

Javascriptは同名をオーバーライドします
そのためwindow.onload = function(){は、複数あってもオーバーライドで一番下だけ実行する
外部ソースにwindow.onload = function(){ があってもトータルでどれか一つしか実行されない
window.onload = function(){
 alert('1');
}
window.onload = function(){
 alert('2');
}

テストしました
<html>
<head>
<script type="text/javascript" src="/js/js1.js"></script>
<script type="text/javascript">
alert('at header 1');
window.onload = function(){
  alert('at window.onload');
}
alert('at header 2 after window.online');
</script>
<script type="text/javascript" src="/js/js2.js"></script>
</head>
<body onload="alert('at body tag onload');">
<script type="text/javascript">alert('at body');</script>
</body>
</html>

下記順番に実行される

1)js 1
2)header1
3)header2 after window.online
4)js2
5)body
6)window.onloadの中で最後のもの一つだけ実行(最下行が強い)
     js1 window.onload(後ろのwindow.onloadあると本項目は実行されない)
   window.onload(後ろのbody tag onloadがあると本項目は実行されない)
  body tag onload(これがあると'at window.onload'は実行されない)
 js2 window.onload(これがあると'body tag onload'は実行されない)

onloadは実行の順番を遅くする方法、他のテクとして
window.addEventListener('DOMContentLoaded', function() {
 これはDOMのツリー構造が完了した時点で実行されるのでonloadより早い
bodyの閉じタグ直前にJSを入れる

//JavaScriptはシングルスレッド、非同期でも待ちが発生する場合もあり遅い、WebWorkersならマルチ可
setTimeoutは 「指定秒数後に実行」ではなく「指定秒数後に実行キューに登録」
https://language-and-engineering.hatenablog.jp/entry/20090614/p1
JavaScriptの非同期処理は並列処理でない
非同期処理では処理が実行できるようになるのを待ち実行できるようになってから実行する
 タイマー系はシングルスレッド問題がある、書き方ではない、()必要、""不要、無名関数でもだめ
  setInterval(set(),10) setInterval("set",10) setInterval(function(){set();},10);
 setTimeout(function(){ }, 0)と書くと擬似的に並列処理ができるらしい

非同期処理の考慮はpromise/async/awaitで行うことが多いが癖が強い、こちらに移行
https://www.bangboo.com/cms/blog/page_341.html

マルチスレッドで実行するにはWebWorkersというAPIを使うと実装可
 Web Workerとメインスレッドでのデータのやり取りにはpostMessageというメソッドを利用する必要がある
https://qiita.com/klme_u6/items/ea155f82cbe44d6f5d88
オブジェクト的な方が早い
手続き型の上から下への書き方は、実行スレッドが通信中に解放されないことである。
UIスレッドからこんなプログラムを実行すればユーザーインターフェイスが無反応になる。
https://satoshi.blogs.com/life/2010/01/sync_vs_async.html

//Web worker 並行処理 postMessage
https://www.html5rocks.com/ja/tutorials/workers/basics/
https://www.atmarkit.co.jp/ait/articles/1201/13/news138_2.html
別ファイルにしてキックするだけで簡単

///引数
https://wp-p.info/tpl_rep.php?cat=js-application&fl=r12
数が多くても少なくても実行される、可変長引数argumentsオブジェクトを使っているから
var f = function(x, y, z){
    console.log(x);
    console.log(y);
    console.log(z);
    console.log(arguments[0]);
    if(arguments.length == 4){ console.log('4'); }
};
f(1, 2, 3); //1,2,3,1
f(1, 2, 3, 4); //1,2,3,1,4
f(1, 2); //1,2,undefined,1

■ES6での変更
https://qiita.com/soarflat/items/b251caf9cb59b72beb9b

///letは再宣言が不可能な宣言、constは再宣言と再代入が不可能な宣言
varは利用する理由がない?varは関数スコープで関数内ならどこでもOK、またグローバル化も可
letとconstはカーリーブラケット{}によるブロックスコープが有効で、For等ブラケット外からアクセスできない
 letとconstは安全、varに単純置き換えはアルゴが変わるのでできない
if (true) {
 var a = 1;
 
 let b = 'aaa';
 b = 'bbb'; // 再代入する
 let b = 'ccc'; // 再宣言はエラー

 const C = 'ddd';
 C = 'eee'; // 再代入はエラー
}
console.log(a); // => 1
console.log(b); // => undefined
console.log(C); // => undefined

///アロー関数(無名関数の省略形、なおthisの扱いが違う)
アロー関数は、関数が定義されたスコープ内のthisを参照する
従来の無名関数は関数の呼び方によってthisの参照先が異なる
const fn = (a, b) => {
  return a + b;
};
// 単一式の場合はブラケットやreturnを省略できる
const fn = (a, b) => a + b;
// ブラケットやreturnを省略してオブジェクトを返したい場合は`()`で囲む
const fn = (a, b) => ({ sum: a + b });
// アロー変数はargumentsがなく可変長引数を使う必要がある
const arrow = (...arguments) => { console.log(arguments); }
arrow(1, 2, 3) //=> [ 1, 2, 3 ]

///関数にデフォルト引数を指定できる
function multiply (a = 5) {

///分割代入
const [a, b, c, d] = [1, 2, {d: 3}, 3];
const object = {a: 1, b: 2, c: {d: 3}};
 const {a, b, c, c: {d}} = object;

///テンプレート文字列(プレースホルダ)
``(バッククオート)で文字列を囲むと${}で文字列内に変数展開ができる
const name = 'soarflat';
const name = 'aaa';
console.log(`AAA is ${name}`);

///スプレッド構文
...で可変長の複数要素を表す、下記のように柔軟に
function func1 (a, ...r) { alert(a + r + r[0]); }
 func1(1, 2, 3, 4, 5);//でa=1、r[0]=2が入る
 console.log(Math.max(r));    // => NaN
 console.log(Math.max(...r)); // => 5 上手くいかないケースでも使える
function func2 (a, b, c){
 func2(...array_arg);//argumentsオブジェクトのようにできる
const [a, b, ...c] = ['a', 'b', 'c', 'C'];
 console.log(c); // => ["c", "C"]
 const array2 = [...c, 4, 5, 6];

for in/for ofで配列やオブジェクトの扱い
const array = [65, 55, 80, 100];
const obj = {name: 'aaa', country: 'Japan'}
for(const index in array) {
  console.log(array[index]);
}//65 55 80 100
for(const key in obj) {
  console.log(key);
}//name country
for(const value of array) {
  console.log(value);
}//65 55 80 100

///try catch
syntaxエラーはtry catchする必要がある、エラーハンドリングはこれ以外に色々ある
try{
let obj = JSON.parse(input);
}catch(e){
console.log(e instanceof SyntaxError);
console.error(e.message);
console.error(e.name);
console.error(e.stack);
flg_e = 'ERROR'
}

///文字置換 正規表現replace
output = input.replace(/\,/g, ",\n"); gを付けなければ最初の一つだけ

■promise/async/await はこちらに移行
https://www.bangboo.com/cms/blog/page_341.html

■FetchはAjax変わりになる
https://qiita.com/tomoyukilabs/items/9b464c53450acc0b9574
https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch

fetchでget post
https://qiita.com/okashi/items/b5d5635b399396294af3


■ショートハンド

糖衣構文(シンタックスシュガー)とも:同じ意味の処理を元の構文よりシンプルに書ける別の書き方のこと
https://www.webprofessional.jp/shorthand-javascript-techniques/
https://qiita.com/kozzzz/items/b4cd57ead41fc6355afd
短縮記法が色々あって読みにくい↑を参考

他にもあるが、下記は参考になったので↓

「!==」(厳密不等価)は「&&」(論理AND)よりも強く結びつく
 つまりnull!==e&&(e.innerHTML=t,e.style.display="block")は
(null!==e)&&(e.innerHTML=t,e.style.display="block") という意味

「&&」は 論理AND は、下記の動作をする
 前から評価する
 評価値「偽」が出たならば、「偽」を返して残りの部分は評価しない
カンマ演算子は、単純にカンマで区切られた式を順番に評価し、最後の式の値を返す
 演算子であるのでカンマで区切られるものはすべて値・関数・式である必要
 最終的にその演算子で繋がった式全体で真または偽となります

<script type="text/javascript">
let aaa={
 displayResult:function(t){
  let e=document.getElementById("result");
  //該当DIVがあれば&&()の処理をする、IFの省略
  null!==e&&(e.innerHTML=t,e.style.display="block")
 }

};
window.onload = function(){
 (function(t){
  let e=document.getElementById("result");
  if(e){
   e.innerHTML=t;
   e.style.display="block";
  }
 })('bbb');
 setTimeout(aaa.displayResult('bbb'),5000);
};
</script>
<div id="result" style="display:none">aaa</div>

■ゲーム
https://qiita.com/doxas/items/9debec7e1f0c19bc8daa チュート8迄でOKか、9でボス10で処理高速化
http://www.west-mira.jp/javascript/list/4/16/ の打打打

どちらもsetTimeoutで自己関数を呼び出すループをしている
var run = true;
var fps = 1000 / 30;
window.onload = function(){
    // ループ処理
    (function(){
     // HTMLを更新
        info.innerHTML = message + ' at ' + mouse.x + ' : ' + mouse.y;
        if(p.length() < chara.size){
            // 衝突があったのでパラメータを変更してループを抜ける
            run = false;
            message = 'GAME OVER !!';
            break;
        }
        // フラグにより再帰呼び出し
        if(run){setTimeout(arguments.callee, fps);}
    })();
};

function Games(){
 //判定処理やら得点処理やら描画処理
 clearTimeout(my_time);//setTimeoutをキャンセル
 if(tokutenn<0){
  game_end=1;
  alert("GAME OVER...");
 }
 if(game_end!=1)my_time=setTimeout('Games();',hayasa);
}

■ネイティブで実現させるフロントエンド
https://blog.kannart.co.jp/coding/1199/
 カルーセル addEventListenerでクリックされると要素分移動する
 ハンバーガ 画面サイズでハンバーガDivの表示切替、クリックでナビDiv表示
 グローバルナビ マウスオーバでナビDiv表示
 フッター固定 スクロール300でposition:fixedを表示
 スムーズスクロール scrollTop分をsettimeoutでループし段々移動
 無限スクロール ローディング画像を非表示>最下部に行けば>ローディングを表示>要素を追加していくが
   ページネーションのURL page.php?p=3から指定の要素を取り込んでいる(サーバサイド処理不要)

///解説系
https://www.nishi2002.com/14962.html フッター表示
https://beginners.atompro.net/smpdhtm_divhide1.html ナビ
https://popo-design.net/template/ シンプルRWD
http://cly7796.net/wp/javascript/implement-infinite-scrolling/ 無限スクロール

///例
カルーセル、ヒーロー、グローバルナビ
https://www.rakuten-card.co.jp/e-navi/members/index.xhtml
スクロール系(タイトルとナビとサブナビとフッターが各スクロールポイントが違う、広告追従、トップ戻るボタン)
 フッターに広告、トップにスクロールで戻るボタン
 https://ferret-plus.com/6385
 https://www.sejuku.net/blog/52998
 https://liginc.co.jp/392786 (グローバルナビも)
 広告がスクロールに追従
 https://dekiru.net/article/19272/
  sticky-state 2.4.1 - (http://soenkekluth.com/) - https://github.com/soenkekluth/sticky-state#readme
 スクロールの進み具合を表示、最後に広告?
 https://blog.hubspot.jp/google-forms
無限スクロール ローディングbyスクロール
https://shopping.yahoo.co.jp/search?p=Oakley+holbrook

ハンバーガ拡大アニメ
https://rfs.jp/sb/javascript/js-lab/resize-header-scroll.html
Wijimo Grapecity 感じのいいレスポンシブ
https://demo.grapecity.com/wijmo/demos/Input/ListBox/InfiniteScroll

ドラッグ&ドロップでHTML要素を移動
https://q-az.net/elements-drag-and-drop/
https://web-designer.cman.jp/javascript_ref/mouse/move/
https://qiita.com/kaikusakari/items/ca45910a35712daca68c

ドラッグ&ドロップでファイルをアップロード
https://platycerium.sakura.ne.jp/node/812
https://www.okushin.co.jp/kodanuki_note/2018/02/%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E3%82%A2%E3%83%B3%E3%83%89%E3%83%89%E3%83%AD%E3%83%83%E3%83%97%E3%81%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC.html
↓使用されるJS
https://lab.syncer.jp/Web/API_Interface/Reference/IDL/DataTransfer/dropEffect/
https://lab.syncer.jp/Web/API_Interface/Reference/IDL/DataTransfer/effectAllowed/
https://lab.syncer.jp/Web/API_Interface/Reference/IDL/Event/preventDefault/
https://app.codegrid.net/entry/dnd-api-1
https://qiita.com/tochiji/items/4e9e64cabc0a1cd7a1ae
https://chaika.hatenablog.com/entry/2019/02/15/090000
DataTransferは、ドラッグ操作やクリップボード操作で転送されるデータ扱うインターフェイス
 コンストラクタ
  DataTransfer() 新しいDataTransferのオブジェクトを作成します。
 メソッド
  clearData() 転送中のデータを削除します。
  getData() 転送中のデータの内容を取得します。
  setData() 転送中のデータの内容を変更します。
  setDragImage() ドラッグ操作中に表示するイメージを設定します。
 プロパティ
  dropEffect 転送データを取り扱う時のドロップ側の操作を返します。
   種類:copy, move, link, none
  effectAllowed 転送データを取り扱う時のドラッグ側の操作を返します。
   種類:copy, move, link, copyLink, copyMove, linkMove, all, none, uninitialized
  files 転送中のファイルの一覧をFileListで返します。
  items 転送中のデータの一覧をDataTransferItemListで返します。
  types 転送中のデータの種類の一覧を配列で返します。
addEventListener()でリッスンするドラッグイベント
 dragstart, drag, dragenter, dragleave, dragover, drop,  dragend
preventDefault() 規定の動作をキャンセルし文字入力やクリックや画面の遷移を行わない等
stopPropagation() イベント伝播を行わないようにする
classList クラス属性でDOM操作できるオブジェクト、クラスの追加/削除/切替/含むか判定等ができる

■ indexedDB
https://dev.classmethod.jp/articles/html5-indexed-database-api/
 キーバリューを保存できる
 このサイトのバックアップもアップロードフォルダーに一応取ってある
/// BANGBOO BLOG /// - Dexie がラッパーとして良き

IndexedDB のインターフェースは非同期でイベントベース
 indexedDB.openのonsuccessで実行が必要だったり、UX上は良いかもしれんが扱いは面倒(毎回Openのonsuccessで良いが)
 色んな形式で保存できるらしい、インデックス化は便利か
https://qiita.com/butakoma/items/2c1c956b63fcf956a137
https://ikkyu.hateblo.jp/entry/2019/11/23/180259
https://blog.htmlhifive.com/2018/06/06/indexed-db/
https://qiita.com/sachiko-kame/items/aebd618ef39de982ed7b

/// 他のクライアントへのデータ保存
1)localStorage/sessionStorageは同期型でgetItem/setItemを実行できる、5MBでStringのみ
 扱いは簡単だが、引っこ抜き安全でない
https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851
https://www.granfairs.com/blog/staff/local-storage-01
https://qiita.com/masamitsu-konya/items/c69515604570150d3ab9

2)Cookieはサーバでヘッダーで生成される、4KBまで、JSで生成し書込/読込できる、サーバ送信される?
 通常ページ表示でCookieがブラウザ保存され、再度そのページにアクセスの際ブラウザからCookieがサーバーに送信
https://qiita.com/dokkoisho/items/b415f1c9852c8fd12ec8
https://www.sejuku.net/blog/28696

Secure属性 httpsの通信の時のみCookieを送信、のぞかれないように、ONに
HHTPOnly属性 JSでの参照を防ぐ、ONに
SameSite属性 上の2つをした上でサイト構成を見てLAX以上にできればする
 Strict: 同一サイト/ドメインリクエスト間のリクエストでのみCookieを送信
 Lax: 他サイト/ドメインの遷移で、GETであればCookieセット
 None: 以前通りリクエスト先がCookieをセットしたドメインであればCookieをセット
https://laboradian.com/same-site-cookies/
https://www.future-shop.jp/magazine/info-samesite
https://www.softel.co.jp/blogs/tech/archives/4942

■知りたい実装
/// e = pow(10)=10の累乗=0の数
31536e3 は 31536 * pow(10,3) = 31536000 であり秒数換算で1年

/// 引数にアルファベット1文字 function(a,b,c,x,y,z,e,t,n,s,o){
 a,b,cとかx,y,zとかの順番とか、後は大体頭文字
 eはイベント、エラー、エレメント、Tはタイプ、テンポラリ、ターゲット、テキスト、Nはナンバー、Sはストリング、Oはオブジェクト、Iはインクリメント等

/// エンコード系
btoa バイナリデータの文字列から base64 エンコードされた文字列を作成、文字列変換なので入力はアスキー化かURIエンコードの事前処理が必要
atob base64 形式でエンコードされたデータの文字列をデコード
escape 文字列をASCII形式でエンコード、ブラウザによってはLatin1ではなくUnicodeになる?
unescape ASCII形式の文字列をデコード
encodeURIComponent スペースが%20になったりURL用エンコード
decodeURIComponent URL用にエンコードされた文字列をデコード
 base64はa-Z0-9と幾つかの記号の64種で画像や音声等バイナリを文字化しメール送信等の用途、普通はURIエンコードだけ使う感じか

==============================
■Chrome DevTools デバッガー
JSをソースタブで開く
 {} でMinifyを解除
ブレイクポイントで止めて変数の状態を調べステップ(イン)で実行
console.log()でロギング
エラー発生時の自動一時停止の有効化
https://qiita.com/d-dai/items/0b580b26bb1d1622eb46
https://ja.javascript.info/debugging-chrome

スタックトレースするにはdebuggerとかconsole.trace()
JavaScriptのデバッグにはdebugger文を使おう - Qiita

リバースエンジニアリング
エレメントタブで影響のあるエレメントのソースを抜き出す
classやidの名前から機能を類推、CSSやJSで使われているか検索する
[Ctrl] + [Shift] + [F] を押すとページが読み込んだソース全体から検索可
https://www.doe.co.jp/hp-tips/browser/chrome-devtools-techniques/

Posted by funa : 07:27 AM | Web | Comment (0) | Trackback (0)


January 4, 2016

通話SIM


あけおめとう。感謝・諦観の年にしたいかと思う。病院、関係各所では世話してもらって、
巡礼「マジ感謝」ができない分、あと改宗する!?留守電がないのが駄目だが、
アプリSmart talkを入れると留守電が使えるようであるので元電話を転送する。

楽天電話 10円/30秒
SmartTalk 8円/30秒
楽天の留守電契約300円/月(これを節約)

■Smart talkのWEBサイトのマイページで留守電設定、無料?
https://smart.fusioncom.co.jp/sfkr/mypage/top
 留守電までの時間を10sや即時にする(即時?)
 メールで送られてくるらしい
 60秒までの伝言を、10件まで、7日間のみ保存
 差出人メールアドレス mail-noreply@fusioncom.co.jp

■楽天通話SIMの転送設定、無料
まずサポートページでオプションとして転送を設定する
http://mobile.rakuten.co.jp/support/
http://mobile.rakuten.co.jp/support/option/call_forwarding/
設置後数日経つと以下の4桁番号が繋がる、開始・停止番号を忘れない
 転送先電話番号の設定・変更
 1429に掛ける
 呼出時間設定(0 ~ 120s の間)13s?
 1429に掛ける
 転送電話サービスの設定内容確認
 1429に掛ける
 転送電話サービス開始
 1421に掛ける
 転送電話サービス停止
 1420に掛ける

楽天モバイルカスタマーセンター
 0800-600-0000(繋がらず無駄遣い)
 ここに問い合わせフォームがある
 http://mobile.faq.rakuten.ne.jp/app/home

Posted by funa : 12:29 PM | Gadget | Comment (0) | Trackback (0)


January 4, 2016

Laravel

https://coinbaby8.com/laravel-php-dekirukoto.html
https://laravel10.wordpress.com/
https://paiza.jp/works/laravel/primer

ルーティング:  URLと対応 .phpで終わせず処理をひとつのファイルやクラスにまとめる
Blade:  テンプレートエンジン
ミドルウェア: URL前後に処理を付加
エラーハンドラ: 例外やエラーが発生した際の処理
DI : サービスコンテナというのを用いクラスインスタンスの依存度を極力下げて、実行時に外部から与えてもらえるように
バリデーション:  入力値のチェックを設定のみで自動的に
データベース連携
認証の自動化

■PHPフレームワーク Laravel入門 サンプルファイルのダウンロード
https://www.shuwasystem.co.jp/support/7980html/5258.html

■XAMPP 7.4.1 インスコ(X-platform/Apache/MySQL/PHP/Perl)
 https://www.apachefriends.org/jp/index.html
 Win用Exeでインスコ C:\xampp\htdocs ← http://localhost/
 xamppコンパネのショートカットをデスクトップに作成
Composer PHPのパッケージ管理システム
 https://getcomposer.org/download/
 Win用Exeで通常(devでなく)でインスコ
 PHPはC:\xampp\php\php.exe、ユーザパスはC:\xampp\php
Laravel インスコ(プロジェクト作成)
 コマンドを打つと自動でインスコ
 cd C:\xampp\htdocs
 composer create-project laravel/laravel prj_laravel --prefer-dist
 5分位掛かる

Xampp(appach, mysql)起動し、Laravelプロジェクト起動はコマンドを打つ
 cd C:\xampp\htdocs\prj_laravel
 php artisan serve
  次のURLへアクセスする http://localhost:8000/
   8000のルートはここ C:\xampp\htdocs\prj_laravel\public

http://localhost では:80
php artisan serve --port=8000 がデフォ、Xamppは80
netstat -an でリスナーを見れる(XAMPPコンパネでもOK)
C:\xampp\apache\conf\httpd.conf でDocumentRootを変更できる
 Alias / "C:\xampp\htdocs\prj_laravel\public"でエイリアス?

自由に使えるか?
1)C:\xampp\htdocs\prj_laravel\public\direct_test1.php を置くとhttp://localhost:8000/direct_test1.php でPHPが動くページにアクセスできる
2)ビューで自由にPHPを動かせるか?→例えばtest.blade.phpに<?php --- ?>でコードを書けば動く
 http://localhost:8000/_test でアクセスすれば下記ルートとビューが使われtest.blade.phpだけで動く
 routes/web.php
  C:\xampp\htdocs\prj_laravel\app\Http\Controllers  無し
  config/app.php ファサード無し サービスプロバイダ無し
  C:\xampp\htdocs\prj_laravel\app\Http\Middleware フィルタ無し
  C:\xampp\htdocs\prj_laravel\app\Http/Kernel.php ミドルウェア無し
 C:\xampp\htdocs\prj_laravel\resources\views\test.blade.php

http://localhost:8000/fun/

php artisan make:controller FunController --resource

MySQLにDB:test ID:test/testtestを設定しテーブルを作成
CREATE TABLE `fun_inquiry` (
  `no` bigint(20) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL default '',
  `inquiry` text,
  `title_ex` varchar(255) NOT NULL default '',
  `inquiry_ex` text,
  `date_latest` datetime NOT NULL default '1000-01-01 00:00:00',
  `date_2ndlast` datetime NOT NULL default '1000-01-01 00:00:00',
  `date_first` datetime NOT NULL default '1000-01-01 00:00:00',
  `ip` varchar(255) NOT NULL default '',
  `flag_who` tinyint(4) NOT NULL default '0',
  `flag_active` tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (`no`)
) ENGINE=InnoDB
  DEFAULT CHARACTER SET utf8
   COLLATE utf8_unicode_ci;
/*
flag_who 1:customer,2:admin
flag_active 1:有効,2:削除
*/

ダミーデータ挿入
INSERT INTO `fun_inquiry`(`title`, `inquiry`, `date_lastest`, `date_first`, `ip`, `flag_who`, `flag_active`) VALUES ('あああ', 'いいい', now(), now(), '192.168.56.1', '2', '1')

.env とconfig/database.phpに DB情報を記入
 変更後は php artisan config:cache

C:\xampp\htdocs\prj_laravel\routes\web.php にコントローラ渡し記述
 index crate store show($id) edit($id) update(Request $request, $id) destroy($id)
C:\xampp\htdocs\prj_laravel\app\Http\Controllers\FunController.php にView渡し記述
C:\xampp\htdocs\prj_laravel\resources\views\index.blade.php など
 index crate store show edit update destroyのViewファイルを作成し リンク設定
 href=/でルートからリンクを指定
 パスはルート/が安定する、相対だと理由不明で階層が崩れる事があった、Form methodを入れる
 
情報を表示させたい
 コントローラに
 $param = ['items' => $items,
  'msg' => 'データを追加しました',
  'request' => $request,
  'response' => $response];
 return view('index', $param);
 ビューに
 <?php dump($items);
 dump($msg);
 dump($request);
 dump($response); ?>

バリデーションするのに同カラム保持のpostsテーブルが必要であったので作成(多分ダミー)
テーブル作成方法: php artisan make:model posts をCMDしSQL流し込み
CREATE TABLE `posts` (
  `no` bigint(20) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL default '',
  `inquiry` text,
  `title_ex` varchar(255) NOT NULL default '',
  `inquiry_ex` text,
  `date_latest` datetime NOT NULL default '1000-01-01 00:00:00',
  `date_2ndlast` datetime NOT NULL default '1000-01-01 00:00:00',
  `date_first` datetime NOT NULL default '1000-01-01 00:00:00',
  `ip` varchar(255) NOT NULL default '',
  `flag_who` tinyint(4) NOT NULL default '0',
  `flag_active` tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (`no`)
) ENGINE=InnoDB
  DEFAULT CHARACTER SET utf8
   COLLATE utf8_unicode_ci;
エラー後は元のページに戻るが元の値とエラーを出すには
 <input name="title" value="{{old('title')}}">
 @if($errors->has('title'))
    @foreach($errors->get('title') as $message)
     <br><red>{{ $message }}</red>
    @endforeach
 @endif
//バリデーション例
https://qiita.com/fagai/items/9904409d3703ef6f79a2
https://blog.capilano-fw.com/?p=341#digitsdigits_between
$validate_rule = [
    'title' => 'required|unique:posts|max:255',
    'inquiry' => 'required',
    'title_ex' => 'required|unique:posts|max:255',
    'inquiry_ex' => 'required',
    'date_latest' => 'required|date_format:Y-m-d H:i:s',
    'date_2ndlast' => 'date_format:Y-m-d H:i:s',
    'date_first' => 'required|date_format:Y-m-d H:i:s',
    'ip' => 'required|ip',
    'flag_who' => 'required|integer|between:1,2',
    'flag_active' => 'required|integer|between:1,2'];
$this->validate($request, $validate_rule);

自分で命名したデータベースをLaravelに参照させたいときは、テーブル名をモデルファイル内で指定しなければいけない
php artisan make:model DbTblFunInquiry をCMDし
app/DbTblFunInquiry.php を編集
namespace App;
use Illuminate\Database\Eloquent\Model;
class DbTblFunInquiry extends Model{
    protected $table = 'fun_inquiry';
}

コントローラでDB追加
$now = date('Y-m-d H:i:s');
$input = ['title' => $request->title,
    'inquiry' => $request->inquiry,
    'date_latest' => $now,
    'date_first' => $now,
    'ip' => $request->ip(),
    'flag_who' => '1',
    'flag_active' => '1'];
$insert = DB::insert('insert into fun_inquiry(title, inquiry, date_latest, date_first, ip, flag_who, flag_active) values (:title, :inquiry, :date_latest, :date_first, :ip, :flag_who, :flag_active)', $input);

DB操作で同じパラメータを使おうとしてもSQLで数が合わないとだめで$input作り直した
→エラーはrequest/responseインスタンスをダンプしキッチリと見ると原因がわかる
$update = DB::update('update fun_inquiry set
        title = :title,
        inquiry = :inquiry,
        title_ex = :title_ex,
        inquiry_ex = :inquiry_ex,
        date_latest = :date_latest,
        date_2ndlast = :date_2ndlast,
        ip = :ip,
        flag_who = :flag_who,
        flag_active = :flag_active
        where no = :no', $input);
$input = ['no' => $request->no];
$items = DB::select('select * from fun_inquiry where no = :no', $input);



■ララベルの基本
gitの管理対象から外す
.gitignore ファイルに追加
環境毎に変更したい情報
.env ファイルにステージング環境、本番環境の情報をまとめる
設定情報は下記以下、DB接続/メール/サービスプロバイダ登録/ファサード登録等
config/
バリデーションメッセージの日本語化
resources/lang/ja/validation.php

===============

├── app
│   └── Article.php
│   └── Http
│       └── Controllers
├── resources
│   └── views
└── routes

//基本構成
 routes/web.php
 C:\xampp\htdocs\prj_laravel\app\Http\Controllers ある程度処理をする?モデル化?
 config/app.php ファサード サービスプロバイダ
 C:\xampp\htdocs\prj_laravel\app\Http\Middleware フィルタ
 C:\xampp\htdocs\prj_laravel\app\Http/Kernel.php ミドルウェア
 C:\xampp\htdocs\prj_laravel\resources\views\test.blade.php
CRUDはリソースコントローラで一気作成ができる
 php artisan make:controller PostsController --resource
モデルを作成cmd EloquentでDB接続 app/Article.php
 php artisan make:model Article
ファサード
 対象となるクラスの作成 class Payment {
 サービスプロバイダの作成 php artisan make:provider PaymentServiceProvider
 サービスコンテナに paymentキーでPaymentクラスをバインド
 config/app.php に PaymentServiceProviderと エリアスを追加
認証用ビューとルートを作成(認証機能はプロジェクト作成時点で既成)
 php artisan make:auth

//php artisanコマンド(独自作成も可)
何ができるかリスト確認cmd
php artisan list
使い方確認cmd
php artisan help コマンド名
cmdでララベル機能が使える
php artisan tinker
古いパッケージをチェック
composer update --dry-run
古いパッケージをチェック(グローバルの場合)
composer global update --dry-run

.env変更後は
php artisan config:cache
コントローラを作成cmd
php artisan make:controller WelcomeController
モデルを作成cmd
php artisan make:model Article
Form Request を生成
php artisan make:request ArticleRequest
CRUDはリソースコントローラで一気作成ができる
php artisan make:controller PostsController --resource
認証用ビューとルートを作成(認証機能はプロジェクト作成時点で既成)
php artisan make:auth
ルーティングのリストを表示
php artisan route:list

//jsファイルやcssファイルはpublicフォルダ配下に入れる、HTMLやIMGも
 public
   |__ css
   |__ js
   |__ img
   |__ html
 asset('ファイルパス')はpublicディレクトリのパスを返す関数、SSLならsecure_assset()
 <script src="{{ asset(mix('js/app.js')) }}" defer></script>
 <link href="{{ asset(mix('css/app.css')) }}" rel="stylesheet">
 <img alt="ロゴ" src="{{ asset('/img/logo.png') }}">
 url()で完全なURL、SSLならsecure_url( )
 .hoge::before { background: url("../img/hoge.svg") no-repeat center center; }
 レスポンスでHTMLファイルを返したい時
 Route::get('fun/html', function() {
     return File::get(public_path() . '/html/test_direct.html');
 });

//ルーティング routes/web.php
必須パラメータ(値がないとエラー)
 Route::get('login/{id]/{pass}', function($id, $pass){
任意パラメータ
 Route::get('login/{id?]/{pass?}', function($id='noname', $pass='unknown'){
 login/taro/aaa でアクセスするときRouteにlogin/taro/{pass?}とlogin/{id?]/{pass?}があればどうなる?
  通常 http://url/コントローラ/アクション と設計され Route::get('パス', 'コントローラ@アクション' (アクションはコントローラ内のメソッド)
Route::get('/', 'WelcomeController@index');
Route::get('contact', 'WelcomeController@contact');
正規表現を配列にして、複数指定
Route::get('foo/{id}/{name?}', function($id, $name = 'init') {
    return "パラメータ $id, $name";
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
下のようにnamed rootで名付けも
Route::get('articles', 'ArticlesController@index')->name('articles.index');
Route::get('articles/{id}', 'ArticlesController@show');
Route::post('articles', 'ArticlesController@store')->name('articles.store');

//コントローラ app/Http/Controllers/WelcomeController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WelcomeController extends Controller{
    public function index(){
        return view('welcome');
    }
    public function contact(){
        return view('contact');
    }
}
class ArticlesController extends Controller {
    public function create() {
        return view('articles.create');
    }
    public function store(ArticleRequest  $request) {
 //コントローラはメソッドの引数にタイプヒントでクラスを記述するとインスタンスを自動生成して渡してくれます
        //$inputs = \Request::all(); //フォームの入力値を取得
        //dd($inputs); //デバッグ: $inputs の内容確認
        Article::create($request->validated());//マスアサインメントで記事をDBに作成
        return redirect()->route('articles.index')->with('message', '作成!'); //記事一覧へリダイレクト
    }
}

//ビュー resouces/views/welcome.blade.php
resources/view/contact.blade.php
view('aaa')の場合、ビューはaaa.blade.phpが読まれる、なければaaa.php
blade では PHP で評価した結果を表示する場合、ダブルカーリー {{ }}
{{!! XXXX !!} はPHP評価をエスケープ処理を行わず表示(htmlタグがでる)、{{ XXXX }} のエスケープ(htmlタグがでない)
@csrfでCSRFトークン(hidden)を挿入
{{-- コメント文 --}}

ビューテンプレ
親ビューですべきこと
 大まかレイアウトを記述し、各子ビュー固有のパーツをどこの@yieldで反映させたいかを指定
 <html><body>
 @yield('body')
 </html>
子ビューですべきこと
 @extendsで親ビュー継承、@sectionで自分固有のパーツを定義
@extends('common.layout')//resources/views/common/layout.blade.php dotはフォルダの事
@section('body')
    <p>表示したい内容<p>
@endsection

@extends('layout')
 <h1>About Me: {{ $first_name }} {{ $last_name }}</h1>
    {{-- エラーの表示を追加 --}}
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
 {!! Form::open() !!}
<div class="form-group">
    {!! Form::label('title', 'Title:') !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('body', 'Body:') !!}
    {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('published_at', 'Publish On:') !!}
    {!! Form::input('date', 'published_at', $published_at, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::submit($submitButton, ['class' => 'btn btn-primary form-control']) !!}
</div>

 大元のレイアウトビュー resouces/views/layout.blade.php
 <!DOCTYPE HTML>
 <html lang="ja">
 <body>
       @if (session('message'))
            <div class="alert alert-success">{{ session('message') }}</div>
        @endif
     @yield('content')
 </body>
 </html>

変数を渡す場合
ビューファサードは第二引数へ配列でパラメータを渡す
Route::view('sample/view', 'sampleview', ['number' => 123456789]);
コントローラでは配列で渡す
public function create(Request $request, Response $response){
    $items = DB::select('select * from fun_inquiry');
    $param = ['items' => $items,
    'msg' => 'データを追加するにはログインが必要です',
    'request' => $request,
    'response' => $response];
    return view('index', $param);
他にはcompact関数又はwithメソッドで送信
public function test() {
    $test_1 = "テスト1";
    $test_2 = "テスト2";
    return view('test.normal',compact('test_1','test_2'));
}
public function test() {
    $test_1 = "テスト1";
    $test_2 = "テスト2";
    return view('test.normal')->with([
       "test_1" => "テスト1",
       "test_2" => "テスト2",
    ]);
}
フォーム
    <input type="text" name="textbox" value="">
    <input type="radio" name="radio-btn" value="選択1">
    <input type="radio" name="radio-btn" value="選択2">
    テキストボックスは{{$post_data['textbox']}}
    ラジオボタンは{{$post_data['radio-btn']}}
処理系ディレクティブ
@isset($msg) {{$msg}} @else 今何してる? @endisset
@for($i=1;$i<10;$i++;) {{$i}} @endfor
@while($msg=='') 今何してる? @endwhile
@break @continueも
        @foreach($db_data as $recode)
           {{$recode->id}}
           {{$recode->name}}
           {{$recode->old}}
        @endforeach
        {{$db_data[0]->name}} 0番目
        $count = $db_data->count(); カウント
        $avg = $db_data->avg('old'); 平均

//モデル app/Article.php
DBとモデルオブジェクトを対応付ける機能を Eloquent という
Eloquent の機能を継承しビジネスロジックを加えたクラスがモデル
ORM(Object-relational mapping)でDBアクセスをする
 $items = DbTblFunInquiry::all(); //モデルを作成しているのでコレでDBアクセス可
 $items = DbTblFunInquiry::where(no, '>=', 3)->get();
Eloquentのリレーションには、1対n、1対1やn対n等が
$this->hasMany('App\Article');
$this->belongsTo('App\User');

//バリデーション
エラーが出て前のページに戻る
public function update(Request $request, Response $response){
        $validate_rule = [
            'title' => 'required|unique:posts|max:255',
            'inquiry' => 'required'];
        $this->validate($request, $validate_rule);

作り方、まずコントローラでは
    $upfileRequest = new upfileRequest();
    $rules = $upfileRequest->rules();
    $errorMsg = $upfileRequest->messages();
    $result = $this->validate($request, $rules, $errorMsg);
cmdでリクエストクラスを生成
$ php artisan make:request upfileRequest
下記のように
class upfileRequest extends Request{
    public function rules(){
        return [
            'title'                => 'required',
            'address'              => 'required',
            'url'                  => 'url',
            'img'                  => 'file|image|mimes:jpeg,jpg,png,gif|max:' . config('const.validate_limits.upload_image_size'),
            'img_update_flag'      => 'sometimes|accepted',
        ];
    }
    public function messages(){
        return [
            'title.required'               => 'タイトルは必須です',
            'address.required'             => '住所は必須です',
            'url.url'                      => 'このURLは不正です(http://またはhttps://から記述してください)',
            'img.mimes'                    => '選択できる画像はJPEG・GIF・PNG形式のみです',
            'img.max'                      => '1MB以下のファイルを選択してください',
            'img_update_flag.accepted'     => '1MB以下のファイルを選択してください',
        ];
    }
}

//ミドルウェアでフィルタリングを実行 
記事の作成や編集、削除はログインしていないと実行出来ないように制限する等
app/Http/Middleware/ にミドルウェアがある(vendor/laravel/framework 以下にも多数ある様)
 ├── CheckForMaintenanceMode.php
 ├── EncryptCookies.php
 ├── RedirectIfAuthenticated.php
 ├── TrimStrings.php
 ├── TrustProxies.php
 └── VerifyCsrfToken.php
app/Html/Kernel.php の中でミドルウェアをシステムに登録
1)グローバルミドルウェア(全ての HTTP リクエストに適用)
2)ルートミドルウェア(Routeで使用)
3)グループ(Web等)で登録可
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
ミドルウェアの使用
 routes/web.phpで定義したルートには全てwebミドルウェアが適用される
 ルートミドルウェアを使う場合(Routeに配列で登録)
  Route::get('admin/profile', function () {
      //処理
  })->middleware('auth', '2つ目', ...);
 // ホーム(ログインしていないと見れないよう)
 Route::group(['middleware' => 'auth'], function() {
     Route::get('/home', function () {
         return view('home');
     });
 });
 コントローラで使う場合
   ログインをしていなくてもindexとshowの表示が可能
  class ArticlesController extends Controller{
      public function __construct(){
          $this->middleware('auth')
              ->except(['index', 'show']);
      }
 ビューでの使用
  @auth
  ログインしています
  @endauth
Middleware の新規作成(基本的なものは元々ある)
 php artisan make:middleware MyMiddleware
 登録確認メールの確認が済んでいるかミドルウェアで
  https://laravel10.wordpress.com/2015/05/05/laravel5

//ファサード
サービスコンテナで利用可能なクラスへのstaticインターフェースを提供
サービスコンテナからオブジェクトへのアクセスを提供するクラス
Hoge::ぶらぶら とシンプルにコードが書けるようになる
Route::get('/', 'WelcomeController@index'); はファサードがあり実際は下記
$this->app->make('router')->get('/', 'WelcomeController@index');
<?php namespace Illuminate\Support\Facades;
class Route extends Facade {
    protected static function getFacadeAccessor() {
        return 'router';
    }
}
実際に作成↓
対象となるクラスの作成 class Payment {
サービスプロバイダの作成 php artisan make:provider PaymentServiceProvider
サービスコンテナに paymentキーでPaymentクラスをバインド
class PaymentServiceProvider extends ServiceProvider {
    public function boot(){  }
    public function register()    {
        $this->app->bind(
        );
    }
}
config/app.php に PaymentServiceProviderを追加
ファサードクラスを作成
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Payment extends Facade {
    protected static function getFacadeAccessor() {
        return 'payment';
    }
}
config/app.php に Paymentファサードのエリアスを追加
    'aliases' => [
        'Payment' => App\Facades\Payment::class,
    ],
app/Http/route.php 内で Paymentファサードを使用
Route::get('pay/{money}', function($money){
    return \Payment::pay($money);
})->where('money', '[0-9]+');
この場合はここへアクセス http://localhost:8000/pay/10000
            'payemnt', 'App\Services\Payment'

//セッションはキーと値 https://qiita.com/reflet/items/5638ab18fd7cededed17
$requet->session()->put(key, value); 値を保存
$v = $request->session()->get(key); 値を取得
$request->session()->flush(); セッション破棄 session()->forget('key');個別
$request->session()->all(); 全取得

//クッキー
\Cookie::queue('testcookie', "aaa", 60); 書き込み60分
$test = \Cookie::get('testcookie');取得
setcookie('testcookie');削除

//httpヘッダー
以下を入れて見れる
Controllerで
use Illuminate/http/Request;
use Illuminate/http/Response;
public function create(Request $request, Response $response){
        $param = ['msg' => 'データを追加します',
            'request' => $request,
            'response' => $response];
        return view('create', $param);
Viewで
<?php
dump($msg);
dump($request);
dump($response);
?>
下記メソッドも
$request->url() クエリ変数がつかないURL
$request->fullUrl() クエリ変数つきフルURL
$request->path() ドメインがないパス部分
$response->status()
$response->content()
$response->setContent(値)

//認証
https://reffect.co.jp/laravel/laravel-authentication-understand
https://qiita.com/apricotcomic/items/d7407d4b12f41e2ff5ed
http://recipes.laravel.jp/recipe/64
https://takahashi-it.com/php/laravel54-auth-customize/
https://saba.omnioo.com/note/6246/laravel6-0-makeauthが無くなった/

基本ページと認証仕組みをcmdで入れ込む
 (users/pw_resetsテーブル等はmigrationで作成しておく必要)
 php artisan make:auth はv6から使えない様
 vue省略型、React性能高
composer require laravel/ui
php artisan ui vue --auth
 Nodeを入れて下記が必要のようだが(管理者権限が要るCMD)
cd C:\Program Files\nodejs
npm init --yes
npm install
npm run dev
 下記ページができる
http://localhost:8000/login
http://localhost:8000/register
http://localhost:8000/password/reset
 ルーティング関連(コントローラ)
 C:\xampp\htdocs\prj_laravel\app\Http\Controllers\HomeController.php
 C:\xampp\htdocs\prj_laravel\app\Http\Controllers\Auth
 ルーティングAuth::routes();から下記へ
  C:\xampp\htdocs\prj_laravel\vendor\laravel\framework\src\Illuminate\Support\Facades\Auth.php
  C:\xampp\htdocs\prj_laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php
  C:\xampp\htdocs\prj_laravel\vendor\laravel\framework\src\Illuminate\Foundation\Auth
 migration するとデータは消えるのか? php artisan migrate ではDropされない、migrate:flushだと消える
 Auth自動生成ページ系の遷移設定
  protected $redirectTo = RouteServiceProvider::HOME;
   HOMEは定数(C:\xampp\htdocs\prj_laravel\app\Providers\RouteServiceProvider.php で
    public const HOME = '/fun';に設定
  コントローラ類に下記を追加することで制御が可能だがコントローラを分ける必要がありそう
  public function __construct(){ $this->middleware('auth'); }
  public function __construct(){ $this->middleware('guest'); }
  public function __construct(){ $this->middleware('guest')->except('logout'); }
ビューでログイン判定可
<?php
$user = \Auth::user();
if ($user) {
    echo 'ログイン中: ' . $user->name;
?>
  | <a href={{ route('logout') }} onclick="event.preventDefault();document.getElementById('logout-form').submit();">ログアウト</a>
  <form id='logout-form' action={{ route('logout')}} method="POST" style="display: none;">
    @csrf
</form>
<?php
}else{
?>
<a href="/login">Login</a>  |
<a href="/register">Register</a>
<?php
}
?>
ビューにこんな感じでも
 @if(Auth::check())
     {{ Auth::id() }}
 @endif
 @auth
   <p>ログインユーザーに表示する。</p>
 @guest
   <p>ログインしていないユーザーに表示する。</p>
 @endguest
編集機能ページ等はコントローラでログイン判定しMSG表示とページ変遷(ログインするとCreateとUpdate可)
    public function edit(Request $request, Response $response)
    {
        $user = \Auth::user();
        if ($user) {
            $input = ['no' => $request->no];
            $items = DB::select('select * from fun_inquiry where no = :no', $input);
            $param = ['items' => $items,
                'msg' => '#' . $request->no . 'を編集できます',
                'request' => $request,
                'response' => $response];
            return view('edit', $param);
        }else{
            $input = ['no' => $request->no];
            $items = DB::select('select * from fun_inquiry where no = :no', $input);
            $param = ['items' => $items,
                'msg' => '#' . $request->no . 'を編集するにはログインが必要です',
                'request' => $request,
                'response' => $response];
            return view('show', $param);
        }
    }
コントローラでユーザ判定
 use Illuminate\Support\Facades\Auth;
 class モデル名Controller extends Controller
 {
     public function ブレード名(){
         $auths = Auth::user();  // ログイン中のユーザー情報
         $user_no = Auth::id();  // ユーザーIDのみ
         if (Auth::check()) {
          if($a==1){ Auth::logout(); }
ログアウト時の変遷
logoutメソッドの本体は、AuthenticatesUsers にあるのでHOMEへ変更
 C:\xampp\htdocs\prj_laravel\vendor\laravel\framework\src\Illuminate\Foundation\Auth
 //return $this->loggedOut($request) ?: redirect('/');
 use App\Providers\RouteServiceProvider;
 return $this->loggedOut($request) ?: redirect(RouteServiceProvider::HOME . '?fr=logout');
https://takahashi-it.com/php/laravel-login-authenticated-override/
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php の
中に、ログイン処理のリダイレクト直前で実行される authenticated() メソッドが書かれているが空で
LoginController.php でオーバーライドする形で実装
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 protected function authenticated()
 {
     Session::put('session_start_time', date('H:i'));
 }

Session にログイン時間を入れる
 use Session;//これは場合によって不要なようである
 Session::put('session_start_time', date('H:i'));
 $session_start_time = Session::get('session_start_time');
 @if (Session::has('session_start_time'))
  {{ Session::get('session_start_time') }}
 @endif
Authと連動しログアウトするとSessionがなくなる

//サービスプロバイダー ServiceProvider
 処理や表示したいビューを登録しておける(初期処理用、カウンターのようにインクリできない)
 クラスを作りboot()に付与して、例えばいつでもその処理とメッセージをビューに呼び出す
 MVCでビューにビジネスロジックを書く必要がある矛盾を解消するもの?

クラス作成 C:\xampp\htdocs\prj_laravel\app\Http\Gadget\Lucky.php
namespace App\Http\Gadget;
class Lucky
{
    public $count = 0;
    public $rate = 0;
    public function addupCounter(){
        $this->count++;
    }
    public function getCounter(){
        $this->count++;
        return $this->count;
    }
    public function getLucky(){
        $this->rate = rand(1, 100);
        return $this->rate;
    }
}
サービスプロバイダの作成 php artisan make:provider GadgetServiceProvider
 app/Providers/AppServiceProvider.php に追記でもいい
config/app.php に GadgetServiceProviderを追加
GadgetServiceProviderのbootに追記
    public function boot(){
        \View::composer(
            'index', function($view){
                $LuckyInstance = new \App\Http\Gadget\Lucky;
                $view->with('lucky', $LuckyInstance->getLucky());
            });
index.bladeのビューに追記 {{ $lucky }}

//ユニットテスト(Laravel PHPunit)
リファレンス https://readouble.com/laravel/5.7/ja/http-tests.html#assert-see
 https://qiita.com/rev84/items/12fbd16d210d6a86eff9
処理を全部書かないと駄目か https://qiita.com/shindex512/items/4f28f8e06ef2d10e8d2b
PHPUnitが入っていてTestsフォルダに
TestCaseクラスにあるメソッドはtestで始まる名前のメソッドと判断し実行する、testABC()とか
DB_DATABASEが使用されるのでDBに用意する、設定等
database/factoriesにダミーデータ作成ファクトリーがある、必要な形式のデータが作られるよう調整する
 $factory->define(App\User::class, function (Faker\Generator $faker) {
     static $password;
     return [
         'name' => $faker->name,
         'email' => $faker->unique()->safeEmail,
         'password' => $password ?: $password = bcrypt('secret'),
         'remember_token' => str_random(10),
     ];
 });
 $factory->define(App\Person::class, function (Faker\Generator $faker) {
     return [
         'name' => $faker->name,
         'mail' => $faker->safeEmail,
         'age' => random_int(1,99),
     ];
 });
テストクラス作成 php artisan make:test LuckyTest
use Tests\TestCase;
use App\Http\Gadget\Lucky;
class LuckyTest extends TestCase{
    public function testLucky(){
        $response = $this->get('/fun');
        $response->assertStatus(200);
  $lucky = new Lucky;
  $lucky_num = $lucky->getCounter();
  $response->assertGreaterThanOrEqual(1, $lucky_num);
  $response->assertLessThanOrEqual(100, $lucky_num);
 }
}
 use DatabaseMigration; を入れておくとテスト前後で自動でロールバックするらしい
テスト実行cmd vendor\bin\phpunit

//ページネーション
コントローラ側: $items = DB::table('fun_inquiry')->Paginate(7);
ビュー側: {{ $items->links() }} 合計{{ $items->total() }}
CSS側:
 ul.pagination { text-align: center; margin: 0; padding: 0; }
 .pagination li { display: inline; margin: 0 2px; padding: 0; display: inline-block; background:#eeeeee; width: 25px; height: 25px; text-align: center; position: relative; }
 .pagination li a:hover, .pagination li a.active{ color: #000; background: #ccf; }
 下記ではオブジェクトではなく配列を返しておりエラー
  $items = DB::select('select * from fun_inquiry')->simplePaginate(7);
 下記のようにクエリビルダかエロクエントならばOKのよう
  $users = DB::table('users')->paginate(15); //query builder example
  $users = User::where('votes', '>', 100)->paginate(15); //eloquent example
  $users = DB::table('users as u')->select(['u.email','u.name','u.created_at'])->whereRaw("u.id in (select max(ui.id) from users ui where ui.status = 0)")->orderBy("ui.id","desc")->paginate(3)
吐き出されるソース resources/views/pagination/default.blade.phpで修正可能
 <nav>
 <ul class="pagination">
 <li class="page-item disabled" aria-disabled="true" aria-label="pagination.previous">
 <span class="page-link" aria-hidden="true">&lsaquo;</span>
 </li>
 <li class="page-item active" aria-current="page"><span class="page-link">1</span></li>
 <li class="page-item"><a class="page-link" href="http://localhost:8000/fun?page=2">2</a></li>
 <li class="page-item">
 <a class="page-link" href="http://localhost:8000/fun?page=2" rel="next" aria-label="pagination.next">&rsaquo;</a>
 </li>
 </ul>
 </nav>

===============
■その他の機能
オートローダー
 require "vendor/autoload.php";
 autoload設定はcomposer.json を修正
ロガー
 Monolog\Logger
エラーログ
 storage/logs/*.log
メール送信
 Mail::raw()
 Laravel 5.3 からは artisan make:mail でMailable の派生クラス
  php artisan make:mail Hello
  app/Mail/Hello.php が作成される、Viewで本文
  Mail::to('reciver@example.com')->send(new Hello($name));
データベース管理(migrationファイルを作成→migration実行)
 php artisan make:migration create_users_table --create=users
 php artisan migrate
  database/migrations/2014_10_12_000000_create_users_table.php ができる
  php artisan migrate:rollback でロールバック
Bootstrap
 靴紐のソースを npm でダウンロードしLaravel Mixで public に配置
デバッガー
 composer require barryvdh/laravel-debugbar でインスコ
  config/app.php のサービス・プロバイダーとファサードに以下の設定を追加
  Barryvdh\Debugbar\ServiceProvider::class,
  'Debugbar' => Barryvdh\Debugbar\Facade::class,
デバッグ
 dd($articles->first());  // dump and die ダンプして停止
   Log::debug("incoming: GET hello");
   Log::info("incoming: GET hello");
   Log::warning("incoming: GET hello");
  debug,info,notice,warning,error,critical,alertの7つ、storage/logs/に出力
全件
 $articles = Article::all();
作成日の降順に記事をソート
 $articles = Article::orderBy('published_at', 'desc')->orderBy('created_at', 'desc')->get();
$articles = Article::latest('published_at')->latest('created_at')->get();
現在より以前
 $articles = Article::latest('published_at')->latest('created_at')->where('published_at', '<=', Carbon::now())->get();
フラッシュメッセージ
 composer require laracasts/flash
Named rootはURLでなくルーティングに別名をつける
 return redirect()->route('articles.index')
CRUDはリソースコントローラで一気作成ができる
 php artisan make:controller PostsController --resource
 // routes/web.php
 Route::resource('posts', 'PostsController')->only(['index', 'show']);
 Route::resource('posts', 'PostsController')->expect(['create', 'store', 'update', 'destroy']);
IDEでファサードの補完を行う
 composer require barryvdh/laravel-ide-helper
 php artisan ide-helper:generate
ページネーションで1ページに表示するデータ数を指定
$articles = Article::latest('published_at')->paginate(15);
 render() でページネーションリンクをビューに生成 {!! $articles->render() !!}
ダミーデータ生成
 seeder/factory/fakerで
サービスコンテナ
 インスタンス化を管理する
 サービスコンテナへクラスをバインドすると(キー名とクラスの紐付け)、クラス間の依存性を管理しやすい
 インターフェイスでバインドとタイプヒントで依存性注入
 $this->app->bind('SenderInterface', 'MailSender');
  singleton()でバインドすると何度コンテナが呼び出されても同じインスタンスが返されメモリ効率が良い
  $this->app->singleton('sender_single', 'MailSender');
 Route::get('send/{message?}', function(Messenger $messenger, $message = '合格') {
    return $messenger->send($message);
 });
シングルトン(Singleton)パターンは
 あるクラスのインスタンスを一つだけにする
 同じクラスを使って新しいオブジェクトを再度作成すると最初に作ったオブジェクトの参照になる
 function Singleton () {
   // すでにSingleton.instance が存在する場合にはSingleton.instance を返す
   if(typeof Singleton.instance === 'object') {
     return Singleton.instance;
   }
サービスプロバイダー
 config/app.php にリストアップされ起動時に読込
 Composerを使ってパッケージをインストールしたもの
 vendor/laravel/framework/src/illuminate/Auth\AuthServiceProvider等を見ると
 register()に登録を実装、boot()でそのサービス固有の初期処理を自由に実装
  作成は php artisan make:provider MessengerProvider
エリクサー
 Elixirはnode.jsのgulpをラッピングした自動化ツール
 SassをCSSに変換、複数のファイルを1ファイルに結合、ミニファイ(余計な空白や改行を削る)、ファイルの変更を監視してタスクを実行、リロード用にCSSやJavaScriptのファイル名にバージョンを付与
ファイルアップロード
 https://reffect.co.jp/laravel/how_to_upload_file_in_laravel
 https://team-lab.github.io/skillup/step2/07-upload.html
 https://laraweb.net/tutorial/2707/
 https://qiita.com/mashirou_yuguchi/items/14d3614173c114c30f02
 php.iniで定義: upload_max_filesize post_max_size等
 windowsはパーミッションの設定は不要、XamppのTMPはここ C:\xampp\tmp\
  $request->file('upfile')->getRealPath();//C:\xampp\tmp\php103B.tmp
 dump($request->file('upfile'));

vendor\symfony\http-foundation\Request.phpにまつわるもの
$request->file('file')->store($path);
$request->file('file')->storePublicly($path);
$request->file('file')->storePubliclyAs($path);
$request->file('file')->storeAs($path,$filename);
 $pathにtestならstorage/app/testに保存される

vendor\laravel\framework\src\Illuminate\Http\Request.phpにまつわるもの
$request->file('file')->move($destinationPath);
echo $request->file('upfile')->getPathname() . '<br>'; //C:\xampp\tmp\php76B8.tmp
echo $request->file('upfile')->getClientOriginalName() . '<br>'; //kanoe.jpg
echo $request->file('upfile')->getClientMimeType() . '<br>'; //image/jpeg
echo $request->file('upfile')->guessClientExtension() . '<br>'; //jpeg
echo $request->file('upfile')->getClientSize() . '<br>'; //20367
echo $request->file('upfile')->getError() . '<br>'; //0
echo $request->file('upfile')->isValid() . '<br>'; //1
echo $request->file('upfile')->getMaxFilesize() . '<br>'; //41943040
echo $request->file('upfile')->getErrorMessage() . '<br>'; //The file "kanoe.jpg" was not uploaded due to an unknown error.

こういうのもあるが、、、
echo $request->file('upfile')->getRealPath() . '<br>'; //C:\xampp\tmp\php9EA6.tmp
echo $request->hasFile('upfile') . '<br>'; //1
echo $request->file('upfile')->path() . '<br>'; //C:\xampp\tmp\php9EA6.tmp
echo $request->file('upfile')->extension() . '<br>'; //jpeg
ビューでは
 <form action="{{ url('upload') }}" method="POST" enctype="multipart/form-data">
     {{ csrf_field() }}
     <input type="file" name="upfile">
     <input type="submit">
 </form>
 @if ($errors->any())
 <ul>
     @foreach($errors->all() as $error)
     <li>{{ $error }}</li>
     @endforeach
 </ul>
 @endif
 @isset ($filename)
 <div>
 <img src="{{ asset('storage/' . $filename) }}">
 </div>
 @endisset
コントローラでは
 public function upload(Request $request){
  $this->validate($request, [
      'file' => [
          'required',
          'file',
          'image',
          'mimes:jpeg,png',
      ]//1行だと上手くいかんかった
  ]);
  if ($request->file('file')->isValid([])) {
      $path = $request->file('file')->store('public');//適当な名前でstorage/app/publicに保存
      return view('home')->with('filename', basename($path));
  } else {
      return redirect()
          ->back()
          ->withInput()
          ->withErrors();
  }
 }
 名前をつけたいのであれば
 $new_filename = 'up_' . $request->file('file')->getClientOriginalName();
 $request->file('file')->storeAs('public', $new_filename);
  storage/app/publicに保存されるからアクセスするにはpublic/storageからシンボリックリンクを張る
  cmdのphp artisan storage:link
ストレージ
 https://reffect.co.jp/laravel/laravel-storage-manipulation-master
 config/filesystems.php に設定があり
 'public' => [
     'driver' => 'local',
     'root' => storage_path('app/public'),
     'url' => env('APP_URL').'/storage',
     'visibility' => 'public',
 ],
 storage/app/publicがpublic diskになっておりファイルが保存されるが
 アクセスするにはpublic/storageからシンボリックリンクを張る必要がある
 ララベルでは/publicに通常アクセスさせるから
 php artisan storage:link
URLメソッド
 https://blog.capilano-fw.com/?p=2537
 echo url('/'); //url()の引数に空白もしくは/を指定するとトップページを取得
定数 const
 https://qiita.com/clustfe/items/4fa169c6d5114a9b6f4e
 https://hiroto-k.hatenablog.com/entry/2018/03/28/213000
 config/*.phpにenv()の値を入れてconfig()から参照
  config/const.phpを作り下記を入れCache更新で読まれる
 <?php
 return [
     'validate_limits' => [
         'MAX_UPLOAD_SIZE' => 4032,
     ],

 ];
 呼び出しconfig('const.validate_limits.MAX_UPLOAD_SIZE')

■依存性の注入という概念を核とするフレームワーク
依存性の注入,Dependency Injection(DI),Inversion of Control(制御の反転)とも言われ(IoC)
DI コンテナでクラスの生成を1箇所に集約、保守性、柔軟性、テスト性が上がる
composerでカレントディレクトリにPimpleをインストール
 composer require pimple/pimple:~3.0
Illiminate\Foundation\Application クラスが DI コンテナにあたります
<?php
require "vendor/autoload.php";
interface SenderInterface {
    public function send($message);
}
 
class MailSender implements SenderInterface {
    public function send($message) {
        return "メールで送りました。";
    }
}
class GMailSender implements SenderInterface {
    public function send($message) {
        return "GMailで送りました。";
    }
}
class Messenger {
    protected $sender;
    public function __construct(SenderInterface $sender) {
        $this->sender = $sender;
    }
    public function send($message) {
        return $this->sender->send($message);
    }
}
//Config(DIコンテナにバインドすると言う)
$container = new Pimple\Container();
$container['mail'] = function($container) {
    // return new MailSender();
    return new GMailSender();
};
// メールで送る
$messenger = new Messenger($container['mail']);
echo $messenger->send("合格通知") . "\n";
?>

■ジョブキュー(Job Busというのもあるらしい)
時間の掛かる処理を非同期で実行、下記の6種類くらい
sync: デフォルト設定で、実際には同期処理として動きます
database: データベースをジョブキューとして使います
beanstalkd: beanstalkd オープンソースのジョブキューです
sqs: Amazon Simple Queue Service 有料サービスです
データベースの場合
.env、config/queue.phpを編集
ジョブテーブルが必要
php artisan queue:table
php artisan queue:failed-table
php artisan migrate
ジョブの作成
php artisan make:job SendReminderEmail --queued
app/Jobs/SendReminderEmail.php にできるので処理
コンストラクタでこのコマンドに必要なデータを受け取る
handle() メソッドでこのコマンドがやることを実装
routes.phpでQueue::push()やコントローラを作成しdispatch()を使う
データベースの jobs テーブルを確認
select * from jobs;
キューの中のジョブを実行するには、キューリスナーを動かす必要がある
php artisan queue:listen
キューの最初のジョブだけ実行したい場合(リスナーならずっと動くから)
php artisan queue:work

■タスクスケジューラ(Cronの代わり)
app/Console/Commands/Kernel.phpに記載
$schedule->command('auth:clear-reminders')->daily();
$schedule->call('YourClass@someMethod')->hourly();
$schedule->exec('cp oldThing newThing')->weekly()->mondays()->at('13:00');
毎分のcronエントリー1つだけ必要
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1

■イベントとリスナー
app/Providers/EventServiceProvider.phpに登録
class EventServiceProvider extends ServiceProvider {
    protected $listen = [
        'App\Events\UserWasRegistered' => [ //イベント
            'App\Listeners\SendWelcomeMail', //リスナー
        ],
    ];
}
イベントとリスナーの生成
php artisan event:generate
 event:generateは、a

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


Navi: <  1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19  >
PhotoGallery


TWITTER
Search

Mobile
QR for cellphone  QR for smart phone
For mobile click here
For smart phone click here
Popular Page
#1Web
#2Hiace 200
#3Gadget
#4The beginning of CSSレイアウト
#5Column
#6Web font test
#7Ora Ora Ora Ora Ora
#8Wifi cam
#9みたらし団子
#10Arcade Controller
#11G Suite
#12PC SPEC 2012.8
#13Javascript
#14REMIX DTM DAW - Acid
#15RSS Radio
#16Optimost
#17通話SIM
#18Attachment
#19Summer time blues
#20Enigma
#21Git
#22Warning!! Page Expired.
#23Speaker
#24Darwinian Theory Of Evolution
#25AV首相
#26htaccess mod_rewite
#27/// BANGBOO BLOG /// From 2016-01-01 To 2016-01-31
#28竹書房
#29F☆ck CSS
#30Automobile Inspection
#31No ID
#32Win7 / Win10 Insco
#33Speaker
#34Arcade Controller
#35Agile
#36G Suite
#37Personal Information Privacy Act
#38Europe
#39Warning!! Page Expired.
#40GoogleMap Moblile
#41CSS Selectors
#42MySQL DB Database
#43Ant
#44☆od damnit
#45Teeth Teeth
#46Itinerary with a eurail pass
#47PHP Developer
#48Affiliate
#49/// BANGBOO BLOG /// From 2019-01-01 To 2019-01-31
#50/// BANGBOO BLOG /// From 2019-09-01 To 2019-09-30
#51/// BANGBOO BLOG /// On 2020-03-01
#52/// BANGBOO BLOG /// On 2020-04-01
#53Windows env tips
#54恐慌からの脱出方法
#55MARUTAI
#56A Rainbow Between Clouds‏
#57ER
#58PDF in cellphone with microSD
#59DJ
#60ICOCA
#61Departures
#62Update your home page
#63CSS Grid
#64恐慌からの脱出方法
#65ハチロクカフェ
#66/// BANGBOO BLOG /// On 2016-03-31
#67/// BANGBOO BLOG /// From 2017-02-01 To 2017-02-28
#68/// BANGBOO BLOG /// From 2019-07-01 To 2019-07-31
#69/// BANGBOO BLOG /// From 2019-10-01 To 2019-10-31
#70/// BANGBOO BLOG /// On 2020-01-21
#71Bike
#72Where Hiphop lives!!
#73The team that always wins
#74Tora Tora Tora
#75Blog Ping
#76無料ストレージ
#77jQuery - write less, do more.
#78Adobe Premire6.0 (Guru R.I.P.)
#79PC SPEC 2007.7
#80Google Sitemap
#81Information privacy & antispam law
#82Wifi security camera with solar panel & small battery
#83Hope get back to normal
#84Vice versa
#85ハイエースのメンテ
#86Camoufla
#87α7Ⅱ
#88Jack up Hiace
#89Fucking tire
#90Big D
#914 Pole Plug
#925-year-old shit
#93Emancipation Proclamation
#94Windows env tips
#95Meritocracy
#96Focus zone
#97Raspberry Pi
#98Mind Control
#99Interview
#100Branding Excellent
Category
Recent Entry
Trackback
Comment
Archive
<     July 2024     >
Sun Mon Tue Wed Thi Fri Sat
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Link