ffmpeg 使い方

ソースのダウンロードは SVN から

 svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg

 また、Windows バイナリは携帯電話用の動画をなるべく簡単に作りたかったので作ってみた変換君(3GP Converter)に含まれているものを使うのが簡単な方法です(cores ディレクトリ内)。
Windows用バイナリは「お気に入りの動画を携帯で見よう」からダウンロードできます。
他の入手方法についてはこちらの記事を参照してください。
 

 
– MP3 から PCM 形式オーディオファイル out.wav に変換

ffmpeg -i in.mp3 out.wav

 このように指定した場合、入出力ともに拡張子から自動判別します。
 (指定できる拡張子は後述の「対応フォーマット/コーデック一覧」を参照してください)
 ただしデフォルトのままだとビットレートやサンプリングレート等が変わって劣化やサイズ肥大してしまうことがあります。この場合、次のように明示することで任意の画質、音質で出力することが可能です。
 
– Windows Media Audio 形式(WMA)から MP3 形式にビットレート(128kb/s)、サンプリングレート(44100Hz)指定で変換

ffmpeg -i in2.wma -ab 128 -ar 44100 out2.mp3

 
– Flash 動画ファイル(flv)から、音声を抽出してモノラルで MP3 で保存する
( -vn オプションによるビデオ消去, -ac 1 でチャンネル数を1 = モノラルに)

ffmpeg -i in3.flv -vn -ac 1 out3.mp3

  
 
参考:
FFmpeg
 公式.
http://www.xucker.jpn.org/keyword/ffmpeg.html
 aki さんのサイト。日本語でのFFmpeg の情報が豊富です。
 
ffmpeg 対応フォーマット(-f)/コーデック(-acodec, -vcodec)一覧:

(ffmpeg -formats で得られる表示)
それぞれ先頭に D がついているものは入力として指定可能(Decordable),
E がついてるものは出力として指定可能(Encordable)です。
また、Codecs: については、先頭に A がついているものは音声コーデック(Audio Codecs),
V がついているものは動画コーデック(Video Codecs)を指します。

ffmpeg version CVS, build 4759, Copyright (c) 2000-2004 Fabrice Bellard
  configuration: –enable-mp3lame –enable-faac –enable-faad –enable-amr_nb –enable-amr_wb –disable-ffplay –enable-small –enable-memalign-hack –enable-gpl –enable-xvid –enable-dts –enable-a52 –disable-vhook –enable-pthread –enable-x264
File formats:
  E 3g2 3gp2 format
  E 3gp 3gp format
 D 4xm 4X Technologies format
 D RoQ Id RoQ format
 DE ac3 raw ac3
 DE alaw pcm A law format
 DE amr 3gpp amr file format
 DE asf asf format
  E asf_stream asf format
 DE au SUN AU Format
 DE audio_device audio grab and output
 DE avi avi format
 D avs Avisynth script
  E crc crc testing format
 D dts raw dts
 DE dv DV video format
  E dvd MPEG2 PS format (DVD VOB)
 D ea Electronic Arts Multimedia Format
 DE ffm ffm format
 D film_cpk Sega FILM/CPK format
 D flic FLI/FLC animation format
 DE flv flv format
 DE gif GIF Animation
 DE h261 raw h261
 DE h263 raw h263
 DE h264 raw H264 video format
 D idcin Id CIN format
 DE image image sequence
 DE image2 image2 sequence
 DE image2pipe piped image2 sequence
 DE imagepipe piped image sequence
 D ipmovie Interplay MVE format
  E ipod iPod MP4 format
 DE m4v raw MPEG4 video format
 D matroska Matroska file format
 DE mjpeg MJPEG video
 DE mmf mmf format // SMAF 形式オーディオ
  E mov mov format
 D mov,mp4,m4a,3gp,3g2 QuickTime/MPEG4 format
  E mp2 MPEG audio layer 2
 DE mp3 MPEG audio layer 3
  E mp4 mp4 format
 DE mpeg MPEG1 System format
  E mpeg1video MPEG video
  E mpeg2video MPEG2 video
 DE mpegts MPEG2 transport stream format
 D mpegvideo MPEG video
  E mpjpeg Mime multipart JPEG format
 DE mulaw pcm mu law format
 D nsv NullSoft Video format
  E null null video format
 DE nut nut format
 D ogg Ogg
  E psp psp mp4 format
 D psxstr Sony Playstation STR format
 DE rawvideo raw video format
 D redir Redirector format
 DE rm rm format
  E rtp RTP output format
 D rtsp RTSP input format
 DE s16be pcm signed 16 bit big endian format
 DE s16le pcm signed 16 bit little endian format
 DE s8 pcm signed 8 bit format
 D sdp SDP
 D shn raw shn
 D sol Sierra SOL Format
  E svcd MPEG2 PS format (VOB)
 DE swf Flash format
 DE u16be pcm unsigned 16 bit big endian format
 DE u16le pcm unsigned 16 bit little endian format
 DE u8 pcm unsigned 8 bit format
  E vcd MPEG1 System format (VCD)
 D vmd Sierra VMD format
  E vob MPEG2 PS format (VOB)
 DE wav wav format
 D wc3movie Wing Commander III movie format
 D wsaud Westwood Studios audio format
 D wsvqa Westwood Studios VQA format
 DE yuv4mpegpipe YUV4MPEG pipe format
  
Image formats (filename extensions, if any, follow):
 DE gif gif
  
Codecs:
 D V 4xm
 D V D 8bps
 DEA aac
 D V D aasc
 DEA ac3
 DEA adpcm_4xm
 DEA adpcm_adx
 DEA adpcm_ct
 DEA adpcm_ea
 DEA adpcm_ima_dk3
 DEA adpcm_ima_dk4
 DEA adpcm_ima_qt
 DEA adpcm_ima_smjpeg
 DEA adpcm_ima_wav
 DEA adpcm_ima_ws
 DEA adpcm_ms
 DEA adpcm_swf
 DEA adpcm_xa
 DEA adpcm_yamaha
 D A alac
 DEA amr_nb
 DEA amr_wb
 DEV D asv1
 DEV D asv2
 D V D camtasia
 D V D cinepak
 D V D cljr
 D V D cyuv
 D A dts
 DES dvbsub
 D S dvdsub
 DEV D dvvideo
 DEV D ffv1
 DEVSD ffvhuff
 D A flac
 D V D flic
 DEVSD flv
 D V D fraps
 DEA g726
 DEV D h261
 DEVSDT h263
 D VSD h263i
  EV h263p
 DEV DT h264
 DEVSD huffyuv
 D V D idcinvideo
 D V D indeo2
 D V indeo3
 D A interplay_dpcm
 D V D interplayvideo
  EV ljpeg
 D V D loco
 D A mace3
 D A mace6
 D V D mdec
 DEV D mjpeg
 D V D mjpegb
 DEA mp2
 DEA mp3
 D A mp3adu
 D A mp3on4
 DEVSDT mpeg1video
 DEVSDT mpeg2video
 DEVSDT mpeg4
 D A mpeg4aac
 D VSDT mpegvideo
 DEVSD msmpeg4
 DEVSD msmpeg4v1
 DEVSD msmpeg4v2
 D V D msrle
 D V D msvideo1
 D V D mszh
 DEV pam
 DEV pbm
 DEA pcm_alaw
 DEA pcm_mulaw
 DEA pcm_s16be
 DEA pcm_s16le // Windows PCM 形式オーディオ(*.wav)
 DEA pcm_s8
 DEA pcm_u16be
 DEA pcm_u16le
 DEA pcm_u8
 DEV pgm
 DEV pgmyuv
 DEV png
 DEV ppm
 D V D qdraw
 D V D qpeg
 D V D qtrle
 DEV rawvideo
 D A real_144
 D A real_288
 D A roq_dpcm
 D V D roqvideo
 D V D rpza
 DEV D rv10
 DEV D rv20
 D A shorten
 D V D smc
 DEV snow
 D A sol_dpcm
 DEA sonic
  EA sonicls
 D V D sp5x
 DEV D svq1
 D VSD svq3
 D V theora
 D V D truemotion1
 D V D ultimotion
 D V vc9
 D V D vcr1
 D A vmdaudio
 D V D vmdvideo
 D A vorbis
 D V vp3
 D V D vqavideo
 D A wmav1
 D A wmav2
 DEVSD wmv1
 DEVSD wmv2
 D V wmv3
 D V D wnv1
 D A ws_snd1
 D A xan_dpcm
 D V D xan_wc3
 D V D xl
  EV xvid
 DEV D zlib

PEAR – HTTP_Client で proxy を利用するには

HTTP_Request には setProxy() がありますが、HTTP_Client にはプロキシ指定メソッドが存在しません。
しかし、HTTP_Client のマニュアルには直接書かれていませんが、次のようにすることで HTTP_Client でも proxy を利用することができます。

$client =& new HTTP_Client(array(
    ‘proxy_host’ => $host, // proxy ホスト
    ‘proxy_port’ => $port, // proxy ポート(省略時 8080)
    ‘proxy_user’ => $user, // proxy の認証ユーザ名(省略時認証なし)
    ‘proxy_pass’ => $pass // proxy の認証パスワード(省略可)
));

内部的には第一引数が HTTP_Request のコンストラクタに渡され、HTTP_Request のコンストラクタで proxy を設定する、という流れになります。
参考:
PEAR::Manual – HTTP_Client のコンストラクタ
http://pear.php.net/package/HTTP_Request/docs/latest/HTTP_Request/HTTP_Request.html#methodHTTP_Request“>PEAR::Manual – HTTP_Request のコンストラクタ(API Docs)

IE – innerHTML で OBJECT タグを正しく取得できない

SWFObject.js を使っていて気が付いたのですが,
IE では 以下のような処理で、(element).innerHTML がどうもうさんくさい動作をします。
(検証バージョン: Internet Explorer Version 6.0)

<span id=”exp_object_tag”>
    <object id=”foo” classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″ width=”100%” height=”100%”>
      <param name=”movie” value=”foo.swf” />
      <param name=”bgcolor” value=”#CCCCFF” />
      <param name=”quality” value=”high” />
      <param name=”scale” value=”noscale” />
      <param name=”flashvars” value=”message=hello” />
    </object>
</span>
<script type=”text/javascript”>
//<![CDATA[
    alert(document.getElementById(“exp_object_tag”).innerHTML);
//]]></script>

このコードを含むHTMLの表示結果は、単純にソースのまま表示されるという一般的な期待に反して次のようになります。

(注:実際は改行はありませんが、見やすさのため改行をいれてあります)
<OBJECT id=sotester height=”100%” width=”100%” classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000>
<PARAM NAME=”_cx” VALUE=”5080″>
<PARAM NAME=”_cy” VALUE=”5080″>
<PARAM NAME=”FlashVars” VALUE=””>
<PARAM NAME=”Movie” VALUE=”so_tester.swf”>
<PARAM NAME=”Src” VALUE=”so_tester.swf”>
<PARAM NAME=”WMode” VALUE=”Window”>
<PARAM NAME=”Play” VALUE=”-1″>
<PARAM NAME=”Loop” VALUE=”-1″>
<PARAM NAME=”Quality” VALUE=”High”>
<PARAM NAME=”SAlign” VALUE=””>
<PARAM NAME=”Menu” VALUE=”-1″>
<PARAM NAME=”Base” VALUE=””>
<PARAM NAME=”AllowScriptAccess” VALUE=””>
<PARAM NAME=”Scale” VALUE=”NoScale”>
<PARAM NAME=”DeviceFont” VALUE=”0″>
<PARAM NAME=”EmbedMovie” VALUE=”0″>
<PARAM NAME=”BGColor” VALUE=”FF66FF”>
<PARAM NAME=”SWRemote” VALUE=””>
<PARAM NAME=”MovieData” VALUE=””>
<PARAM NAME=”SeamlessTabbing” VALUE=”1″>
<PARAM NAME=”Profile” VALUE=”0″>
<PARAM NAME=”ProfileAddress” VALUE=””>
<PARAM NAME=”ProfilePort” VALUE=”0″>
<PARAM NAME=”AllowNetworking” VALUE=”all”>
<PARAM NAME=”AllowFullScreen” VALUE=”false”>
</OBJECT>

時動的にパラメータを追加するのはともかく、

<PARAM NAME=”FlashVars” VALUE=””>

とされてしまうのはいただけません。
 
なお、 += オペレータでも同様の現象が発生するため、次のようにすると FlashVars でパラメータが渡せなくなってしまい、不具合の原因になります。

document.getElementById(“exp_option_tag”).innerHTML += “Break it!!”;

 
参考:
innerHTML Property (MSDN)
Can’t pass innerHTML to Internet Explorer containing <param ../>(mootools forums)

symfony – Criteria で SQL の interval が使えない

日付範囲指定をするのに interval が使いたくて
Criteria のドキュメントやソースを追ったところ、
 
Criteria::CURRENT_DATE,
Criteria::CURRENT_TIME,
Criteria::CURRENT_TIMESTAMP
 
という ANSI SQL 関数は定義されていたのですが、SQL で日付の加減指定をする方法はないようです。
 
次のように

$c = new Criteria();
// 本日更新されたレコード
$c->add(FooTablePeer::UPDATED_AT,
    Criteria::CURRENT_DATE, Criteria::GREATER_EQUAL);

と単体で指定するのは有効ですが、

$c = new Criteria();
 // 過去 24 時間以内に更新されたレコードのつもり
$c->add(FooTablePeer::UPDATED_AT,
    Criteria::CURRENT_TIMESTAMP . ” – interval 1 day”,
    Criteria::GREATER_EQUAL);

のように、値に式を含めた場合、生成される SQL 文は

SELECT * FROM foo_table WHERE foo_table.updated_at >= ‘CURRENT_TIMESTAMP – interval 1 day’

と、エスケープ/クオート処理の対照になってしまい、望む結果を得ることはできません。
 
代替の方法として
A. Propel::getConnection() で得られる接続インスタンスに対して生のクエリを発行する
B. php の date(), time() 関数で日時を計算する
 
の二つの方法があります。
 
前者については Definitive Guide to symfony の8章の「生のSQLクエリを使う」の項を参照すると具体的な手順が書いてありますが、今回はデータベースサーバとWebサーバの時間差を気にしなくていい環境だったので、簡単に後者で対応しました。
 

$c = new Criteria();
// 過去 24 時間以内に更新されたレコード
$c->add(FooTablePeer::UPDATED_AT,
    date(‘Y-m-d H:i:s’, time() – 24 * 60 * 60),
    Criteria::GREATER_EQUAL);

symfony + Ajax で Helloworld

symfony で Ajax を使って HellowWorld を表示するまでの手順は以下のようになります。
(前提として Apache, PHP, symfony がインストールされているものとします)
 
1. まずは symfony のお約束、project, application, module 作成から。

$ pwd
 /usr/local
$ mkdir sf_ajax
$ cd sf_ajax
$ symfony new sf_ajax
$ symfony app helloworld
$ symfony module helloworld ajax

プロジェクト名、アプリケーション名、モジュール名は任意の名前で構いませんが、ここではそれぞれ sf_ajax, helloworld, ajax としました。
 
ここで、プロジェクトフォルダの web/ に sf ディレクトリがない場合は

$ cp -pr /usr/local/share/pear/data/symfony/web/sf ./web/

または

$ ln -s /usr/local/share/pear/data/symfony/web/sf ./web/

のように、symfony のインストールフォルダからコピーするかシンボリックリンクを張ります。
 
2. プロジェクトフォルダの web/ を web からアクセスできるようにします
(注: Apacheの Rewrite エンジンを使ってアプリケーション名を判別させる場合は web/ を DocumentRootにする必要があります)。
 

$ # /var/www が Apache の DocumentRoot の場合
$ ln -s /usr/local/sf_ajax/web /var/www/sf

 
この時点で

http://localhost/sf/helloworld_dev/ajax

(DocumentRootにした場合は http://localhost/helloworld/ajax )
のようにして web ページを開くと

Module “ajax” created

という symfony のデフォルトページが表示されるはずです。
 
3. ajax モジュールのアクションを編集する

$ cd apps/hello
$ cd apps/helloworld/modules/ajax/
$ vi actions/actions.class.php

 
actions.class.php: (編集前)

class ajaxActions extends sfActions
{
  /**
   * Executes index action
   *
   */
  public function executeIndex()
  {
   // $this->forward(‘default’, ‘module’);
  }
}

actions.class.php: (編集後)

class ajaxActions extends sfActions
{
  /**
   * Executes index action
   *
   */
  public function executeIndex()
  {
    // $this->forward(‘default’, ‘module’); ←コメントアウト
  }
  // ↓ 追加
  public function executeTime()
  {
    return $this->renderText(“Hello world!! (at “.date(“Y-m-d H:i:s”).”)”);
  }
}

 
4. ajax モジュールのテンプレートを編集する

$ vi templates/indexSuccess.php

 
indexSuccess.php:

<?php use_helper(“Javascript”);?>
<div id=”res”></div>
<?= link_to_remote(“Click!!”,array(‘url’=>”ajax/time”, ‘update’=>”res”,)) ?>

1 行目: symfony で Ajax を使うために JavaScriptHelper を読み込みます。
2 行目: 結果表示先のタグ。
3 行目: Javascript を実行するアンカータグを生成します。
       url: クリック時に HTTP リクエストを行うURLのモジュール以降の部分を指定します。GET パラメータを指定する場合は ajax/time?key=value のようにします。
       update: url で指定したページの読み込みが完了した際に表示先にするDOM の id を指定します。
       
 
ここで再び先程のページ(http://localhost/sf/helloworld_dev/ajax)を開き、 Click!! という文字をクリックすれば, 押すたびに

Hello, world!! (at 2007-07-05 23:30:12)

の日時の部分が更新されて表示されるはずです。
 
5. さらに link_to_remote() の引数の配列パラメータを追加することでよりインタラクティブな動作を実現できます。

<?php use_helper(“Javascript”);?>
<div id=”res”></div>
<div id=”error” style=”color:red”></div>
<div id=”loading” style=”display:none”>Now loading…</div>
<?= link_to_remote(“Click!!”,array(
    ‘url’=>”ajax/time”,
    ‘update’=> array( // update は失敗時と成功時で反映先を変えることができます
         ‘success’ => ‘res’, // HTTP コード 2XX
         ‘failure’ => ‘error’, // それ以外
       ),
    // 以下コールバックイベント指定
    ‘loading’ => “Element.show(‘loading’)”, // 読み込み開始時に実行する JavaScript
    ‘success’ => “Element.hide(‘loading’)”, // 読み込み結果 HTTP コードが 2XX の場合実行する JavaScript
    ‘failure’ => “Element.show(‘error’); alert(‘Error!!’)”, // 読み込み結果 HTTP コードが 2XX 以外の場合実行する JavaScript
    ‘complete’ => visual_effect(‘blind_down’, ‘res’, array(‘duration’=>0.5)), // 読み込みの成否にかかわらず、読み込み完了後(success,failure 判別,実行後)に実行する JavaScript
)) ?>

コールバックイベントには他にも before, after, loaded, interactive, 404 といったものがあります。詳しくはsymfony bookの Javascript ヘルパー – コールバックの項を参照してください。
  
参考:
symfony book 日本語ドキュメント Javascript ヘルパー
 Javascript ヘルパーの使い方について。
script.aculo.us Documentation
  symfony で利用している Javascript クラスライブラリ scriptaculous のドキュメントページ。symfony に最初から組み込まれているので、 use_helper(“Javascript”) とすればそのまま使えます。
symfony Code Snippets – ajax
symfony を使った実用ソースコード集。

GD でメモリエラー

GD でピクセルサイズの大きい JPEG や PNG などの画像を開こうとすると

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 6400 bytes) in …

のようにエラーが出ます。
例えばファイルサイズが 500KB 程度で php.ini の memory_limit に対して十分小さく見えても、ピクセルサイズが 1600×1200 のように極端に大きいとエラーになります。
 
原因は GD 内部でリソースとして読み込む際に、圧縮がとけるためのようです。
元画像のピクセルサイズが大きい程、読み込み時のサイズが大きくなる可能性が高くなるため、対策として php.ini で memoly_limit に十分な値を指定するだけでなく、GetImageSize() によりピクセルサイズをチェックするのが賢明です。

$size = filesize($file);
list($w, $h) = GetImageSize($file);
if($size > 1*1024*1024 || $w > 1200 || $h > 1200){
    throw new Exception(“ファイルサイズが大きすぎます”);
}

 
または、ImageMagick ならば同様のケースでもエラーなく処理ができるため、状況によって使いわけるといいでしょう。
 
参考:
BBS – PHP の基礎体力

convert Tips – 標準入出力の利用と画像形式を指定の方法

convert コマンドを使っていて、パフォーマンスを考えるとファイルを介さずパイプを使いたい、という場合が多々あります。
こういう場合、ハイフン “-” を入出力ファイル名として指定することでそれぞれ標準入力、標準出力を使うという意味になります。
 
標準入力から画像を読み取る(STDIN):

cat foo.jpeg | convert – -resize 320×320 out.bmp

結果を標準出力に書き出す(STDOUT):

convert foo.jpeg -resize 320×320 – | cat > out.jpg

 
なお、標準入力を使う場合はこのままでも自動判別してくれるのでよいのですが、標準出力を使う場合はファイル指定する時と違い、拡張子による出力判別ができないため、デフォルトの動作はソースの形式と同じ形式で出力になってしまいます。
 
こういう場合に役立つ方法として、ファイル名の接頭語による画像形式指定があります。
たとえば /tmp/foo というファイルを明示的に GIF として読み込み、PNG として標準出力に出力する場合は以下のようにします。
 

convert gif:/tmp/foo png:-

 
参考:
ImageMagick: Command-line Processing
Standard In の項参照。

symfony の基礎 – セッションとスコープ

Action クラスにて

スコープ

get 方法

set 方法

用途

インスタンス スコープ(ページ スコープ)

echo $this->foo;

$this->foo = “boo”;

View でローカル変数のように参照可能

リクエストスコープ

$this->getRequest()->getAttribute(“key”)

$this->getRequest()->setAttribute(“key”,$value)

リダイレクト時などアクション間でのデータ参照に利用

ユーザスコープ($_SESSION と同等)

$this->getUser()->getAttribute(“key”)

$this->getUser()->setAttribute(“key”, $value)

ショッピングカートなどページ遷移のあるトランザクションで利用

J2EE でのスコープと照らし合わせて symfony での変数(データホルダ)の種類をリストアップしました。
(アプリケーションスコープについては必要性が薄いので割愛)
 
参考:
パラメータホルダー(symfony book 日本語ドキュメント)

GDB でコアダンプの原因を探る

プログラム実行中に Segmentation Fault や Bus Error などで Core dumped となった場合、
core ファイル(または *.core)が作業ディレクトリに出力されます。
 
これを解析する場合, GDB(GNU Project Debugger)コマンドが有用です。

$ gdb <コアダンプした実行可能バイナリ> <コアダンプファイル>

例えば以下の perl のスクリプト(仮に foo.pl とします)の実行中にコアダンプした場合..

#!/bin/perl
 
# 何かの処理
 

この場合はスクリプト(foo.pl)ではなく、実際にコアダンプしたバイナリプログラム(/bin/perl)について gdb を実行します。

$ gdb /usr/bin/perl core
GNU gdb 4.18 (FreeBSD)
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-unknown-freebsd”…Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 2627 in elfstab_build_psymtabs
Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 933 in fill_symbuf
 
Core was generated by `perl’.
Program terminated with signal 11, Segmentation Fault.
 
以下ライブラリ読み込み、エラー箇所表示が続く

 
具体的なトレースの仕方については参考サイト参照のこと。
 
参考:
gdbを用いたデバッグ
  core ダンプ解析方法を含む GDB によるデバッグの基本が分かりやすく書かれています。
 
Debugging with GDB(日本語)
  GDB 公式ドキュメント日本語訳

symfony – データベースを扱うには?

symfony ではデータベース処理に Propel を使っています。
次の手順を踏むことで、テーブルをオブジェクトとして扱うことが可能になります。
 
1. propel.ini の設定

<project_dir>/config/propel.ini

 

$ symfony propel-*-*

で利用するデータベース接続の設定.
propel.database.* の設定を変える以外はデフォルトでよい。

; unix socket 接続(TCP接続ならデフォルトにならえばよい)
propel.database.createUrl = mysql://root:dbpass@unix+/
propel.database.url = mysql://root:dbpass@unix+/dbname

 
2. databese.yml の設定

<project_dir>/config/database.yml

web,batch から利用する symfony の設定

all:
  propel:
    class: sfPropelDatabase
    param:
# dsn: mysql://root:dbpass@ecoop.net/dbname
# unix socket 接続
        phptype: mysql
        hostspec:
        database: dbname
        username: root
        password: dbpass
        port:
        encoding: utf8
        persistent:

3-1. DB, テーブルを設定ファイルから新しく作る場合,
こちら(symfony で開発日記)を参考に、

config/schema.yml

を以下のように設定する

propel:
  table1:
  table2:
    _attributes: { phpName: FooTable }
    table1_id:
    name: varchar(255)
    amount:
       type: integer
       unsigned:true
       notnull:true
    created_at:
    updated_at:

説明..
  propel: … 接続名。
  table1 が最低限のテーブル構造例(id カラムのみ持つ)。
  table2 については以下のカラムを定義している
     id … int not null auto_increment primary key。デフォルトで定義される。
     table1_id .. int 型。 <table_name>_id とすることで table_name に Foreign key を張る
     amount … amount int unsigned not null というカラム定義。
     created_at … DATETIME 型。symfony がレコード作成日時を自動挿入してくれる
     updated_at … DATETIME 型。symfony がレコード更新日時を自動挿入してくれる。
  また、table2 はモデルクラスにマッピングする時(後述)に、
   __attributes: { phpName: FooTable } で指定した名前(FooTable)でマッピングされます。
 
3-2. propel.ini で設定した名前の空の DB を作成する。

symfony propel-build-db

 
3-3. schema.yml から CREATE TABLE の SQL 文を生成する

symfony propel-build-sql

 
3-4. (3-3) で生成した SQL 文を実行してテーブルを作成する。

symfony propel-insert-sql

 
Note: 3-1 とは逆に既存 DB のテーブルから schema.yml を作成するには

symfony propel-build-schema

を実行します。
 
4. symfony プロジェクトで利用できるように schema.yml からモデルクラスを生成する

symfony propel-build-model

ここで生成したモデルクラスは

<project_dir>/lib/model/

以下に作成されます。
 
5. (4)で作成したモデルクラスを使い、symofony プロジェクト内で参照する

apps/app_name/modules/model_name/actions/actions.class.php

等で以下のようにして参照します(require,include は不要)。

public function executeIndex()
{
   // 最も簡単なレコード挿入の例
    // 新規レコード用インスタンスを生成
    $table1 = new Table1();
    // データベースに実際にレコードを書き込む
    $table1->save();
 
   // カラムに値を設定して挿入する例
    $fooTable = new FooTable();
    
    $fooTable->setTable1Id(1); // カラム table1_id に 1 を指定
    $fooTable->setName(“milk”); // カラム name に milk を指定
    $fooTable->setAmount(123); // カラム amount に 123 を指定
    // 書き込む
    $fooTable->save();
 
   // プライマリキーからカラムを取得し、削除する例
    // プライマリキーカラム(id)が 1 のレコードのインスタンスを取得する
    $fooTable = FooTablePeer::retrieveByPK(1);
    if($fooTable){
        // id = 1 のレコードがあれば削除
        $fooTable->delete();
    }
     
    // 更新の場合, 既存レコードを取得して変更後 save() すればよい。
     $fooTable = FooTablePeer::retrieveByPK(1);
     if($fooTable){
         $fooTable->setAmount(10);
         $fooTable->save();
     }
    
    // プライマリキー以外からレコードを得る場合は *Peer::doSelect(), doSelectOne() を使う
     // 単純に SELECT した場合の一番始めのレコードを取得
     $fooTable = FooTablePeer::doSelectOne(new Criteria());
     
     // name が milk で, 作成日時の古い順に全てのレコードを配列で取得
     $c = new Criteria();
     $c->add(FooTablePeer::NAME, “milk”); // 条件
     $c->addAscendingOrderByColumn(FooTablePeer::CREATED_AT); // ORDER
     $tables = FooTablePeer::doSelect($c);
     
}

Criteria クラスの利用方法については
The Definitive Guide to symfony
8 章(日本語)の Criteria についての項に詳細に書かれています。
なお、Criteria クラスの実体は symfony インストールフォルダの

vendor/propel/util/Criteria.php

で定義されています。
  
参考:
symfony フレームワークテスト置場
  おおまかな手順、設定ファイルの設定の仕方、それぞれの意味など。
symfony book 日本語ドキュメント コマンドラインインターフェイス

 symfony propel-*-*

についてはこちらを参照。
schema.yml がどこまで楽させてくれるか(symfony で開発日記)
  schema.yml の書き方についてまとめられています。
MySQL4.1以降+symfonyのときのdatabase.yml
  MySQL4.1 以降では encoding: utf8 を指定しないと化ける、とのこと。