MW211 EXIT

devlog
JavaScript/特定の文字以降を抜き出す
2014年04月30日
┌──────────────────────────────────────┐
│GETパラメータ部分のみ = (URLアドレス.match(/\?.*$/) || [''])[0];            │
└──────────────────────────────────────┘
URLアドレスからGETパラメータ部分のみをJavaScriptで抜き出す方法。
つまり「?」を境にその後ろを抜き出すってこと。
ついでに、「?」がなければ空文字という仕様も追加。

結構厄介だ(っていうかもっと簡単な方法がありそうだが)

match()メソッドで正規表現を使って抜き出す訳だが…。

問題1:結果が配列で返ってくる
  ということで、「[0]」を後ろにつけて配列の一番目の値だけ取得するようにする。

問題2:該当がない場合にはnullになる
  「null」は「''」とは違うという根本的な問題もあるが、
  「null」を配列とみなして「[0]」なんかをつけると例外が起きてしまうのが致命的。
  ってことで、「null」の場合は「''」に変換してあげなければならないが
  その後に配列として扱うことが見えているので「['']」と
  (一番目が空文字の)配列に変換してあげる深謀遠慮が必要。
  「null」判定は「||」によるOR条件付加で一発でできる。
分類:JavaScript
PHP/file_get_contents()とセキュリティ
2014年04月28日
「file_get_contents()」を使って、別サーバの情報を入手するには、
「php.ini」の設定で「allow_url_fopen=on」としなければならない。

これはファイルマニピュレーション機能を可能にするということで、
システム上のファイルの更新を許すということになる。

つまり、セキュリティ的によろしくない。

よって、「allow_url_fopen=off」設定とすることが望まれる。

そうなると別サーバのURLを指定して「file_get_contents()」で
そこの内容を取得するってことができなくなる。

でも、結構これは便利で使いたい。
ということで、代案。
curlってのを使って、以下のような感じにすればよい。
┌──────────────────────────────────────┐
│function fileGetContents代替($url) {                                        │
│    $session = curl_init($url);                                             │
│    curl_setopt($session, CURLOPT_HEADER        , FALSE);  // ヘッダ不要    │
│    curl_setopt($session, CURLOPT_RETURNTRANSFER, TRUE );  // 文字列で返却  │
│    $return = curl_exec($session);                                          │
│    curl_close($session);                                                   │
│    return $return;                                                         │
│}                                                                           │
└──────────────────────────────────────┘

「file_get_contents()」で「allow_url_fopen」の設定の影響を受けるのは
あくまで別サーバをリモートで参照する場合のみ。
自サーバ(のファイル)を参照する分には影響を受けないので
「allow_url_fopen=off」設定で上記代案を併用している場合でも
自サーバに対しては「file_get_contents()」が使用できる。
分類:PHP
JavaScript/配列操作いろいろ
2014年04月24日
配列中から特定の値を除外する。
┌──────────────────────────────────────┐
│配列 = 配列.filter(function(v) {                                            │
│    return v != 値;                                                         │
│});                                                                         │
└──────────────────────────────────────┘

配列中の重複した値を除外する。
┌──────────────────────────────────────┐
│配列 = 配列.filter(function (x, i, self) {                                  │
│    return self.indexOf(x) === i;                                           │
│});                                                                         │
└──────────────────────────────────────┘
分類:JavaScript
jQuery/$.postと論理型データ
2014年04月21日
jQueryの「$.post」で、bool値(論理型)を送信すると、文字型に変換されるようだ。

送信側でこのように送信して…。
┌──────────────────────────────────────┐
│$.post(受信先, {"test":true});                                              │
└──────────────────────────────────────┘

受信側で、ダンプ表示してみた場合。
┌──────────────────────────────────────┐
│var_dump($_POST);                                                           │
├──────────────────────────────────────┤
│array(1) {                                                                  │
│  ["test"]=>                                                                │
│  string(4) "true"                                                          │
│}                                                                           │
└──────────────────────────────────────┘
「true」は文字型で認識されている。

途中で変換をかけているのであろうか。

「jQuery1.10.1」でのお話(なので最新もそんなはず)。

URLエンコードが施されたURLクエリーの文字列に変換されるのが原因の模様。
分類:jQuery
設計/隠し情報とAjax
2014年04月20日
Ajaxでこっそり読み込み、非表示(display:none)にしておく。

このデータは、ソース上には見えてこない。

非表示なので、画面上にも見えてこない。

上手いこと隠蔽したと思ったけど、
FirefoxのFirebugであっさり見破られてしまうのであった。

だから、ボタンを押すまで結果がわからないで欲しい情報は
押した瞬間にAjaxで読み込むのがベストで
事前に読み込んで隠しておくということは見破られますよということです。
分類:設計
設計/md5によるパスワード隠蔽
2014年04月18日
md5で変換(PHPでは「md5()」)すると、不可逆変換なので、元の値が類推できない。
この特性を使って、パスワードをmd5変換後の値で管理し、
万が一それが流出してもパスワードを読み取られないようにする対策がある。
#照合は変換後の値で同一かを判定する
  変換前の値を知らないと変換後の値を生成できないという寸法

但し、そのまま変換してしまうと、変換表を使って逆算できてしまう。
#想定される頻出の文字列を実際に変換してみて以下のような変換表がつくれる。
  ┌────┬────────────────┐
  │ 変換前 │             変換後             │
  ├────┼────────────────┤
  │pass    │1a1dc91c907325c69271ddf0c944bc72│
  ├────┼────────────────┤
  │passwd  │76a2173be6393254e72ffa4d6df1030a│
  ├────┼────────────────┤
  │password│5f4dcc3b5aa765d61d8327deb882cf99│
  ├────┼────────────────┤
  │admin   │21232f297a57a5a743894a0e4a801fc3│
  ├────┼────────────────┤
  │abc     │900150983cd24fb0d6963f7d28e17f72│
  ├────┼────────────────┤
  │123     │202cb962ac59075b964b07152d234b70│
  └────┴────────────────┘
「1a1dc91c907325c69271ddf0c944bc72」を入手した場合は、元は「pass」と類推できる。
また、隣の人と同じ変換後の値であれば、元も同じだったと類推できる。

ということで、ユーザIDなどの一意な情報を組み合わせて(文字列結合)、
変換すればセキュリティが高まるだろう。

また、「ユーザID+パスワード」だけだと類推されてしまう可能性があるので
「ユーザID+パスワード+適当な文字列」とかにすれば、もっとよい。
分類:設計
HTML/明細の送信
2014年04月17日
┌──────────────────────────────────────┐
│<form method="post" action="">                                              │
│  <table>                                                                   │
│    <thead>                                                                 │
│      <tr>                                                                  │
│        <th>項目1</th>                                                      │
│        <th>項目2</th>                                                      │
│      </tr>                                                                 │
│    </thead>                                                                │
│    <tbody>                                                                 │
│      <tr>                                                                  │
│        <td><input type="text" name="col1[]" value="1-a"/></td>             │
│        <td><input type="text" name="col2[]" value="2-a"/></td>             │
│      </tr>                                                                 │
│      <tr>                                                                  │
│        <td><input type="text" name="col1[]" value="1-b"/></td>             │
│        <td><input type="text" name="col2[]" value="2-b"/></td>             │
│      </tr>                                                                 │
│    </tbody>                                                                │
│  </table>                                                                  │
│  <input type="submit" value="送信"/>                                       │
│</form>                                                                     │
└──────────────────────────────────────┘
明細をPOSTする場合、name属性を個別に配列にすると、項目ごとの配列となってしまう。
┌──────────────────────────────────────┐
│$_POST['col1'] = array(                                                     │
│    0 => '1-a',                                                             │
│    1 => '1-b',                                                             │
│);                                                                          │
│$_POST['col2'] = array(                                                     │
│    0 => '2-a',                                                             │
│    1 => '2-b',                                                             │
│);                                                                          │
└──────────────────────────────────────┘

データベースからデータを取得したような多次元連想配列にしたい場合には?
┌──────────────────────────────────────┐
│$_POST['data'] = array(                                                     │
│    0 => array(                                                             │
│        'col1' => '1-a',                                                    │
│        'col2' => '2-a',                                                    │
│    ),                                                                      │
│    1 => array(                                                             │
│        'col1' => '1-b',                                                    │
│        'col2' => '2-b',                                                    │
│    ),                                                                      │
│);                                                                          │
└──────────────────────────────────────┘

まず、name属性をつけて直接POSTするのではなく、class属性で束ねて
それらを編集してPOSTする方式に切り替える。
よって、submitボタンではなく、buttonボタンを使用する。
┌──────────────────────────────────────┐
│<form method="post" action="">                                              │
│  <table>                                                                   │
│    <thead>                                                                 │
│      <tr>                                                                  │
│        <th>項目1</th>                                                      │
│        <th>項目2</th>                                                      │
│      </tr>                                                                 │
│    </thead>                                                                │
│    <tbody>                                                                 │
│      <tr>                                                                  │
│        <td><input type="text" class="name-col1" value=""/></td>            │
│        <td><input type="text" class="name-col2" value=""/></td>            │
│      </tr>                                                                 │
│      <tr>                                                                  │
│        <td><input type="text" class="name-col1" value=""/></td>            │
│        <td><input type="text" class="name-col2" value=""/></td>            │
│      </tr>                                                                 │
│    </tbody>                                                                │
│  </table>                                                                  │
│  <input type="button" id="submit" value="送信"/>                           │
│</form>                                                                     │
└──────────────────────────────────────┘
さて、送信方法だが、二つの案がある。(以下jQueryを使用、PHPで受信を例とする)

【案1】hidden項目で送信する方法
┌──────────────────────────────────────┐
│$('#submit').click(function() {                                             │
│    var index = 0;                                                          │
│    $('tbody tr').each(function() {                                         │
│        $(this).closest('form')                                             │
│            .append($('<input>').prop('type', 'hidden')                     │
│                                .prop('name', 'data[' + index + '][col1]')  │
│                                .val($(this).find('.name-col1').val())      │
│            )                                                               │
│            .append($('<input>').prop('type', 'hidden')                     │
│                                .prop('name', 'data[' + index + '][col2]')  │
│                                .val($(this).find('.name-col2').val())      │
│            );                                                              │
│        index++;                                                            │
│    });                                                                     │
│    $('tbody').closest('form')                                              │
│        .submit();                                                          │
│});                                                                         │
├───┬──────────────────────────────────┤
│PHP側 │$配列 = $_POST['data'];                                             │
└───┴──────────────────────────────────┘
  hidden項目を生成して、そこに設定して送信する。
  よって、そのまま使える。

【案2】JSON文字列で送信する方法
┌──────────────────────────────────────┐
│$('#submit').click(function() {                                             │
│    var jsonArray = new Array();                                            │
│    $('tbody tr').each(function() {                                         │
│        jsonArray.push({                                                    │
│            "col1" :$(this).find('.name-col1').val(),                       │
│            "col2" :$(this).find('.name-col2').val()                        │
│        });                                                                 │
│    });                                                                     │
│    $('tbody').closest('form')                                              │
│        .append($('<input>').prop('type', 'hidden')                         │
│                            .prop('name', 'data')                           │
│                            .val(JSON.stringify(jsonArray))                 │
│        )                                                                   │
│        .submit();                                                          │
│});                                                                         │
├───┬──────────────────────────────────┤
│PHP側 │$配列 = json_decode($_POST['data'], TRUE);                          │
└───┴──────────────────────────────────┘
  一旦、連想配列(ハッシュオブジェクト)にしたものを
  「JSON.stringify()」でJSON文字列に変換して、送信する。
  PHP側では「json_decode()」でデコードする必要がある。
  一つの項目として送信するので(変換処理は必要だが)管理がしやすいという利点あり。
分類:JavaScript、HTML
JavaScript/配列とJSON文字列
2014年04月15日
以下のような多次元連想配列(ハッシュオブジェクト)があった場合、
JSON文字列に変換すると…。
┌──────────────────────────────────────┐
│var 配列 = new Array();                                                     │
│配列.push({                                                                 │
│    "列1"   :'値1-1',                                                       │
│    "列2"   :'値1-2'                                                        │
│});                                                                         │
│配列.push({                                                                 │
│    "列1"   :'値2-1',                                                       │
│    "列2"   :'値2-2'                                                        │
│});                                                                         │
│var ハッシュオブジェクト = {                                                │
│    "header"    :'ヘッダ',                                                  │
│    "data"      :配列                                                       │
│};                                                                          │
├──────────────────────────────────────┤
│var JSON文字列 = JSON.stringify(ハッシュオブジェクト);                      │
└──────────────────────────────────────┘

JSON文字列の結果は以下のような文字列になる(実際には改行・余白はない)。
┌──────────────────────────────────────┐
│{"header":"ヘッダ",                                                         │
│       "data":[{"列1":"値1-1","列2":"値1-2"},{"列1":"値2-1","列2":"値2-2"}]}│ 
├──────────────────────────────────────┤
│{                                                                           │
│    "header"    :"ヘッダ",                                                  │
│    "data"      :[                                                          │
│        {                                                                   │
│            "列1"   :"値1-1",                                               │
│            "列2"   :"値1-2"                                                │
│        },                                                                  │
│        {                                                                   │
│            "列1"   :"値2-1",                                               │
│            "列2"   :"値2-2"                                                │
│        }                                                                   │
│    ]                                                                       │
│}                                                                           │
└──────────────────────────────────────┘

ちなみにこのJSON文字列をPHP(json_decode())で配列に変換すると、
以下のようなデータとなる。
┌──────────────────────────────────────┐
│var_export(json_decode($JSON文字列, TRUE));                                 │
├──────────────────────────────────────┤
│array (                                                                     │
│  'header' => 'ヘッダ',                                                     │
│  'data' =>                                                                 │
│  array (                                                                   │
│    0 =>                                                                    │
│    array (                                                                 │
│      '列1' => '値1-1',                                                     │
│      '列2' => '値1-2',                                                     │
│    ),                                                                      │
│    1 =>                                                                    │
│    array (                                                                 │
│      '列1' => '値2-1',                                                     │
│      '列2' => '値2-2',                                                     │
│    ),                                                                      │
│  ),                                                                        │
└──────────────────────────────────────┘
分類:JavaScript
PHP配列/var_export()
2014年04月10日
PHPの配列は以下のような感じで定義する訳だが、
┌──────────────────────────────────────┐
│$配列 = array (                                                             │
│    キー => 値,                                                             │
│    内部配列 => array (                                                     │
│        0 => array (                                                        │
│            キー => 値,                                                     │
│        ),                                                                  │
│    ),                                                                      │
│);                                                                          │
└──────────────────────────────────────┘
定義後の「$配列」から、右辺を再現する方法がある。
「var_export($配列);」だ。

第二引数に、「TRUE」を付ければ、標準出力ではなく、左辺に代入もできる。
┌──────────────────────────────────────┐
│$文字列 = var_export($配列, TRUE);                                          │
└──────────────────────────────────────┘

で、これを配列に復元させるには…、コピペしてソースに貼り付ければいい。
ってな、冗談はさておき、といってもこれが結構実用的だったりする。

プログラム的に復元するには、「eval()」を使うことになる。
(ソースにコピペしたような挙動をしてくれる便利な関数だ)

一連の流れをまとめると以下のような形となる。
┌──────────────────────────────────────┐
│$文字列 = var_export($配列, TRUE);                                          │
│$配列 = var_import($文字列);                                                │
├──────────────────────────────────────┤
│function var_import($string) {                                              │
│    eval('$array=' . $string . ';');                                        │
│    return $array;                                                          │
│}                                                                           │
└──────────────────────────────────────┘
但し、「eval()」は万能過ぎるので、致命的なこと(例えばファイル削除)を
意図せずして行われる危険性を伴う(SQLインジェクションみたいな感じで)。

なので、あまり、使わない方がいいようだ。
ってことで、「var_export()」は手動コピペと共にってのが上手な付き合い方かも。
分類:PHP配列
PHP/マルチバイト文字数
2014年04月09日
マルチバイト文字の文字数等を取得する関数は以下の通り。

【UTF-8】マルチバイト文字はだいたい1文字あたり3バイト分を使用
┌────────────┬────────────┬────────────┐
│         文字数         │         文字幅         │        バイト数        │
├────────────┼────────────┼────────────┤
│mb_strlen('a')       →1│mb_strwidth('a')     →1│strlen('a')          →1│
├────────────┼────────────┼────────────┤
│mb_strlen('あ')      →1│mb_strwidth('あ')    →2│strlen('あ')         →3│
├────────────┼────────────┼────────────┤
│mb_strlen('aあ')     →2│mb_strwidth('aあ')   →3│strlen('aあ')        →4│
├────────────┼────────────┼────────────┤
│mb_strlen('①')      →1│mb_strwidth('①')  →1★│strlen('①')         →3│
└────────────┴────────────┴────────────┘

【SJIS-win(シフトJIS(CP932))】マルチバイト文字は1文字あたり2バイト分を使用
┌────────────┬────────────┬────────────┐
│         文字数         │         文字幅         │        バイト数        │
├────────────┼────────────┼────────────┤
│mb_strlen('a')       →1│mb_strwidth('a')     →1│strlen('a')          →1│
├────────────┼────────────┼────────────┤
│mb_strlen('あ')      →1│mb_strwidth('あ')    →2│strlen('あ')         →2│
├────────────┼────────────┼────────────┤
│mb_strlen('aあ')     →2│mb_strwidth('aあ')   →3│strlen('aあ')        →3│
├────────────┼────────────┼────────────┤
│mb_strlen('①')      →1│mb_strwidth('①')  →1★│strlen('①')         →2│
└────────────┴────────────┴────────────┘

問題は「mb_strwidth()」における記号(「①」など)の扱い(★)。
半角(1バイト幅)扱いで算出されてしまうのだ。

これは仕様で文字コードの帯域によって、以下のように定義されているからだ。
┌───────┬─────┐
│U+0000~U+0019│ 0バイト幅│
├───────┼─────┤
│U+0020~U+1FFF│ 1バイト幅│
├───────┼─────┤
│U+2000~U+FF60│ 2バイト幅│
├───────┼─────┤
│U+FF61~U+FF9F│ 1バイト幅│
├───────┼─────┤
│U+FFA0~      │ 2バイト幅│
└───────┴─────┘

ということで、全角文字なのに、半角扱いされてしまう文字を当てはめてみると…。
┌───────┬─────┐
│U+0000~U+0019│ 0バイト幅│
├───────┼─────┤
│U+0020~U+1FFF│ 1バイト幅│ω(U+03C9)
├───────┼─────┤
│U+2000~U+FF60│ 2バイト幅│※(U+203B)、①(U+2460)、★(U+2605)、℃(U+2103)
├───────┼─────┤
│U+FF61~U+FF9F│ 1バイト幅│
├───────┼─────┤
│U+FFA0~      │ 2バイト幅│
└───────┴─────┘
ん?辻褄が合わない?

さて、こんな挙動が不審な「mb_strwidth()」対策は?
思い切って使うのを止めてしまう(安定するまで)。

シフトJISならバイト数=文字幅なので、これを利用して、
シフトJISに変換してバイト数を求めるのが無難なやり方みたい。
で、変換できない(「?」になる)UTF-8特有文字とかの対策は?ってことになるが
ま、そいつらは黙殺するしかないか。
分類:PHP
前へ 1 2 次へ