SQLite3とphpのPDOを使用した、DBテーブルの自動作成

構築中のWebサイトに、SQLデータベースを導入することにしました。

今回のWebサイトは友人と分業して作っているため、Ubuntuで開発したあと、ソースツリーだけコピーしてxampp環境でテストできなければなりません。
「できるだけ導入作業がいらない」(というか事前準備がない)のが大事、ということになります。
つまり、DB側であらかじめテーブルなどを作成する必要がないように作りたいのです。

普通、商業サイトなどを作る際は、DB環境構築は一回きりなので、自動化などがされていない場合もあるようです。

データベースの自動セットアップ

PHPコード側は、「PHPプログラミングの教科書」様のデータベースを自動セットアップ(テーブルを自動作成)するには様の通りにすればよいです。

PHPからSQLite接続してテーブルを作成したら、.sqliteファイルが作成されます。

データベース操作関数にPDOを使うようにしておけば、mysqlなどへの移行も比較的簡単になるそうですが、いずれ移行することをねらうなら、実際にMySQLで試したほうがよいと思います。

一番下にPHP(PDO)によるサンプルソースがあります。

SQLiteの導入

Ubuntu

主にWorld Wide Windblue様のページを参考に。必要パッケージを導入します。
sudo apt-get install sqlite3 php5-sqlite
「2.適当なディレクトリにDBを作成してみる」に書いてあったDBファイルの作成手順ですが、私の環境と違うのか、ただSQLiteに接続して終了するだけでは、.sqliteファイルは作成されないようです。

結果的に事前に.sqliteファイルの作成は不要だったので、問題なしです。

ただし、.sqliteファイルを作成するディレクトリの権限を変更する必要があります。
chmod a+w indbfile/

PHPコードからsqliteにアクセスして、DB作成したら.sqliteファイルも問題なく作ることができました。

xampp

xampp v3.1.0にて、特に設定することなくsqliteを使うことができました。
これはかなり良いです。

TIPS:「カラムを書き込もうとしたらSQLiteのDBからテーブルが消えていた」場合

SQLiteはいろいろ気が利いている、と聞いていたのですが、それが原因で悩むことに。
CREATE TABLE したら、PDOを閉じないうちにカラムをINSERT しないと、空のtableが自動で削除されるようです。
.sqliteファイルのサイズがゼロだったので気づきました。



TIPS:SQLite環境でカラムを日付データ順にソートする

timestamp型への挿入はYYYYMMDDHHMMSS(PHPのdateで'YmdHis')だけかと思っていたのですが、'Y-m-d H:i:s'も使えるようです。
最終的に、date (DATE_RFC822) に落ち着きました。
でもSQLiteだからかもしれません。MySQLなどへの移行の際に苦労しそうで怖いです。

※(2013/07/04追記)
日付情報によるSQLカラムの並び替えに失敗していることが判明しました。
日付情報をRFC822形式から data('Y-m-d H:i:s') に変更しました
SQLiteには日付型が存在しないことが、ソート失敗の原因と思われます。
日付によってSQLカラムを並び替える方法、そして任意の順位のカラムを取り出す方法は、リンク先の記事をどうぞ。
この方法で上手く行かない場合や、他のDBMS移行後に問題が発生したら、あらためて追記します。


その他のTIPS

INSERT動作の確認は、
select * from テーブル名
コマンドで行えば、表示部を作る前に書き込みができているかチェック可能です。


エラー表示については、PDOがPDOExceptionを投げてくれない件様を参考に追記する必要がありました。


ソース

テーブルを作成し、PDOを閉じる前に最初のカラムを書き込むサンプルです。

//DBに画像を追加
function addImgDB ($imgOrgName, $imgFileName, $username, $passwd){
    $uptime   = date (DATE_RFC822);
    $askcount = 1;
     try {
   
        $dsn = "sqlite:imgfile.sqlite";
        $conn = new PDO($dsn);
               
        $sql = "CREATE TABLE IF NOT EXISTS imgfile(
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        origname   char(128) not null,
                        filename   char(128) not null,
                        uptime     timestanp not null,
                        askcount   integer   not null,
                        username   char(64),
                        passwd     char(64)
                     
                 )";
        $stmt = $conn->prepare($sql);
        $stmt->execute();
               
               
         // データ格納
        $sql = "INSERT INTO
                imgfile(origname, filename, uptime, askcount, username, passwd)
                VALUES (:origname, :filename, :uptime, :askcount, :username, :passwd)";
        print "sql:". $sql."<br>";
              
        $args = array(':origname' => $imgOrgName, ':filename' => $imgFileName, ':uptime' => $uptime,
                ':askcount' => $askcount, ':username' => $username, ':passwd' => $passwd);
        $stmt = $conn->prepare($sql);
        $stmt->execute($args);
           
    } catch (PDOException $e){
        echo "失敗しました\n";
        var_dump($e->getMessage());
    }
           
    return true;
}





XAMPP環境における日本語ファイル名の文字化け解決法

前置き

WebページのPHPコードをUbuntuで書いているのですが、テスト環境としてxamppでも動かすことになりました。
開発をスムーズに進めるために、Linuxとxamppで同一ソースを使える必要があります。



XAMPPで書き出し、読み込みの両方で文字化けが発生していることがわかる



xampp環境は、Ubuntuよりも前衛的というか、Ubuntu環境がスルーする非推奨な関数などに対して敏感なようです。Ubuntu環境では問題ないPHPコードでも、エラーメッセージを出してくれます。
(面倒ではありますが)ソースコードから非推奨な関数や書き方を取り除く良い機会だとも思ったので、エラーメッセージに対してひとつずつソース修正を行うことにしました。
たぶん、xampp でデバックするコツは、検索ワードを「エラーメッセージ+エラーを起こした関数名」にすることかなと思います。
たいていの問題は、解決法がWeb上にありました。検索すればこれぞというページが出てくるので楽でした。


ところが、「日本語ファイル名の取り扱い」で、突然立ち往生することになりました。
xammp環境でPHPを使ってファイルを読み書きすると、ファイル名が文字化けします。この現象について書かれたページを探したのですが、見つけた対処法がどれも効きません。

・「php.iniを書き換える」という対処法があるのですが、自分の環境では上手く行きませんでした。
また、できれば変更はプロジェクトディレクトリの中で完結させて(バージョン管理システムで管理できるから)、環境設定はできるだけデフォルトから変更せずに済むほうが良いです。

・解決法の中には「出力をSJISにします」というものもありました。
PHPの内部エンコーディングはUTF-8が基本であり、UTF-8とSJISをソース内で混在させたら、それこそ私の手に負えない複雑なコードになりそうです。
それを避けようと思ったら、すべてをSJISに統一するしかありません。index.phpもHTMLソースもcharsetも、すべてSJISを指定して書くことになります。でも、この解決法は完全に「Windows環境で開発する」ことを意味していると思います。
わたしの場合、メインの開発環境はUbuntu Linuxで、サーバもUNIXの予定です。Linux環境でテキストはUTF-8ですし、HTMLソースやcharsetを書き換えるのも面倒です。

なんにせよ、文字化けの原因は文字コードです。

それで試行錯誤の結果、自分なりの方法を見つけたので記事にすることにしました。
 結論としては、「ファイル名の文字コードをmb_convert_encoding ()関数で相互変換する。PHP内部ではUTF-8を使い、Windows上のファイル名はCP932を使う」です。


コードサンプル

xampp(Windows)でファイル読み書きするためのPHPコード

 例:xampp環境でファイルを読み書きする(開発中コードから切り出したもの)
ファイルを書く場合
//POSTでファイルを受け取る部分
(ブラウザから受け取ったファイル名を、Windowsディレクトリへ書き出すためにWindows環境の文字コードへ変換)
  $localFN = mb_convert_encoding
                ($_FILES["upfile"]["name"],"CP932", "UTF-8");
  if (move_uploaded_file($_FILES["upfile"]["tmp_name"],
          "imgs/" . $localFN)) {

      (略)
  }

ファイルを読む場合
readdir()関数でフォルダの中身を読み込むと、
  while (false != ($imgName = readdir($dir))){
    $imgName = mb_convert_encoding($imgName, 'UTF-8', 'CP932');

      (略)
  }



Ubuntuとxampp(windows) 環境で動くようにする



ファイルを読む場合
  if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ){
    //xampp対応。Windows系の場合、文字コードを変換。
    $imgName = mb_convert_encoding ($imgName, 'UTF-8', 'CP932');
  }


ファイルを書く場合
他の箇所で使う予定もあったので、内部コードから環境の文字コードへの変換は、関数にまとめました。
  $localFilename = conv_str_to_local($_FILES["upfile"]["name"]);
    
    //環境を判定して文字コード変換(内部コード->環境の文字コード)
  function conv_str_to_local ($inString){
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ){
      //xampp対応。Windows系の場合、文字コードを変換。
      $localString = mb_convert_encoding

                        ($inString,"CP932", "UTF-8");
    }else{
      $localString = $inString;
    }
      
    return $localString;
  }



この方法ならxampp環境を変更せずにソースの変更だけで済みます。他の方法より書いたり管理するのが単純です。


解説


おおまかにまとめると、
・PHPの内部エンコーディングはUTF-8
・使っているHTMLソースもUTF-8
・Windows日本語環境はCP932(≒SJIS)
よって、「Windowsファイルシステムを読み書きする際に文字コード変換の必要有り」です。

そこで、PHP内部ではファイル名をUTF-8で取り扱います。
ファイルを読み書きする際に、ファイル名を表す文字列を文字コード変換してから、ファイルを開きます。
これにより、PHP内部ではUTF-8以外の文字コードを扱うことによる問題を最小限に抑えられます。
また、変換するかどうかは、OSの種類がWindowsかどうかを判別して決めますが、「とりあえず関数に通す」だけで済むようにして、コードが複雑になるのを防ぎます。


そもそも、私の書いていたWebページの不具合は、文字コードが原因である、独立した2つの問題でした。
・POSTで取得した日本語ファイルを保存すると、文字化けしている。
・日本語画像ファイルをWebページに表示しようとすると、ファイル名が文字化けして、画像が表示できない。

読み込みの文字化けを解消(ブラウザ表示)

書き込みの文字化けを解消(アップロード)


文字化けした名前で読み書きすることは可能
(2重変換のようなことになっていなければ)


その他

今回扱ったのはファイル名の文字コードであり、テキストファイルの内容は文字コードを変更していません。
今回書いたWebページでは、テキストファイルはすべてWebページ上のテキストボックスから書き込み、PHPを通してWebページへ書き戻すので、読み書きがすべてUTF-8で完結しています。書き出したテキストファイルをメモ帳などのWindowsアプリケーションで読み書きする場合は、ファイルから読み出したテキストデータも文字コード変換する必要があるかもしれません。(TeraPadなどのUTF-8対応テキストエディタを使ったほうが楽だと思いますが。)


 「mb_convert_encoding()を使ってエラーが出るときは、mb_language("Japanese");を宣言するといいよ」と書いてあるサイト様を見かけましたが、今回の例では不要でした。

最後に参考サイト様を。
OSの判定方法は、PHPリファレンスマニュアルのphp_uname()関数から。
アップロードファイルの書き出しは、サイト様のXAMPP(Apache+PHP+MySQL+Mercury)での文字コード関連関連から。


Knotterを使ってみた。 トポロジカルなデザインツール

Knotterは、セルティック ノット(Celtic knot)デザイン専用の画像エディタです。
セルティック ノットを日本語でどう訳すのかよくわかりませんが、「ケルト縄風デザイン」 とでもすれば良いのでしょうか。

Libre Graphics Worldの記事(英語)でKnotterが取り上げられていて、興味が湧いたので触ってみました。
英語で探しても情報がほとんど見つからず、不明な点も多いですが、現在わかっていることをまとめています。

試したバージョンは knotter_0.9.3-2_amd64.deb (2013年6月当時の最新版)。
環境は Ubutnu13.04-amd64です。


インストール

インストーラへのリンクが公式サイトにあるので環境に合わせて選択。
ソフトウェアセンターでインストールすると、「インストールに失敗しました」とダイアログが出ますが、問題なく起動します。
(追記 注: パッケージマネージャが不具合を起こしてアップデートなどができなくなります。knotterをアンインストールすれば解決します。)

knotter起動状態
Knotter起動状態

基本操作

何はともあれ、Edge Loopツールを選択して書いてみます。

Edge Loopツールを使用
Edge Loopツールを使用
とりあえず書くだけならばLibre Graphics Worldの記事(英語)でもリンクされている動画が参考になります。


出てくるものが「角」ばかりなので、言葉と意味の対応づけに気をつけないと混乱します。
・knot(縄)
設定されている縄の性質(「柔らかい・硬い」的な)で、角の形がどうなるか決まります。
Knotterが縄だけを書く専用ツールなので、「この画像で使うedgeのデフォルト設定」 くらいの理解で良いのかもしれません。

・edge(角)
エディタ上では赤いドットで表されている部分のことです。
・cusp(先端)
edgeの形状を指すようです。
 
 記事でも取り上げられていた星型の先端(star cusp)の作り方ですが、Selection Styleの項目StyleStar Cuspを選択するだけです。

krutterの角
knotterの角

 Style以外の設定項目
 ・Curve
  角の両脇にある出っ張り部分の、膨らみ具合を調節できます。
 ・Gap
  描画線が重なる箇所の余白サイズを調節できます。
 ・Angle
  ガイドの角の角度と描画される角の角度の関係をあらわしているようですが、詳しくはわかりませんでした。
 ・Distance
  角の伸び具合(サイズ)を調節できます。




使っていて明らかになった点をいくつか
#ループ(仮) に含まれる角をすべて選択する方法
ループに含まれる角をどこでも1つ選択してから、メニューのNodes->Select Connected またはCtrl+Lで、その角を含むループの角すべてが選択されます。
角が多いループを選択する場合に楽です。
複数の角を選択したい場合、CtrlまたはShiftを押しながらクリックしなければならないため、数が多いと苦労することになります。


複数の角を選択してFlipすることができるます。
Vertical Filp・Horizontal Filp はそれぞれ 上下・左右 反転です。
選択や回転は、選択した角同士の中間地点を中心とするようです。


色付けはKnot Display(縄の設定)のCustom Colorや、Boader設定で行います。
縄ごとに個別の色設定などはできないようです。
縄の色は、Custom Color で指定された順番に割り当てられるようです。
Knotterで描いた図形は、トポロジカルに縄の本数・結びつき方や重なり方が変わります。
縄に付ける色をマウスなどで指定することはできません。形だけ作ってから、Custom Colorの順番を入れ替えて試すしかないようです。(それでも順番によっては使えない色使いもありそうですが)
場合によっては、別途GIMPなどに取り込んで着色してしまったほうが楽かもしれません。


Knotter、慣れるまではひたすら頭を悩ませてくれそうです。

Ubuntu13.04で使える動画編集ソフト一覧

タイトル通り、Ubuntuで使える動画編集ソフトウェア一覧です。
2013年5月にUbuntu 13.04でインストールを検証しています。


なお、Linux環境で使える動画編集ソフトウェアの一覧としては「玉虫色に染まれ!」様のページが大変よくまとまっています。
2008年の情報ですが、字幕やマルチトラックなど、実際の動画編集を行った感想が載っているので、動画編集ソフトウェアを選ぶ際には目を通すべきです。
 Linuxで使える動画編集ソフト(その1)
 紹介ソフトウェア:kino / Avidemux / Stopmotion / PiTiVi
 Linuxで使える動画編集ソフト(その2)
 紹介ソフトウェア:kdenlive / Open Movie Editor / LiVES


紹介されている以外にも、以下のソフトウェアが存在します。
そうはいっても、用途が違うソフトウェアもあり、動画編集ソフトとしてはFlowbladeが一押しといったところです。
luciole / Cinelerra / toonloop / Flowblade Movie Editor / ffDiaporama

紹介順は基本的に、見比べやすいように上記の「玉虫色に染まれ!」様に準拠しましたが、Open Shot Video Editor / Open Movie Editor / Cinelerra / Flowblade / ffDiaporamaに関しては、ソフトウェアセンターからインストールできないため、この記事の先頭で紹介しています。


各ソフトウェアごとに、名前・アイコン・スクリーンショットを用意し、インストール方法・検証・感想をつけました。

とりあえずすべてのソフトウェアで、動画再生できるか検証しています。
検証で使った動画は、H246/AAC 形式です。(「よくわかる現代魔法」ノンテロップOP  再生時間 1分30秒, Container:MPEG-2 Transport Stream, サイズ:1920 x 1080, オーディオ audio/x-private-ts-lpcm)
インポートと再生(サウンド出力含む)ができるかどうか検証しています。
ただし、今回紹介するソフトの一部は、普通の動画編集ソフトではないため、検証の対象外となっています。
本来なら検証は動画のインポートではなく、エフェクトを使った素材の張り込みや、字幕の作成ができるかどうかを見るべきですが、それは機会があればいずれ。

感想:
検証以外で、使ってみて気になった点などがあれば追記しています。



Open Shot Video Editor





 sudo add-apt-repository ppa:openshot.developers/ppa
 sudo apt-get update
 sudo apt-get install openshot
( frei0r-pluginsは自動導入されるようです)

 なお、わたしの環境ではこのリポジトリ追加後 apt-get update でエラーが出るようになるので、インストール後にリポジトリを削除しました。
(sudo rm /etc/apt/sources.list.d/openshot_developers-ppa-raring.list)

検証:
動画も音声も問題なく再生できた。

感想:
落ちることもなかったので、もしかしたら良いかもしれません。誰か実際の編集作業をレビューして欲しいです。



Open Movie Editor (インストール手順を調査中)

13.04版のパッケージはありません。(Ubuntu10.04 (Lucid Lynx)版のパッケージはある。)
仕方がないのでソースを入手してコンパイルします。

./configureファイルを実行します。
ライブラリ不足でエラーメッセージを吐くので、それに従って必要パッケージをインストールしていきます。

libsamplerate0-dev
libsndfile1-dev
libgavl-dev
libgmerlin-avdec-dev
libgmerlin-dev
libquicktime-dev
libjack-dev
libportaudio19-dev
libfltk13-dev

エ ラー「configure: error: Lame Codec in libquicktime not found, reinstall libquicktime with lame enabled」 の問題を解決するのは面倒そうだったので、作業を一時停止。
いずれ、libquicktimeのlameオプション付きコンパイルを試すか、別の手を考えます。



cinelerra





https://launchpad.net/~cinelerra-ppa/+archive/ppa
に従って、
/etc/apt/source.listに以下の二行を追記
  deb http://ppa.launchpad.net/cinelerra-ppa/ppa/ubuntu raring main
  deb-src http://ppa.launchpad.net/cinelerra-ppa/ppa/ubuntu raring main 
鍵の登録は「ubuntuのダウンロードでCinelerraがダウンロードできません・・」様より
gpg --keyserver keyserver.ubuntu.com --recv-keys CBDFA02B432BB368
gpg -a --export CBDFA02B432BB368 | sudo apt-key add -


インストールはコマンドを実行
sudo apt-get update
sudo apt-get install cinelerra-cv

検証:
再生できなかった。
ドラッグアンドドロップできないので、ファイル選択ダイアログでインポート。
トラックに追加しようとしたら、アプリケーションがクラッシュした。

感想:
UIが古い。(マルチウィンドウ&小さなビットマップ・フォント)
パーツ類も、GTKやQtのツールキットではなく、Blenderのような独自実装の雰囲気があります。
ドラッグアンドドロップによるビデオ取り込みができませんでした。
日本語のディレクトリ名は文字化けして、インポートが難しくなります。

Flowblade Movie Editor




Ubuntu Sharing様が紹介していました。
ただ、このサイトで紹介しているppaがUbuntu13.04環境で使えないので、公式サイトの指示でdebファイルをダウンロード。この方法なら問題なくインストールできました。
どうでもいいことですが、Ubuntuで使うと表示されるアイコンが違います。

検証:
現代魔法OP(h264/AACのmp4動画)の動画を再生できませんでした。
悔しかったのでmkvファイル(まどかマギカBD6巻の本編)で試したところ、インポートできました。
どうやらインポート時にファイル形式かエンコードを見て、インポート可能か判定しているようです。

感想:
最初、動画のインポート方法がわかりませんでした。MediaタブのBinsをAddするのではなく、同じタブの隣のAddボタンで、素材のインポートが可能です。
インポート可能なファイルを、インポート時のファイル選択ダイアログが判定してくれる機能も、そうとわかれば気が効いていると感じます。



追記(2013/06/28):

ffDiaporama





SourceForge.jpにて紹介されていましたので、ffDiaporamaをインストールしてみました。
公式ページであるhttp://ffdiaporama.tuxfamily.org/のDownloadページから、debファイルをダウンロード。今回はリポジトリ登録はやめておきました。

検証:
現代魔法OP(h264/AACのmp4動画)は、静止画として認識するようでダメでした。
mkvファイル(まどかマギカBD6巻の本編)は動画としてインポートできました。
Flowblade Movie Editorと似た結果です。

感想:
エフェクト(トランジション)選択画面で、各トランジションがプレビュー動画になっていました。
どんな効果を適用できるのかとてもわかりやすく、とっつきやすいソフトウェアだと思います。



kino






検証:
再生できなかった。
インポートダイアログが出るのだが、いつまでたってもインポートが終わらない。



Avidemux 




 検証:
動画は問題ないが、音が再生されなかった。
一時停止ボタンがどこにあるのかしばらく悩んでしまいました。再生ボタンと兼用で、気づいてみれば、アイコンもよく考えられた形になっています。

感想:
 AvidemuのパッケージにはGtk版とQt版がありました。今回はgtk版を選択。もしかしたら対応コーデックや不具合の数が違うのかもしれませんが、Qt版は試していません。



 Stopmotion




感想:
動画をインポートする方法がわかりませんでした。「コマ撮り画像を繋げて動画にするソフト」と紹介されていますし、使い方が違うのでしょう。



PiTiVi





検証:
動画を再生できなかった。
オーディオプラグインが認識されず、動画をインポートできない。「マルチメディアプラグインを検索しています」と出て、プラグインのインストールを促されるが、プラグインをインストールすると検索に戻って、以下無限ループ。

感想:
デコーダにGStreamerを使っているようで、もしかしたら動画を再生できなかったのはPiTiVi自体の問題ではなく、システムに適切なデコーダが必要なのかもしれません。(実際、Ubuntu13.04デフォルトのTotemメディアプレイヤーでも、同じようにデコーダのインストールを促され、動画を再生できない。)


kdenlive




検証:
動画・サウンド共に問題なく再生できた。
特に問題ありません。動画再生時間の数字がブルブル震えるのが気になるくらいです。

感想:
kedenliveは起動時にウィザードが起動しますが、ウィザードに適当に答えても、動画をインポートするとインポート動画にプロジェクト設定を合わせるかどうか問い合わせてくれます。
不意なクラッシュを経験したので、2008年からまだ不安定さを解決しきれていないようです。
そうはいってもクラッシュ後にプロジェクトをリカバリする機能もついているようです。


LiVES



LiVES初期起動時の設定画面(これ以外に文字化けしている場合もあった)

LiVESシンプル(クリップエディタ)モード
LiVESシンプル(クリップエディタ)モード

LiVESマルチトラックモード
LiVESマルチトラックモード
検証:
「無効な再生速度です」と出るのですが、動画のfpsとプロジェクトの設定を合わせないといけないのでしょうか。(47.95いくつ、と設定するのが面倒だったのでスルー。そして、fpsの異なる動画を組み合わせる場合はどうするのでしょうか。)

感想:
クリップ編集モード/マルチトラックモード があります。(単純なカット編集か、複数の動画を組み合わせたものを作るのか、でモードが違うようです。)
マルチトラックモードは、全画面表示にしておかないとUnityデスクトップではみ出します。しかも、ウィンドウ幅を小さくすることができませんでした。
それから、下の情報ウィンドウで状況はわかるので困らないですが、情報ダイアログに文字が表示されない不具合はどうなのだろうか、と思いました。

LiVESの情報ダイアログ(文字が正常に表示されていない)



luciole



検証:
検証対象外。lucioleはコマ撮り動画作成ツールであって、動画編集ソフトではないので。


toonloop





検証:
検証対象外(?)。そもそも起動しない。

感想:
検証対象外というか「ライブアニメーションエディター」ってlucioleと同じようなものなのでしょうか。
なぜか起動しなかったので、スクリーンショットもなしです...。



おわりに (とりとめのないメモとして)

「Open Shot Video Editor」と「Open Movie Editor」が紛らわしいです。Google検索ですら、「Open Shot Video Editor」を検索すると「Open Movie Editor」が出てくることがありますが、2つは別々のソフトウェアです。
注意して調べないと、混同して混乱します。

Flowbladeを見つけたのも偶然でした。"Open Movie Editor"で検索して引っかかりました。
オープンソースの動画編集ソフトって、実はもっとたくさんあって、まだ日本語で紹介されていないだけなのかもしれないな、と思いました。
(日本にもJavieなどがありますが、Linux対応していないです...)

toonloop起動しない...。

もしかしてcinelerra人気なのでしょうか。私の検証方法が悪かったのかもしれません。

英語のサイトで見かける意見ですが、「Blenderはイイ動画編集ソフトウェアだよ!」って言われましても困ります...。

オープンソースではありませんが、LightworksのLinux版があるそうです。

英語版Wikipediaに動画編集ソフトウェア一覧がある!
 Lumiera、 VideoLAN Movie Creator(VLMC)など、見たことのないソフトウェアが登録されているので、後日チェックしたいです。


なお、このページのアイコンおよびスクリーンショットは、自由に転用していただいて構いません。
(もちろん、転載者が自分の責任で使用してください。私は一切の義務と責任を負わないこととします。私が許諾できる範囲で使用を自由にするだけです。アイコンおよびアプリケーション自体の権利は各ソフトウェア作者やプロジェクトが持っていることを忘れないでください。)

そして、誰か2013年下半期版や2014〜版の、動画編集ソフトウェア一覧を作ってください。編集機能のレビューも読みたいです。
(自分で調べる面倒がなくなって助かります。)


ひとつのボタンから複数の情報を送る (HTMLでPOST、そしてhidden)

formでユーザの入力やファイルを送信する際、IDを付与したり、送信した情報を紐付けるか、などの情報を一緒に送信したい場合があります。
その場合、ID情報はブラウザに表示しないのがベストです。ユーザに見せたり、編集してもらう必要はありません。

 わたしの場合、10個の画像が並んだ画像一覧ページで、画像ひとつずつにコメント欄があり、どの画像に対するコメントなのか特定する必要がありました。

「画像にコメントを付けられるサイト」のスクリーンショット(一部を切り出したもの)



追記:「fancyBoxで装飾したフォームからPOSTを送信する」方法とサンプルコードを公開しました。


formによる送信は、送る側でnameとvalueを指定すると、受け取る側で$_POST連想配列の中身として情報を受け取れる、という仕組みになっています。
例:
送信する側 (HTML)
    <input name="name" value="string value or other.">
受信する側 (PHP)
    $inValue = $_POST["name"];
 
今回の場合、情報をまとめて送り、受け取る側では、$_POSTを配列として扱うことで、
    //画像に対するコメントを保存
    saveComment ($_POST["imagename"], $_POST["comment"]);
などと書きたいわけです。

これを実現する方法として、 inputタグのtype="hidden" を使います。
ユーザを惑わせることなく、複数の情報を同時に送信できるようになります。


なお、検索すると、JavaScriptでpostするという解決法が出てきますが、そんなに大げさなことをする必要はありません。(それに、JavaScriptが無効にされていたら情報が送信できなくなります。)


POST(GETでもよいですが)で送信する側

HTMLで以下のように書きます。
例:
    <form action="capture_post.php" method="post">
        <p>
        コメント:<br>
        <input type="hidden" name="imgname" value="samplefile.png">
        <textarea name="comment" rows="3" cols="30"></textarea><br>
        <input type="submit" name="button">
        </p>
    </form>

なお、この例ではPOSTを受け取るページ(formタグのactuon要素)はcapture_post.phpとなっています。action="#"と書くことで、このページ自身をPOSTの受け取りページとして指定することもできます。
ボタンを押すと、ブラウザは新しいページを要求しながらPOSTデータを送ります。ページ側では、次の「受け取る側」PHPコードを書いて、POSTデータを受け取ります。

受け取る側


HTML中のPHPで以下のように書きます。
この例では、コメントがあった際に、指定されたファイル名と書き込まれたコメントを表示しています。
例:
  function capture_comment(){
      if ("" == $_POST["comment"]){
          return false;
      }
      print "コメント:" . $_POST["imgname"] . "<br>\n";
      print $_POST["comment"] ."<br>\n";
  }

※本番環境で使う場合は、セキュリティのためにPOSTメッセージを変換する必要があります。

POST結果の表示例(一部を切り出したもの)
POST結果の表示例(一部を切り出したもの)
上のスクリーンショットはPOSTテストのための簡単な表示です。
実際にコメントをサイトに表示する際には、もっと見やすくてわかりやすいデザインをする必要があります。

SQLデータベース:ソートしてから特定順位のカラムを取り出す

なお実行環境はPDO(Ubuntu13.04のPHP)+SQLiteです。

仮定:
アップロードされた時間でソートされたn番目の行からファイルIDを取得したいとします。

アップロードされたファイルの情報を、データベースに格納しています。
ファイルごとに、一意なIDとしてid、アップロードされた時刻としてuptimeが記録されています。
テーブルはfilesTable、id,uptime列(それぞれidがinteger型、uptimeがtimestamp型)
テーブルにはその他にファイル名なども記録されていますが、今回は関係ありません。

アップロードされたファイルは、DB中ではIDで管理します。 ファイル名FromID ()IDFromアップロードの順番 ()などの関数がPHPソース内で散見されることになる予定です。



3行目のIDを取得するなら、こんな感じです。
SELECT id FROM (SELECT id, uptime FROM filesTable ORDER BY uptime) LIMIT 1 OFFSET 3;

 実際には、アップロードされた順に使う(表示するとか)と思うので、
SELECT id FROM (SELECT id, uptime FROM filesTable ORDER BY uptime DESC) LIMIT 1 OFFSET 3;
 として降順に並べ替える使い方になると思います。


このSQLクエリーができるまで

おまけです。

まずは、「テーブルからなんか取り出す」レベルの適当さで、最低限のクエリーを書きます。
SELECT * FROM filesTable;

上の例ではすべての列を取り出しますが、必要な情報はidとuptimeだけなので、そのようにします。
SELECT id,uptime FROM filesTable;

アップロード時間でソートする必要があるので、ソート関数を探してきて、くっつけます。
SELECT id,uptime FROM filesTable ORDER BY uptime;

ここから混迷した探索の時間。(主にネットからコピペしたSQLクエリーが動かない)
"OFFSET 1*2" などとするのですが、OFFSETは環境によって記法が違うとのこと。
PDO環境ではLIMITの後でないとOFFSETが使えないかのようです。

とにかく"LIMIT 1 OFFSET n"を指定すれば、n番以降の1つだけを取得することができます。

改めて完成版 :
 SELECT id FROM (SELECT id, uptime FROM filesTabel ORDER BY uptime DESC) LIMIT 1 OFFSET 3;

 要するに、「ソート済したテーブルの先頭から、3番目以降の行を最大1つ取り出す」という考え方です。


 実際には、まだSQLに慣れていないので、試行錯誤の過程でもっと寄り道をしています。テスト環境(SQLiteデータベースファイル)を作って、ターミナルでSQL文を打って結果を見ながら動作確認している感じです。
SQLiteをターミナルで操作する sqlite3 ./mytestdb.sqlite やテーブルの状況を見られる SELECT * FROM  filesTable; などのコマンドが大変役立っています。

たった2行で外部ライブラリも使わずにPHPだけでテンプレートを実現する

 PHPの基本機能だけでテンプレートっぽいことを実現します。
 使用するPHPの関数は、file_get_contents ()とprintf ()だけです。

この手法のメリットとしては主にこのようなものがあります。
・ページ本体のソースが読みやすくなる
・テンプレート化した部分を、他のページで使いまわすことができる

テンプレートエンジンを使わないことには以下のようなメリットがあります。
・素のhtmlに近い形で書けるようになり、読み書きが楽になる
・導入の手間がかからない
・新しくテンプレートエンジンの文法を覚えなくてよい
・余計な不具合を持ち込まずに済む
・不具合が起きても、仕組みが単純なので原因特定が容易

もちろんデメリットもあります。あまり複雑なことができません。

いろいろ工夫はできますが、もう少し複雑になったら、テンプレートエンジンか別の手を検討すべきです。しかし、ちょっとしたWebページなら、わざわざ追加のライブラリを加えて仕組みを複雑にすることは避けるべきだと思います。

個人的な事情として、「漏れのある抽象化の法則」(Joel on Software)に則って、必要な知識が身につくまでは、ライブラリの導入は避けて素のhtml+phpを使おうという方針の問題もあります。



実際の記述

読みこむ側が、file_get_contents ()でテンプレートを変数に読み込みます。
printf ()にテンプレートを渡せばokです。
例:
        $srcStr = file_get_contents("imgarea_templete.html");
        printf ( $srcStr, $imgUrl, basename($imgUrl));


テンプレートファイルの中身はこんな感じです。
例:(imgarea_templete.html)
    <div class="imgarea">
        <img src="%s" width=200 align=left><br>
        画像についてメモする<br>
           
            <textarea></textarea>
           
        <Br clear="left">%s
    </div>
    <br><br>

どう見ても、単なるprintf ()関数の第一引数ですね。
ダブルクオーテーション(")をバックスラッシュ(\)でエスケープしなくて済むのも良いです。


私はforループの内部で使っています。
これでfor文の中がかなりすっきりします。
例:
        $srcStr = file_get_contents("imgarea_templete.php");        for ($i = 0; $i < 10 ; $i++ ){
            $imgIndex = ($page-1)*10 +$i;
            if ("" != ($imgUrl = imgUrlfromNum($imgIndex, $imgArray))){
                printf ( $srcStr, $imgUrl, basename($imgUrl));
            }else{
                break;
            }
        }

おまけ:テンプレート化までの過程

ちなみに発展の過程はだいたい以下の順序です。

(1)とりあえずprint関数が並んでいる
例:
    print '<img src=". $imgUrl .">';
    print '<br><br>';

(2)ごちゃごちゃしはじめる
ブラウザ側のHTMLソースを見ながらデバッグするので、改行やタブを入れておかないと読みづらいです。でも、改行やタブを入れると、サーバ側ソースのPHP文が汚くなっていきます。
例:
    print "\t" . '<img src="' . $imgUrl . '"><br>' . "\n";
    print '<br>' . "\n";

ちなみに、HTMLソースはダブルクオーテーション(")を多用する性質があります。
そのため、シングルクオーテーションで囲む記法のダブルクオーテーションを含むHTMLソースの書きやすさと、ダブルクオーテーション囲む記法で使える書式文字による改行やタブの利便性は、トレードオフの関係になります。
例:
    print "\t" . '<img src="' . $imgUrl . '" width="300" ><br>' . "\n";
    print "\t<img src=\"" . $imgUrl . "\" width=\"300\" ><br>\n";

(3)行数が増えていく
ページが作成が進むほど、html文が長くなっていきます。
例:
    print "\t" . '<img src="' . $imgUrl . '"><br>' . "\n";
    print "\t<textarea></textarea><br>\n";
    print '<br>' . "\n";

実際にはさらに<div>タグやalign要素などが増えていきます。
このあたりで、将来的にリンク<a href>や送信フォーム<form>も追加する必要があるなぁ、毎回print関数とタブと改行を連結させるコードを書くのは大変だなぁ、と気づきます。

(4)printを一つにまとめる
これまで一行ごとにprint関数を呼んでいましたが、行数が増えたらまとめられることに気づきます。
例:
    print  "<div>\n".
    "\t<img src=\"". $imgUrl . "\">\n".
    print  "</div>\n".
なお、phpのソース中で文字列を改行して折り返す場合、2つの方法があります。
1.行をまたいで文字列を連結する
    "<div>\n".
    "</div>\n";
2. 文字列中で改行する
    "<div>\n
    </div>\n";
(5)printf文が登場
ところで、ここまでのprint文は、実のところfor文の中に入っていました(唐突ですが)。for文の中はすっきりしていたほうが読みやすいです。
複数行の文字列をまとめると、 変数に格納することができるようになります。そうはいっても、ファイル名などの部分は置換しなければならないので、変数に書式文字列を格納してprintf関数を使うという形になります。
例:
    $str = "<div>\n".
    "\t<img src=\"%s\">\n".
    "</div>\n";
    for($i=0;$i < 10; $i++){
      printf ($str, $arg[$i]);
    }

(6)外部ファイル化
冒頭の例になる、というわけです。


テンプレートは素のhtml文に近いほうが読みやすいし書きやすいです。そして簡単に置換ができるのが良いテンプレートだと思います。




記事タイトルがライフハック系エントリみたいですね...。

追記:
初めてのPHPを読んでいたのですが、str_replace() すごい便利そうですね。
どうして検索で引っかからなかったんだろう。

PHPでアップロード可能なファイルサイズの上限値を取得する

 PHPでアップロードファイルサイズの上限値を設定する方法は見つかるのですが、設定が反映されているかどうかを確認する方法が見つからないので関数を書いてみました。
PHP側で最大ファイルサイズを取得すれば、.htaccessやapacheサーバ設定の兼ね合いで実際の上限値が思った値になっていなかった場合でも、そのことが簡単にわかります。

具体的には、アップロードページで「『アップロードできるファイルのサイズは20MBまでです』などと表示しつつ、実際には2MBのファイルまでしかアップロードできない」といったような、厄介な不具合を回避できます。

この関数を書くにあたって、Apptechs Blog様の.htaccessへのアップロード上限の設定方法から上限値を決める設定オプションを、PHPリファレンスマニュアルのini_get()関数から設定オプションの値を取得する方法とバイトサイズへの変換関数を、それぞれ参考にさせていただきました。


 PHPソース

    //アップロードファイルサイズの上限を取得する
    function getMaxUploadSize(){
        /*アップロードファイルサイズの上限は以下の3項目のうちの最小値。
        通常は memory_limit > post_max_size > upload_max_filesize
        */
        $limit_max = (ini_get_bytes('post_max_size') < ini_get_bytes('upload_max_filesize') )?
                    'post_max_size' : 'upload_max_filesize';
        $limit_max = (ini_get_bytes($limit_max) < ini_get_bytes('memory_limit'))?
                    $limit_max : 'memory_limit';
        return ini_get($limit_max);
    }

   
    //設定オプションを整数表現に変換して返す。   
    function ini_get_bytes($varname) {
        $val = ini_get($varname);
        $val = trim($val);
        $last = strtolower($val[strlen($val)-1]);
        switch($last) {
            // 'G' は PHP 5.1.0 以降で使用可能です
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }

        return $val;
    }
   

追記

PHPリファレンスマニュアルのini_get()関数のページに「ini_get()で取得できる設定値は"2M"とかのstringでintじゃないから、しっかり変換噛ませないとだめだよ」と書いてあるのに、うっかりしてini_get()の戻り値をそのまま比較してしまいました。
最初はこんな風に書いて値を比較しようとしていたわけです。
        $limit_max = ($limit_max < ini_get('memory_limit'))?
                   
$limit_max : ini_get('memory_limit')?
おかげで、「最大サイズ128MB」と表示されて「おかしいなー」と頭をひねることに。
リファレンスマニュアル側でわざわざ例として関数return_bytes()を示してまで強調してくれていたのに、恥ずかしい限りです。
そして、ini_get_bytes()関数はこのreturn_bytes()を改造したものです。

jsのasyncなメソッドをfor,loop内で同期的に呼び出す

async/awaitを使ったjavascriptのコードをnodejsで使用する際、非同期呼び出しとなっている関数をloopの中で動機呼び出しする方法。 この前かなり真剣にPromiseのドキュメントを読んで、これをいずれ使うことになるのか、使いこなすの大変そうだな、と思っ...