MW211 EXIT

devlog
PHP/ヒアドキュメントで定数を使う
2011年11月27日
ヒアドキュメントってのは以下みたいなやつだ。(かなり重宝している)
┌──────────────────────────────────────┐
│echo <<<___HTML___                                                          │
│結果は、{$result}です。                                                     │
│___HTML___;                                                                 │
└──────────────────────────────────────┘

でも、定数だと反応してくれない(この場合「成功」ではなく「RESULT」が表示される)
┌──────────────────────────────────────┐
│define(RESULT, '成功');                                                     │
│echo <<<___HTML___                                                          │
│結果は、{RESULT}です。                                                      │
│___HTML___;                                                                 │
└──────────────────────────────────────┘

ま、一旦変数に代入すりゃ回避できるのだが…。
┌──────────────────────────────────────┐
│$result = RESULT;                                                           │
│echo <<<___HTML___                                                          │
│結果は、{$result}です。                                                     │
│___HTML___;                                                                 │
└──────────────────────────────────────┘
なんか一気にやってしまいたい。

そこで、サブメソッドを使う方法。
┌──────────────────────────────────────┐
│echo <<<___HTML___                                                          │
│結果は、{$this->def(RESULT)}です。                                          │
│___HTML___;                                                                 │
│- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │
│private function def($define) {                                             │
│  return $define;                                                           │
│}                                                                           │
└──────────────────────────────────────┘
「return $define;」の部分は「return constant($define);」ならより丁寧か。

それじゃ、静的メソッドにしちゃって
どこからでも簡単に使えるようにしたらいいじゃん、と思ってやってみた。
┌──────────────────────────────────────┐
│echo <<<___HTML___                                                          │
│結果は、{Edit::def(RESULT)}です。                                           │
│___HTML___;                                                                 │
└──────────────────────────────────────┘
答えはNG。ダメでした。
先頭の「$」が肝らしく、これがないと反応してくれない。
分類:PHP
PHP/小数点以下桁数チェック
2011年11月22日
┌──────────────────────────────────────┐
│$decimal = explode('.', $値);                                               │
│$桁数 = isset($decimal[1]) ? strlen($decimal[1]) : 0;                       │
└──────────────────────────────────────┘
「123.456」の場合、小数点以下桁数「3」桁と判定できる。
分類:PHP
PHP/乱数
2011年11月21日
「0~9」の範囲で、整数の乱数を発生させたい場合
┌──────────────────────────────────────┐
│rand(0, 9)                                                                  │
├──────────────────────────────────────┤
│mt_rand(0, 9)                                                               │
├──────────────────────────────────────┤
│floor(lcg_value() * 10)                                                     │
└──────────────────────────────────────┘
昔は乱数の種を設定しないといつも同じ結果となっていたので
「rand()」では「srand()」を、「mt_rand()」では「mt_srand()」を
事前に実行する必要があったみたいだが、今は自動でやってくれるので必要ないみたい。
#「lcg_value()」は元々そういうのは不要

で、「rand()」と「mt_rand()」の違いだが、「mt_rand()」の方がよりよいらしい。
具体的には高速みたい。
「mt_rand()」を使うのがおすすめみたい。
分類:PHP
PHP/URLエンコード
2011年11月17日
まずは、基本から。
┌──────────────────────────────────────┐
│エンコードされた値 = urlencode(元の値);                                     │
├──────────────────────────────────────┤
│元の値 = urldecode(エンコードされた値);                                     │
└──────────────────────────────────────┘

で、実用編。
GETパラメータで日本語を扱いたい場合、
例えば年号をそのままパラメータとしたい場合、以下のような感じになる。
┌──────────────────────────────────────┐
│http://….php?nengo=平成                                                    │
└──────────────────────────────────────┘

これくらいなら問題ないけど、記号とか絡んでくるとややこしいので、
┌──────────────────────────────────────┐
│「%E5%B9%B3%E6%88%90」 ← urlencode('平成')                                 │
└──────────────────────────────────────┘
上記のようか感じでエンコードして、それで渡してあげる。
┌──────────────────────────────────────┐
│http://….php?nengo=%E5%B9%B3%E6%88%90                                      │
└──────────────────────────────────────┘
んでもって、受け取る側でデコードして元に戻して受け取るという感じ。
┌──────────────────────────────────────┐
│「平成」 ← urldecode($_GET['nengo])                                        │
└──────────────────────────────────────┘
これは文字コード「UTF-8」の場合の例です。

送り側も、受け側も同じ文字コードであれば問題ないけど
もし、違う文字コードの場合は文字コード変換とか絡んでくるのだろう。
分類:PHP
PHP/正規表現の置換で文字列を除去(抽出)
2011年11月06日
「preg_replace()」は正規表現が使える便利な置換関数だ。

例えば「ABCDE」という文字列があったとして、
「B」より前を除去したい場合は「^.*B」を
「」(空文字)に置換するように指定すればよい。
┌──────────────────────────────────────┐
│preg_replace('/^.*B/', '', 'ABCDE');                               →「CDE」│
└──────────────────────────────────────┘
「^」は先頭を表し、「.*」は一種のワイルドカードみたいなものだ

一方、「D」より後を除去したい場合は、「D.*$」を「」に置換だ
┌──────────────────────────────────────┐
│preg_replace('/D.*$/', '', 'ABCDE');                               →「ABC」│
└──────────────────────────────────────┘
「$」は末尾を表す

では、この二つを同時に行い「C」のみを抽出したい場合には?
一時変数を使って順番に二段階で処理すればできそうだが(実際にできるが)
なんと、一発でできてしまう。
┌──────────────────────────────────────┐
│preg_replace('/^.*B|D.*$/', '', 'ABCDE');                            →「C」│
└──────────────────────────────────────┘
「|」は「or」みたいなもんで、前出の二つのいずれかに該当したものを
一気に処理してくれる。
もちろん「|」の前後を入れ替え可能、結果は同じだ。
┌──────────────────────────────────────┐
│preg_replace('/D.*$|^.*B/', '', 'ABCDE');                            →「C」│
└──────────────────────────────────────┘

では、互いの領域まで侵犯する入れ子状態の置換はどうなるのだろうか?
「A~D」と「B~E」を同時に置換で除去してしまう。
ってことで「BCD」が両方でかぶってる場合だ。

こんな感じの結果だった。
┌──────────────────────────────────────┐
│preg_replace('/^.*D|B.*$/', '', 'ABCDE');                            →「E」│
└──────────────────────────────────────┘
「ABCDE」─(「A~D」を置換」)→「E」─(「B」がみつからず置換できず)→「E」
…ってな感じだろうか。

それじゃ、「|」の前後を逆にしたらどうだろう?
「ABCDE」─(「B~E」を置換」)→「A」─(「D」がみつからず置換できず)→「A」
…かと思いきや
┌──────────────────────────────────────┐
│preg_replace('/B.*$|^.*D/', '', 'ABCDE');                            →「E」│
└──────────────────────────────────────┘
で、変わらず。

文字列の先頭から処理していくのが原則みたいだ。
分類:PHP
PHP/POSTパラメータは画面リロードでどうなってしまうのか?
2011年10月26日
submit後のGETパラメータはURIの一部になっているので、
「ctrl+r」とかで画面リロードしてもGETパラメータはそのままだ。

SESSIONはもちろんセッション領域に書き込まれるので
リロードしても問題なし(変化なし)。

となるとPOSTパラメータって、リロードするとどうなるのだろう?(消えたりする?)

ということで実験してみた。

万全を期して(?)、他のページへactionで遷移するようにして
そこでprint_r()でダンプを画面に表示してみた。
(遷移先のページにはPOSTする要素はないので雑音なし…という想定)

で、POST直後、hiddenやtextから入力した値がダンプ表示されるのをまず確認。
さで、ここから本番だ、リロード!
すると、見慣れた以下のダイアログが登場、すかさず「再試行」を実行。
┌────────────────────────────────────┐
│このページを再表示するには、以前送信した情報を再送信する必要があります。│
└────────────────────────────────────┘

さきほどのダンプはそのままだ。
つまり、POSTパラメータは消えません。

………あれ?そういや見慣れたダイアログに答えが書いてあったじゃん。
「以前送信した情報を再送信」ってね。
分類:PHP
PHP/NULLを文字列結合すると文字型になる
2011年10月25日
「gettype()」って便利な関数があって、変数のデータ型を調べられるのだが、
以下のような結果となった。
┌──────────────────────────────────────┐
│echo gettype(NULL);                                                 →NULL  │
│echo gettype(NULL . NULL);                                          →string│
└──────────────────────────────────────┘
つまりは、NULLを文字列結合すると文字型扱いとなるのだ。

ってことは、「is_null(NULL . NULL)」は偽となってしまうのである。

これは変数を介した時にハマりやすい罠だ。
「$c = $a . $b;」で「if (is_null($c)) {…」とかって処理を書いてしまうと
「$a」も「$b」もNULLの場合、当然真になる…なんて間違いを犯してしまうことになる。
分類:PHP、注意
PHP/try&catchのサブ関数化
2011年10月22日
元々、こんな感じでtry&catchな処理を行っているとする。
┌──────────────────────────────────────┐
│public function メソッド() {                                                │
│  try {                                                                     │
│    $dbh = new PDO(…);                                                     │
│  } catch (PDOException $e){                                                │
│    echo $e->getMessage();                                                  │
│  }                                                                         │
│}                                                                           │
└──────────────────────────────────────┘
だけど、一部、サブ関数化(サブメソッド化)して他に持っていきたい場合がある。
例えばこんな感じ。
┌──────────────────────────────────────┐
│public function メソッド() {                                                │
│  try {                                                                     │
│    $dbh = $this->サブメソッド;                                             │
│  } catch (PDOException $e){                                                │
│    echo $e->getMessage();                                                  │
│  }                                                                         │
│}                                                                           │
├──────────────────────────────────────┤
│public function サブメソッド() {                                            │
│  $dbh = new PDO(…);                                                       │
│  return $dbh;                                                              │
│}                                                                           │
└──────────────────────────────────────┘
でもtryの中身を他に持っていくと、catchができなくなる。
メイン側で、サブ関数から戻ってきた直後にエラー判定して、
疑似的にエラーにして、catchに拾ってもらう?
いやいや、そんな面倒なことはしなくてよい。
「throw」してやればいいのだ。
┌──────────────────────────────────────┐
│public function メソッド() {                                                │
│  try {                                                                     │
│    $dbh = $this->サブメソッド;                                             │
│  } catch (PDOException $e){                                                │
│    echo $e->getMessage();                                                  │
│  }                                                                         │
│}                                                                           │
├──────────────────────────────────────┤
│public function サブメソッド() {                                            │
│  try {                                                                     │
│    $dbh = new PDO(…);                                                     │
│  } catch (PDOException $e){                                                │
│    throw $e;                                                               │
│  }                                                                         │
│  return $dbh;                                                              │
│}                                                                           │
└──────────────────────────────────────┘
エラー情報のたらいまわしですな。
分類:PHP
PHP/データ量の多い折れ線グラフ描画
2011年10月19日
X軸一目盛に対してY軸の値が一つずつ並んでいるような配列があるとする。

例えばGDを使って以下のように折れ線グラフを描画したりできるような配列だ。
┌──────────────────────────────────────┐
│for ($x = 1; $x < 100; $x++) {                                              │
│  imageline(出力先, $x - 1, $y[x - 1], $x, $y[x], 色);                      │
│}                                                                           │
└──────────────────────────────────────┘

このデータが10倍になったけど描画する領域がそのままの場合。
つまり描画できる横幅よりもデータが多い場合に、
1/10に圧縮して、ローソク足グラフのように、縦幅のあるグラフを描画する方法。
┌──────────────────────────────────────┐
│for ($x = 0; $x < 1000; $x++) {                                             │
│  $y1 = min(array_slice($y, $x, 10));                                       │
│  $y2 = max(array_slice($y, $x, 10));                                       │
│  imageline(出力先, $x, $y1, $x, $y2, 色);                                  │
│}                                                                           │
└──────────────────────────────────────┘
上記のような感じで、「min()、max()、array_slice()」を駆使すればよい。
これで、最小値から最大値までの縦幅のもつ線が横にずらっと並んでいく。
まるで、横に押しつぶしたかのようにだ。
分類:PHP
PHP/ゼロパディング
2011年10月18日
「1」を「0001」とかのいわゆる書式付文字列にして出力する方法。
C言語の「sprintf()」関数を流用する。
以下のような感じ。
┌──────────────────────────────────────┐
│sprintf("%04d", 1)                                                          │
└──────────────────────────────────────┘
分類:PHP
前へ 1 … 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 次へ