[php]第50回PHP勉強会@関東に参加してきました

Written by uechoco 2月 23

第50回PHP勉強会@関東に参加してきました。

記念すべき50回目ということで、OpenSocialをテーマにした大人数の勉強会となりました。会場は株式会社コンテンツワンさんです。ありがとうございます。発表はmixiのWebooさん、エムズリンクのKuniTsujiさん、ウノウの個々一番さんでした。ちょっとだけオフレコな情報もありましたね。またUstはi-ogiさん、司会進行はyuchimiriさん、幹事はgusagiさんでした。いつもありがとうございます。

OpenSocialという今一番アツい市場の勉強会ということで(?)、参加者もすごい人がちらほら。

まぁ、ざっくりとまとめ。Ustreamはhttp://www.ustream.tv/channel/phpstudyです。

  • mixiのwebooさん
    • mixiプラットフォーム
    • mobileのPVはPCの約4倍
    • mixiはソーシャルグラフ(対して、他社のSNSはバーチャルグラフ)
    • アプリがヒットすると数千万〜数億PV/日のアクセスが来る
    • 友人と一緒に使わないものはヒットしない
    • わかりやすさ、ソーシャル性、巻き込み性、継続性のあるアプリがヒットする
  • エムズリンクのKuniTsujiさん
    • mixiアプリをWebサービス風に開発したい
    • PCは分からないが、mobileなら一般的なWebサービスと変わらない開発が出来そうだ
    • ログイン周り、認証周り、ヘルパー周りをOpenSocial対応にする
  • ウノウの個々一番さん
    • まちつく!mixiアプリ版は大盛況
    • 外部のAPIは信用しない(エラーに適切に対処出来るゆるふわ系のコーディング)
    • リリース日は開始数分でLAが100になるとか。とりあえず重たい画像生成をキュー(not Q4M)にしたり、ボトルネックを排除したり、ハードウェアの購入をするとか。
    • 初期の頃は、1日10万ユーザ増えていき、回線も足りなくなってきたので、画像などをAmazon S3に、一部の機能をAmazon EC2で代用させた。またmemcachedの適用範囲を増やし、一部の機能は企画レベルで見直して、負荷が軽くかつより良い機能に変更した。またMySQLのwriteが厳しかったのでDBマスタ分割を行った。トランザクションはごにょごにょ。
    • 中期になると、保守コストの面でDBマスタ分割も厳しくなったので、DBサーバをいいものに変えた。また本格的な機能改善を行い、一部処理はQ4MにしてEC2を使わなくした。機能改善ののち、課金機能などをリリースした。
    • DB分割やらを考えるとORMは導入しておいた方がいいかも
    • OpenSocialはトラフィック的な意味では甘えは許されない

懇親会はバーを貸しきってLTを挟みつつの立ち飲みでした。50回記念ということで、垂れ幕を作ったり、オリジナルカクテルを3種類も作ったりと、気合が入っていました。

PHP界隈は今年も元気です!OpenSocial界隈も元気ですのでPHP x OpenSocialでもっと盛り上げていきたいですね!

[symfony]Webデバッグツールバーにピークメモリを表示する

Written by uechoco 12月 08

知りませんでした。symfonyのWebデバッグツールバーに表示されているメモリ使用量は、メモリの最大使用量ではなかったのです現在の確保されたメモリ量というのが正しいです。これってsymfony使いの常識ですか?

当然、メモリの最大使用量を表示したいですよね。symfony 1.2以上であれば、簡単に実装できます。(symfony 1.0をお使いの方は、sfWebDebugで、より正確なメモリ使用量を見るには - Sooeyをご覧ください。)

symfonyのWebデバッグツールバーのカスタマイズ方法は、Cookbookにしっかりと載っているのです。今回参考にするのは、The symfony Cookbook | Webデバッグツールバーをカスタマイズする方法 | symfony | Web PHP Frameworkです。実際にやってみましょう。

まずはメモリの最大使用量を表示するためのsfWebDebugPanelクラスの派生クラスを作成します。sfWebDebugPanelMemoryクラスをほんの少しだけ変えただけのクラスです。libフォルダなどに作りましょう。

PHP:
  1. <?php
  2.  
  3. /**
  4.  * sfWebDebugPanelPeakMemory adds a panel to the web debug toolbar with the peak memory used by the script.
  5.  *
  6.  * @package    symfony
  7.  * @subpackage debug
  8.  */
  9. class sfWebDebugPanelPeakMemory extends sfWebDebugPanel
  10. {
  11.   public function getTitle()
  12.   {
  13.     if (function_exists('memory_get_peak_usage'))
  14.     {
  15.       $totalMemory = sprintf('%.1f', (memory_get_peak_usage() / 1024));
  16.  
  17.       return '<img src="'.$this->webDebug->getOption('image_root_path').'/memory.png" alt="Peak Memory" /> peak:'.$totalMemory.' KB';
  18.     }
  19.   }
  20.  
  21.   public function getPanelTitle()
  22.   {
  23.   }
  24.  
  25.   public function getPanelContent()
  26.   {
  27.   }
  28. }

お気づきかと思いますが、Webデバッグツールバーの1つ1つの項目はsfWebDebugPanelクラスの派生クラスです。構造化がうまくなされているので、追加も簡単という訳です。

次に、Webデバッグツールバーに登録します。今回はプロジェクト全体で適用したいので、ProjectConfiguration.class.phpを変更します。frontendConfiguration.class.phpでも同じコードで動きます。

PHP:
  1. class ProjectConfiguration extends sfProjectConfiguration
  2. {
  3.   public function setup()
  4.   {
  5.     // ...
  6.     $this->dispatcher->connect('debug.web.load_panels', array($this, 'configureWebDebugToolbar'));
  7.   }
  8.  
  9.   public function configureWebDebugToolbar(sfEvent $event)
  10.   {
  11.     $webDebugToolbar = $event->getSubject();
  12.     $webDebugToolbar->setPanel('peak_memory', new sfWebDebugPanelPeakMemory($webDebugToolbar));
  13.     $webDebugToolbar->removePanel('memory');
  14.   }
  15.  
  16. }

字面でなんとなくわかるかもしれませんが、Webデバッグツールバーのロード時にconfigureWebDebugToolbar()メソッドを呼び出すように登録しています。メソッド内では、さきほど作成した最大使用量を表示するパネルを追加し、代わりに元々あったメモリ表示のパネルを削除しています。

実際に使用したときのWebデバッグツールバーがこのようになります。
sfWebDebugPanelPeakMemory
上記sfWebDebugPanelPeakMemoryクラスの中で、わかりやすく「peak:」を表示するようにしています。

今一度、symfonyを見直してみるのもいいかもしれませんね。

[php]ctype関数でバリデート

Written by uechoco 12月 07

PHP: Ctype 関数 - Manual

最近のフレームワークは独自にバリデート機構を持っているので昔ほどバリデートに気を使うことも少なくなりましたが、自前でバリデートすることもまだあるでしょう。一般的には、正規表現のpreg_match()やis_numeric()、is_int()などがよく使われるのですが、ctype系の関数は知らない人も居るかもしれません。

ctype関数は、C言語のctype.hという標準ライブラリに由来があります。

ctype 関数は、正規表現よりもつねに好ましく、さらに str_* および is_* のような いくつかの等価な関数よりも好ましいことに注意してください。 これは、ctype 関数がネーティブな C ライブラリを使用しており、処理が著しく 高速であるためです。PHP: Ctype 導入 - Manual

とあるように、文字の種別をチェックする場合はctype系関数は断然お勧めという訳です。特に、ctype_alnum()は知っておいて損は無いでしょう。その名の通り与えた文字列が英数字の場合にtrueを返す関数です。正規表現でやっちゃっている人も多いと思います。

ところで、ctype系関数にはこんな比較をしている人がちらほらいます。

ctype関数はCライブラリを使用しているため,is_*, str_*より高速とのこと.
だが実際に比較してみると,is_* の方が速い.ctype と is_* , str_* の処理速度比較 - memo.xight.org

上記引用記事では、is_int()とctype_digit()を比較して、is_int()の方が速いという主張をしていますが、この比較はそもそも本質的に間違っていますis_int()は型チェックのための関数であり、ctype_digit()は文字列チェックのための関数です。これらの関数は想定している対象がそもそも違うので、適材適所で使用するというのが正しいでしょう。

というわけで、ctype関数は遅いというのは偏見です。ctype関数を有効活用しましょう。

[php]needle in a haystack

Written by uechoco 11月 30

プログラミングをやっていると、慣習的に用いる変数名、引数名と言った物があります。例えばfor文の変数はi、j、kとか。たまに知らない慣習もあります。今回調べたのは「haystack」と「needle」。文字列検索系の関数の引数名としてよく使われています。例えば下記のstrposやらstrstrやら。

int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

string strstr ( string $haystack , mixed $needle [, bool $before_needle = false ] )

この習慣はphpだけのものではなくて、C言語から来ています。

char *strstr(const char *haystack, const char *needle);

で、実際のところ、なんでhaystackとneedleなのかというところですが、恥ずかしながら、私はhaystackという英単語を知りませんでした。haystackは「干し草」という意味のようです。needleはもちろん「針」ですね。

英語がわかる人には常識なのかもしれませんが、英語には、haystackとneedleという単語を用いた慣用句があるんです。

  • needle in a haystack: 見つけることが不可能なもの、捜しても見つかりそうにないもの、無駄骨
  • find a needle in a haystack: 干し草の山の中の針を見つける、見つかる望みのないものを見つける
  • look for a needle in a haystack: 干し草の山の中にある1本の針を探す、無駄骨を折る

だいたい同じような意味で用いられます。
C言語が定義された頃は、文字列検索関数が対象文字列(haystack)から目的の文字列(needle)を見つけ出す様は、干し草の山の中から針を見つけるくらいに大変なことだった、ということでしょうか?(適当に考えていますが、そういう意味としかとれないですよね)

プログラミングの世界にもうんちく話ってありますよね。
他にもこういった慣習をご存知の方はコメントに書いてください!

[php]php.iniをミスるとphp.iniが適用されない

Written by uechoco 11月 12

先日、Mac OS XにMacPortsを使って、apache2、php 5.3.0、MySQL 5.1を導入して、しばらく開発をエンジョイしていたのですが、いろいろと作業をしているうちに、MySQLが使えなくなっていることに気がつきました。

具体的にはsymfony 1.2で、DB設定も前に済んでいて、しばらく開発をしていたのに、突然PDO connectionエラー([2002] No such file or directory、MySQLのソケットファイルが無いときに出るエラーです)がでてきたのです。何がおかしいのだろうといくつか見てみると、php.iniやシェル上のphp -i | lessで閲覧してソケットの設定がしてあるのにも関わらず、当該アプリケーションのディレクトリでphpinfo()を見てみると、php.iniの設定が全く適用されていなかったんです

確かに個々最近、php.iniをちょこちょこ弄った気がしますが、間違ったことはしていないよなと、php -i | lessを見ていたところ、かすかにphp.iniの文法エラーらしき文言を見つけました。そう、php.iniをちょっとでも書き間違えると、mod_php上のphpにはphp.iniが適用されないようなのです

私の場合は、error_reportingのE_ALLからE_DEPRECATEDから取り除こうと変な論理式(確かXORビット演算子を使っちゃったかな?)を書いてしまったようです。