Shin x blog
第24回PHP勉強会に参加してきました。
第24回PHP勉強会
第24回PHP勉強会に参加してきました。詳細なレポートはshimookaさんのところにあるので;-)、ざっくりと感想を。
extensionがアツい!
最近はフレームワークに注力してたのであまり追いかけてなかったのですが、やはり動いているモノ(ミサイルw)を見ると引き込まれます。以前少しだけCを書いていた時期があるのでバイナリアン系のネタは聞いているだけで楽しいです。
既に完成しているライブラリをPHP化するなら、ネタも色々ありそうなので何かやってみたいですね。単純に「extension作れる=かっこいい」というのもありますし。;-)
携帯+PC連携
内容とは微妙に違いますが、前から思っていたのが「汎用テンプレートって無いのか?」ということ。PHPだろうがPerlだろうがPythonだろうがRubyだろうが・・・テンプレートエンジン使うんだったら同じ書式のテンプレートを使ったら良いのに。
開発者側はそれぞれ覚えれば良いですが、デザイン側にそれを押しつけることはできないので結局今いる環境から動けない、なんて人もいる気がします。(実際それで新しいものを取り入れるのを躊躇したり。)
たとえばSmartyで書いたテンプレートが他の言語でも使えるとかで良いわけです。(うーん作ってみたいな。。。)
見える化
まさに一見にしかずです。上手く説明できないですが、できたものを見るとなぜかわくわくします。自然と「おー」と声が出ます。何か上手く使ってみたいです。
ちょっと体調不良だったり、宿難民になったりでいろいろありましたが、参加して良かったです。
会社から言われたわけでなく、自分でわざわざこういった勉強会に参加される方は当たり前ですが学習意欲の高い方ばかりなわけです。そんな方々と自分の興味ある分野で、ああだこうだとお話できたら、楽しくないわけがない!!
日頃、開発は一人でやっているのでとても良い刺激を受けました。また近いうちに参加したいと思うのでよろしくお願いします。:-)
# Twitterで実況してましたが誰も見てない気がしてやめました:-p
# せっかくなんでいちおうログ出しときます。Twitter検索 : @phper
- コメント (Close): 1
- トラックバック: 0
第24回PHP勉強会に参加してきます。
今からPHP勉強会に参加してきます。
shimookaさんがblogで実況されるとの事なので、私はTwitterで実況してみようと思います。
Twitterのアカウントはshin1x1です。
では参加される皆さんよろしくお願いします。
- コメント (Close): 4
- トラックバック: 0
CakePHP Controller#Object()が外部から呼べる
以前あった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できっちりマッピングしておいた方が安全かなあと思ったりします。(まあ利便性とのバランスですが)
いちおうチケットは出しておいたので修正されるのを待ちたいと思います。
- コメント (Close): 0
- トラックバック: 0
クエリ文字列のセッションIDはクッキーには出力されない
- 2007-05-10 (木)
- PHP
セッション固定化(Session fixation)を調べている時に気づいたのですが、PHPではクエリ文字列内のセッションIDはクッキーとしては出力されないんですね。
良くセッション固定化で例に挙げられるが下のような例です。
- 攻撃者がセッションID付きURL[http://example.com/?PHPSESSID=abcd]をユーザAに踏ませる
- ユーザAのセッションが[セッションID=abcd]で生成される。
- ユーザAがログインする。
- 攻撃者が[セッション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の受け渡しを行う場合は、例の手順でセッションを乗っ取ることができます。
- コメント (Close): 1
- トラックバック: 0
Wiiリモコンが反応しない
- 2007-05-06 (日)
- 雑記
Wiiを起動したところリモコンが反応しなくなったのでメモ。
症状はWii本体起動時から何を押してもリモコン下部のインジケータがちかちかするのみで画面は反応しないというもの。当然ながら画面にはカーソルが出てきません。
Googleで検索して、本体<->リモコンをSyncしたり、リモコンを手で叩いたりしてみたのですが改善せず。
で、見つけたのが↓
開発の当初は、蛍光灯の光に反応してしまうことがあったり、予想外のことがたくさんありました。蛍光灯や、太陽光に反応しにくくする仕組みというのは地味なところではありますけど、そうとう苦労したところです。
(任天堂総合開発本部 開発部 開発第5グループ 池田 昭夫 氏)
夜だったんで日光は無いですが、念のため蛍光灯を切って本体<->リモコンをSyncすると無事解決しました。
Syncする時は蛍光灯を切るのが良いかと。
- コメント (Close): 2
- トラックバック: 0
Twitter検索がRSS対応になりました
既にお気付きかと思いますが、Twitter検索がRSS対応になりました。
キーワード検索の検索結果をお好きなRSSリーダーで見ることができます。
同じキーワードを定期的にチェックしたい方は活用してみてください。
↓のような使い方が面白いかも。
-
自分のユーザ名で検索。
=>自分宛に書いた投稿をチェック -
気になるキーワードで検索。
=>キーワードに合致する投稿をチェック -
でも検索結果が0。
=>いつか誰かが書くかもしれないので、いちおうRSS購読(by @jazzanovaさん)
- コメント (Close): 8
- トラックバック: 0
ITmediaでTwitter検索/Twitterで暇つぶしが紹介されました。
ITmediaでTwitter検索とTwitter で暇つぶしが紹介されました。
昨日ちょうどアクセスログを眺めている時にリファラで知りました。;-) やはりこうやって取り上げて貰えると嬉しいですね。
特に暇つぶしが取り上げられたのが嬉しかったり。
どちらのツールも登録等せずに誰でも使えるので、お暇な時にお試し下さい。
- コメント (Close): 3
- トラックバック: 0
CakePHP モデルのvalidates()に注意
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に存在するかを確認するしか無いようです。
- コメント (Close): 6
- トラックバック: 2
CakePHP $_GET/$_POSTの値はどこに?
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['foo'] = 'server';
$_ENV['foo'] = 'env';
putenv('foo=getenv');
// server を出力
var_dump(env('foo'));
unset($_SERVER['foo']);
// env を出力
var_dump(env('foo'));
unset($_ENV['foo']);
// foo を出力
var_dump(env('foo'));
}
}
?>
6. $_REQUEST/$_GLOBALS
$_REQUEST/$_REQUESTの値は特に参照する方法は用意されていません。フレームワークでも参照している箇所は見当たりませんでした。
- コメント (Close): 0
- トラックバック: 0
Twitterで暇つぶし
またまたTwitterネタ。
Twitter 検索が某ネタのおかげで好評でした(@ieiriさん、ありがとうございました)ので、調子に乗ってこんなのも作ってみました。
携帯でTwitterのステータス(投稿)を見るだけのサイトです。
外出している時に携帯でTwitterを見ていると意外と更新されずに何度もリロードする事ありません?
Friendsをバンバン増やせば良いのでしょうけどあまり増やしすぎると今度PCで見るときがつらかったり。
知らない人のステータスをただ見るだけなのですが意外と面白かったりします。
登録等は一切不要なので「Twitterって聞くけど、何?」な方も一度どうぞ。
- コメント (Close): 0
- トラックバック: 0
- 検索
- フィード
- メタ情報
