12月 10
最近、CMSを使わないサイトの場合、ZendFramework + Smary + DB_DataObjectというのが、僕の中で効率よく開発できるパターンになってきました。(DB_DataObject? Smarty? …プ! とか言わないで ///)
先日、とあるサイトに、とあるシステムを納品したのだけれど、本番環境で動作確認してみると、Zendframeworkが下記のエラーを出力。もちろん、テスト環境では十分テストして、ライブラリのパス等も絶対に間違ってないのに、なぜか、下記エラーが。
Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (index)’ in /xxx/xxx/ZendFramework/library/Zend/Controller/Dispatcher/Standard.php:242
Stack trace:
#0 xxxxxx/ZendFramework/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 xxxxxx/xxxx/index.php(34): Zend_Controller_Front->dispatch()
#2 {main} thrown in /xxxx/xxxx/ZendFramework/library/Zend/Controller/Dispatcher/Standard.php on line 242
通常、このエラーは、単に該当のControllerのphpファイルが無い場合に出たりするんだけれど、今回は違う。ソースも全部もってきて確実にファイルは存在する。しかし、エラーが消えない。
テスト環境と本番環境でPHPのバージョンにすこし違いがあったから、Zendframeworkがちゃんと機能してないのか?と、Zendframeworkのバージョンを下げてみたけど変わらず。
悩みに悩んで、ググりつつ、やっと解決。最初にコールされるindexのコントローラファイルが、
indexController.php
になっていたのだ!!!
Controllerファイルは、
http://blog.favrik.com/2008/08/30/invalid-controller-specified-zend-framework/
に書いてあるように、コントローラ名+Contoroller.phpになるのだが、コントローラ名は、最初大文字、以後小文字でなければならない。つまり、
IndexController.php
としなければならない。テスト環境は、サーバにMacを使っていたため、HFS+で、Case Insensitiveだから、大文字小文字の区別なく(=区別できず)、誤ったファイル名でも、動いていたのである。
いやー、冷や汗かきました。ちなみに、ErrorControllerを作ってない場合は、
Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (error)’ in /xxx/xxx/ZendFramework/library/Zend/Controller/Dispatcher/Standard.php:242
がでます。IndexController.phpを探しに行ったけど無い→エラーを投げる→ErrorController.phpも無い→Invalid controller specified (error)となり、よけい分かりづらくなります。
Macのファイルシステムを、Case Sensitiveなものにすることもできるけど、これはこれで、Mac上のネイティブアプリ等に影響がでるらしく、問題ありそう。
コントローラファイルは存在するのに、上記エラーが出る場合は、ファイル名の大文字・小文字を疑ってみてください。
Popularity: 3% [?]
written by ANN
7月 29
phpにはstrip_tagsという、タグを取り除く関数があるが、特定のタグに挟まれた部分をごっそり削除したい場合、これは該当しない。PEARを探してみたけど、それっぽいのを発見できず。しょうがないので正規表現で書いてみる。(むしろ備忘録)
具体的にどういう時に使うかというと、PHPからの出力時に、
- <style>~</style>タグの中身を全部削除したい
- <script>~</script>タグの中身を全部削除したい
- コメント用の独自タグを、出力時にタグの中身もろとも削除したい。
などなど。テンプレートHTMLの編集時には必要だけど、最終的な出力時にはいらないタグとか。
また、RSSなど、出力先によっては、本文中に含まれるscriptタグが不要な場合などに。
>>>>>続きを読む
Popularity: 19% [?]
written by ANN
5月 22
ニーズが無いだろうけど、書く!
PHPのGDで巨大な画像ファイルを処理すると、負荷がすごい。そこでMacのサーバ限定だけど、sipsコマンドを使うことで低負荷/高速/高画質の画像変換ができるんじゃね?というのが前回のエントリーの内容。
実際に某サーバーの処理を書き換えて試してたところ、うまくいく場合と、いかない場合があることに気づいた。なかなか原因がわからなかったが、やっとわかったので、sipsコマンドをPHPから呼び出す際の注意点について書いてみたい。
sipsコマンドの使い方としては、こんな感じ。
/usr/bin/sips –resampleHeight 100 変換前ファイル –out 変換後ファイル
php内では、ふつうにsystem()でOK.
$srcfile = "/var/home/hoge/fuhihi.jpg";
$dstfile = "/var/home/hoge/fuuu.jpg";
system("/usr/bin/sips --resampleHeight 100 $srcfile --out $dstfile");
このとき、出力側のファイルとなる$dstfileのパスに、シンボリックリンクが含まれていると、sipsが書き出しに失敗する。
なぜか、入力側($srcfile)にシンボリックリンクが含まれていても問題ない様子。
画像変換した後のファイルの出力において、なぜ区別する必要があったのだろうか。単純にバグだろうか。
いや、普通に考えて画像変換程度で、区別する必要はないだろう。
しかし、そうなってる以上、考えてもしょうがないで対策。
$srcfile = realpath("/var/home/hoge/fuhihi.jpg");
$dstfile = realpath("/var/home/hoge/fuuu.jpg");
system("/usr/bin/sips --resampleHeight 100 $srcfile --out $dstfile");
単純に、sipsに渡すパスに対して、realpath()を通してやることで、シンボリックリンクが実体のパスになるので、これで問題なし。
便宜上、PHPで使う場合…という感じで書いたが、system()からはshell経由で呼ばれるはずなので、shell上でも同じ問題が発生します。
ただし、あくまで出力ファイルのパスにシンボリックリンクが含まれているのがまずいだけであって、たとえば、カレントディレクトリにシンボリックリンクが含まれていても、sipsコマンドのパスに含まれてなければOKです(ややこしい。だからなかなか原因がわからなかった)
最近は、OS X Serverを使ったりしてるので、その周りも後ほど書いてみたい。
Popularity: 7% [?]
written by ANN
4月 16
phpで画像処理する定番といえば、組み込みのGD(PHP: GD – Manual)が定番なのだけれど、どうも処理元の画像が大きいと、非常に処理が重たい気がする。
とある画像データベースサイトでは、デジカメで撮影した画像を大量にアップロード・リサイズする必要があり、GDで処理していたのだが、最近のデジカメは1ファイルが12~15Mバイトもめずらしくなく、コレを何十枚と処理していくと、結局、apacheさんの負荷およびCPUの負荷がハンパなく、すぐにLoad avgが急上昇してしまう。
なんとか改善できないかと考えて、サーバがMac(OS X)だから、sipsコマンド【Scriptable Image Processing System(スクリプト可能イメージ処理システム)】が使えないかと考えた。変換処理をコマンドに任せることでapache(httpd)の負荷も減らせるかもしれないし。
- sips 公式テクニカルノート Technical Note TN2035: ColorSync on Mac OS X
- SIPS コマンド – 画像をコマンドラインで – その1 (リサイズ / 回転 / 反転 など) — — 脳みその中身-
試しにいくつかリサイズしてみたところ、体感的にはPHP/GDのリサイズより早い気がした。
気がしただけでは面白くないので、実際に簡単なサンプルを作ってベンチマークをとってみた。
つまり、SIPS vs GDである。
>>>>>続きを読む
Popularity: 13% [?]
written by ANN
4月 14
PHPでプログラムの処理速度を調べたりするのに、xdebugを使ったりするのもよいけど、手軽で簡単なのものに、PEARのbenchmarkというのがあります。
benchmarkそのものが入ってない場合は、
$ pear install Benchmark
でOK.(必要に応じてsudoで)
使い方はググればすぐサンプルがでるが、だいたいこんな感じ。
require_once 'Benchmark/Timer.php';
$t = new Benchmark_Timer();
$t->start ();
$t->setMarker( 't1' );
for($i=0;$i<10000;$i++){
// 処理
}
$t->setMarker('m2');
$t->stop();
$t->display ();
これを、ブラウザ上から実行すると、HTMLのtableにフォーマットされた結果が表示される。
↓こんな感じ
| |
time index |
ex time |
% |
| Start |
1239674031.65831000 |
- |
0.00% |
| m1 |
1239674031.65838100 |
0.000071 |
0.59% |
| m2 |
1239674031.67032200 |
0.011941 |
99.03% |
| Stop |
1239674031.67036800 |
0.000046 |
0.38% |
| total |
- |
0.012058 |
100.00% |
で、今日のTipsとして、普通にBenchmark_Timer::display()を使うと、画面上に結果が表示されてしまうので、結果を表示せずに取得する方法。
簡単。Benchmark_Timer::getOutput()もしくは、Benchmark_Timer::getProfiling()を、displayの替わりに使えばOK。
getOutput()は、上記tableと同様のHTMLコードを取得できる。
getProfiling()は、上記tableと同様のデータを連想配列として取得できる。
↓こんな感じ
Array
(
[0] => Array
(
[name] => Start
[time] => 1239674550.91492500
[diff] => -
[total] => -
)
[1] => Array
(
[name] => m1
[time] => 1239674550.91499700
[diff] => 0.000072
[total] => 0.000072
)
[2] => Array
(
[name] => m2
[time] => 1239674550.92797600
[diff] => 0.012979
[total] => 0.013051
)
[3] => Array
(
[name] => Stop
[time] => 1239674550.92806900
[diff] => 0.000093
[total] => 0.013144
)
)
なぜかPear/Benchmarkにはドキュメントが無くて、ソースを読むしかないので、Benchmark使えなねー!と思ってる人がいるかもしれないので書いてみました。
…と思ったら、結構getOutput,getProfilingの解説してるページがあった(///
重複してるだけでなく、こちらにはそれ以上の情報が無いのが辛いが、せっかくなので公開。
Popularity: 12% [?]
written by ANN
11月 26
例)hoge.pdfの表紙(1ページ目)から解像度72dpiのout.pngを作成
Ghostscriptの場合
#gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -r72 -dFirstPage=1 -dLastPage=1 -sOutputFile=out.png hoge.pdf
解像度とかを指定したりできるしねー。
ImageMagickの場合
#convert hoge.pdf[0] out.png
こりゃ楽だなぁ。
PHP + ImageMagick ⇒ pecl :: Imagick の場合
※最新バージョンを利用するにはPHP5.1.3以上、ImageMagick6.2以上が必要です。
インストールはpecl install imagick
$img = new Imagick('hoge.pdf');
$img->setImageIndex(0);
$img->writeImage('out.png');
//$img->writeImages('out.png');とすると全ページを画像にしてくれる
$img->destroy();
もちろんリサイズとかもOK。
ImageMagick以外にもGraphicMagickとかあるのね。ImageMagick2もあるらしい。
Popularity: 22% [?]
written by joy-pop
11月 08
MOONGIFT: » 必見!怖くなるくらい優秀なCMS「concrete5」:オープンソースを毎日紹介
具体的にどのへんが怖くなるのか書いてないので解らないけれど、とにかくすごそうなので、concrete5を試してみた。
concreteって、コンクリート??でいいの??
ウェブ用のディレクトリに適当にコピーして、DBを作っておいて、
設置したパスにアクセス。インストールするための画面がでるのて、適当に入力してサブミット。
(詳しくはこの方を参考→☆CMS「concrete5」を試してみた – toytools log)
で、実際に使ってみようとおもったら、インストールでコケた。
そこで、インストールする際の注意点を書いてみる。
>>>>>続きを読む
Popularity: 44% [?]
written by ANN
6月 06
テーブルの追加等もあり、久しぶりにPEAR::DB_DataObjectのcreateTables.phpを実行したら、なにやらErrorがでまくる。あれれ?前にErrorが出たときにはDBをアップグレードしたらOKだったのでDBのアップグレードを試みるとまたまたErrorが…。なんで?ということでPEAR自体をアップグレードしようとしてみたら、
$ pear upgrade PEAR
PEAR_Remote: unexpected HTTP response
ということで、もう完全におかしい。人を疑ってはいけないけど、先日鯖屋に設定してもらったup2dateを疑う。まあ、疑っても仕方ないので対処方法をググる。
同じエラーが出てる書き込みが
http://pear-forum.org/topic1855.html
にあって、その対処方法の参考になりそうなページがリンクしてあった。
Bug #12990 Issues with PEAR Upgrade News Item from 1/3/08
http://pear.php.net/bugs/bug.php?id=12990
どうも2008.3.1から古いPEAR::Console_Getoptだとv2 package.xmlが読み込めないので、新しいPEARにしてねってことのようだ。
pearのバージョンを確認すると1.3.2。あれえ?前にアップグレードした気がするんだけどなあ…。まあ、順を追って対処していくしかない。
$ pear upgrade –force http://pear.php.net/get/Archive_Tar
http://pear.php.net/get/XML_Parser
http://pear.php.net/get/Console_Getopt-1.2.2
$ pear upgrade –force http://pear.php.net/get/PEAR-1.3.3
(※↑これはpearのバージョンが1.3.2以下の人のみ)
$ pear upgrade –force http://pear.php.net/get/PEAR-1.4.3
$ pear upgrade PEAR
ん、これで一応、OKになった。
いやでも、これ前にやっぱりやった覚えあるぞ。うーむ。
Popularity: 10% [?]
written by joy-pop
4月 28
某社に限ったことなのかもしれないが、営業の人はExcelが好きのようだ。納品書や請求書などサーバーのデータを利用して出力する際、アウトプットするファイルをPDFにしたりすると不評のようだ。とにかく普段、取り扱いになれているExcelだと喜ばれる。
PHPでExcelファイルを出力するには、Spreadsheet_Excel_Writer、WindowsのサーバーならばCOMを利用する方法、Excel2007に限った話ならPHP Excelなんてのがある。入力に関しては前にSpreadsheet_Excel_Readerっていうのがあったような気がしたけど、見つからないな…。
で、以前、Spreadsheet_Excel_Writerを使って、PHPでシート追加して、セルの書式を設定して、セルに文字や数値をして…ということ延々繰り返し出力するということはやっていたけど、Spreadsheet_Excel_Readerがあるなら、Spreadsheet_Excel_Writerと組み合わせてExcelファイルを読み込んで、必要なところを書き換えて出力することができないかなーと考えていたら(考えてみただけ…)、もうやってくれている人がいたー!!やっほーい。
Excel_Reviser
Excel_Reviser便利です。今のところ複雑なファイル(グラフや画像オブジェクトが含まれたりしたファイル)は生成したりしていないので、問題もない。使い方はいたって簡単。
ベースとなるExcelブックを用意して、
require_once ‘reviser.php’;
$er = new Excel_Reviser();
//シートに文字列を挿入
//シート番号、行番号、列番号は0から始まる数値
$er->addString(シート番号,行番号,列番号,’文字列’);
//シートに数値を挿入
$er->addNumber(シート番号,行番号,列番号,数値);
//出力
$er->outfile(’ベースとなるExcelブックpath’, ‘出力ファイル名’);
もちろん細かく書式を設定したり、シートをコピー・削除・リネームしたり、ファイルに出力することも可能。サンプルファイルを参考にすれば、すぐ利用することができる。changeStr()という既存の文字列を置き換えるメソッドが存在するけど、空文字で置き換えようとすると出力するファイルが壊れるので注意。
計算式の挿入できるのかな?分かんね。addFomulaRecordというメソッドが存在するけど、binary-recordってどういうこっちゃ?教えてくださいエロい人。
元ファイルのVBAを引き継ぐことは無理のようだ。また、開発環境などdisplay_errors Onでerror_reporting E_ALLだとNoticeがでまくるので注意。error_reporting E_ALL ^ E_Noticeで使った方がいいみたい。
関連してExcel_Peruserというのもある。これはExcelファイルを読み込み、各セルの値を取得可能にする。ExcelファイルをHTMLに出力することができるなど、こちらも素晴らしい。
Popularity: 21% [?]
written by joy-pop