2015年12月9日水曜日

JavaScriptまとめ4:即時関数

function hoge() {
  alert(1);
}

hoge(); // 1

// 上記の関数定義と関数呼び出しをまとめて書くと↓

(function hoge() {
  alert(1);
})();


○即時関数メリット
1. グローバル変数に関数の割り当てがなされない
2. 即時"関数"だから関数内部の変数はローカルに限定される
 
○即時関数の別の記述方法
 
(function hoge() {
  alert('即時関数どす');
})();
これが一般的に即時関数と称されるコードです。
ですが、関数を式として評価させる方法はカッコでくくる以外にも方法があり、
+function() {
  alert('これでも即時関数');
}();

・その他記述方法 
 即時関数(function(){ ... })()の別の書き方いろいろ



○参考
 知ってて当然?初級者のためのJavaScriptで使う即時関数(function(){...})()の全て - 三等兵

2015年11月7日土曜日

JavaScriptまとめ3()

ただし、これは ECMAScript3 の仕様での話です。ECMAScript5 の仕様からグローバル変数 undefined についての記述を引用します。
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262%205th%20edition%20December%202009.pdf
15.1.1 Value Properties of the Global Object
15.1.1.3 undefined
The value of undefined is undefined (see 8.1). This property has the attributes { Writable: false, Enumerable: false, Configurable: false }.
ECMAScript5 の仕様では undefined プロパティの Writable が flase となっていますので、値を変更することができなくなりました。






undefined はただのグローバル変数


こんなことだって可能
alert(undefined); // "undefined"
var undefined = "こんにちは";
alert(undefined) // "こんにちは"



自分の意思でundefinedを自由に書き換えることができる
つまり、undefinedは常にundefinedである保証はどこにもないから、undefinedを使うのを避けるべきとうことです。
対して、void演算子を使えば、常に本当のundefinedを返すので、安全です。


function test () {
    var undefined = true; //undefinedを上書き

    if(undefined){
        console.log( 'undefined: ' + undefined );
    }

    if(void 0 ){
        console.log( '決して実行されない' );
    }
}

test();


voidを使わずにundefinedを獲得する方法

(function(a,b,undefined){
    console.log(undefined)
})(1,2);

これはjQueryのソースでも使われている手法
無名関数をその場で実行し、実引数には1,2しか渡していないのに、仮引数のほうではa,b以外に、
もう一つundefinedという最初から渡されないと仮定した仮引数をセットすることで、安全にundefinedを獲得


○参考
 `undefined`の代わりに、`void 0`を使ったほうがいい
http://liginc.co.jp/web/js/38494

2015年8月3日月曜日

システム殴り書き備忘録1

CSS
http://www.slideshare.net/hiloki/a-good-css-and-sass-architecture?related=1

jQUeryアンチパターン
http://www.slideshare.net/paul.irish/perfcompression

実例で学ぶ、JOIN (NLJ) が遅くなる理屈と対処法
http://qiita.com/yuku_t/items/208be188eef17699c7a5?utm_content=buffer77626&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer

忘れがちなJavaScriptの基礎中の基礎
http://qiita.com/Yama-to/items/5e0827dfd2bd440537d0?utm_content=buffer8fe4a&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer

2015年6月18日木曜日

PHPまとめ1:エルビス演算子

/*━━━━━━━━━━━━━━■PHP■━━━━━━━━━━━━━━*/
○エルビス演算子
$c = $a ?: $b;

○三項演算子の場合
$c = $a ? $a : $b;


/*━━━━━━━━━━━━━━■JavaScript■━━━━━━━━━━━━━━*/
c = a || b;

・補足
JavaScriptでは、論理演算子&& ||の比較対象としてBoolean以外の値を指定した場合、その値をBooleanに変換せず返します。
よってJavaScriptでは論理演算子||をエルビス演算子の代わりとして用いることが出来ます。

論理演算子&& ||がBoolean以外の値を返すのはJavaScriptに限った話ではありません。
他のプログラミング言語でもこのような実装になっている言語が存在します。
よってこの記事で紹介したテクニック(と呼べるほどの事かは疑問ですが)はJavaScript以外の言語でも利用できます。


/*━━━━━━━━━━━━━━■PHP7で2項演算子「??」が新設■━━━━━━━━━━━━━━*/

オペランドがnull以外の値であればその値を、そうでなければ右オペランドを返す
var_dump(null ?? false ?? true); // false

これはPHP 5.3で導入されたエルビス演算子「?:」と少し似ています。
エルビス演算子は真偽の判断
??演算子はnullかどうかの判断を行う点が異なる

var_dump(null ?: false ?: true); // true

それだけでなく、??演算子はisset()と同様に未定義値をチェックしてもエラーになりません。
これは非常に大きな違いで、??演算子があれば今までのisset()地獄から解放されるかもしれません。

var_dump($arr["foo"] ?: "bar"); // 未定義だとUndefined variableかUndefined indexで怒られちゃう
var_dump(isset($arr["foo"]) ? $arr["foo"] : "bar"); // 結局こう書いてたよね…
var_dump($arr["foo"] ?? "bar"); // PHP7ではこれで動く!

PHP7調査(11)??演算子の新設
JavaScriptではエルビス演算子を論理演算子で代用できる
エルビス演算子でスマートに変数を初期化

2015年5月11日月曜日

jQueryまとめ3:deffered

$.when(
    ajax1(),
    ajax2(),
    ajax3()
)
.done(function() {
    afterAjax();
});


function ajax1()
{
    var dfd = $.Deferred();
    $.ajax({
        type     : '',
        url      : '/',
        dataType : 'html'
    })
    .done(function(re){
        dfd.resolve();
    })
    .fail(function(){
        dfd.reject();
    });
    return dfd.promise();
}

結局jQuery.Deferredの何が嬉しいのか分からない、という人向けの小話 

  爆速でわかるjQuery.Deferred超入門

なぜ、今、jQuery deferred?
 
$.Deferred で楽しい非同期ライフを送る

2015年5月8日金曜日

2015年4月21日火曜日

jQueryまとめ1:ポップアップ以外をクリックしたら、ポップアップを閉じる

○コード
$(document).click(function(event) { // (1)
    if (!$.contains($("#popup")[0], event.target)) { // (2)
        $("#popup").hide();
    }
});


○解説
ポイントは、$.contains( container, contained )
このメソッドは、DOM要素containerがDOM要素containedを 内包していたらtrueを返します。
ちなみに、containerとcontainedはjQueryオブジェクトではなくて、
DOM要素なので気をつけて!


では、コードの解説。
上述のコード(1)では、すべてのクリックイベントを捕捉しないといけないので、 document要素に対してハンドラをバインドします。

コード(2)では、$.contains()の第1引数にポップアップ要素であるDOM要素を指定してます。 $("#popup")はjQueryオブジェクトなので、$("#popup")[0]とすることでDOM要素を取得してます。
そして第2引数には、イベントオブジェクトeventのプロパティで、イベント発生源のDOM要素が格納されている event.targetを指定します。
さらに$.contains()の前に"否定"を意味するビックリマーク!をつけます。
ということでここでは、ポップアップ要素の中にクリックイベント発生源の要素が存在しなかったら、 つまりポップアップの外側でクリックされたらtrueを返すということになり、
このときポップアップを非表示にするという処理が実行されます。
参考
http://s3pw.com/milestoner/2013/06/jquery-tips-for-closing-popup/

2015年3月31日火曜日

良くある備忘録2:日付計算

【PHP】指定時間前や指定時間後の日時を求めるの「注意」にあるように、日時によっては正確な月を取得できない場合があります。
※指定日時は「2014-03-31」
$startDate = date("Y-m-01", strtotime("-1 month"));
→2014-03-01
$endDate =  date("Y-m-t", strtotime("-1 month"));
→2014-03-31

「2014-03-31」の1ヶ月前は「2014-02-31」
そんなもんねーよ、ってことで「2014-03-01」として扱われる

月末ではなく初日を基準にして計算すること


$targetDay = date("Y-m-01", time());
$startDate = date("Y-m-01", strtotime($targetDay . "-1 month"));
$endDate =  date("Y-m-t", strtotime($targetDay . "-1 month"));

参考
http://ysklog.net/php/2095.html

2015年3月16日月曜日

DBまとめ2:ACID特性

トランザクションは,次の4つの特性をすべて保証しなければなりません。

原子性(Atomicity)
トランザクションは,すべてが完全に実行されるか,全く実行されないかどちらかです。つまり,トランザクションを構成する「一連の処理」は,これ以上分割できない最小単位です。

一貫性(Consistency)
トランザクションの開始時と終了時で,データが整合性を保っていなければなりません。データは以前の「有効な状態」から新しい「有効な状態」に変化します。

隔離性(Isolation)
複数のトランザクションを同時に並行して実行しても,終了するまでトランザクション同士はお互いに干渉しません(あるトランザクションからほかのトランザクションは見えません。あるいは,ほかのトランザクションの影響を受けません)。

持続性(Durability)
トランザクションが正常に終了した結果は必ず「永続化」され,障害によって失われることはありません。
 これらの「トランザクション特性」のことを,頭文字を取って「ACID」(アシッド)と呼び,ACIDを満たすトランザクションを「ACIDトラ ンザクション」と言います。逆に言うと,この特性に当てはまる業務処理をシステムで実装する場合に,トランザクションの機能を利用するメリットを享受でき るのです。この4つをすべてクリアした場合,「トランザクション特性」を満たすと言います。


http://itpro.nikkeibp.co.jp/article/lecture/20070528/272630/

DBまとめ1:分散Key-Valueストア

クラウド時代のデータベース「分散Key-Valueストア」

グーグルがインターネットの世界をここまで席けんできた最大の理由
検索技術ではなく、同社が生み出した巨大な分散データストア、「Bigtable」にあります。

Bigtableは、Google検索をはじめ、YouTubeやGoogle Map、Google Earth、Google Analytics、Google App Engineなど、グーグルの70以上のプロジェクトの基盤として利用されています。合計で数PB(ペタバイト)に達する天文学的規模のデータを、全世界 36カ所以上のデータセンターに配置された数万〜数十万台のサーバに分散して格納し、これらグーグルの各種サービスの圧倒的なスケーラビリティと高可用性 を低コストで実現しています。

Bigtableは、リレーショナルデータベース(以下、RDB)ではなく、いわゆる「分散Key-Value Store(以下、KVS)」の1つです。KVSは、プログラミング言語の連想配列Mapと同様に「Key(キー)」と「Value()」のペアからなる、ごくシンプルなデータモデルに基づくデータストアです。KVSは「キー・バリュー型データストア」「Key/Valueストア」などと呼ばれることもあります。

分散KVSが苦手なトランザクションの「ACID特性」

RDBのように、テーブルとテーブルを結合(SQLでいうJOIN文)して複雑な条件検索や集計処理を一発でこなすような芸当はできません。また、トランザクションによる「ACID特性」の確保も分散KVSが苦手な分野です。


RDBが不得意な分散/拡張

そのため、これらの不足をアプリケーション側で補うためのさまざまな工夫やフォローが必要となります。その一方で、分散KVSはデータストア全体をいくらでも多くのサーバに分散(スケールアウト)できるのが最大の特徴です。
 一方でこれは、RDBが最も不得意とするところです。RDBでは、その長所であるテーブル結合やACIDの確保がボトルネックとなり、複数のサー バにスケールアウトさせることが「原理的」に容易ではありません。そのため、負荷分散や高可用性を低コストで実現することが困難です。


RDBで負荷分散させようとすると……

例えばMySQLを使う場合、1テーブルのレコード件数が数百万〜数千万件を超えるような規模になると、1台のDBサーバだけでは実用的なパ フォーマンスが達成しにくくなります。そこで一般には、以下のような対策によってRDBのスケーラビリティを引き上げる努力が必要となります。
  • RDBサーバのスケールアップ(大型サーバへの載せ替え)
  • DBのレプリケーションシャード(パーティション)分割によるクラスタ構築
  • 分散キャッシュOracle RACmemcachedなど)によるクラスタ構築
経験者ならばお分かりいただけるとおり、このどれもが結果的に「高コスト」となるソリューションです。



利点その【1】負荷分散や可用性に悩まないでいい!負荷分散や可用性に悩まないでいい!
 まず、実用上は制限のないスケーラビリティのおかげで、「負荷分散や可用性のことで悩んだりコストを掛けたりする必要があまりなくなる」ということです。
利点その【2】データを効率よく集約できる!データを効率よく集約できる!
 そしてもう1つの、かつ最も重要な利点は、「アプリケーションの分散化対応によって、クラウドによる全体最適のメリットを享受できる」ことです。

例えるなら、「一戸建て」と「タコ部屋」である

これは例えるなら、独立した仮想マシンやOS、DBインスタンスを占有していた「一戸建て」の環境を捨て、100人くらいで1つの部屋を共有する「タコ部屋」に入居するようなものです。このタコ部屋では、分散KVSという使いにくい収納しかありません。


http://www.atmarkit.co.jp/ait/articles/0907/02/news101.html

2015年2月21日土曜日

良くある備忘録1:リダイレクト・フォワード

○基本
【モジュール名】/【コントローラ名】/【アクション名】.phtml
別のアクションのテンプレートを読み込む

【モジュール名】/【コントローラ名】/【別アクション名】.phtml
$this->render('【別アクション名】');




○リダイレクト
/hoge/foo にリダイレクトする。
$this->_redirect('/hoge/foo');

http://www.example.com/hoge/foo/bar にリダイレクトする。
$this->_redirect('http://www.example.com/hoge/foo/bar');

http://www.example.com/hoge/foo/bar?a=1&b=2 にリダイレクトする。
$this->_redirect('http://www.example.com/hoge/foo/bar?a=1&b=2');

/【コントローラ名】/【アクション名】 にリダイレクトする。
$this->_helper->redirector('【アクション名】', '【コントローラ名】');



○フォワード
別のアクションにフォワードする
$this->_forward('【別アクション名】');
【モジュール名】/【コントローラ名】/【別アクション名】

別のコントローラにフォワードする
$this->_forward('【別アクション名】', '【別コントローラ名】');
【モジュール名】/【別コントローラ名】/【別アクション名】

別のモジュールにフォワードする
$this->_forward('【別アクション名】', '【別コントローラ名】', '【別モジュール名');
【別モジュール名】/【別コントローラ名】/【別アクション名】

パラメータを指定してフォワードする
$params = array(
    'a' = '1',
    'b' = '2'
);
$this->_forward('【別アクション名】', '【別コントローラ名】', '【別モジュール名】', $params);
【別モジュール名】/【別コントローラ名】/【別アクション名】/a/1/b/2

参考:http://pentan.info/php/zend_fw/redirector.html



○リダイレクトとフォワードの違い
リダイレクトの場合、クラアイアントがページXを要求すると、サーバがページYを要求する指示をクライアントに戻します。これによって“クライアントは自動的に”ページYを要求し、結果としてページYがクライアントに戻されます(ページXとページYは、必ずしも同一サーバからのレスポンスではない)。これに対しフォワードは、クライアントがページXを要求すると、“サーバ内で”ページXからYへ処理が移送され、ページYが応答として戻されます(ページXとページYは、必ず同一サーバからのレスポンス)。

 以上の説明を図示すると以下のようになります。
リダイレクトは、サーバからクライアントに異なるページYにアクセスする要求を返すことでページYへの遷移を実現する。これに対し、フォワードはサーバ内でページYに処理を転送し、ページYを結果としてクライアントへ返すことでページ遷移を実現する

 この結果、「リダイレクト」と「フォワード」には、以下のような違いが発生します。

    リダイレクトよりもフォワードの方がパフォーマンスが良い
    リダイレクトがクライアントとサーバ間を2往復(ラウンドトリップ)する非効率な処理であるのに対して、フォワードは通常のリクエスト同様に1回のリクエスト/レスポンスで処理が完結します。これは、単純に2倍のトラフィックが発生するというだけのことではありません。リダイレクトによって発生した2回目のリクエストは、待ち行列の末尾に配置されるため、特にトラフィックの多いサーバにおいては、要求待ちによる遅延が発生する可能性があります。一方、フォワードは、1つのリクエスト処理内の連続したロジックとして処理されるため、こうした遅延の心配はありません。

    フォワードはサーバ内部の転送にのみ使用できる
    遅延が起こらないからといって、ページの自動的な転移を常にフォワードで行えば良いというわけではありません。フォワードは、「サーバ内」で処理を転送するというその性質上、同一サーバ内ページ(クラス)間でしか利用することができません。外部のサーバ上のページに対して移動したいという場合には、リダイレクトを使用する必要があります。

    リクエスト情報を引き継げるのはフォワードのみ
    リダイレクトでは、ページA、Bへの要求はまったく独立した「2つの」リクエストとして扱われるため、リクエストパラメータやリクエスト属性などの情報を両者で共有することはできません。しかし、フォワードでは、ページA、Bの処理は「1つの」リクエスト処理として扱われるため、リクエストパラメータやリクエスト属性はすべて引き継がれます。




参考:http://www.atmarkit.co.jp/fjava/javatips/062jspservlet029.html

2015年1月14日水曜日

サーバーまとめ1:リバースプロキシ(reverse proxy)

リバースプロキシ(reverse proxy)とは
恥ずかしがり屋なWebサーバさん用代理交渉人のこと。


○ホームページが表示されるまでの流れ

1.Webブラウザ→「このページおくれ」→Webサーバ
2.Webブラウザ←「ほれ、そのページだよ」←Webサーバ
Webサーバさんの身代わりになってホームページを返してくれるサーバさんのこと。


○プロキシサーバが入ったホームページ表示までの流れ

1.Webブラウザ→「俺の代わりにこのページ貰ってきておくれ」→プロキシサーバ
2.プロキシサーバ→「このページおくれ」→Webサーバ
3.プロキシサーバ←「ほれ、そのページだよ」←Webサーバ
4.Webブラウザ←「ほれ、貰ってきたページだよ」←プロキシサーバ


○リバースプロキシサーバが入ったホームページ表示までの流れ

1.Webブラウザ→「このページおくれ」→リバースプロキシサーバ
2.リバースプロキシサーバ→「このページくれってきたよ」→Webサーバ
3.リバースプロキシサーバ←「じゃあこのページ返してあげて」←Webサーバ
4.Webブラウザ←「ほれ、そのページだよ」←リバースプロキシサーバ

普通のプロキシさんの場合は「Webブラウザ+プロキシサーバ」で一つのクライアント
リバースプロキシさんの場合は「リバースプロキシサーバ+Webサーバ」で一つのサーバになるイメージです。


○メリット
(1).身元を隠せる
(2).負荷分散ができる

(1)のメリットは普通のプロキシと同じです。
矢面に立つのはリバースプロキシサーバなのでWebサーバの正体はバレません。
(2)はちょっとややこしいのですが、1つのリバースプロキシに複数のWebサーバを割り当てることができる


参考:http://wa3.i-3-i.info/word1755.html
http://itdoc.hitachi.co.jp/manuals/3020/30203M0461/EM040070.HTM
http://www.atmarkit.co.jp/ait/articles/1406/17/news013.html


○関連項目
nginx
1日に数億リクエストを処理するような大規模サイトを中心に、近年急速にシェアを拡大しているWebサーバーが「Nginx(エンジンエックス)」です。
HTMLドキュメントや画像ファイルといった静的コンテンツを高速で配信し、消費メモリが少なく、リバースProxyやロードバランサーといった機能も有した注目の軽量Webサーバーです。ネットクラフト社の調査によると、2014年6月時点でApache HTTP、Microsoft IISに次ぐ第3位のシェアを獲得しています。