Main menu:


 

2008年 3月
« 2月   4月 »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

最近の投稿

最近のコメント

カテゴリー

アーカイブ

 

運営サイト

Twitter

MAの輪

リンク

RSS

ʸۿƱ

Profile

社会人を始めた時にはコンサルタントという名のC/C++プログラマーでした。それから12年、プログラミングから離れて10年近く、似非エンジニアと周りには言われつつ、35歳を目前になんだかやたら燃えてます。最近はRubyを覚えたいなと本を買ったのはいいけど、PHP/JavaScriptの便利さに引きずり込まれ、何もできていない状況、、、

 

MA3

最優秀賞を頂きました!

2008/03

[PHP][ 開発日誌]get_headers()とX-JSON

ONGMAPのVersion2をいま作っているんですが、利用しているWeb-APIを久々に見直していたら、とあるWeb-APIの仕様が全く変わっていました(といっても、公開されているAPIではないので、文句は言えないのですが・・・)

で、新しくなったAPIを見てみると、初めて見る形。Prototype.jsあたりで使われているそうなんですが、HTTPヘッダーの中に、「X-JSON」という項目を埋め込んで、データとコンテンツを切り離して送るやり方だそうです。

ただ、ONGMAPでは、一旦サーバーサイドで処理したいので、PHPでそれを処理したい。でも、いつも使っている「file_get_contents()」ではヘッダー部分は取得できないので、調べたところ、get_headers()という関数が使えるらしい。

で、早速使ってみたんですが、get_headersのバグなのか仕様なのか、よく分からない挙動にはまってので、メモしておきます。

get_headersはヘッダーをハッシュに整形して出力してくれるので、X-JSONであれば、

$hd = get_headers($url,1);
$xjson = $hd['X-Json'];

で簡単に取得できると思っていたところ、なぜかうまくいかない。$xjsonを出力しても、尻切れトンボになってしまっていて、後ろ部分のデータがどこかにいってしまっている。

色々と出力を調べたところ、X-JSON部分のデータが複数にぶつ切りされてしまっていた。つまり、

$hd = array(
  ...
  ["X-Json"] => ([...][...]...[...],
  [5] => [...][...]...[...],
  [6]=> [...][...]...[...])
  ...
);

みたいな感じに、なんの脈絡もないフィールドに分断されて格納されてしまっている。これは、X-JSONフィールドが大きすぎたためにget_headersの仕様として分断したのか、 バグなのかよく分からないけど、とにかく分断されているものを結合しないとどうにもならないので、結合(とくに間に何も詰めないで結合しました)

で、その後に、最初と最後にくっついている”(”と”)”を削除して、json_decodeとやったら、無事デコードされてくれました。

[PHP][ 開発日誌]PHPでの型

はまったので、メモ

PHPで文字列と数値を比較すると、文字列が自動的に数値にキャストされてから比較される

そもそも比較するなという突っ込みもありますが 、PHPの本か何かに書いてあったようななかったような。つまり、$aが文字列、$bが数値だとすると、

$a == $b  → (integer)$a == $b

ということなんですね。で、何にはまったかというと、

function foo($a){
  if($a != 0){ 処理 }
  ...
}
$arr = array(0,"hello","world",...);
foreach($arr as $item){
  foo($item);
}

こんな感じの処理。$aに”hello”とか”world”とか入っていた場合、0じゃないので処理をしてもらいたいのが、$a!=0はfalseになってしまって、処理をやってくれない。

何が起きているかというと、

"hello" != 0  → (integer)"hello" != 0 → 0 != 0 → FALSE

という具合。つまり文字列は数値にキャストすると0になってしまう。

(でも、実はそんなに単純じゃなくて、”1cm”とか”4kg”みたいな文字列は、それぞれ数値の1と4に変換される。つまり文字列の最初に数字がある場合はその数字が続くところまでを取り出して数値 に変換して、何も無い場合は0に変換するということですね。)

まだまだ初心者の域をでてないなと痛感した「はまり」でした。

ちなみに上の処理は単純に、値と型の両方を比較する「===」や「!==」を素直に使えば済む問題です。

[Ext JS][ 開発日誌]Ext JSのGridPanelでword-wrap(テキスト折り返し)

ExtのGridでword-wrapをしたいときの方法(ここで発見):

.x-grid3-cell-inner, .x-grid3-hd-inner {
   overflow: 	    auto;
   white-space:  normal;
}

助かった!

[API][ メモ]Google AJAX Language API

Google AJAX Language API

ちょっと試してみましたが、色々と工夫しないとまだまだな印象でしょうか?文章そのもを訳すのではなく、メニューとか短めのメッセージなんかは意外といけるかもしれないですね。となると、ONGMAPの多国語化ができる!?

ただ、日本語から直接変換できるのは今のところ英語だけなので、他の言語に変換するには一旦英語を経由する必要があります。なので、英語への変換がこけると他の言語への変換は目もあてられなくなりますね。 英語→?の変換はどの程度の精度か分かりませんが、英語は用意した方がいいですね。

*デモを作ってみました

[メモ]Safari3.1がすごく速い

最近リリースされたSafari3.1ですが、なんだかやたらと速くないですか?

特にJavaScriptの実行速度(体感)がもう最強最速な感じです。

FireFox3b4も大分速くなった印象がありますが、それにしてもこのSafari3.1の速度は尋常じゃないなぁ。なぜだ?Windows環境でも動かしてみたけど、速い。とにかくJavaScriptが速いっっっっっっ!

ONGMAPはSafari3.1でご利用ください!

これだと普段使うブラウザはSafariに乗り換えた方が気持ちいいかも(前は使えなかったWordPressのエディタも使えるようになってるし!)

これで、Safari用のFireBugとかGreasemonkeyとかあったら最高なんだけど 。

[PHP][ 開発日誌]AJAXリクエストの戻り値をgzencodeで圧縮、これって当たり前?

ちょっと前にApacheでのJavaScriptファイルの圧縮設定についてのメモを書きましたが、JSファイルだけじゃなくてAJAXリクエストをしたときにサーバーから返される文字列も圧縮できないかと思い、phpの「gzencode」関数を使ってみたら、サクッと動いてくれました(gzencode関数を使うにはzlibライブラリが必要になります)

やり方は、返したい文字列をgzencodeで圧縮するだけなんですが、ヘッダーに圧縮方式を指定してあげないとブラウザ側で解凍できないので、こんな感じになります:

$out = "何かの文字列";
if(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip')!==false && function_exists('gzencode')){
  header('Content-Encoding:gzip');
  $out = gzencode($out);
}
echo $out;

それにしても、gzencodeでググったのですが、あんまり事例が出てこないですね。当たり前すぎのノウハウ?

[PHP][ 開発日誌]Xdebug on Leopard

Windowsでも利用していたXdebugをLeopardでも使おうと思ってインストールしようとしたところ、ここ数日のハマリ癖のせいか、またまたはまってしまいました・・・。

以前書きましたが、僕のMacBookProでは、ApacheとPHPはLeopardにデフォルトで入っているものを、MySQLはMacportを利用してインストールしました。

そんな環境にXdebugを入れようと思いコマンドラインから、

pecl install -a xdebug

と、やってみたところ、普通に「xdebug.so」が生成されて以下のディレクトリにインストールされていました

/usr/lib/php/extensions/no-debug-non-zts-20060613

そこで、php.iniに以下の3行を追加

extension=xdebug.so
xdebug.profiler_enable=1
xdebug.profiler_output_dir = "/var/log/xdebug"

そのあと、Apacheを再起動して、phpinfoで確認してみるけどxdebugがロードされていない。色々とググって「extension=」を「zend_extension=」としてみたり 、フルパスで指定してみたり試してみたけど、Apacheは起動するのに、xdebugのライブラリはどうにもロードされない(一旦xdebugをあきらめて、ZendDebuggerを入れようとしてみたけど、同様にロードされず)

あんまり気が進まないけど、どうもLeopardデフォルトのPHPがいまいちっぽいので Makeすることにしてみました(デフォルトのPHPは5.2.4。今日現在、最新の安定版は5.2.5なので、これをダウンロード)

色々とconfigが面倒なので、「Mac OS X LeopardでPHP開発環境を整える」を参考に自分の環境に合わせて:

./configure
--prefix=/usr/local/php5
--program-suffix=
--infodir=/usr/local/share/info
--mandir=/usr/local/share/man
--with-config-file-path=/usr/local/lib/php5
--with-config-file-scan-dir=/usr/local/lib/php.d
--with-pear=/usr/local/lib/php5/pear
--sysconfdir=/usr/local/lib/php5/etc
--with-apxs2=/usr/sbin/apxs **
--with-zlib-dir=/opt
--enable-sockets
--enable-exif
--with-mysqli=/opt/local/lib/mysql5/bin/mysql_config
--with-mysql=/usr/local/mysql5 **
--with-xml
--enable-mbstring
--with-libmbfl
--enable-wddx
--enable-zend-multibyte
--enable-discard-path
--enable-cgi
--enable-track-vars
--enable-force-cgi-redirect
--with-gd=/opt/local
--with-jpeg-dir=/opt/local
--with-png-dir=/opt/local
--with-freetype-dir=/opt/local
--with-pdo-mysql=/opt/local/lib/mysql5

(変更したのは、**のところ)

もちろん、案の定エラーでまくり。結果的これらのエラーを一つ一つ解決しようとしてはまったわけですが・・・。

まずは、なんだか色んなライブラリが入ってないみたいなので、上のサイトを参考にしながらMacportsを使って、適当にライブラリを入れてみました(jpegとかgd2とか)。

(自分用メモ:「–with-mysql=」ではmysqlのベースディレクトリを指定する必要があって、そのディレクトリの下には「include/」と「lib/」が必要なんだけど、そんな構成のディレクトリが見つからなかったので、作る必要がありました。なぜか、以前macportでインストールしたmysql5は、「/opt/local/」の下の、「include/mysql5/mysql」と「lib/mysql5/mysql」に散らばっていたので、「/usr/local/」の下にmysql5を作って、そこにそれぞれへのディレクトリへのリンクを張る形でベースディレクトリを作ってみました。「bin」もついでに作りました。)

あと、iconvまわりでもエラーがでるので、それについては「Leopard に PHP をインストール」

ext/iconv/iconv.c の iconv_open と iconv_close を libiconv_open と libiconv_close に書き換える。

を参考にしました。

これでようやくPHPのmake&installが完了したので、Apacheを再起動しようとしたら、今度は新しく作ったlibphp.so がロードできないと言って、Apacheが起動してくれない・・・。

頭に来たので、Apacheもデフォルトのものを捨ててインストールしようと思って、再度Macports。

が、しかし、エラー、エラー、エラー!まったく意味が分からないエラー が発生。

ググったところ、同じ問題に直面したかたのブログを発見→「MacPortsのApache2.2.8」。ここを参考にして、

/opt/local/var/macports/build/_opt_local_(中略)_www_php5/work/build/config_vars.mk

を修正して、再度 Macports(port install apache2)したところ、なんとかインストール完了。

これまでのApacheをkillして、新しいApacheをstartしたところ、よ・う・や・く、xdebugがロードされてた!

ただ、xdebugだけだとプロファイルログが全然読めないので、Windowsで使っていたWinCacheGrindの大元のKCacheGrindを今日散々お世話になったMacportsでインストール(port install kcachegrind)したところ、なんだか関連するライブラリのインストールが始まり、それが延々と続き、1時間以上かかってようやく完了。

xdebug入れるためだけに、環境全て再構築してしまいました ・・・。

ただ、やっぱりxdebugでプロファイル見たおかげで、濡れ雑巾絞るように非効率な部分のチューニングはできました。

[開発日誌]IE7ではまった・・・

IE7、個人的にほとんど使ったことないんですが、それなりのシェアになってきているようなので、無視することもできず、昨日今日とはまりました。

IE6みたいにムチャクチャな動きをするわけではないけど、でも完全にこちらの意図どおりに動いてくれるわけでもなく。

IE6みたいに豊富な情報がつみあがっているわけでもないので、ググっても中々解決法が出てこず。

具体的には、Ex JSでRowExpanderを組み込んだGridPanelを生成する際に、 複数のColumnをHidden状態にしていると、レイアウトが微妙にずれてしまう、という気持ち悪い状況(って、まったく意味分かりませんよね)

なんとか、Ext.isIE7みたいな気持ち悪いやり方で幅を調整する手段をとったけど、気持ち悪いものは気持ち悪い。

普段は解決法見つけてからブログに書くんですが、どうにも見つかりそうにないので、愚痴を書いてみました。

・・・

あ、あと、OSX版のFireFoxでは、なぜかDIVのScrollbarがすべてに優先して一番上に来てしまって困ってます 。だれか、解決方法しりませんかぁ・・・?

[Javascript][ 開発日誌]JavaScriptの圧縮と難読化

JavaScript の圧縮と難読化の定番ツールといえば、「packer」ということを聞いて、試してみました(実は以前にも試したことがあったのですが、なかなかエラーを取り除くことができずギブアップしたことがあります)

今回はちゃんとHelpページを読んで、Firebugでエラー箇所を追いかけながらやってみたところ、なんとか動かすことができたので、そのメモ:

「Packerを使うときは、セミコロン(;)に注意」

ヘルプページにも書いてありますが、functionの定義の終わりにセミコロンを入れないとエラーになってしまいます。あと、functionと同じく、オブジェクトリテラルも「{…};」みたいな感じでセミコロンを入れないとエラー。

要はオブジェクト定義の最後にはセミコロン、ということです。実際のところ、FireFoxもIEもオブジェクト定義の最後にセミコロンが無くても普通に動いてしまうので、今回圧縮したコードにはこの「セミコロン抜け」が結構な数見つかりました・・・。

packerにはオプションが二つあって、

  • Base62 encode
  • Shrink variables

 

この二つを使わないと、単純に空白と改行を取り除いてくれるだけなので、それほど圧縮も難読化もできません(今回のコードで約25%の圧縮)。

「Base62 encode」を使うといい感じに圧縮&難読化されます(約50%の圧縮)

「Shrink variables」を使うとさらに数パーセント圧縮されるのですが、今回のコードではなぜか、ここでエラーがでてしまい、デバッグのやり方も分からず今回はこのオプションは使わずに「Base62 encode」だけを利用してみました。