MW211 EXIT

devlog
PHP/(UTF-8→Shift_JIS)文字化けタイミング
2015年01月13日
┌──────────────────────────────────────┐
│<meta http-equiv="Content-Type" content="charset=Shift_JIS"/>               │
└──────────────────────────────────────┘
「Shift_JIS」のホームページに、「Shift_JIS」にはない「UTF-8」の「☑」文字を
入力した場合の挙動。

(1) 「☑」をコピー    →クリップボード上は「UTF-8」的に記録(CF_UNICODETEXT)
(2) 「☑」を貼り付け  →ホームページ上は「UTF-8」で表示
(3) POST送信(submit)  →「Shift_JIS」に変換(ここで文字化け「?」)
分類:PHP
PHP/PDOが効かなくなった
2014年10月26日
PHPのインストール時に、PostgreSQLのPDOをインストールしたのだが
何か拍子に(たぶん何かをインストールしたことによる影響と思われる)、
そのPDOが効かなくなった(「phpinfo()」で参照しても見えてこない)

再インストール(ChangeもしくはRepair)を行っても解消しない。
(インストール済みになる、一回削除してからやっても同じ)

で、Apacheのエラーログ「apache-error.log」を見たら以下のエラーが出ていた。
┌──────────────────────────────────────┐
│Warning:  PHP Startup: Unable to load dynamic library                       │
│ 'C:\Program Files (x86)\PHP\ext\php_pdo_pgsql.dll'                         │
│ - このオペレーティング システムでは %1 は実行されません。                  │
└──────────────────────────────────────┘

この解決方法は以下の通り。

Apacheの設定ファイル(httpd.conf)の末尾に、以下が自動で追加されるので
そこに以下の一行(★)を追加すれば解消された。
┌──────────────────────────────────────┐
│PHPIniDir "C:\Program Files (x86)\PHP\"                                     │
│Loadfile "C:\Program Files (x86)\PHP\libpq.dll"                 ←★これを追加
│LoadModule php5_module "C:\Program Files (x86)\PHP\php5apache2_2.dll"       │
└──────────────────────────────────────┘
「C:\Program Files (x86)\PHP」の部分はPHPのインストール先。

なんでだろう?
分類:PHP、Apache
PHP/パスワード管理(2)
2014年10月19日
パスワードを暗号化するのにハッシュ関数を使う。
以下は「md5()」を使った例。
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = md5($平文);                                                       │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (md5($入力文) == $暗号文) {                                              │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
これで、ほぼ十分なのだが、問題がある。
例えばよく使うパスワードの文字として「password」ってのがあるが
これは「5f4dcc3b5aa765d61d8327deb882cf99」に変換されるのだ。
(自分で変換してみればいい)
つまり「5f4dcc3b5aa765d61d8327deb882cf99」が流出すれば
元々「password」だったってことがわかってしまう。
この地道な作業を繰り返せば、機械的な変換表ができてしまう。

では、これにどう対策したらいいか。
つまりは、決まった変換が公になっているのが問題なのだ。

ということで、いたずらで私的な文字列を追加してあげればよい。
ハッシュ関数なのでちょっとした違いだけで、結果が大きく変わる。
こんな感じ。(「$適当な文字」には「1」とか「A」だけでもよい)
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = md5($平文 . $適当な文字);                                         │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (md5($入力文 . $適当な文字) == $暗号文) {                                │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
でも、問題がある。「$適当な文字」の管理が煩雑だ。
忘れると照合できなくなる一方、流出の恐れもある。
また、何をつかえばよいかも悩みどころだ。

ということで、これを簡単に実現してくれるのが「crypt()」だ。
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = crypt($平文);                                                     │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (crypt($入力文, $暗号文) == $暗号文) {                                   │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
「$適当な文字」的なところを、暗号文自身に付加してあげる感じ。
「crypt()」では、その「$適当な文字」的なところを抜き出して、
これを使って暗号化してくれるという仕組みだ。

なによりも「crypt($平文)」の部分は、実行する度に結果が変わる。
ハッシュを二重にかけているような感じだ。

ちなみに「crypt()」の「salt」は種別によって以下のような感じとなる。
┌───────┬──────────────────────────────┐
│CRYPT_STD_DES │xx                                                          │
├───────┼──────────────────────────────┤
│CRYPT_EXT_DES │_0000xxxx                                                   │
├───────┼──────────────────────────────┤
│CRYPT_MD5     │$1$xxxxxxxx$                                                │
├───────┼──────────────────────────────┤
│CRYPT_BLOWFISH│$2a$00$xxxxxxxxxxxxxxxxxxxxx                                │
│              │$2x$00$xxxxxxxxxxxxxxxxxxxxx                                │
│              │$2y$00$xxxxxxxxxxxxxxxxxxxxx                                │
├───────┼──────────────────────────────┤
│CRYPT_SHA256  │$5$xxxxxxxxxxxxxxxx                                         │
│              │$5$rounds=5000$xxxxxxxxxxxxxxxx                             │
├───────┼──────────────────────────────┤
│CRYPT_SHA512  │$6$xxxxxxxxxxxxxxxx                                         │
│              │$6$rounds=5000$xxxxxxxxxxxxxxxx                             │
└───────┴──────────────────────────────┘
分類:PHP
PHP/パスワード管理(1)
2014年10月18日
設定パスワードは平文で管理していては流出した時にすぐばれてしまうので
復号化できない暗号文の状態で保存しておくのが鉄則。

パスワード照合の場面では、入力された平文のパスワードを同様に暗号化、
お互い暗号文の状態として、そこで一致すれば、合格ということになる。

もし、暗号化された設定パスワードを流出し、誰かの手に渡っても
パスワード入力の場面で、それをそのまま使うとさらに暗号化されてしまい
別な文字になるので、照合できなくなる。

つまり、暗号化せずに照合するか、平文に戻して入力するかの
いずれかの方法をとらねば照合できないわけだ。
ところが、前者はもちろんシステムの問題だから手が出せない(*1)。
一方、後者は復号化できない暗号化がなされているので、無理ということになる(*2)。
  *1:但し、そういう機能が存在した場合には、そのルートをみつけだせばよい。
      よって、パスワード照合機能を実装する場合には注意が必要だ。
  *2:従って、元々のパスワードがなんだったかの問い合わせには回答できない。
      よって、パスワードを忘れた場合には、再発行ということになる。

ということで、復号化できない暗号化により、パスワードは強固なものになる。
で、その実現方法。
ハッシュ関数を使う。
まさにこれにうってつけの関数なのだ。

まず、バラバラに暗号化される。つまり、隣の文字(例えば「1」と「2」)でも
まったく関係のない文字に変換される。つまり、類推が難しい。

そして、復号化できない。
大雑把にいえば、例えば、どんな文字でも、必ず「松」「竹」「梅」に変換されるとして
「松」は元々何という文字だったか?というような仕組みだ。
もちろん、「鶴」と入力しても「亀」と入力しても「松」では、
パスワードとして不安を感じるが、この衝突が起こらない程度に大きな範囲で
変換されるのがハッシュ関数といえる。
#理論的には衝突が起きる可能性があることが復号化できないことにつながるが
  事実上は衝突が起きないという感じか。
分類:PHP
PHP/日時の書式
2014年07月26日
現在時刻を「YYYY/mm/dd HH:ii:ss」と出力するのに
以下のように一つ一つ呼び出して文字列結合していた。
┌──────────────────────────────────────┐
│echo date('Y') . '/' . date('m') . '/' . date('d')                          │
│   . ' '                                                                    │
│   . date('H') . ':' . date('i') . ':' . date('s');                         │
└──────────────────────────────────────┘

でも、ちょくせつ書式を中にはめ込むことができるのだね。
┌──────────────────────────────────────┐
│echo date('Y/m/d H:i:s');                                                   │
└──────────────────────────────────────┘

っていうか前者だと、タイミングによって、
時と分とかが違ったりするリスクがありそうだ
例えば、11:59に時を取得し、12:00に分を取得した場合、「11:00」になったりして。
(これは大晦日とかだと年とかまで波及する)
#でも、秒が切り替わるちょっとした隙間だから稀だろうけど。

現に、間に「sleep(1)」とかいれて連続で出力してみると、
前後で値が変わってしまう。

つーことで、一回変数に代入してから分解した方が賢明のようだ。
分類:PHP
PHP/表示のタイミング
2014年07月03日
情報量の多いページの場合、以下の二つのパターンがある。
  (1) 部分的に徐々に表示する
  (2) 全部出揃うまでは表示せず、最後に一気に表示する

たいては、(2)なのだが、それは「php.ini」の以下の設定による。
┌──────────────────────────────────────┐
│implicit_flush = Off                                                        │
└──────────────────────────────────────┘

これを「On」にすると、「echo」などを行う場合、都度、「flush()」で出力され
部分的に表示される形となる。

但し、「On」にすると著しい性能低下を生じさせるので、
これをするのはやむを得ないデバッグの時に限定すべきらしい。
分類:PHP
PHP/PHPログと任意のログ
2014年06月06日
「error_log()」では、PHPログ(「php.ini」で定義するシステムログ)や
任意のログに出力させることができる。
でも、PHPログに出る内容は、任意のログに出力させることはできない。

両者を統合するには、以下の方法が考えられる。
(1) PHPログと任意のログをセットとして、
    同一フォルダに出力して両方を見る
(2) PHPログの出力先を任意のログに設定してしまい、
    任意のログに出すべき内容をPHPログに出力させ、
    PHPログ(=任意のログ)に一本化する
分類:PHP
PHP/代理関数
2014年05月24日
例えば「hex2bin」は、PHP5.4以降でのみ実装されており、それ以前はない。
でも、それ以前でも動作させたい場合には、自前で定義してあげればよい。
┌──────────────────────────────────────┐
│//==========================================================================│
│//  代理関数                                                                │
│//==========================================================================│
│if (!function_exists('hex2bin')) {                                          │
│    function hex2bin($data) {                                               │
│        $bin = '';                                                          │
│        $i = 0;                                                             │
│        do {                                                                │
│            $bin .= chr(hexdec($data{$i} . $data{($i + 1)}));               │
│            $i += 2;                                                        │
│        } while ($i < strlen($data));                                       │
│        return $bin;                                                        │
│    }                                                                       │
│}                                                                           │
└──────────────────────────────────────┘
この場合「function_exists()」で関数が定義されているか確認の上
関数を定義する形となる。
分類:PHP
PHP/POST内容の確認
2014年05月23日
「var_dump()」「var_export()」「print_r()」などで、
「$_POST」を出力してあげればよい。
┌──────────────────────────────────────┐
│<?php                                                                       │
│var_dump($_POST);                                                           │
└──────────────────────────────────────┘

ブラウザの既定文字コードがシフトJISの場合、UTF-8だと文字化けしてしまうが、
文字コードは以下のように宣言することができる。
┌──────────────────────────────────────┐
│<?php                                                                       │
│header('Content-type: text/plain; charset=UTF-8');                          │
│var_dump($_POST);                                                           │
└──────────────────────────────────────┘

「var_dump()」の改行を活かすには「pre」タグで囲うのが一番いいみたいだ。
┌──────────────────────────────────────┐
│<?php                                                                       │
│header('Content-type: text/html; charset=UTF-8');                           │
│echo '<pre>';                                                               │
│var_dump($_POST);                                                           │
│echo '</pre>';                                                              │
└──────────────────────────────────────┘
「nl2br」(\n→<br/>)をそのまま使うのは無理っぽい。
分類:PHP
PHP/allow_url_fopen無効時の影響
2014年05月03日
「allow_url_fopen=off」にした場合の影響
  ・以下の関数でURL指定が使えなくなる
    ・「fopen()」                →外部ファイルの読み込みができなくなる
    ・「file()」                 →外部ファイルの読み込みができなくなる
    ・「file_get_contents()」    →外部ファイルの読み込みができなくなる
    ・「filesize()」             →外部ファイルのサイズ算出ができなくなる
    ・「file_exists()」          →外部ファイルの存在判定ができなくなる
    ・「is_file()」              →外部ファイルの種別判定ができなくなる
    ・「is_readable」            →外部ファイルの読込可能判定ができなくなる
    ・「copy()」                 →外部ファイルのコピーができなくなる
    ・「unlink()」               →外部ファイルの削除ができなくなる
    ・「simplexml_load_file()」  →外部XMLファイルの読み込みができなくなる
    ・「opendir()」              →外部ディレクトリの情報を取得できなくなる
    ・「is_dir()」               →外部ディレクトリの種別判定ができなくなる
    ・「mkdir()」                →外部ディレクトリの作成ができなくなる
    ・「rmdir()」                →外部ディレクトリの削除ができなくなる
  ・以下のインクルード系関数でURL指定が使えなくなる
    (別途「allow_url_include=on」の指定も必要)
    ・「include()」              →外部ソースファイルの読み込みができなくなる
    ・「include_once()」         →外部ソースファイルの読み込みができなくなる
    ・「require()」              →外部ソースファイルの読み込みができなくなる
    ・「require_once()」         →外部ソースファイルの読み込みができなくなる
分類:PHP
前へ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 … 18 次へ