Category: PHP

わりとよく使うがHELPが見づらかったりサンプルがなかったりするのでメモ。毎回過去の自分のコードを引っ張り出してくるのも効率が悪いし。

導入

$ pear install --alldeps HTTP_Request

–alldepsで用意されると思うが、Netパッケージに依存しているので以下のファイルが必要になる。

  • Net/Socket.php
  • Net/URL.php

(さらに…)

今までの流れからするとだいぶ唐突なネタだが、仕事で半日苦労したのでメモしておく。

まとめていたらえらく長文になったので先に結論。

  • Postfixのaliasは正規表現を使ってマッピングできる
  • Postfixでlocalがregexpを使う場合ローカルパートしか渡さない(らしい)
  • $_ENVがnullの場合はphp.iniのvariables-orderディレクティブをチェック

●メールでデータを受け取りたい

ご存知の通り、携帯はブラウザのフォームからMultipartでPOSTできないようになっている。つまり、ファイルのアップロードができないということだ。ユーザからテキスト以外のデータ投稿を受け付けようとすると、メールに添付してもらうしか方法がない。

一方、携帯のユーザの行動パターンには「メールアドレスをころころ変える」という特徴がある。個人的には気に入ったアカウントは長く使いたいと思うのだが、若年層のケータイユーザはそうではないらしい。となると、ユーザ側で簡単に変更できるメールアドレスをキーにするのはあまり都合がよろしくない。それ以外の情報でユーザを識別する必要がある。

●メールを送ってきたユーザを識別したい

私が担当しているコンテンツの前任者は、以下の手段でメール送信ユーザを識別していた。

  • ユーザIDを適当に暗号化
  • mailto:タグのbody要素に仕込む
    →クリックすると本文が入力された状態で端末のメーラが起動する
  • 受信したメールをパーズしてユーザIDを復号

正直あまりよろしくない方法である。ユーザが本文にテキスト情報を付与して送信することができないし、本文のキーをいじられるとあまりいいことはない。

一方、例えばmixiの「携帯で日記を投稿する機能」などは、ローカルパート(メールアドレスの内「@」以前の部分」に識別キーを入れて送るようになっている。これによってメールのsubjectが日記のタイトル / メールのbodyが日記の本文 / 画像が添付されていれば写真投稿、というメール一通で日記投稿を完結させることが可能になる。

ああ前置きが長くなった。つまり、ローカルパートに情報を載せたメールを処理するための設定方法をメモしておく、というのが本題である。

(さらに…)

久しぶりに私が講師での社内勉強会。Railsの案件に乗り遅れてしまい、楽しかったり目新しかったりするテーマでできないのがもどかしいところ。だからといってこのテーマはどうなの?とは思うが。

い、いちおうフォローしておくと、今回はdisるけど次回は前向きに!という前フリなのである。さらっと20分ほどで終わってしまったが、準備には意外と時間がかかった。ダメコードとはいえ検証したしね。

しばらく中断していた社内勉強会を復活させた。お題は前からやろうやろうと思っていたセキュリティ関係。資料とデモができあがったのが開始1分前という綱渡りでの開幕になったが、なんとかなるのが社内勉強会のいいところ。

例によって崩れているがSlideShare。資料と攻撃に使った書き込みは固めてダウンロードできるようにしておいた。

「20090218_post.zip」をダウンロード

デモに使ったスクリプトは、教科書として使用した「PHPサイバーテロの技法―攻撃と防御の実際」のサンプルを利用させていただいた。

まだまだセキュリティについては勉強不足だし、チームの意識も十分とは言えない。今後も情報収集と啓蒙に努めていこうと思う。

Amazon.co.jp: PHPサイバーテロの技法―攻撃と防御の実際: GIJOE: 本
http://www.amazon.co.jp/exec/obidos/ASIN/4883374718/bottomline02-22

PHPサイバーテロの技法 – 読者サポート・正誤表
http://www.peak.ne.jp/support/phpcyber/

開発者のための正しいCSRF対策
http://www.jumperz.net/texts/csrf.htm

はてなダイアリーXSS対策 – はてなダイアリーのヘルプ
http://hatenadiary.g.hatena.ne.jp/keyword/%e3%81%af%e3%81%a6%e3%81%aa%e3%83%80%e3%82%a4%e3%82%a2%e3%83%aa%e3%83%bcXSS%e5%af%be%e7%ad%96

徳丸浩の日記 ? そろそろSQLエスケープに関して一言いっとくか ? SQLのエスケープ再考
http://www.tokumaru.org/d/20080601.html#p01

前回準備した「PHPUnit」のサンプル。「オブジェクト倶楽部」で紹介されている「車窓からのTDD」(PDF)という記事を参考に、TDD(Test Driven Development / テスト駆動開発)とペアプログラミングの演習記事をPHPUnitでなぞってみた。残念ながら自宅で独りで書いたので、ペアプロのサンプルにはならないが。

作るのはスタッククラス。仕様は…

  • isEmpty()でスタックが空の場合、true。それ以外false を返す。
        boolean isEmpty()
  • size()でスタックのサイズを取得する。
        int size()
  • push()で引数の値をスタックの一番上に積む。
        void push(int value)
  • pop()でスタックの一番上の値を取り除く。
        void pop()
         スタックが空の場合、java.util.EmptyStackException が発生する
  • top()でスタックの一番上の値を取得する。
        int top()
         スタックが空の場合、java.util.EmptyStackException が発生する
  • (p.3)

…となっている。

(さらに…)

やらねばならないのは痛いほどわかっていたが、面倒なのでひたすら先延ばしにしていたユニットテスト。既存のコードに組み込むのはほぼ不可能というのを言い訳にしてきたが、さすがに新しくフレームワークを実装するとなれば書かないわけにはいかないだろう。

そんなわけでPHP用UnitTestの本流、xUnitファミリの一員であるPHPUnitを導入してみる。環境はWindows XP SP3 / xampp 1.6.6a。

(さらに…)

PHPの大御所「Do You PHP?」の中の人が困っていた問題に、同僚がずっぽりハマってしまった。

「multipart/form-data使ってアップロード」で助けて~ – Do You PHP はてな
http://d.hatena.ne.jp/shimooka/20080526/1211792488

PHP5.2.6で「multipart/form-data使ってアップロード」の続き – Do You PHP はてな
http://d.hatena.ne.jp/shimooka/20080527/1211872306

ファイルをアップロードするための「enctype="multipart/form-data"」なフォームからPOSTされた内容が、PHPの文字コード変換(mbstring.http_input -> mbstring.internal_encoding)を通らない、という不具合だ。

(さらに…)

PHPには数種類のアクセラレータがある。仕組みはPHPスクリプトのコンパイル結果(バイトコード)をファイルだったり共有メモリだったりにキャッシュしておいて、次回以降のコンパイル分処理効率を向上させる、という仕組み。

ちょっと古い記事だがGIGAZINE比較記事があり、リンク先ではベンチマーク結果が公表されていた。その中から「成績がよい」「ドキュメントが和訳されてる」「2008年にstableリリースがある」という理由でAPC(Alternative PHP Cache)を選択した。

(さらに…)

PDOを使って、よくあるコードを書いていた。

<?php
/* 前略 */
    public function getData($data_id, $user_id = -1)
    {
        // $pdo : PDO object
        $sql = "SELECT * FROM data" .
               "  WHERE data_id = :data_id" .
               // ↓テストのためにコメントアウトしてみる
//             "    AND user_id = :user_id" .
               "    AND valid   = true" ;
        $pdoStatement = $pdo->prepare($sql) ;
        $pdoStatement->bindParam(":data_id", $data_id, PDO::PARAM_INT) ;
        $pdoStatement->bindParam(":user_id", $user_id, PDO::PARAM_INT) ;
        if ($pdoStatement->execute())
        {
            return $pdoStatement->fetchAll() ;
        }
        return false ;
    }
/* 後略 */
?>

コメントの通りuser_idをチェックする条件を外してみた。つまり、プレイスホルダがないステートメントにパラメータをバインドしようとしている、という状態。bind先がないなら無視してくれてもよさそうなものだが…

(さらに…)

前回(たくさんのパラメータを効率よく管理する)で触れたYAMLハンドラ。SyckよりはLibYAMLのほうがよさそうだな…とも思ったのだが、Windowsローカルに開発環境を作るのが非常に大変なので、相変わらずSpycを使うことにした。キャッシュはPEAR::Cache_Liteに変更して、読み込みだけキャッシングするラッパを実装してみた。

(さらに…)