LVMでファイル消しちゃったときの復旧方法(VM利用を前提)

実は…VMのLinux上で開発してたときに間違ってファイルを消してしまいました(爆)
調べてたら、extundeleteってのがありますので、それに頼りました。(ちなみにext3,ext4が対象です)
しかも、(CentOSのせた)LVM(論理ボリューム)なので、さらに厄介です。

まず、やっちまったLinux上でrunlevelを1にします。1になったところですかさずshutdown。

su
telinit 1
shutdown

そして、対象のハードディスクのイメージを安全な場所にコピーします(バックアップ)。

次に、LVMをマウントしてないLinuxを1つ用意します。
(ちなみに私のとこでは、別にDebianの環境があったので、それを使いました)
このマシンにさきほどの(復旧したい)ディスクイメージをつなぎます。
そしてそのマシンに、extundeleteを入れます。
C++と、ext2fsライブラリがいります。Debianだとこれで入ります。

aptitude install g++
aptitude install ext2fs-dev

extundeleteを展開し、configureしてmakeします。

bunzip2 -c -d extundelete-0.2.0.tar.bz2 | tar xvf -
cd extundelete-0.2.0
./configure
make
make install

デフォルトでは、LVMはマウントされてないはずなので(dfしてみてマウントされてなかったら大丈夫)、これからLVMの確認作業です。
pvscanで、いま繋がってるLVMのPhysical Volume一覧がでてきます。

pvscan

vgscanで、いま繋がってるLVMのVolume Group一覧がでてきます。デフォルトで「VolGroup00」とか出るあれです。

vgscan

lvscanで、論理ボリューム(Logical Volume)一覧がでてきます。

lvscan

いづれも、引数なしでOKです。

これで、LVMの VolumeGroup と LogicalVolume がわかると思います。
デフォルトは「VolGroup00」、「LogVol00」のはず。

これまでの /dev/sda1 と同じようなデバイス指定方法だと、

/dev/VolGroup00/LogVol00

みたいなかんじになります。

わかったところで、extundeleteを実行します。

extundelete --after (エポック時間) --restore-all /dev/VolGroup00/LogVol00

「エポック時間」は、time(2)で返される、1970年1月1日0時ジャストからの経過秒数です。
これで、指定時間「以降」に削除されたファイルが復元されます。

ま、LVMでも仕組みわかれば従来のファイルシステム同様に扱えるわけで。

とりあえず。
ひさびさに、マジで心臓に悪い思いをしました…。

とりあえず、一番大事なことは

  • 落ち着く
  • 容赦なく落とす
  • バックアップをとる

こんだけ。

参考にしたサイト

Perlでリモートのsyslogサーバにsyslogを送りつける

CPANのSys::Syslogを使えば一発。

リモートのsyslog(UDP経由)を受けられるsyslogdが稼働してるホストを loghost として。

#!/usr/bin/perl

use Sys::Syslog ;
use Sys::Syslog qw(:standard :macros) ;

Sys::Syslog::setlogsock( "udp" , "loghost" ) ;

Sys::Syslog::openlog( 
         'testsyslog33' ,
         'nowait' ,
         'local0' ) ;

Sys::Syslog::syslog( 'info' , "homu!homu!homuhomu!" ) ;

Sys::Syslog::closelog() ;

こんなかんじで書けば、loghostのsyslogdにこんなかんじで出てくる。

Nov 24 09:31:56 localhost.local testsyslog33: homu!homu!homuhomu!

FacilityとLevelについては適当にやったけど、このへんはRFC3164とか見てくれ。
(ってかsyslog扱うんならこのへん知ってる前提で)

Zend Frameworkで何か作ってみた(参考にしたサイトメモ)

単なるリンク集です…。
初めて扱ったので、そのために参考にしたサイトを載せておきます。

●本家

●基本

●今回はすっ飛ばしたけど、読んでおいて欲しいmodelのはなし。

CakePHPでは標準ではActiveRecordを採用していると思いますが、ここがCakePHPやsymfonyで学習してきた人が一番最初に戸惑う部分ではないかと思います。

Zend Frameworkのメイン開発者の方のコメントとして、Model !== Databaseだという主張が明確に述べられています。

正直、ここ、この概念で一番はまりました。
まさに、ずっとCakePHPやsymfonyでやってきたので(^_^;
実は今回はmodelは使ってません。

●データベース

●フォーム

formに関してはsymfonyのsfFormみたいなかんじでやる方法もあるけど今回は割愛。

●レイアウトとビュー

●ルーティング

●環境依存

public/index.phpで、set_include_path()することで解決。
余談ですが、ヘテムルだと「CLIの」phpを実行するとPHP4が呼ばれるので、bin/zf.shのPHP CLIパス検索処理部分で「php」になってるところを「php5」にしてください(合計3つ)。

# find php: pear first, command -v second, straight up php lastly
if test "@php_bin@" != '@'php_bin'@'; then
    PHP_BIN="@php_bin@"
elif command -v php5 1>/dev/null 2>/dev/null; then
    PHP_BIN=`command -v php5`
else
    PHP_BIN=php5
fi

●そんでもって。

作ったのが、「●●少女まどか☆マギカ(タイトルジェネレータ)」です。
アイディアそのものは2日ほど前に漠然と浮かんでて、実装は今朝考えました。10時くらいからとりかかって、Zend Frameworkのドキュメントを読みながら15時くらいにはできあがりました。
各種サイトを読んでからというよりは、読みながら必死になって書いたほうが案外なんとかなったというか…。

今回は、魔法少女まどか☆マギカだけのになりましたが、他のも簡単に作れるように今後コードを追加する予定。
(そのときは名前変えて新しくリリースの予定)

symfony : はじめてのsfForm

この記事はSymfonyアドベントカレンダー2010の22日目です

はじめに…の前に

symfonyに関わるようになってから半年くらいたちます。
思いっきり、仕事で関わってます。
実際使い始めて、「書きやすい」「扱いやすい」「自分に合ってる」というかんじでしたね。
自社開発ではほとんどがsymfony(1.4)での開発となっております。

他のみなさんの記事は、Symfony2だったり高度な記事が多くてちょっとびびってますが、敢えて初心に戻って(私が割と混乱してた)symfony1.4のフォームについて書いてみたいと思います。

はじめに

symfony 1.4になってから、フォームまわりがsfFormクラスからの生成のみとなり、input_tagとかいったものが使えなくなりました。
DRY的考え方だと「フォームもDon’t Repeat Yourself」で理にかなってるのですが、おそらくなじめない方も少なからずいるんじゃないかなと思います。
私のサイトのアクセスログを見ていると、「symfony 1.4 input_tag」での検索がぼちぼち来ていますので、この変更に混乱してるかたも少なからずいらっしゃるんだろうな、と思いまして、input_tagが使えない1.4以降のフォーム周りの基本的な話をしてみようかと思います。

考え方

フォームも1つのクラスとして考えます。
クラスとして定義することにより、使い回すことを想定しています。
module、template、form classの関係は下記の図のようになります。
2010122201

実際の扱い

(sfFormクラスの派生の)BaseFormをベースとしたformのクラスを生成します。
ファイルの場所は基本、 lib/form/ 以下となります。
このクラスで、フォームの部品やvalidationの定義します。
これらの定義は、configure()メソッドで行います。

簡単な例:まずは1つのテキストボックスで

1つのテキストボックスを持つフォームのクラスを定義する場合、下記のようになります。
ファイル名 SimpleForm.class.php です。

class SimpleForm extends BaseForm
{
  function configure()
  {
    $this->setWidgets(array(
        'intext' => new sfWidgetFormInputText() ,
    ));
  }
}

setWidgetsで、引数にフォームのウィジェットを定義した配列を与えてあげます。

これを実際のフォームとして表示するには、
・moduleのaction class内でこのformのインスタンスを作る
・templateで表示処理を書く

module(action.class.php)ではこうします。

function executeIndex(sfWebRequest $request)
{
  $this->form = new SimpleForm() ;
}

これに対応した、template(IndexSuccess.php)での表示処理はこうなります。

<form action="do.php" method="POST">
<table border="1">
<?php echo $form ; ?>
<tr><td colspan="2"><input type="submit" value="ぽちっとな"></td></tr>
</table>
</form>

$form だけの場合、レイアウトはデフォルトのままになります。
表示結果はこうなります。
2010122203

自身でレイアウトしたい場合、inputタグ該当部分は以下のように render() を使います。

<?php echo $form['intext']->render() ; ?>

スタイルを設定したい場合などは、render()の引数に配列で与えます。

<?php echo $form['intext']->render(array('style'=>'width:300px;')) ; ?>

フォーム系タグとウィジェットの対応

使いたいタグと、指定するウィジェットは下記のようになります。

input-text

<input type="text" ...>

$w = new sfWidgetFormInputText();

input-password

<input type="password" ...>

$w = new sfWidgetFormInputPassword();

input-hidden

<input type="hidden" ...>

$w = new sfWidgetFormInputHidden();

textarea

<textarea>
</textarea>

$w = new sfWidgetFormTextarea();

select(プルダウン)

<select>
 <option value="1">select 1</option>
 <option value="2">select 2</option>
 ...
</select>

static $choicelist = array('1'=>'select 1','2'=>'select 2',...);
$w = new sfWidgetFormSelect(array('choices'=>$choicelist));

radio(ラジオボタンセレクト)

<input type="radio" value="1">choice 1
<input type="radio" value="2">choice 2
...

static $choicelist = array('1'=>'select 1','2'=>'select 2',...);
$w = new sfWidgetFormChoice(array('choices'=>$choicelist));

主に使うのはこのへんでしょうか。

バリデーターを使ってみる

Formクラスのconfigure()メソッド内で、setValidatorでセットします。

class SimpleForm extends BaseForm
{
  function configure()
  {
    $this->setWidgets(array(
        'intext' => new sfWidgetFormInputText() ,
    ));
    $this->widgetSchema->setNameFormat('data[%s]');
    $this->setValidators(array(
                                'intext'=>new sfValidatorString(),
                         )) ;
  }
}

setValidatorの引数に連想配列でvalidatorクラスをセットします。

2つめのsetNameFormatは、名前のフォーマットを指定します。
この場合、「 data[intext] 」のような形になります。
バリデーション処理でバインドするとき(後述)にここの名前を使います。

話を元に戻して。
sfValidator〜 (validatorスキーマ)では、引数でvalidationの設定を行います。
以下の場合は、intextが必須でなくなります。

'intext'=>new sfValidatiorString(array('required'=>false)),

以下のようにすると、intextが必須になり、抜けていた場合は「intextは必須です。」のメッセージを返すようになります。

'intext'=>new sfValidatiorString(array('required'=>true),
                                 array('required'=>'intextは必須です。')),

validationにはねられた場合のエラー表示は、template内で下記のようにします。

<?php echo $form['intext']->renderError(); ?>

validatorのスキーマは文字列や数値、日付以外にも、Eメールなどいろんな種類があります。
多いのでここでは説明を割愛します。詳しくは下記にまとまってます、
symfony Forms in Action | 付録 B – バリデーター | symfony | Web PHP Framework

実際にバリデーションを行う、action.class.phpでは、以下のようにします。

    $form = new SimpleForm();
    $form->bind($request->getParameter('data'));

    $v = $form->isValid() ;
    if ( $v ) {
      // validation 成功
      $intext = $form->getValue('intext') ;
    }
    else
    {
      // validation 失敗の処理
    }

流れとしてはこうです。
1.フォームのクラスを作る
2.バインドする (form class内でsetNameFormatした名前を当てる)
3.バリデーションする

また、バリデーションを設定すると、デフォルトでCSRFチェックを行います。
自分でフォームをレンダリングする場合、template内で以下のようにCSRF対策用トークンを追加してあげてください(hiddenで渡されます)。

<?php echo $form['_csrf_token']->render(); ?>

どうしてもvalidationに失敗してしまう場合、多分これが抜けてる可能性があります。

最後に

フォームに関しては公式のsymfony Forms in Action | symfony | Web PHP Frameworkにいいまとめがあるのですが、少し読みづらいかんじがしました。
「とりあえず動くもの」を示してみて、そこから入っていけるためのとっかかりになってくれればなあ、と思いまして、記事を書いてみました。

参考

Symfony Advent 2010について

Symfony Advent 2010では12月1日から12月24日までを使って日替わりでsymfonyでイイなと思った小さなtipsから内部構造まで迫った解説などをブログ記事にして公開していくイベントです。

ffmpegのインストール (MacOS Xへ)

メモ。
ffmpegを入れる必要が出たので。

当然ながら野良ビルド。
もちろんXcode入れてる前提で。

$ tar xvfz ffmpeg-0.6.1.tar.gz
$ cd ffmpeg-0.6.1
$ ./configure
$ make
$ sudo make install

最終的に、which ffmpegしてインストールされてるかを確認。

「パーフェクトPHP」がよかった件

先日買いました。

はっきり言うと「レベルが高い」…けど「必要なことはすべて書いてある」。
でも、個人的には超がつくおすすめの1冊。
今、PHPプログラマとして働きたい人には是非読んで欲しいと思ってます。
(ちなみに私の会社では必読書にしたいと思ってます、そのくらいね)

読み方としては、「書いてあることを全部理解する」ことはしないほうがいいと思う、特に初心者は。
まず一通り目を通しておく。とにかく、どんなことが書いてあったかを頭に入れておく。
書いてある内容を理解という意味ではその次でいいと思う。

そういえば。
PHPってバージョン3の頃から触ってたなあ、と。
最初に入社した会社のときでした。10年くらい前かな?

CentOS 5.5でPHP5.2.x

yumで入れるとPHP 5.1.xになっちゃうので、symfony 1.4を動かせなかったり、いろいろ不都合が多くて、ね。

ちなみに。
さくらのVPSさくらインターネットさんの専用サーバ エントリーのOSのバージョンがまさにこれなんで、思いっきりぶちあたりました。
多分今後参照する人が増えると思うので、メモがてら。

対策としては2つあります。

(1)根性で野良ビルド

私はこれでやりました。ちなみに5.2.14。
慣れないと難しいけど最強な方法。
逆を言うと「–with-apxs2ってなにそれ?」って人は絶対にやっちゃだめ。

参考までに私のとこでの configure 設定例を載せておきます。
php -i した結果です。

コンパイル環境や開発用のライブラリをyumコマンドで前もっていれておく必要があります。

manaka(専用サーバのほう)

Configure Command => ‘./configure’ ‘–prefix=/usr’ ‘–with-apxs2’ ‘–with-mysql’ ‘–with-pdo-mysql’ ‘–enable-calendar’ ‘–with-curl’ ‘–enable-mbstring’ ‘–with-mcrypt’ ‘–with-ncurses’ ‘–with-gd’ ‘–with-t1lib’ ‘–with-zlib’ ‘–with-png-dir=/usr/lib’ ‘–with-jpeg-dir=/usr/lib’

nene(VPSのほう)

Configure Command => ‘./configure’ ‘–prefix=/usr’ ‘–with-libdir=lib64’ ‘–with-apxs2’ ‘–with-mysql’ ‘–with-pdo-mysql’ ‘–enable-calendar’ ‘–with-curl’ ‘–enable-mbstring’ ‘–with-mcrypt’ ‘–with-ncurses’ ‘–with-gd’ ‘–with-zlib’ ‘–with-png-dir=/usr/lib’ ‘–with-jpeg-dir=/usr/lib’

VPSのほうは64bitなんで、’–with-libdir=lib64’が要ります。これ注意ね。

(2)パッケージを利用する

野良ビルドがわからない人向け。(できればこのほうをおすすめしたい)
yumでリポジトリを明示的に指定してする方法です。
「centOS 5.5 PHP 5.2」で検索するとこちらの方が圧倒的に多いですね。

位置情報取得と測地系のあれこれ

iPadで位置情報取得

iPadで位置情報をとりたかったので、書いてみた。

<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type="text/javascript">
<!--
function getpos(position){
 posstr = "Lon=" + position.coords.longitude + 
          " / Lat=" + position.coords.latitude ;
 alert(posstr);
}
function getposi(){
 navigator.geolocation.getCurrentPosition(getpos);
}
//-->
</script>
</head>
<body>
<a href="#" onClick="getposi();">POSITION</a>
</body>
</html>

geolocationって、iPadやiPhoneだけじゃなくて、FireFoxでもとれるのね。
ちなみに世界測地系。

参考:Geolocation API Specification

ちなみに、Androidでも似たようなかんじで取得できる。
これに関しては参考になるページがあったので紹介。
Android携帯でブラウザから緯度経度情報を取得 – PHP,MySQL,Flexな日々+イラストとか

日本測地系と世界測地系

実は400m程度ずれてるので補正が必要。
これに関しては「日本測地系」「世界測地系」で調べればいっぱい出てくる。
APIによって測地系が違ったりするので、このへんは変換が必要。

参考になりそうなとこ。

doctrineでちょい複雑なクエリをつくってみる

3つくらいのテーブルを結合した結果を出力したいとき。
たとえば、こーんなSQLの結果が欲しいとき。

SELECT 
p.id , p.pcs , p.price , u.text , y.name
FROM
Price as p , Update as u , User as y
WHERE
p.shop_id = $shopid
and p.item_id = $itemid
and p.id = u.id
and u.user_id = y.id
ORDER BY p.create_time desc
LIMIT 10

こんなかんじにかきます。

    $q_plistshop =
      Doctrine::getTable('Price')
      ->createQuery('p')
      ->addFrom('Update as u')
      ->addFrom('User as y')
      ->select('p.id,p.pcs,p.price,u.text,y.name')
      ->where('p.shop_id =  ' . $shopid )
      ->andWhere('p.item_id = ' . $itemid )
      ->andWhere('p.id = u.id')
      ->andWhere('u.user_id = y.id')
      ->addOrderBy('p.create_time desc')
      ->limit(10) ;
    $this->plistshop = $q_plistshop->execute(array(),Doctrine::HYDRATE_NONE);

一見、 $q_plistshop->fetchArray() でいけそうだけど(うまくハイドレーションできんぞ?とかで)怒られる。
いろいろ調べた結果、「Doctrine::HYDRATE_NONE」するとうまくいくっぽい。
この場合、$this->plistshop[数字]じゃないととれないので注意。
あと、勝手に列の順番を並べ替えられたりする(アルファベット順?)のでそのへんも注意。

……まてよ?

p.id as id1 , p.pcs as pcs , ... 

というふうに明示的に名前指定すればハイドレーション関係で怒られずにすむかもしれない。
Doctrineがこのへんで混乱してたようなメッセージ出してた気がするので。

ぶっちゃけ、よくわからん。
このへん、も少し勉強する必要ありそうですね。

参考

symfonyでメールを送る(かなり強引編)

プラグインとか使おうとして挫折したので力業編。
お世辞にも美しくないですがこれで動いてるので。
正直言って「よい子は真似しちゃだめだよ」レベルです :D

なお、mailsendSuccess.php は HTML ではなくplain textで書きます。
単にrequire してるので、$this->foo = $bar ; とかしないで $foo = $bar でいい。
それと、そもそもmailsendSuccess.php って名前は不適切かもしれない。

function Mailsend()
{
    ob_start();
    require '../apps/アプリ名/modules/モジュール名/templates/mailsendSuccess.php';
    $body = ob_get_contents() ;
    ob_end_clean();
    ob_start();         // symfony側にout bufferを渡す

    // $body = "テスト" ;
    $mailto = $this->rgdb->getEmail() ;
    $header  = "From: =?ISO-2022-JP?B?" . base64_encode(mb_convert_encoding("テストさん","iso-2022-jp","utf-8")) . "?= <info@example.com>\n" ;
    $header .= "Mime-Version: 1.0\n" ;
    $header .= "Content-Type: text/plain; charset=iso-2022-jp\n" ;
    $header .= "Content-Transfer-Encoding: 7bit\n" ;
    $subject = "=?ISO-2022-JP?B?" . base64_encode(mb_convert_encoding("お知らせ","iso-2022-jp","utf-8")) . "?=" ;

    mail($mailto,$subject,mb_convert_encoding($body,"iso-2022-jp","utf-8"),$header,'-f info@example.com') ;
}

Ruby Twitter Gem(とRuby OAuth Gem)のバージョンが変わったら動かなくなった件

前回までの話
Ruby Twitter GemでOAuth認証のクライアントを作る

サーバの移行でバージョンが変わりました。
すると、こーんなエラーが出て動かなくなりました。

/usr/local/lib/ruby/gems/1.8/gems/oauth-0.4.3/lib/oauth/client/helper.rb:64:in `amend_user_agent_header’: uninitialized constant OAuth::VERSION (NameError)

いろいろ調べた結果、こうするのが正解だったようです。

「クライアントプログラム側でOAuth::VERSIONを定義する」
定義してないプログラム用に、〜/oauth/version.rb を作成しました

OAuth::VERSION = "0.4.3"

これをやったあと、クライアントプログラムでOAuthまわりの部分に1行追加

gem 'oauth'
require 'oauth/consumer'
require 'oauth/version'         # ← これを追加!

Ruby twitter gemを使ってる場合は、この追加は不要です。このまま。

gem 'twitter'
require 'twitter'

以下は、「まいんぼたん」的変更。
twitter gem の0.9.12でupdate時にJSON処理まわりで例外を吐いてしまうようなので、rescueで強引に対策。

tw_oauth = Twitter::OAuth.new( OAUTH_CONSUMER_KEY , OAUTH_CONSUMER_SECRET )
tw_oauth.authorize_from_access( oa_token  , oa_secret )

client = Twitter::Base.new(tw_oauth)
begin
   res = client.update( in_post )
rescue
   reserr = 1
end

参考:Togetter – 「RubyでOAuthをごにょごにょ」

SSL証明書のインストール(CentOS)

ここを参考にした。
CSRの作成方法 (Apache+ModSSL)
SSL証明書のインストール方法

キーや関係ファイルは /etc/httpd/conf 以下にフォルダ作ってそこにまとめた。
今回は証明書の関係から1024bitのキーを作った。
(が、これからは2048bitなんで注意。→どういうことかは「SSL 2010年問題」でググってみるべし)

cd /etc/httpd/conf/ssl.key
openssl genrsa -des3 -rand ファイル名 1024 > mydomain.key.with_pass

※ファイル名のとこは乱数の種にするので、適当なファイルにすればいい。アクセスログとか。
※2048bitの鍵の場合は、1024を2048にすればいい。
鍵ファイルにかかったパスワードを解除します。

openssl rsa -in ./mydomain.key.with_pass -out ./mydomain.key
rm mydomain.key.with_pass
chmod 600 mydomain.key

んで、CSRの作成。

cd ../ssl.csr
openssl req -new -key ../ssl.key/mydomain.key -out ./mydomain.csr
chmod 600 mydomain.csr

このCSRファイル(mydomain.csr)を認証局に送ります。

認証局から証明書(crtファイル)が来ますので、それをインストールします。
入れる場所は /etc/httpd/conf/ssl.crt/ とします。
私が使ったとこは中間証明書も必要だったので、これは /etc/httpd/conf/ssl.ca/ に置くこととします。
CentOSなら、 /etc/httpd/conf.d/ssl.conf にすでに設定がありますんで、これをなおします。

SSLEngine on
# キー
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/mydomain.key
# 証明書
SSLCertificateFile /etc/httpd/conf/ssl.crt/mydomain.crt
# 中間証明書
SSLCACertificateFile /etc/httpd/conf/ssl.ca/cacertificate.ca

これだけです。
あとは、

# /etc/init.d/httpd restart

で再起動するだけ。

念のため https://mydomain/ でアクセスして証明書の情報を確認すること。

CakePHP、規定内/外の呼び方チートシート

コンポーネントやヘルパーなどからモデル等を呼び出すときに何を使えばいいかの表。
2010062901
黄色は普通のやりかた。紫色が普通じゃないやりかた。灰色は知らない。
とりあえず、
・「コンポーネントからモデル」「ヘルパーからモデル」の場合、邪道な方法を使う
・「コンポーネントからコンポーネント」は普通に var $components = … で宣言しておけばいい
・「ヘルパーからヘルパー」も同様に var $helpers = … で宣言しておけばいい

symfony 1.4 ではまったことメモ

多分何人か同じ過ちを犯すと思われるので(笑)
なかにはsymfony関係ねー、ってのもありますがそこはご愛敬ってことで勘弁を。

(1)とりあえず…symfonyの最初の画面が拝めないです。なんというか、/path/to/symfony/web がない。

$ ./symfony generate:project myproject
$ ./symfony generate:app frontend
$ ./symfony generate:module frontend default

最悪、これで frontend の default で、web フォルダにアクセスすれば、 symfonyの画面が見えるはず。

(2)途中に web とか入るのがださいです
→ Apacheの DocumentRoot を、 /path/to/symfony/web/ とすればいいです。

(3)input_tag を使おうとすると undefined function になる
→これはエラーメッセージではなく、正しくは以下の内容です。
「えーマジinput_tag!?キモーイ」
「FormHelperが許されるのは1.3までだよねキャハハハハh」
元ネタ
…そんなわけで、1.4からFormHelperがdeprecatedになっちゃったので、sfFormだけです。頑張りましょう。
symfony Forms in Action | symfony | Web PHP Framework あたりの説明が役に立つと思います。

(4)devではちゃんと動いてたのにprodにした途端、画面が真っ白になったり、動かなくなったりする。
→とりあえず、 symfony cc してみましょう。
参考:dev環境からprod環境に変えると動かなくなる時の対処方法 « symfonyで開発日記

(5)/backend/ としたいのに /backend.php/ でしか動かせない
→ ApacheのMultiviewの設定。 .htaccess に Options MultiView を追加するなどすればOKです。

あとで追加予定。

hetemlで共用ssl(https)でcakephpを使う方法

先日ログを見たところ、検索キーワードランキングでダントツの1位で「cakephp heteml ssl」とかきてました。
該当記事がなかったので大変申し訳ございませんでした。
と同時にこれは書け、ということなので、一応書いておきます。
(この前ようやくうまくいったんで)

・・・ま、いろいろ頑張った結果、こうするしかなかったです。


--- A/webroot/index.php      2010-06-05 21:34:15.000000000 +0900
+++ B/webroot/index.php   2010-06-06 12:42:34.000000000 +0900
@@ -78,6 +78,12 @@
                        define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
                }
        }
+       // define img/css/js
+       define ( "URLBASE" , "/../自分のユーザー名/ディレクトリ/" ) ;
+        define('IMAGES_URL', URLBASE . 'img/');
+        define('CSS_URL', URLBASE . 'css/');
+        define('JS_URL', URLBASE . 'js/');
+
        if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
                trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
        }

URLBASE、IMAGES_URL、CSS_URL、JS_URLを webroot/index.php で変更するしかなかったです。
しかもURLBASEを相対パスで書かなければならないという。