作ったプログラムを置いてみる場所。PHPの専門家だったと思うけど好きじゃないので(ぉ)、人を馬鹿にした書きなぐりPHPが多くなりそう。いやほんとに謙遜でも冗談でもなく書きなぐりなので気をつけてください。フレームワーク作りのポイントプログラムPHPにはいろんなフレームワークがあって、その中のどれが一般的!というのはたぶん、あまり決まっていない。あるし、どれも長所と短所がある。「別にフレームワークなんかいらない」というのも一つの選択肢だし(そしてそれがけっこう採用されている)、フレームワーク自作!というのもいいだろう。個人的な現状での結論は、フルスクラッチだ。既存のモノを選ぶと高級すぎるから。できるだけ機能の少ないフレームワークをまず作る。PHPで仕事をする以上、PHPの技術者が集まってるはずで。標準的なフレームワークは決まっていないから、みんな共通で知っているのはネイティブPHPだけなんである。そんな状況で、フレームワーク独自の記法とか、大量のライブラリのAPIをみんなに読んでもらうとか、そんなことは現実的じゃない。誰もが知っているフレームワークとかが、あるなら考えるけど。Frameworkとかがそういうものになってくのかもしれないけど。あれはそんなに悪くなさそうとは思うんだけど、なんか好きじゃない(笑)。個人的な意見ですよあくまで。経験十年!なんて人たちの意見と食い違っていることもあると思いますが。そのときは、どれが説得力あるか判断するのは読者諸氏です。フレームワークを選ぶ/改造するときは、次にあげるような基準で考えるといい。自作するときは次のような機能を作る。グローバルスコープを使わないあまりにあたりまえのことだ。変数だろうと関数だろうと、グローバルにはなにも置いてはならない。置いていいのはクラス定義だけ。define文はできる限り使わないようにする。グローバルをひとつでも使うと、そこから汚染が拡がっていくことになる。できる限り早い段階で撲滅しておきたい。選んだフレームワークやライブラリがグローバルを使っているならしかたないけど。それ以外では、絶対に使わないようにしなければいけない。これをフレームワークの選定基準にしてしまうと、けっこうな数が落第になってしまうわけだが(笑)。ネイティブPHPを活かすフレームワークを使う以上、本当なら、できるだけフレームワークが用意したモノを使うべきだ。「Util::dateFormat()」という関数があったとき。開発メンバー全員が?はっきりいってムリ。本当なら、たとえまったく同じ機能だとしても、ラップしてあることには意味がある。本当なら、採用したフレームワークが用意したモノをできるだけ使うべきなんだけど。現実的にムリなんだからしかたない。フレームワークにはたいてい、いろんなライブラリが付属している。しておけば「これもできます!」といえるから。客寄せのためなんである。いうか一般に「あれもこれもできます!」系のものでないと、選ばれないんである。有名な奴はたいてい、過剰だ。わたし自身はわりと、リファレンスを必死で読むほうだ。しょうじきなところ、いつも徒労感がある。こと、それらを使わないことにしてしまっていい。配列を使わないフレームワークには、たとえばO-Rマッピング用のライブラリとかがついているかもしれない。それを使う前にちょっと待とう。find()メソッドが、2次元の連想配列を返していないだろうか?そうなっていたら、その部分は自作したほうがいい。連想配列ではなく、データを格納するためにはオブジェクトを使うべきだ。全部publicメンバだったとしても、オブジェクト指向には、クラスで宣言していないメンバを追加したくないインセンティブが働く。連想配列は、あとから勝手にいろいろ追加されてしまう。「基本型への固執」(『リファクタリング』)は本当に、最悪の病理だ。汚染はあっという間に拡がる。アクティブレコードにするかどうかはなんでもいいけど、とにかく連想配列は撲滅しておいたほうがいい。高級なファクトリー機構は使わないフレームワークが、オブジェクトを生成するためのファクトリー機構を用意しているかもしれない。名前を文字列で渡すと対応するオブジェクトが作られるとか(......まあ、こんなアホな仕組みをなぜ作っちゃうのか知らないけど)。実際のところ、よほどよくできたメンバーが集まっていない限り、そういうのは結果的に無視されることになる。みんなわりと、newと書きたがる。本当にnewと書かせたくないのなら、newできない仕組みを組みこまなければならないだろう。あとは、たぶん自作じゃないと組みこまれていないけど必要なからくりを作る。本番環境用と開発環境用、二つの設定ファイル置き場(ディレクトリ)を作る本番環境用の設定行をコメントアウトしてその下に開発環境用の設定を書くとか、なんであえてそんなリスクを犯すの?という話だ。はじめから分けておき、$_SERVERかなにかを見て、自動的にディレクトリを差し替える仕組みを作っておく。設定ファイルは細かく分ける何百行もある設定ファイルとか。管理できると思うほうがどうかしてる。いうのはすぐに「使わなくなったけど怖くて消せない設定」が溜まっていくことになる。DB用ならDB用と、できる限り細かく分割する。すれば、影響範囲が特定しやすいから、あとで不要になったときに消せる。いややっぱり怖くて消せないかもしれないけど、可能性があるだけマシ。グローバルスコープも定数も使わない。static変数またはクラス定数だけを書いたクラスになるだろう。ほんとにconst1行しか書いてないクラスとかでいいから、細かく細かく分けるべき。細かくしても、あとでどうせ勝手に追加されて大きくなっていくんだし。.iniファイルとかXMLとかでもいいけど、あまり高級なものをつかうと、不具合が出たときに疑う対象が増えてしまう。コアな部分ほどシンプルな実装を採用したほうがいいと思う。高級なフレームワークを敬遠する理由は、そういうところにもある。テストコード置き場を作るリリース用のファイルとテストコードが同じ場所に混在しているとか、それこそ管理できるはずがない。リリースのときには消さなきゃならないわけだから、プロジェクトリーダーにとっては、そういうのも管理対象に含まれているんである。いうわけで、テストコード専用のディレクトリをはじめから作っておく。いえ、置き場を作ったとしても、そこを使ってくれるのは理解のある少数だけかもしれない。それがしょうじきなところだ。それでも、ないよりはマシなのだ。バックアップのとりかたを考えておくソースのバックアップはできるだけ毎日とる。これはあとで戻せるようにするためじゃなくて「いつでも戻せるから」と宣言するため。ソース中にコメントアウトを残すとか、そういう愚かな行為をさせないためにバックアップをとるんである。SVNを使うとか、いろいろやれることはあると思う。ようするに、開発メンバーはつねに予想以上にフリーダムだ。それでもプロジェクトリーダーは管理しなければならない。開発前に手間を減らす工夫をしておかなければ大変なことになる。有名なフレームワークをダウンロードしてきて使うのは、もちろんいい。それで手間が増えてしまうくらいなら、簡単なものを自作したほうがいい。きの悪いフレームワークがあったりするし。機能を限定したライブラリじゃなくてフレームワークの開発ばかりが盛んなところが、PHPの現状をよくあらわしている。けっきょくどう使っていいのかが決まっていないんである。いわゆるアーキテクトたちにとっては、腕の見せどころ!といえなくもない。じつは、そこらのJavaだの.NETだのの開発よりもよほど、高い技術力を持ったアーキテクトの存在を必要としてる。PHPはどうもバカにされる言語なので。技術力に見あう報酬は約束できませんがねー。10:05PHP最小のテンプレートエンジンプログラムPHPはもともとがテンプレートエンジンみたいなモノで、別にわざわざテンプレートエンジンを使う必要なんかない気もする。使うと便利なときもある(かえって不便なときもある)。テンプレートエンジンに必要な機能ってなんだろう。変数をアサインするテンプレートファイルを読み込んで表示するテンプレート中で、アサインした変数を(簡単に)呼び出せるif文とfor文まあそういうことだよな。テンプレートエンジンを使わない場合、単純なincludeとかでテンプレートファイルを呼び出せばいい。テンプレートを分けないよりは何千倍もいい。PHPそのものなら、if文でもなんでもつかえる。テンプレートエンジンの機能はすでに実現されているわけで、つまりincludeがあればテンプレートエンジンは必要ないんである。テンプレートエンジン記法のほうが読みやすい、PHPネイティブだとif文の{}とかがすごく見づらい、という意見もあるかもしれない。これには解決法があって。?>こう書きかえれば、だいぶ読みやすくなる。じっさい、このためにこんな記法が残ってる。こんなのでも、JSPのうんたらタグとかよりは書きやすい気がするし(わたしが慣れてないだけ)。いうか、テンプレートエンジンごとの独自記法なんていちいち憶えられないし、これでいいような気もする。この方法だと、グローバル変数を使うことになってしまうんである。グローバル変数はもちろん大問題だ(世界中のすべての人にこう思ってほしい......)。テンプレートエンジンを使う場合と使わない場合、なにが違うかといえばこれだ。表示用変数の名前を制限するとか、コーディング規約的なやりかたで縛るという方法はあるだろう。規約を守る体制があるなら、それでもいいだろう。規約は守られないので、なにか強制力のある仕組みが必要なのである。いうわけで、PHPのテンプレートエンジンに必要な機能があるとすれば。「グローバルでない、表示専用のスコープを提供すること」なんじゃないか。いったことをふまえて、ネイティブPHPの機能を最大限に活用したテンプレートエンジンを書いてみよう......。'piyo';$template->show('foo.tpl.php');これでも、なんかそれっぽい書きかたにはなる。(PHPは、定義していないpublic変数を外から作られても文句をいわない)うーん、ほんとにこれでいいなあ......。余計なことしないし、パフォーマンスの問題もないし、なにより学習の必要がない。いう人がいてもいいと思う。01:51よくきく「PHPなんてただのテンプレートエンジンで、言語じゃない」っていうのはぜったい信じちゃダメと思う。そんなこといってる人は本物の技術を知らないと思う。上のはそういう意味じゃないです。20:18掲示板のコメントスパム対策プログラム以前も書いたけど、そのページは事故で消えましたorz数ヶ月たつけど荒らしにはあってないので、方法を紹介だけします。スパムは人間ではありません。理解して対策をとれば防ぐことができます。ロボットでは人間さまにかなわないのです。スパムがロボットであるという前提に立って考えてみます。ロボットはどうやって、コメントフォームを捜すのでしょうか?Googleのクローラーと同じ。リンクを辿ってやってくるのです。単純に考えて、formタグを捜すのでしょう。(あくまで推測)というわけで、ロボットに対抗するために考えられる方法は↓。フォームを、ロボットには見えないようにするとそんなことを考えて、このサイトでとってる方法。フォームタグをHTML中に書きません。Javascriptのdocument.writeで書きます。PHPでやる場合のソース↓。')+"';}HTML特殊文字と、\とあとてきとうに何文字かをString.fromCharCode()に変換。これで、formという単語すらなくなります。ロボットでは、フォームがあることがわかりません。ロボットがJavascriptを解釈しはじめたら別。なったら別の方法を考えるしかない。この方法の欠点は、すでにスパムサーバのDBに登録されてしまっているページでは効かないかもしれないというところ。いうDBがあるのかどうかは知らないけど。「半角英数のみで、URLが含まれる投稿」をNGとする以前ここで使ってた方法。効くけど、でもこれじゃあ、外国人を排除してしまう。あと、近ごろは韓国からのスパムとかも増えてるらしい。サイト全体で投稿コメントに含まれるURLを集計し、頻度の高いものをNGとするはてなはこんな方法らしい。すごく大きなサイトでしかできない。コメントフォームへのリンクにJavascriptを仕込むただのaタグじゃなくて、onclickでページ遷移させる。理屈としてはこのサイトの方法と同じ。確実だろうけどユーザビリティを犠牲にしてるIP制限こういうめんどくさい方法は本質的にダメだと思うけど......、まあ効くのは確かだろう。20:58HTML特殊文字エスケープのやりかた日記プログラムDB登録時にHTML特殊文字をエスケープして登録してるPHPシステム。コレ久しぶりに喰らった。いうわけで改めて、正しいやり方を書く。HTML特殊文字は表示の直前にhtmlspecialchars!htmlspecialcharsには第2引数でENT_QUOTESをつけろ!(シングルクォートもエスケープ)変数を表示するときは、基本全部htmlspecialchars!「表示の直前」である。htmlspecialcharsをしたら、その後はいっさいの加工をしてはいけない。「あたりまえじゃん」と思った人はずっと忘れないで。エスケープするタイミングはできるだけ一致させないと、あとでわけわからなくなる。「直前」が一番わかりやすい。ENT_QUOTESについては異論もあるらしい。いうのは、「正しいか正しくないか」じゃなくて「できるかできないか」なのだ。ひとりで作ってるなら個別に正しい判断も可能だが、システムは不特定多数が触る。わかりやすく全部つけときゃいい。定数だろうとなんだろうと全部。どれをやってどれをやらないか、判断できる人もいるだろうが、不特定多数の全員ではない。わかりやすく全部、できるだけ同じ方法でエスケープ。それで支障があるのなら、設計が悪い。いまなおさないと、いつか問題が起こる。......なんか、書いててレベル低い話だなあと思うけど。PHPってそういう世界だからさ......。PHPに関してはいつも思うが、間違ったこと書いてるサイトがあまりに多いという問題もある。これに関してはGoogleの罪かも。00:56ajaxの作法?プログラムajaxとか流行っちゃって、わりと気軽につかわれてたりするわけですが。これがけっこう、やばいことになりがちなのです。サーバに何回リクエストを投げるのかというのを意識しないで、onclickとか複数選択のselectタグのonchangeとか、危険なところにajaxを仕込んであったりする。いうイベントは、下手をするとすごい回数発生してしまうのです。サーバにも同じ回数のリクエストが飛ぶわけなので、そのあたりは意識しなければいけない。サーバでは多くの場合、リクエストを受けるたびにSQL発行するはずだ。いうコードは大変まずいのです。いうわけで、こんな関数を用意しておくといいと思う。}1秒間イベントが来なかったら初めてajaxする。作法っていうか、考えてないとDBサーバが固まっちゃったりとか平気でするんで、ぜひとも気をつけたい。09:00プログラムを。