CakePHPで携帯サイトをいくつか作成してきたが、とりあえずセッションの維持に関してのみ気を付けていることを世にさらしてみる。
(仕事ではこのような技術的なことを自分だけで調査・検討せねばならず、ひょっとすると間違えたことを書いているかもしれませんが、その場合コメント等で暖かく指摘していただけいると助かります)


基本は「クッキー食えないドコモだけ」は use_trans_sid 、他はCookieを使う。
ドコモでも「iモードブラウザ2」の機種は他と同様Cookieが使えるが、単純な文字列比較程度で「iモードブラウザ2」が判定できないため、「ドコモ=クッキー食えない」と単純に判定し処理を簡略化する。(iモードブラウザ2の仕様にはユーザーエージェントが「DoCoMo/2.0」で始まると書かれているが、movaからFOMAに変わった際にすでに「DoCoMo/2.0」になっている。)


config/session_docomo.phpを作成し、

if ($iniSet) {
    ini_set('session.use_trans_sid', 0);
    ini_set('session.serialize_handler', 'php');
    ini_set('session.use_cookies', 1);
    ini_set('session.name', Configure::read('Session.cookie'));
    ini_set('session.cookie_lifetime', $this->cookieLifeTime);
    ini_set('session.cookie_path', $this->path);
    ini_set('session.auto_start', 0);
    ini_set('session.save_path', TMP . 'sessions');
    if (isset($_SERVER['HTTP_USER_AGENT']) && strncmp($_SERVER['HTTP_USER_AGENT'], 'DoCoMo', 6) === 0) {
        ini_set('session.use_trans_sid', 1);
        ini_set('session.use_only_cookies', 0);
        ini_set('session.use_cookies', 0);
    }
    Configure::write('Session.save', 'cake');
}

config/core.phpでセッション維持方法を切り替える。

:
if (isset($_SERVER['HTTP_USER_AGENT']) && strncmp($_SERVER['HTTP_USER_AGENT'], 'DoCoMo', 6) === 0) {
    //Cookie食えないドコモだけ
    Configure::write('Session.save', 'session_docomo');
} else {
    //Cookie食える
    Configure::write('Session.save', 'cake');
}
:

リンクなどはuse_trans_sidで一気に変換してくれるが、リダイレクトに関してはapp_controller.phpなどでredirect()を上書きし、セッションIDが維持できるようにする。

:
    function redirect($url, $status = null, $exit = true, $use_session = true)
    {
        $session_id = session_id();
        if ($use_session && !empty($session_id) && strncmp($_SERVER['HTTP_USER_AGENT'], 'DoCoMo', 6) === 0) {
            $session_name = session_name();
            if (is_array($url)) {
                //$urlが配列の時はQueryStringをキー"?"にセット
                if (empty($url['?'])) {
                    //URLにQueryStringを含まない
                    $url['?'] = $session_name . "=" . $session_id;
                } else {
                    if (strpos($url['?'], $session_name) !== false) {
                        //URL中にセッションIDが含まれる場合、削除する
                        $url['?'] = preg_replace("/(\?|&)({$session_name}[^&]*)($|&)/", "$1$3", $url['?']);
                    }
                    $url['?'] .= '&' . $session_name . "=" . $session_id;
                }
            } else {
                //$urlが配列で無い場合は文字列とみなす
                if (strpos($url, $session_name) !== false) {
                    //URL中にセッションIDが含まれる場合、削除する
                    $url = preg_replace("/(\?|&)({$session_name}[^&]*)($|&)/", "$1$3", $url);
                }
                $hash = '';
                $pos = strpos($url, '#');
                if ($pos !== false) {
                    $hash = substr($url, $pos + 1);
                    $url = substr($url, 0, $pos);
                }
                $url .= (strpos($url, '?') ? '&' : '?') . $session_name . "=" . $session_id;
                if ($hash) $url .= '#' . $hash;
            }
        }
        parent::redirect($url, $status, $exit);
    }
:

(参考)