2007年09月19日

PHP5でRSSフィード等のXMLをパースする時にハマってしまったら

PHP4からPHP5への移行でハマりました。

PHP5 + PEAR::XML_Unserializer という組み合わせなので、ほとんど有り得ないケースだとは思いますが一応書いておきます。いきなり結論。

UTF-8でない文字コードのXMLをパースする時は、文字コード変換するだけでなくXML宣言のencoding指定も忘れずに書き換えておきましょう

そもそも論として今のご時世にUTF-8じゃなくてEUC-JPとかShift_JISでXMLを出力してくれているという事実に殺意すら覚えるのですが、まぁそうも言ってられないので curl なり HTTP_Client で取得したRSSを


$rss = mb_convert_encoding($rss, 'UTF-8', 'Shift_JIS');

とかって問答無用にUTF-8に変換してあげる訳です。そしてそのままXML_Unserializerに食わせてやります。...がここでPHP5の場合はWarning発生。


Warning: xml_parse(): input conversion failed due to input error in /[path]/[to]/[pear]/XML/Parser.php on line 509
Warning: xml_parse(): Bytes: 0xA0 0xE3 0x82 0xB9 in /[path]/[to]/[pear]//XML/Parser.php on line 509

こんなWarningメッセージが大量に出力されてXMLをパース出来ません。さて、ここで愕然としてどうしたものか...とググってみたり試行錯誤すること1時間。XML_Unserializerに食わせる直前のRSSをデバッグ出力した所を眺めていて非常に痛い所に気が付きました。


<?xml version="1.0" encoding="Shift_JIS" ?>
<rss version="2.0">
...(省略)...

RSS全体としては mb_convert_encoding によってUTF-8にしていたものの、XML宣言では Shift_JIS というチグハグな状態になっていた訳でして、そりゃ変な挙動をしても文句言えませんね。

そんな訳で


$rss = mb_convert_encoding($rss, 'UTF-8', 'Shift_JIS');
$rss = str_replace('Shift_JIS', 'UTF-8', $rss);

ってな感じにしてやると Warning も無くなりすんなりパースok。厳密に言うと str_replace ではダメなケースも出てくる筈なのでそこはXML宣言の該当部分だけ置換するようにちゃんと書きましょうって事で。


PHP4では上記のような現象は発生せずPHP5でのみ発生した理由についてもっと深く理解しておきたい所ですが、今は時間がないので納得出来ないながらも華麗にスルー。また暇を見付けて調べます。

ちなみにこの現象、ほとんど無いであろう PHP5 + XML_Unserializer の組み合わせで僕は遭遇していたのですが、ググって調べる過程でPHP5のSimpleXMLを使っても同様のエラーが発生している旨の書き込みを発見しました。...ので、そういうもんなのかも知れません。


ようは、言ってる事(XML宣言)とやってる事(XMLの中身)とを一致させましょねという非常に当たり前の事なのでした。はは...(泣)


っていうか、もう全部UTF-8にしちゃおうよというのは極論でしょうかね。EUC-JPはまだ理解できますが、Shift_JISなんて勘弁して下さい。Windowsローカルだけで良いじゃないですか(T_T)

2007年09月17日

PHP4からPHP5への移行についてのメモ

PHP4が2007年末をもってサポート終了、重大なセキュリティ問題への対処は8月8日まで...とPHP4に最後通告が出されて早くも2ヶ月が経過しました。年内の移行が勧められている状況下にあり、当社もこれに追随すべく移行作業中です。

PHP: Hypertext Preprocessor

とりあえず読んでおきたい記事をメモがてらに記録しておきます。色々とPHP5への移行について調べてみましたが、概ね以下の2つのリンク先をざーっと眺めておけば大丈夫なんじゃないでしょうか。

そろそろPHP5への...の方には関連するドキュメントへのリンクが多数掲載されていますので、そちらも併せて。それほど互換性は低くないので、結構何もしないでもサックリ移行が終わってしまうケースがあるんでしょうね。

...と良いながらウチは自前のRSS関連のフレームワーク(plaggerのPHP版みたいなモン)でちょっと修正する必要がありました。plug-inのような仕組みを持つプログラムの場合、get_class() 関数の挙動が4と5で違ったりとか、まぁでもそんなに大層な変更ではないでしょう。

PHP4に比べて遅いとか、互換性がほとんど無いってな評価はもう過去のモノだし、PHP5移行へのメリット/デメリットをどうこう言う時代は終焉を迎えようとしています。サポート外のものを使う訳にもいきませんから、どんどんPHP5化していきましょって事で。


個人的にはPHP4の中途半端なオブジェクト指向から脱却できるっていうのと、早くからPHP5専用への道を行ってしまわれたPHPUnitをようやくまともに使えるって事がとっても嬉しかったりするのです。


既存のプログラムがあって、どうしても移行が大変だという時にはアシアルさんとこのPHP移行支援コンサルティングにお願いしても良いかも知れません。

PHPで通常配列と連想配列とを区別する方法

PHPで配列を使う時、キーに整数値が並ぶリスト的な通常配列である場合と、スカラーであるキーとそれに対応する値をセットにした連想配列(ハッシュ)である場合とに大きく分かれます。そのいずれであっても同じように扱えるのが便利ではあるのですが、時に、その両者を区別したくなったりします。

リスト的な通常の配列は


Array
(
[0] => hoge
[1] => hige
[2] => huge
)

ってな感じにキーが連番になってる訳ですね。これは誰でも知ってる事です。かたや連想配列の場合は


Array
(
[key1] => hoge
[key2] => hige
[key3] => huge
)

こうなる訳です。こちらもおなじみですね。

この2つの配列を区別して処理を分けたい。後者のような連想配列の場合だけ特定の処理をしたい...といったようなケース。そんな時、キーの部分をうまく使います。


if(array_keys($array) === range(0, count($array)-1)){
    //通常配列の場合(前者)
}else{
    //連想配列の場合(後者)
}

対象となる配列からキー一覧を配列として持ってきて(array_keys関数)、連番生成した配列(range関数)と比較してやる訳です。これはとあるブログ(どこか忘れてしまいました、すいません)で発見したのですが、それまで難しく考え過ぎて時間をロスっていた自分に少し凹みながら判定式の美しさに惚れ惚れとした次第です。なるほどねー。

...という訳で、まぁこの手の区別が必要となるケースは余り無いと思うのですが、もしそんなケースがあれば是非。

2007年09月15日

RSS2.0のアイテム内のlinkやguidタグに & が含まれているとRSSフィードとして正しく評価されない件

プログラムでRSSを出力する事はよくある話。何度も何度もハマっていて今回もまたハマって、学習能力が無さげな自分に呆れながら記録としてブログに残す事にしました。もう掲題の通りです。

RSSのアイテムは


<item>
    <title>タイトル</title>
    <link>http://example.com/item/3/15/</link>
    <description>;lt;![CDATA[アイテムのlinkとguidの値に要注意]]></description>
    <guid>http://example.com/item/3/15/</guid>
    <pubDate>Sat, 15 Sep 2007 04:02:13 +0900</pubDate>
</item>

ってな感じに書かれるのが一般的。feedburnerを通していたり、ポッドキャスティング用だったりすると、もう少しタグの数は増えますが、itemとしては基本これぐらいの構成です。

この link と guid がくせ者。(いぁまぁ当たり前といえば当たり前なのですが)

例えば、link が http://example.com/item.php?hoge=3&hige=15 というようにアイテムのURLが動的生成するページになっているのはよくある事ですが、そのURLに2つ以上のパラメタが並んで&が入っていると、IE7もFireFoxも正しく表示してくれません。(Safariでは正しく表示されます)

IEではエラー
skitched-20070915-160859.jpg


FireFoxでは空っぽのRSSに見える
skitched-20070915-160846.jpg

初めて遭遇すると、なかなか気付かず時間を無駄にしてしまいます。プログラム的には正しくRSSを出力しているのだけどIE7やFireFoxで開いたときに表示がおかしい場合は、まず link タグと guid タグの中身を疑ってみましょう。&を&amp; に変更し、

http://example.com/item.php?hoge=3&amp;hige=15

のようにしておきます。これで問題なく表示されます。それでも表示されない場合は別に原因がある可能性がありますので、RSSの仕様書や参考書を見て確認してみましょう。

あ、ちなみに、同じ理由でRSSそのものを表す channel タグ内の link タグにも注意しましょう。

2007年09月01日

QuickSilverとAtokの組み合わせでQuickSilverが暴走するのを回避する

余りに嬉しかったので思わずエントリ。

OSXが立ち上がったらまず最初にTerminalを起動する系の開発者なMac使いの多くがインストールしているアプリケーション「QuickSilver

30A230D5309A30EA30B130FC30B730E730F3

いわゆるランチャーというヤツですが、その万能ぶりに色んなサイトで取り上げられているのをご存じの方も多いでしょう。

Bezel Interface

でもこのソフト。どうもFEP(今はこんな表現しないか。Atokやことえり等のカナ漢字変換システム)と相性が悪いのです。僕はAtokを使っていますが、Atokを巻き込んでQuickSilverが暴走してしまう事がしばしば。

アプリケーションをcoolにコマンドラインから立ち上げようとしたのに、かえって「強制終了」「QuickSilver再起動」なんて手間が加わって、こんな事ならマウス使ってアイコンをダブルクリックした方が早いやん!という事がままありました。

でも格好良過ぎるランチャーだし、ランチャーの割に色んな作業をこなしてくれる万能アプリ(?)なのでずっと使ってた訳ですよ、時々「イラッ」としながらね。

...が!今日になって以下のエントリにその暴走を止める方法が載ってるのを発見して狂喜乱舞。これでストレス感じる事無くcoolにQuickSilverを使いまくれるぞとなった訳です。古橋さん、ありがとう。

開発環境としてのMac OS Xカスタマイズ

方法は、とあるオプションを外すだけ。QuickSilverのPreferenceを開いて、左のメニューからAppearanceを選択、そして「Superfluous visual effects」のチェックを外します。QuickSilverでコマンド入力を開始する時に表示されるニョキっというアニメーション周りが悪さをしていたという事ですね。

Preferences

こんな事なら最初から全オプションをチェックしておけば良かったと今更ながら後悔。余りにもオプションが多いので、どれが原因か、どの組み合わせがトリガになって暴走しているのか調べるのが面倒臭かったんですよね。



という訳で、Windowsでは絶対に味わえないcoolなランチャー(もはやランチャーの域を超えているとも言う)「QuickSilver」を満喫出来るようになりました。万歳。

QuickSilverをお使いでAtokやらことえりやらを巻き込んで暴走してしまう現象に見舞われてQuickSilver使うの止めちゃおうかな...なんて考えた事のある方は是非お試し下さいませ。

2007年08月18日

特定条件にマッチするプロセスをまとめてにKILLする方法

こういう状態になること自体が余り望ましくないような気がしますが、何かの理由(いぁ自分が理由の場合がほとんどですが)でゾンビなプロセスが大量に発生してしまった時とか、サーバーの再起動は出来ない状況下で大量のプロセスを殺したいような時に。ちょっとそんな場面に遭遇してしまったので簡単な shell script のメモです。

プロセス一覧を ps -ax とかで表示させると

skitched-20070818-085215.jpg

こんな感じになりますが、1カラム目のプロセスIDを抽出してforループで回してkillしていくみたいな感じで。


for pid in `ps ax | grep 'hoge_process' | awk '{print $1;}'`
> do
> kill -KILL $pid
> done;

こういう時、shell script の便利さ & cool さを感じます。awkはまだまだ全然使いこなせていませんが、ちょっと知ってるだけで便利なコマンドですね。(awkは奥が深すぎます...(T_T))

2007年07月29日

jQueryの $.getJSON 等を使った Ajax でIEが動作しない件

javascript のライブラリとして最近 jQuery を使ってます。

;jQuery:

選んだ理由は

  • 複数ブラウザに対応(当然)
  • 軽量である
  • 最近のversion upで相当速度向上したらしい
  • DOM指定にXpathやCSS表記が使える事(個人的な好み)

です。XPathという珍しいモノ(?)に触れるのもXMLの勉強になって良いです。(ちょっとチガウ)

さて、jQueryにもAjaxを非常に簡単に実装できる便利関数が幾つか用意されているんですが、リクエスト先からJSONオブジェクトが返ってくるようなケース(ほとんどがそうだと思いますが...)では $.getJSON を使うのが便利。


$.getJSON('script.php', {param1:value1, param2:value2}, function(json){
alert(json.value);
})

ってな感じに、eval する事無くいきなりJSONオブジェクトとして扱えるモノを引数として貰えるからです。1行でもjavasriptのコードを少なくしようという jQuery のコンセプトがこんな所にも表れているような気がします。

...が、FirefoxやSafariで実験している時は良いのですが、deployしてIEで確認してみると動かない...というか callback が呼ばれないという事態に陥る事があります。そんな時はリクエストを投げる先である script.php で明示的にConent-typeのレスポンスヘッダを指定してやると巧くいきます。

header('Content-type: application/json; charset=UTF-8');

jQueryを使ってAjaxを実装するとIEでのみエラーが起きたというページを参考にさせて貰ったのですが(筆者の方に感謝デス!)、これが分かるまで数時間をロスってしまいました。



あ。JSONのMimeTypeについて補足です。

少し気になって調べてみた所、JSONを返す時のMimeType指定は、安易に text/html とかにしちゃうと何かと問題が発生するそうなので、application/json にした方が良い模様。

またRFC4229によるとtext/javascript は obsolete だそうで、RFC4627にはちゃんと application/json と規定されてようです。ここは従っておいた方がよさげですね。

以上、 jQuery , Ajax, IE の組み合わせでハマりましたというメモと JSON の MimeType についてでした。

バンドル切り替えのショートカットを独自に設定する(TextMaterへの道#1)

最初は日本語設定かと思いきや、こいつは省略。かの有名な hetimaさんによる日本語化を参考に感謝しつつ有り難く日本語入力の設定が完了した所から旅は始まるモノとします。

さて本題。

feed.php 2014 mikurabekun_sr

TextMateでは、エディタとしてご多分に漏れず color syntax 対応。これがなきゃ開発屋は仕事になりません。初期状態で用意されている言語の数が半端じゃなく、拡張子に関係なくショートカットでいつでも簡単に切り替えられますから、開発者に優しいエディタですね。

untitled

画面の最下部に表示されていますが、デフォルトでは PlainText。これを違う言語の color syntax に切り替えたい!ってな時はおもむろに [option] + [shift] + [control] を押しながら、言語の頭文字を入力してみましょう。僕の場合は PHP である場合が多いので [option] + [shift] + [control] を押しながら [p] を押してみると...

screenshot_01

PHPが出てきません。なんでやねん。

screenshot_02

マウスを使って言語選択メニューを出せばちゃんとあるんですが、どうやらショートカットが設定されていない模様。ウチの環境だけですかね。

何だかこう最初から挫折しそうな勢いな訳ですが、全ての操作をショートカットでクールに済ませてしまう TextMater (?) を目指す身としてここで諦める訳にはいきません。そして、使えば使うほど手になじむというTextMateならそれが可能な筈。先を行くTextMater諸先輩方ならやってる筈だ!

...という訳で調べました。以下その方法。


Bundle Editor を使います。TextMater ならマウスなんて使いません(多分)。ここはクールに [command] + [option] + [control] を押しながら [b] で立ち上げます。

screenshot_03

言語名が並ぶツリービューからPHP をガガっと開いて

Bundle Editor

その中の、下の方にある PHP を選択します。L アイコンが目印。Languageに関する設定です。

Bundle Editor


この、Language 内の Activation が言語切り替えのショートカットに相当します。コンボボックスが Key Equivalent になってる事を確認して、エディットボックスにフォーカスを移し、[option] + [shift] + [control] を押しながら [p] をエイヤッと押してやります。

Bundle Editor

これで設定完了。エディタ画面に戻って、おもむろにショートカットしてみましょう。

screenshot_04

出た!!

更に[2]を押と coloring が PHPに切り替わる訳ですね。これでキーボードから手を動かさずに切り替えれるようになりました。万歳。It's cool!! もちろん [option] + [shift] + [control] でなくちゃいかんという事はありませんので、そこはお好みに合わせて。


こう書いてると言語の切り替えが syntax coloring だけのように見えますがそんな事はありません。TextMateではBundle(バンドル)と呼んでるモノの切り替えに相当していて、実は凄い事を色々やってくれるらしい。それはおいおい勉強していきます。

ソフトを使いこなすのが苦手な開発者兼社長によるTextMaterへの道 (プロローグ)

TextMate(テキストメイト)

30A230D5309A30EA30B130FC30B730E730F3

この美しいアイコンの先にあるエディタ機能が多くの開発者を魅了してきたそうな。

TextMate を使う為にMacにSwitchする人もいる...なんて大げさな話を聞くことすらあるぐらいで、標準で日本語を使えない為に国内では余り目にしませんが、英語圏ではよく見るようになってきました。開発者でMac使いな方ならもちろんご存じでしょうし、Windowsな方でも Ruby on Rails 等のデモやプレゼンで見た事があるやも知れません。

screenshot_06

とあるサービス開発中の画面。javascriptなソース。良い仕事するんです....TextMateが。


僕はOSX版のEmacsに落ち着いていた期間が結構あったのですが、今はずっとこのTextMateになっちゃってます。こちらのブログを参照して日本語入力が出来るようにした状態を30日間試用した結果、このエディタの魅力に取り憑かれるように購入してしまいました。

Purchase 2014 TextMate

で。買った以上は徹底的に使いこなさないと勿体ない訳なので TextMate 修行を始めたいなと思っとる訳です。これまでどんなソフトも使いこなし切れていなかった開発者である僕が、果たして TextMater を名乗れるまでになれるのか。その旅の記録をしたためていこうと思います。

いぁ、もう何ヶ月も使って随分なれてきてるんですけどね、使いこなし具合は3%ぐらいなのが自分でもよく分かりますし、どうせ勉強していくならブログにメモを書き残しながら進めていく方が身になるかなと。

そんな訳でお付き合い頂けましたら幸いで御座いまする。

2007年06月28日

CakePHPのCheatSheet

相変わらずCakePHPを使ってます。使えば使うほど、何で最初からこれを使ってなかったんだろうという思いで一杯になる訳で。それぐらい便利。

Google Mapplets のディレクトリサイト「Mappletナビ」でも、ウチの主力製品であるIR情報ファイル配信システム「IRcast」でも使っています。請負の案件でも投入していて、もうすっかりBaker(CakePHP使いの事をこう言う)と化してしまいました。使いこなせているとは言い難いですが。


んで、Bakerとしては非常に嬉しい Cheat Sheet を見付けましたのでご紹介。CakePHPを使って何かを実装する時に是非とも覚えておきたい事を網羅してくれている CakePHP の Cheat Sheet です。これは便利。Bakerなら、印刷して一部、机の上に置いておきたいところ。

この手のCheatSheet(チートシート)は開発者の世界では結構一般的で、PHPとかHTMLとかCSSとかJavascriptとか、まぁ色んなCheatSheetが揃ってます。手元に置いておきたいと思う一式がいもろぐさんの、【PHP】web系開発者が持っておくと便利な10のチートシートというエントリにありますのでご参照下さいな。

...と思ったら、ここにも CakePHP の CheatSheet が紹介されていましたね。

2007年06月08日

PHPのみが記述されるソースファイルにおいては終了タグ ?> を書いてはいけない

PHPとの付き合いもそれなりに長くなってきた訳ですが、正直ビックリしてしまった(自分的)新発見をしましたので備忘録として記録します。もうホントにタイトル通りです。

PHPのみが記述されるソースファイルにはPHPの終了タグである ?> を書くべきではないということ。

PHPの勉強を初めてまず最初に目にするのは


<?php
echo phpinfo();
?>

というプログラムだったりする訳でして、PHPのプログラムは <?php で始まって ?> で終わるという事を最初に覚えるのですが、Zend のコード規約によるとどうやらそうじゃないみたい。

付録 A. Zend Framework PHP 標準コーディング規約 : A.2. PHP ファイルの書式
PHP コードのみからなるファイルでは、終了タグ ("?>") は決して含めてはいけません。終了タグは、PHP には必要ありません。 終了タグを省略することで、ファイルの最後にある空白文字が出力に影響することを防ぎます。

と明確に書いてある。これは、ここ最近 PHP に関するメーリングリストで交わされてたスレッドから初めてしった事。いやはや思いも寄らぬ新発見というか勉強になったというか。そんなスレッドを立てて下さった質問者の方に感謝。


確かに思い起こしてみると、終了タグの後に空白文字が意図せずに入っている事が原因で、header()関数をどこかで使ってるプログラムなんかでハマった事が何度かありました。そういう事態を防げる訳ですね。素晴らしい。


これからは、終了タグ ?> を意図的に省くようにしようと思いました。...えと、もちろん HTML の中に埋め込むタイプのPHPコードについては、きちんと <?php ... ?> で囲ってやる必要がありますので忘れないようにという事で。

2007年05月31日

Google Maps の Mapplets 用に「防犯マップ大阪 -Mapplet版(beta)-」を作ってみました

カリフォルニアにて開催された Where2.0 カンファレンスで Google Maps が新機能を搭載したとのニュースがネットの世界を駆けめぐりました。大きくは

  • 道路レベルでの写真も表示できる「StreetView」
  • iGoogle Gadget の Google Maps 版とも言える「Mapplets」

の2つ。...ですが、開発者としてはやはり後者の「Mapplets」に興味がそそられてしまいます。こう言っちゃなんですが道路レベルの写真が見れる「StreetView」より、「作る」楽しみが無限にありそうな「Mapplets」の方がずっと面白いんじゃないかなと。


で、勢いあまって作ってしまいました。
防犯マップ大阪 -Mapplet版(beta)-」です。



当社では大阪府警様の了承を得て、昨年7月から「防犯マップ大阪」というサイトを某防犯グッズ商社様と共同運営しています。大阪府警が公開している犯罪情報から緯度経度をGeocodeしてプロットするという仕掛け。(この実装には Ensemble の共同開発者itokさんに力添えを頂きました。有り難うございます m(__)m)

防犯マップ大阪 -Mapplet版(beta)-」は、大阪府下の犯罪データと Google Maps の橋渡しをする仕掛けとして動作します。...自分で言うのもなんですが結構便利かも。beta 版ですが宜しければ登録してやってみて下さいませ。Mapplets Directory には登録申請しようと思っていますが、とりあえず現状では以下の手順でインストールする事が出来ます。


1, Mappletsが使えるプレビュー版GoogleMapsを開いて「コンテンツを追加」をクリックして下さい。(Googleアカウントでのログインが必要です)



2. Mappletsディレクトリに登録されているMappletが表示されますが、検索窓横の「URLを指定して追加」をクリックして下さい。




3. URLの入力欄に http://feedtailor.jp/mapplets/crimemap/crimemap.xmlを入力して「追加」ボタンをクリック。その後、「Googleマップに戻る」をクリックして下さい。




4. 出てきました。...ので、えいやっとクリックして完了です。



5. このように犯罪情報がプロットされていたらokです。

赤いアイコンはひったくり、青いアイコンは子供に対する被害、緑のアイコンは強盗ってな感じです。クリックすると犯罪の詳細情報が表示されます。



6. あと犯罪種別や表示する期間も設定できますのでお好みに併せてどうぞ。

この Mapplet が全国の犯罪データを網羅できたら結構使えるツールになると思うのですが、いかんせん積極的に犯罪情報を公開している都道府県は極めて少なくて現状は実現不可能と言わざるを得ません。どなたか、各都道府県警や警視庁等にお知り合いがおられたらご紹介して頂けると嬉しいですm(__)m 大阪府警さんと同様に交渉させて頂きに参りたいと思います。




で、やってみて思った事ですが、Mapplet を作成するのはそれほど難しくありません。Google Maps を一度でもさわった事のある人は Google Mapplets のドキュメントに少し目を通すだけでサックリ作れてしまうんじゃないでしょうか。しかも、Google Maps API を使って一からサイト作るよりとっても楽。「位置」に関連した情報を何かお持ちの方は是非是非作ってみて下さいませ。

「地図」+「位置を持った情報」のマッシュアップの世界がまた少し変わりそうな気がしました。Mapplets の今後が楽しみです。

2007年05月07日

Geekの為のイけてるT-Shirts

開発ブログとは言っても開発ネタばかりでは面白くないので、開発を生業とか趣味にしているGeekな関連エントリも書いてみようかと。

とあるサイトで発見した面白いTシャツを紹介します。Geekの為のTシャツと言っても良いでしょう。普段、何かしら開発に関わってる人や、ITの世界と密に接している方にとっては笑えるTシャツばかり。誰かが遊びで作ったんでしょうか。それとも商品として売っている?

Funny Geek shirts


一番僕のツボにハマったのはコレ。

実際にやった事もありますから余り笑えないんですけどね。間違ってもこんなコマンド打っちゃいけません(T_T) (まだ -f オプションがついていないだけでも救いがあるでしょうか)


他にも思わずニヤリとしてしまうTシャツが沢山載っていますので一度眺めてみて下さい。皆さんはどんなTシャツが欲しいですか?(あるいは、どんなTシャツを作りますか? :-)

2007年05月06日

URLをTinyURLで短くしたりもとに戻したりするスクリプト

もうほとんどメモ書きですが。twitterをやるようになって、

  1. URL → TinyURL
  2. TinyURL → URL

といった変換を手軽にやりたくなる事が増えてきました。

2. については Firefox の GreaseMonkey でtip表示してくれるようなものもありますが、自分はMacOSXの専用クライアントソフト「Twitterrific」を使っているし、何かとコンソールで済ませたい今日この頃的には、コピペ & コマンドで格好よくいきたいところ(謎)。

という訳で作りました(作ったという範疇に入らないという話もある)。/usr/sbin とかパスを通している所に適当に放り込んでると予想以上に重宝している次第。


url2tiny

#!/bin/sh
# url --> tinyurl
# $ url2tiny http://www.example.com/
#
if [ -z $1 ]; then
exit 1;
fi
TINYURL_API="http://tinyurl.com/api-create.php?url="
curl ${TINYURL_API}$1
echo


tiny2url

#!/bin/sh
#
# tinyurl --> url
# $ tiny2url http://tinyurl.com/xxxxxx
#

if [ -z $1 ]; then
exit 1;
fi
curl -I -s $1 | grep Location: | sed 's/Location: //'
echo

こんな感じで。

2007年05月04日

javascriptのdocument.writeを出力するPHPで、<textarea>タグを出力する時に気をつけたいこと

何だか意味も無く時間を費やしてしまったので再発防止のための備忘録として書いてみます。

巷に溢れるブログパーツ。賑やかにflashで作られてるモノを最近何だか多く目にするようになってきた訳ですが、そんな中でも硬派(?)なテキスト&せいぜい静止画像が表示されるだけのブログパーツは純粋に javascript で提供されている場合がある訳です。

こんな感じで


<div>
ブログパーツだぜ
<script source="http://example.com/js/blogpartsjs.php" type="text/javascript" />
</div>

提供されていて、blogpartsjs.php なる PHP プログラムが javascript の document.write が並んだソースコードを吐き出して、それがブラウザによる <script> タグの解釈によって評価されるというからくり。(こんな説明は今更感が溢れる訳ですけど..)

ただ単純に出力したい内容文字列を document.write 関数の引数として渡しているようなソースコードを PHP プログラムで出力してやれば良いので非常に簡単な話です。

<?php

/**
* これはブログパーツを出力するjavascriptのソースを出力するPHP
*/

$html = "<div>これがPHPから出力されたブログパーツのHTMLコードだ!!</div>";
echo 'document.write("'.$html.'")';
?>

こんな感じですね。...がしかし、出力する内容が改行を含んでいては具合が悪い。document.write の引数に改行があると、このパーツが貼付けられたhtmlでjavascriptとして評価される時にエラーが出てしまいますから。

<?php

/**
* これはブログパーツを出力するjavascriptのソースを出力するPHP その2
*/

$html <<<= HTML
<div>
これがPHPから出力されたブログパーツのHTMLコードだ!!その2
</div>
HTML;

echo 'document.write("'.$html.'")';
?>

ってなのは駄目な訳です。最初の <div> の後に来る改行(\n) でエラーが発生します。繰り返しになりますが javascript のソースコードとして途中に改行を持ってくると怒られますので、これを回避する為に document.write の引数となる文字列の改行を除いてやろうとすると....

<?php

/**
* これはブログパーツを出力するjavascriptのソースを出力するPHP その2
*/

$html <<<= HTML
<div>
これがPHPから出力されたブログパーツのHTMLコードだ!!その2
</div>
HTML;

$html = str_replace("\n", "", $html);
echo 'document.write("'.$html.'")';
?>

こうなります。これで document.write でエラーが出る事はありません。これで解決。万歳!!...とまぁ普通はこれで良いのです。




....が、

ブログパーツの場合はまず無いと思いますが、このからくりで <textarea> を出力しようとするとちょいとハマる事になってしまうので要注意だったりします。

何度も書きますが、javascriptの document.write 関数の引数内で改行があると評価する側のhtmlでエラーになってしまいますが、その一方で <textarea> タグ内では正しい表示の為に改行が必要であるという、相反する要件が微妙にワナとなって襲いかかる訳ですね。

例えば、こんな html コードを、<script src="...." type="text/javascript" /> とかを貼付けてもらったページに javascript で出力したいとします。

<div>テキストエリア</div>

<textarea rows="10" cols="60">
ここがテキストエリアの内容です。
ここでの改行はテキストエリアとして表示される時に忠実に反映される為、
<textarea>内の改行を削除すると期待通りの表示になってくれません
</textarea>

これをさっきと同じように処理して、改行を除去した状態で

echo 'document.write("<div>テキストエリア</div><textarea rows=\"10\" cols=\"60\">ここがテキストエリアの内容です。ここでの改行はテキストエリアとして表示される時に忠実に反映される為、<textarea>内の改行を削除すると期待通りの表示になってくれません。</textarea>");';

とかってなるような、PHPプログラムを書いてはいけません。こんな感じになってしまいます。




と、ここまでやって僕の場合は気がつきました。(オソイ)

そもそも単純に document.write の引数として渡す文字列の改行を除去するPHPプログラムにしている事が問題で、document.write の引数文字列に改行が入る場合の正しい書き方に準拠すべきなんです。文字列の連結が改行のタイミングで発生する事は許されていますのでそれを使う。つまり、


document.write('<div>テキストエリア</div>'+
'<textarea rows="10" cols="60">'+
'ここがテキストエリアの内容です。\n'+
'ここでの改行はテキストエリアとして表示される時に忠実に反映される為、\n'+
'<textarea>内の改行を削除すると期待通りの表示になってくれません。\n'+
'</textarea>');

と出力されるようなPHPプログラムを書けば良い訳ですね。そうすれば document.write でエラーも発生しないし、textarea タグ内も正しく表示されるという事になります。こんなふうに。

ようは「改行でエラー出るなら除去しちゃえ」と安直な考えに走ってしまった結果のワナにハマってたという訳です。手抜きしちゃいけませんね。...という訳で、上記のような javascript ソースコードを出力する php 関数を作ってみました。


function _js_document_write($str)
{
// 行単位に分割
$lines = split("\n", $str);

//
if(!empty($lines)){
foreach($lines as $i => $line){
$line = str_replace("'", "\'" , $line); // single quotation escape
$lines[$i] = preg_replace("|^(.*)$|", '\'$1\n\'+', $line);
}
}

// 連結
$str = join("\n", $lines);

// 最後の一文字だけ削除
$str = substr($str, 0, strlen($str)-1);

return 'document.write('.$str.');';
}


...っていうか、そもそもコピペで貼付ける先にjavascriptで textarea を出力する必要があるって一体どういう事なのよという話もありますね(苦笑)