Home

Shin x blog

第24回PHP勉強会に参加してきました。

この記事の所要時間: 156

第24回PHP勉強会

events.php.gr.jp

第24回PHP勉強会に参加してきました。詳細なレポートはshimookaさんのところにあるので;-)、ざっくりと感想を。

extensionがアツい!

最近はフレームワークに注力してたのであまり追いかけてなかったのですが、やはり動いているモノ(ミサイルw)を見ると引き込まれます。以前少しだけCを書いていた時期があるのでバイナリアン系のネタは聞いているだけで楽しいです。

既に完成しているライブラリをPHP化するなら、ネタも色々ありそうなので何かやってみたいですね。単純に「extension作れる=かっこいい」というのもありますし。;-)

携帯+PC連携

内容とは微妙に違いますが、前から思っていたのが「汎用テンプレートって無いのか?」ということ。PHPだろうがPerlだろうがPythonだろうがRubyだろうが・・・テンプレートエンジン使うんだったら同じ書式のテンプレートを使ったら良いのに。

開発者側はそれぞれ覚えれば良いですが、デザイン側にそれを押しつけることはできないので結局今いる環境から動けない、なんて人もいる気がします。(実際それで新しいものを取り入れるのを躊躇したり。)

たとえばSmartyで書いたテンプレートが他の言語でも使えるとかで良いわけです。(うーん作ってみたいな。。。)

見える化

まさに一見にしかずです。上手く説明できないですが、できたものを見るとなぜかわくわくします。自然と「おー」と声が出ます。何か上手く使ってみたいです。

ちょっと体調不良だったり、宿難民になったりでいろいろありましたが、参加して良かったです。

会社から言われたわけでなく、自分でわざわざこういった勉強会に参加される方は当たり前ですが学習意欲の高い方ばかりなわけです。そんな方々と自分の興味ある分野で、ああだこうだとお話できたら、楽しくないわけがない!!

日頃、開発は一人でやっているのでとても良い刺激を受けました。また近いうちに参加したいと思うのでよろしくお願いします。:-)

# Twitterで実況してましたが誰も見てない気がしてやめました:-p
# せっかくなんでいちおうログ出しときます。Twitter検索 : @phper

第24回PHP勉強会に参加してきます。

この記事の所要時間: 014

今からPHP勉強会に参加してきます。
shimookaさんがblogで実況されるとの事なので、私はTwitterで実況してみようと思います。

Twitterのアカウントはshin1x1です。

では参加される皆さんよろしくお願いします。

CakePHP Controller#Object()が外部から呼べる

この記事の所要時間: 055

以前あったControllerのメソッドが外部から呼べてしまう問題ですが、フレームワークが修正されて問題は解決したと思っていました。

しかし、よくよく見てみるとObject()だけはまだ呼べる状態になっています。

下のようなコントローラに[http://example.com/hoge/Object]でアクセスすると”**construct”が2回表示されます。

[app/controller/hoge_controller.php]

<?php
class HogeController extends AppController {
  var $uses = array();

  function __construct() {
    parent::__construct();
    var_dump("**construct");
  }
}
?>

コンストラクタを継承してHogeControllerでややこしい事をしなければ、まあ2回呼ばれても良いかもしれませんが、やはり外から呼べる状態は気持ち悪いです。

こういうのを考えるとURLからコントローラとアクションが自動的にマッピングされるより、routes.phpできっちりマッピングしておいた方が安全かなあと思ったりします。(まあ利便性とのバランスですが)

いちおうチケットは出しておいたので修正されるのを待ちたいと思います。

クエリ文字列のセッションIDはクッキーには出力されない

  • 2007-05-10 (木)
  • PHP
この記事の所要時間: 145

セッション固定化(Session fixation)を調べている時に気づいたのですが、PHPではクエリ文字列内のセッションIDはクッキーとしては出力されないんですね。

良くセッション固定化で例に挙げられるが下のような例です。

  1. 攻撃者がセッションID付きURL[http://example.com/?PHPSESSID=abcd]をユーザAに踏ませる
  2. ユーザAのセッションが[セッションID=abcd]で生成される。
  3. ユーザAがログインする。
  4. 攻撃者が[セッションID=abcd]でアクセスするとユーザAがログイン済みの状態になっており、セッションを乗っ取る事ができる。

これ自体はもちろんそうなのですが、PHPではクエリ文字列に含まれるセッションIDでセッションは生成されますが、クッキーにそのセッションIDは出力されません。(PHP5.2.1のext/session/session.cを見るとそんな感じの実装です。)

2.の状態ではサーバ上に[セッションID=abcd]のセッションは存在しますが、そのセッションIDはクライアント側には知らされません。

3.でログイン情報をクライアントからサーバにPOSTで送信しますが、クライアントは2.でセッションIDの通知を受けていないので、セッションIDは送信しません。なのでサーバ上では新規セッションとして新しいセッションIDが生成されます。

その後、4.のように攻撃者が[セッションID=abcd]でアクセスしても、ログイン前のセッション(空のセッション)を参照するだけなので、当然ながら要ログインな画面へはアクセスできません。

つまり単純にセッションID付きURLを踏ませても、認証セッションを乗っ取るのは難しいのかなと。(かといってセッション固定化対策が不要なわけでは無いのであしからず。)

※これはセッションIDの受け渡しにクッキーを使っている場合の話です。携帯のようにクエリ文字列でセッションIDの受け渡しを行う場合は、例の手順でセッションを乗っ取ることができます。

Wiiリモコンが反応しない

この記事の所要時間: 050

Wiiを起動したところリモコンが反応しなくなったのでメモ。

症状はWii本体起動時から何を押してもリモコン下部のインジケータがちかちかするのみで画面は反応しないというもの。当然ながら画面にはカーソルが出てきません。

Googleで検索して、本体<->リモコンをSyncしたり、リモコンを手で叩いたりしてみたのですが改善せず。

で、見つけたのが↓

開発の当初は、蛍光灯の光に反応してしまうことがあったり、予想外のことがたくさんありました。蛍光灯や、太陽光に反応しにくくする仕組みというのは地味なところではありますけど、そうとう苦労したところです。

(任天堂総合開発本部 開発部 開発第5グループ 池田 昭夫 氏)

Wii 最大の敵は日光 – Engadget Japanese

夜だったんで日光は無いですが、念のため蛍光灯を切って本体<->リモコンをSyncすると無事解決しました。

Syncする時は蛍光灯を切るのが良いかと。

Twitter検索がRSS対応になりました

この記事の所要時間: 037

既にお気付きかと思いますが、Twitter検索がRSS対応になりました。

キーワード検索の検索結果をお好きなRSSリーダーで見ることができます。

同じキーワードを定期的にチェックしたい方は活用してみてください。

↓のような使い方が面白いかも。

  • 自分のユーザ名で検索。
    =>自分宛に書いた投稿をチェック
  • 気になるキーワードで検索。
    =>キーワードに合致する投稿をチェック
  • でも検索結果が0。
    =>いつか誰かが書くかもしれないので、いちおうRSS購読(by @jazzanovaさん)

RSS対応の背中を押して下さった@nitoyonさん、@otuneさんありがとうございました。

ITmediaでTwitter検索/Twitterで暇つぶしが紹介されました。

この記事の所要時間: 025

ref:ITmedia Biz.ID:Twitterでゴールデンウィークのヒマをつぶす

ITmediaでTwitter検索Twitter で暇つぶしが紹介されました。

昨日ちょうどアクセスログを眺めている時にリファラで知りました。;-) やはりこうやって取り上げて貰えると嬉しいですね。

特に暇つぶしが取り上げられたのが嬉しかったり。

どちらのツールも登録等せずに誰でも使えるので、お暇な時にお試し下さい。

CakePHP モデルのvalidates()に注意

この記事の所要時間: 138

Model#validates()ですが、「ちょっとどうなの?」な仕様になってます。

このメソッドはModel#save()内で自動的に呼ばれるのか、コントローラのアクションメソッド内で呼ばれるのが一般的な使い方だと思います。

問題が起こるのは後者の方で、空の配列をvalidates()に渡すと、Userl#$validateで何を定義していてもtrueが返ってきます。

下のソースならUserモデルの$validateに入力チェックをいれておけば「ng」が表示されそうですが、実はUser#$validateに関わらず「ok」が表示されてしまいます。

<?php
class FooController extends AppController
{
    var $uses = array('User');

    function blank()
    {
        $this->data = array();
        if ($this->User->validates($this->data)) {
            var_dump('ok');
        } else {
            var_dump('ng');
        }

        exit;
    }
}
?>

原因はModel#invalidFields()の以下の箇所にあります。(invalidFields()はvalidates()から呼ばれます)

[cake/libs/model/model_php4.php]

<?php

		foreach($this->validate as $field_name => $validator) {
			if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
				$this->invalidate($field_name);
			}
		}

?>

$dataはvalidates()に渡される連想配列なのですが、$dataに$validateのキーが存在しない場合はpreg_match自体が処理されず、invalidate()にはなりません。

なのでコントローラからvalidates()を呼ぶ時は、$dataにModel#$validateのキーに存在するかを確認する必要があります。

ちなみにModel#save()ではvalidates()の後の処理でfalseが返るようになっています。ただこれも$dataが空の配列の場合の話で、Model#$validateにキーは無い(入力チェックはしない)が、テーブルにカラムがあるキーのみの配列なら通ってしまいます。

例えば下のソースなら「ok」が表示されます。

<?php
    function blank()
    {
        // User#$validate に id が無い場合
        $this->data = array('id' => '');
        if ($this->User->save($this->data)) {
            var_dump('ok');
        } else {
            var_dump('ng');
        }

        exit;
    }
}
?>

やはりこちらも入力チェックするキーが$dataに存在するかを確認するしか無いようです。

CakePHP $_GET/$_POSTの値はどこに?

この記事の所要時間: 348

PHPのスーパーグローバルの値をどのように参照すれば良いかまとめてみました。

Controller#dataやアクションメソッド引数のようにフレームワークで想定された使い方をしている分には特に問題無いのですが、ちょっと他のことをやろうとすると、どこに値が格納されているか分からず困った事がありました。

# もちろん$_GET/$_POSTを使えば値は取れますが、せっかくのフレームワークなのでなるべくその中で値を使いたいものです。

1. $_GET

$_GETの値はController#params[‘url’]に格納されます。
ちなみに$_GET[‘url’]はURLルーティング(リクエストURIからコントローラ・モデル等を決定)で、$_GET[‘file’]は[app/webroot/js/vendors.php]で参照されています。

[http://example.com/foo/index/?id=1&code=abcd&offset=10]でアクセス

<?php
class FooController extends AppController {
  function index() {
    // $this->params['url']['id'] => 1
    // $this->params['url']['code'] => 'abcd'
    // $this->params['url']['offet'] => 10
  }
}
?>

2. $_POST

$_POSTの値はController#params[‘form’]に格納されます。
なお中でも$_POST[‘data’]は特別で、Controller#data/Controller#params[‘data’]にも格納されます。

[id=1&name=abcd&comment=Hello!!&data[Foo][name]=Bar]をPOST

<?php
class FooController extends AppController {
  function index() {
    // $this->params['form']['id'] => 1
    // $this->params['form']['name'] => 'abcd'
    // $this->params['form']['comment'] => 'Hello!!'

    // 以下3つは同じ
    // $this->params['form']['data']['Foo']['name'] => 'Bar'
    // $this->params['data']['Foo']['name'] => 'Bar'
    // $this->data['Foo']['name'] => 'Bar'
  }
}
?>

3. $_COOKIE

$_COOKIEの値を参照する方法は用意されていません。もし$_COOKIEの値を使用する場合は直接参照するしかないようです。
ちなみにフレームワーク側はCakeSessionクラスがこの値を参照しています。

4. $_FILES

$_FILESはおおよそ$_POSTと同様にキーによって格納される場所が異なります。

まず$_FILES[‘data’]以外の箇所についてですが、これは$_POSTと同じようにController#params[‘form’]に格納されます。

つぎに$_FILES[‘data’]ですが、こちらは$_POST[‘data’]と同じようにController#data/Controller#params[‘data’]に格納されます。ここでは$_FILES[‘data’]がそのまま格納されるわけではなく、下のソースのように[$model][$field][$key]の連想配列に値を格納されます。

[cake/dispatcher.php:340]

		if (isset($_FILES['data'])) {
			foreach ($_FILES['data'] as $key => $data) {

				foreach ($data as $model => $fields) {

					foreach ($fields as $field => $value) {
						$params['data'][$model][$field][$key] = $value;
					}
				}
			}
		}

$_POST[‘data’]の場合と異なり、$_FILES[‘data’]の値はController#params[‘form’]には格納されません。

なお、$_FILESの格納処理は$_POSTの値が格納された後に行われます。つまり$_POSTと$_FILESが同じキーを持つ値は$_FILESの値で上書きされてしまいますのでご注意を。

5. $_ENV/$_SERVER

$_ENV/$_SERVERの値は[cake/basics.php]にあるenv()関数で参照できます。
どちらの変数にも同じキーで値がある場合は、$_SERVERの値が優先され、次に$_ENVの値になります。双方に該当するキーが無い場合はgetenv()の値が返ります。(全てのキーが無ければnullが返ります。)

<?php
class FooController extends AppController {
  function index() {
    $_SERVER&#91;'foo'&#93; = 'server';
    $_ENV&#91;'foo'&#93; = 'env';
    putenv('foo=getenv');
    // server を出力
    var_dump(env('foo'));

    unset($_SERVER&#91;'foo'&#93;); 
    // env を出力
    var_dump(env('foo'));

    unset($_ENV&#91;'foo'&#93;); 
    // foo を出力
    var_dump(env('foo'));
  }
}
?>

6. $_REQUEST/$_GLOBALS

$_REQUEST/$_REQUESTの値は特に参照する方法は用意されていません。フレームワークでも参照している箇所は見当たりませんでした。

Twitterで暇つぶし

この記事の所要時間: 040

またまたTwitterネタ。

Twitter 検索某ネタのおかげで好評でした(@ieiriさん、ありがとうございました)ので、調子に乗ってこんなのも作ってみました。

Twitter で暇つぶし : みんな何してる?
twitter_viewer_qr.jpg

携帯でTwitterのステータス(投稿)を見るだけのサイトです。

外出している時に携帯でTwitterを見ていると意外と更新されずに何度もリロードする事ありません?

Friendsをバンバン増やせば良いのでしょうけどあまり増やしすぎると今度PCで見るときがつらかったり。

知らない人のステータスをただ見るだけなのですが意外と面白かったりします。

登録等は一切不要なので「Twitterって聞くけど、何?」な方も一度どうぞ。

Home

検索
フィード
メタ情報

Return to page top