2008年7月29日火曜日

[Google App Engine]Bulk Data Uploaderでデータをまとめてインポートする

まあ基本的にはマニュアルのとおりなんだけど、一カ所つまづいたのでメモしておきます。ちなみに開発環境の話です。

Loaderクラスを継承したクラスを書いてapp.yamlにエンドポイントを追加してCSVを用意した後
さあデータをアップロードするぞというところで。

./bulkload_client.py --filename people.csv \
--kind Person \
--url http://localhost:8080/load
[中略]
INFO 2008-07-29 10:23:56,365 bulkload_client.py] Importing 6 entities in 101 bytes
ERROR 2008-07-29 10:23:56,461 bulkload_client.py] An error occurred while importing: Received code 302: Requires login
ERROR 2008-07-29 10:23:56,462 bulkload_client.py] Import failed

ログインしてないよというエラーが発生します。

このエラーはbulkload_client.pyにcookieオプションをつけると解決するようです。
(aml.yamlの login: admin を削除すると上手く動くようですが、これは推奨できませんよね。)

./bulkload_client.py --filename people.csv \
--kind Person \
--url http://localhost:8080/load \
--cookie dev_appserver_login="test@example.com:True"
[中略]
INFO 2008-07-29 10:31:49,206 bulkload_client.py] Importing 6 entities in 101 bytes
INFO 2008-07-29 10:31:49,507 bulkload_client.py] Import succcessful


アプリ上でログインした後もtest@example.com:False になっている場合でも、test@example.com:Trueと手動で書き換えれば問題なく動作するようです。

[7/ 30追記]
本番環境にアップロードするのも基本的には同じです。
Googleにログインした状態で下のURLにアクセスすると
http://<yourapp>.appspot.com/load
The bulk load endpoint is: http://<yourapp>.appspot.com/load
Pass this flag to the client: --cookie='ACSID=AJKiYcFGvAqWeiQBFIeybzvHdi-NzXwSCEHHCFBpupSdRbzxamvzdR7qfYma0VZjm6i23Ujea2T...

という画面を見ることができるはずです。
そこに記載されているcookieをコピペして、ローカルのマシンでコマンドを叩くだけ
./bulkload_client.py --filename people.csv \
--kind Person \
--url http://<yourapp>.appspot.com/load \
--cookie ACSID=AJKiYcGf8BeBcd[中略]
INFO 2008-07-30 16:59:58,015 bulkload_client.py] Importing 9 entities in 234 bytes
INFO 2008-07-30 16:59:59,055 bulkload_client.py] Import succcessful



Porting legacy databases to Google App Engine
(http://thomas.broxrost.com/)

2008年7月27日日曜日

rubyでキャッシュ: 例えばrailsのActiveRecordクエリの結果をキャッシュするとか

例えば外部のAPIを叩いたり、データベースの重たい処理をする時など、キャッシュを上手く使った方がいいよねってことで、PHPでモノを作る時にはPEARのCache_LiteとかZend FrameworkのZend_Cacheなどを駆使してきました。Cache_LiteもZend_Cacheもserialize関数,unserialize関数を使って、シリアライズされた配列やオブジェクトをファイルに書き出したり読み戻しています。

ruby、というかrailsでキャッシュしたい時には、これまでrails付属のキャッシュシステム(主にfragmentキャッシュ)を利用してきましたが、railsのキャッシュは出力されるHTMLなどを保存するものですよね。
rubyで文字列やハッシュをキャッシュしたい時にはどうすればいいんだろうと調べていたら、Marshalというモジュールが使えるようです。

Marshal - Rubyリファレンスマニュアル

具体的な例としてActiveRecordクエリの結果をキャッシュするコード

Marshalize (Cache) ActiveRecord Query Results
(http://snippets.dzone.com)

class MyCachedModel < ActiveRecord::Base
class << self
alias_method :rails_original_find_by_sql, :find_by_sql
def find_by_sql(sql)
cache_filename = Base64.encode64(sql)
if File.exists? cache_filename
Marshal.load(File.open(cache_filename))
else
Marshal.dump(records = rails_original_find_by_sql(sql), File.open(cache_filename, 'w'))
return records
end
end
end
end


ファイルがあればMarshal.loadで読み戻し、なければMarshal.dumpで書き出しています。

Spacegallery: 珍しいタイプの画像ギャラリーを作れるjQueryプラグイン


Spacegallery
(http://eyecon.ro/spacegallery)

手前から奥に画像がずらっと並んでいて、画像をクリックすると手前の画像が前にズームアップしながら消えてひとつ奥の画像が現れるという画像ギャラリーを簡単に作れます。
口で言っても分かりにくいと思いますが、デモを見れば一目瞭然。
なんとなくappleが採用しそうなインターフェースではないでしょうか?

2008年7月23日水曜日

Facebox: facebook風のモーダルダイアログを簡単に導入できるjQueryプラグイン


Facebox
(http://famspam.com/facebox)

ダイアログ系のプラグインはたくさんありますが、これはfacebook風の角丸デザインでかわいらしい感じです。

jQuery:bind/triggerの使い方メモ

こういうモーダルダイアログというのは、ダイアログが開いている間はダイアログの周りの部分にオーバーレイがかけられて、その部分を操作することができなくなります。
「close」「閉じる」ボタンを押したり、オーバーレイの部分をクリックするとダイアログが閉じてオーバーレイも消えるようになっているのが普通です。
このFaceboxではその「閉じる」処理をどうやっているのか気になったので、ソースをちょっと見てみました。

基本的に「閉じる」処理を行う時は、document に登録されている close.facebox というイベントをtriggerで実行しているようです。

$(document).trigger('close.facebox')

例: オーバーレを表示する関数。オーバーレイの要素をクリックすると close.faceboxイベントを実行するようにclickイベントを登録しています。
function showOverlay() {
if (skipOverlay()) return

if ($('facebox_overlay').length == 0)
$("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')

$('#facebox_overlay').hide().addClass("facebox_overlayBG")
.css('opacity', $.facebox.settings.opacity)
.click(function() { $(document).trigger('close.facebox') })
.fadeIn(200)
return false
}

肝心のclose.facebox
$(document).bind('close.facebox', function() {
$(document).unbind('keydown.facebox')
$('#facebox').fadeOut(function() {
$('#facebox .content').removeClass().addClass('content')
hideOverlay()
$('#facebox .loading').remove()
})
})


気になったのは close っていうイベントをtriggerで実行できるの?というかそんなイベント登録できるの?ということ。(.facebookの部分はこの前話題にした名前空間ですよね)

jQueryのドキュメントを読んでみると、冒頭にこんな記述があります。
Binds a handler to one or more events (like click) for each matched element. Can also bind custom events.
この「カスタムイベントも登録できるよ」という部分はこれまで完全に無視していましたが、つまりこういうことなんですね。勉強になります。

2008年7月22日火曜日

jGrowl: クールな通知機能を実装できるjQueryプラグイン


jGrowl
(http://stanlemon.net/projects/jgrowl.html)

Mac OS XのGrowl風の通知機能をWebアプリに組み込めるjQueryのプラグインです。
よくあるモーダルダイアログやポップアップとはひと味違ったインターフェースで、思わず使ってみたくなる魅力を持っています。
MOONGIFTさんが詳しく紹介されているので、参考までに。

実は、あまりにも気に入ってしまったので、半分勢いにまかせてdiscvoxxにも組み込んでしまいました。

2008年7月21日月曜日

timeago: 何日前?を教えてくれるjQueryプラグイン


timeago
(http://timeago.yarp.com/)

日付の表示で、日時ではなくX日前を表示しいているサイトはYouTubeのコメント欄などいろいろみかけますが、このtimeagoは日時からX日前(X時間前、X分前)を教えてくれるjQueryプラグインです。

jQuery.timeago(new Date());             //=> "less than a minute ago"
jQuery.timeago("2008-07-17"); //=> "4 days ago"
jQuery.timeago(jQuery("abbr#some_id")); //=> "a day ago" // [title="2008-07-20"]

ご覧のように、作成者が英語圏の方(?)なので、a minute ago、4 days agoという表現になっています。
日本語サイトに導入する場合はソースの該当部分を翻訳する必要があるかもしれませんが、とても分かりやすいので迷うことはないはずです。

jQuery Star Rating Plugin: 簡単に星形投票システムを実現できるjQueryプラグイン


jQuery Star Rating Plugin
(http://www.fyneworks.com/jquery/star-rating/)

YouTubeなどで見かける星形の投票システムを簡単に実装できるプラグインです。
原則的にradioボタンを星画像に自動変換してくれるので

<input name="star1" type="radio" class="star"/> 
<input name="star1" type="radio" class="star"/>
・・・

とclassにstarを指定するだけで導入できます。

ただ、ruby on railsのアプリケーション上でちょっと試してみたのですが、上手く使えませんでした。
原因はどうやら input の name要素で profile[name] のように[]を使用しているため内部的に不具合が発生しているようです。
Google Groupでもこの問題が挙っていたので対応したようですが、いまだに直っていないような(!?)

2008年7月18日金曜日

ruby初心者に参考になる7つの文例集

Ruby Snippets
(http://bendiken.net/snippets/ruby)

rubyではこんな感じで簡単にカッコよく書けるよという7つ文例集です。
それぞれ10行程度の短いコードなのですが、こんな書き方があるんだと感心してしまいました。

例えばRSSをパースするコード

def fetch_rss_items(url, max_items = nil)
%w{open-uri rss/0.9 rss/1.0 rss/2.0 rss/parser}.each do |lib|
require(lib)
end
rss = RSS::Parser.parse(open(url).read)
rss.items[0...(max_items ? max_items : rss.items.length)]
end

items = fetch_rss_items('http://www.digg.com/rss/index.xml', 5)
items.collect { |item| item.title }
=> ["Understanding AJAX - A Beginner's Guide",
"Anti-cancer Compound In Beer", ...]

こんなふうにrequireを書くことができるんですね。不勉強で知りませんでした。

この他に以下のコードが紹介されてるので気になる方はチェックしてみてください。

配列の中身を足し算/かけ算する
ランダムなパスワードを生成する
便利な正規表現
画像のサイズを計測する
階乗を計算する
あらゆる数字を序数化する

[jQuery] 名前空間(namespace)でイベントを管理する

使えそうなのでメモメモ。

jQuery namespaced event binding/unbinding
(http://codesnippets.joyent.com/posts/show/1345)

jQueryを使ってイベントを追加する場合は大抵こんな感じで書く:

jQuery('.class').click(function(){//whatever});

上のコードは下のように書くこともできるのはみんな知ってるよね:
jQuery('.class').bind('click', function(){//whatever});

でも時々イベントを削除したくなる場合がある:
jQuery('.class').unbind('click', function(){//});

で、問題なんだけど、こうやってイベントを削除すると、その要素に登録されている全部のイベントが削除されちゃうってこと。(無名関数を特定する手段がないからね)

でも、jQueryは賢いから、これを制御する方法がある。イベントに名前空間を指定してあげればいいんだ。
jQuery('.class').bind('click.namespace', function(){//}); 
jQuery('.class').unbind('click.namespace');

AJAXによって登録されたイベントを再初期化する場合はこんな感じ:
jQuery('.class').unbind('click.namespace').bind('click.namespace', function(){//});

Color Picker: Adobe Photoshopと同じ感覚で色選択ができるjQueryプラグイン


Color Picker (http://eyecon.ro/colorpicker/)

「Adobe Photoshopと同じように色を選択できるシンプルなコンポネント」らしいです。Photoshopは使ったことがないので使用感の違いが分かりませんが、クォリティは非常に高いのではないでしょうか。
色選択が必要になるシチュエーションというのは限られているものの、この品質の機能をプラグインでサクっと導入できるのはうれしいです。

jQuery Image Cube: 画像をキューブ状に見せるプラグイン


jQuery Image Cube (http://keith-wood.name/imageCube.html)

複数の画像を組み合わせて立体的に見せることができます。
なかなか印象的なプラグインです。
動きのストップ/スタートや、スピードやストップのタイミングの調整などもできるようです。
画像だけでなくテキストもキューブ化できるようなのでいろいろ使えそうですね。

2008年7月17日木曜日

Column Navigation: Mac OS X風のナビゲーションを実装するjQueryプラグイン


Column Navigation (http://plugins.jquery.com/)
デモ
ナビゲーションのインターフェースというとタブ、WindowsのExplore風のツリー形式、アコーディオンなど色々あるけれど、Mac OS X風のこのインターフェース(何て呼んだらいいんだろう?)もなかなかだと思います。
階層の深い形式を扱う時に選択肢のひとつになるはず。
ただ、ソースの例を見ると、HTMLがULタグの入れ子になってて、階層が深くなればなるほど頭がこんがらがりそうです…

jQuery Sparklines: グラフを描画するJQueryプラグイン


jQuery Sparklines (http://www.omnipotent.net/)

折れ線グラフと棒グラフをインラインで表示するシンプルなプラグインです。

<span id="ticker">Loading..</span>
$('#ticker').sparkline([1,2,3,4,5,4,3,2,1]);


オプションで幅・高さ・グラフや背景の色などを指定できます。

シンプルで使いやすいので、ちょっとしたグラフを入れたいという時に役に立ちそうです。

[Ruby on Rails] viewヘルパー::content_tag_for

content_tag_forという便利そうなヘルパーを見つけたのでメモ。ちなみに使えるのはrails2.xから。

<% content_tag_for(:tr, @person) do %>
<%=h @person.first_name %>
<%=h @person.last_name %>
<% end %>

と書くと
<tr id="person_123" class="person">....</tr>

というHTMLが生成されます。
ActiveRecordオブジェクトを展開してリスト表示したい、というのはよくあることなので色々使えそうです。

もちろんidやclassを指定できるし
<% content_tag_for(:li, @person, :class => "bar") %>...

と書くと
<li id="person_123" class="person bar">...

というHTMLが生成されます。

[参考] Rails API ドキュメント

jQuery File Tree: WindowsのExplorer風にメニューをツリー状に表現できるjQueryのプラグイン

エクスプローラ風のツリー表示は個人的にけっこう使いやすい/見やすいと思うのですが、自分で作ろうと思うと意外と面倒だったりするので、こういうライブラリの存在はありがたいです。

jQuery File Tree (http://abeautifulsite.net/)
デモページ

ツリーの情報をAJAXで取得するのが前提になっています。デモページのHTMLソースを見るととてもシンプルですっきりしています。
サーバーサイドのスクリプトもライブラリの中にバンドルされていて
PHP
ASP (VBS)
ASP.NET (C#)
ColdFusion
JSP
Lasso
Python/Django
Ruby
といった言語にあらかじめ対応しています。

2008年7月16日水曜日

Web開発者がすべからく知っておくべき7つのAjax & Javascriptライブラリ

おおげさなタイトルをつけてしまいましたが、The Top 30 Free Ajax & Javascript Code for Web Designersを参考に、知っておくと便利だと思うライブラリをピックアップしてみました。
いくつかはprototype.jsに依存しているのでご注意を。

Lightbox2(http://www.lokeshdhakar.com/projects/lightbox2/)


画像をクールに見せることができるライブラリ。
prototype.js, script.aculo.usに依存しています。
フレームワークに依存しないshadowbox.jsという類似のライブラリもあります。

Timeline (http://simile.mit.edu/timeline/)


出来事を時系列(タイムライン)に沿ってみせることができるライブラリ。Google Mapsのようにドラッグ&ドラッグで操作できるのが特徴です。

Reflection.js (http://cow.neondragon.net/stuff/reflection/)


画像をweb2.0風に鏡面加工できるライブラリ。

Plotr (http://solutoire.com/plotr/)


グラフを作成できるライブラリ。円グラフ、棒グラフ、折れ線グラフに対応しています。
prototype.jsに依存。

Starbox (http://www.nickstakenburg.com/projects/starbox/)


アマゾン等で見かける評価(レーティング)の星付け機能を設置できるライブラリ。
prototype.jsとscript.aculo.usに依存。

Ajax Tabs Content (http://www.dynamicdrive.com/)


AJAXに対応したタブを実装できるライブラリ。

Create Flickr Like Fields (http://dbachrach.com)


テキスト部分をクリックするとinputフィールドに変換するライブラリ。デモ

Appleのサイトで使われてるようなアコーディオン・メニューを実装したい

Appleのサイト(apple.com)で使われてるような折りたたみするメニュー - iPod + iTunesのページ(http://www.apple.com/itunes)で使われているやつ - がカッコいいなあと思ってたら簡単にマネできる方法があるみたいです。


Apple style Accordion Menu

上のサイトにjQueryとddaccordion.jsを使った実装方法の説明がありました。

jQueryとddaccordion.jsを読み込んだ後、ちょっとしたHTMLとJavascriptとCSSを記述するだけ!簡単です。
メニューの背景となる画像をあらかじめアップロードしておくのをお忘れなく。

jqDock: Mac OS X のDock風のメニューを実装するjQueryプラグイン

カーソルをあわせるとぐわっと拡大するあのMacのメニュー(Dock)をWebアプリに組み込めるjQueryのプラグイン。



使い方はいたってシンプル。

<script type='text/javascript' src='jquery-1.2.3.min.js'></script>
<script type='text/javascript' src='jquery.jqDock.js'></script>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('#menu').jqDock(options);
});
</script>

<div id='menu'>
<img src='image1.gif' alt='image1.png' title='' />
...
<a href='page.html' title=''>
<img src='imageN.png' alt='' title='' />
</a>
...
</div>

オプションを指定すると横だけでなく縦にも表示できるようです。

jqDock v1.2 ... a jQuery plugin
http://www.wizzud.com/jqDock/index.php


このためだけにjQueryを使うのもなあ、というかたはこちらをチェックしてみてはいかがでしょう。

A Mac OS X-style Dock in Javascript
(http://safalra.com/web-design/javascript/mac-style-dock/)

AJAXアプリケーションで「戻るボタン」「ブックマーク」を実装する

AJAXを使ったサイトでネックになるのが「ブラウザの戻るボタンが使えない」「ブックマークができない」という点。
「そんなの別に気にしないよ」という人もいるかもしれないけど、作り手としてはその辺もきっちり作り込みたいですよね。
というわけで、AJAXを使ったアプリでも「戻るボタン」「ブックマーク」を実装できるライブラリをチェック。

Really Simple History

Google Code のプロジェクトページ
http://code.google.com/p/reallysimplehistory/

他のフレームワークを使わずに単体で動作するタイプです。

英語でちょっと古いけど下のサイトが一番詳しいのかな。
AJAX: How to Handle Bookmarks and Back Buttons
サンプルコードが充実しているので、コードを眺めてるだけでも使い方が分かると思います。


jQuery history プラグイン

jQuery history プラグイン

こちらはjQueryのplugin

デモ
http://www.mikage.to/jquery/jquery_history.html

どちらも、IEの場合のみiframeを使い,そのほかの場合はlocation.hashを参照しているようです。

PHPのコードを最適化するための42のTIPS

42 tips for optimizing your php code
http://mfw-php.blogspot.com/2008/07/42-tips-for-optimizing-your-php-code.html

中には些細なものもありますが、気になるものをいくつかピックアップ


  • __get, __set, __autoload のようなマジックメソッドを避けよう。

  • require_once() はコストがかかる。

  • includes と requires はフルパスを指定すべし。

  • regex(正規表現) の代わりに strncasecmp, strpbrk, stripos等が使えないか見直すべし。

  • if, elseif, elseif... と書くよりもswitch文を用いたほうがいい。

  • @を使ったエラー制御は遅い。

  • for ($x=0; $x < count($array); $x) のように書くと count() がループ毎に呼ばれるのでforループの中で使ってはいけない。

2008年7月14日月曜日

discvoxx: 盤(ディスク)でつながるソーシャルCDラックサービス


discvoxxという新しいwebサービスをはじめました。
discvoxx
http://discvoxx.com

どんなサービス?
好きなCDを登録して自分専用のオンラインCDラックを作成できるサービスです。
持っているCDをひたすら登録したり購入予定のCDのリストを作ったり。ブログをやっている方はレビューブログとしてもご利用いただけます。

ソーシャルってどういうこと?
discvoxx内で同じCDを登録している人をチェックしやすくなっています。
また、Twitterのように他の人のCDラックを「フォロー」する機能があります。フォローするとその人のラックを受信するようになります。


discvoxx
http://discvoxx.com

discvoxxブログ
http://discvoxx.blogspot.com

2008年7月6日日曜日

RubyとPythonとPHPで暗号化を行うためのメモ

Google App Engineでアプリケーションを開発中に、MD5で暗号化したURLをDatasotreに格納しようとしたら"UnicodeDecodeError / 'ascii' codec can't decode byte 0xe7 in position 3: ordinal not in range(128)"と怒られたのでちょっと調べてみました。

せっかくだからPythonとRubyとPHPで暗号化に関する関数/メソッド(MD5とかSHA-1)の使い方を比較。
MD5もSHA-1も言語ごとの使い方は基本的に同じですね。

Python
マニュアル:
md5 -- MD5 メッセージダイジェストアルゴリズム
SHA-1 メッセージダイジェストアルゴリズム

import md5
print md5.new("some text").digest()


上記のエラーはこのdigestメソッドの返り値を格納しようとして発生しました。
マニュアルにもあるようにdigest()メソッドは「nullバイトを含む非 ASCII 文字が入っているかもしれません。」ということなので、非ASCIIが混入していたのでしょう。
digest()メソッドをhexdigest()メソッドに変更したらエラーはなくなりました。
実はdigest()とhexdigest()の違いなんて意識したことなかったので(!)最初は何のことか分かりませんでした。


Ruby
マニュアル:
Digest::Base

require 'digest/md5'
p Digest::MD5.hexdigest(File.open('ruby-1.8.5.tar.gz','rb').read)

# => "3fbb02294a8ca33d4684055adba5ed6f"


Rubyにもdigest()メソッドとhexdigest()メソッドがあります。


PHP
md5
sha1

使い方は一番シンプル。関数を呼び出すだけ。
$str = 'apple';

if (md5($str) === '1f3870be274f6c49b3e31a0c6728957f') {
echo "Would you like a green or red apple?";
exit;
}
?>


python,rubyのhexdigest()メソッドと同等の関数なのでしょうか。
第二引数にTrueを指定するとバイナリ形式で返ってくるようです。(digestと同等?)

2008年7月1日火曜日

Mac OS X Leopard にApache,MySQL, PHPをインストール

Leoparad には標準でApche, PHP, Ruby, Ruby on Rails, Pythonなどがインストールされているので、買ったら即日開発に着手できるぞ〜なんて思ってたけど、そうは甘くありませんでした。

例えば、標準でインストールされているPHPにはPDOのMySQLドライバが入ってませんでした。
で、MySQLをPDOで使えるようにしようと思ったんだけど、これがけっこう大変なことに・・・

MySQL

MySQL5.0をdmg版をダウンロードしてサクっとインストール
/usr/local の下にインストールされます。
MacPortでインストールするとパスが違うようなので注意。(/opt/の下だったかな?)

~/.bash_profile にパスを追加しておく

PATH=/usr/local/mysql/bin:$PATH
export PATH


よーし、これでMySQLが入ったから、あとはPDOのMySQLドライバを入れれば動くのかな?と思ってMySQLドライバをインストールしたものの動かない・・・
php.iniとにらめっこしたものの、よく分からないが、どうやらpdo_mysql.soをうまく読み込んでくれないらしい(?)。
せっかくデフォルトでインストールされているんだから、あらためてPHPをインストールし直すのはなんだかなあ、と思いつつもPHPを再インストールするのが一番近道なようだ。

PHP
ソースからインストール
オプションは下のサイトなどを参考
LAMP in Leopard OSX 10.5 (PHP5 and Apache 2.2)
How to enable PDO_MYSQL in 5.2.4 PHP included into Leopard

./configure
--prefix=/usr
--mandir=/usr/share/man
--infodir=/usr/share/info
--with-apxs2=/usr/sbin/apxs
--enable-cli --with-zlib-dir=/usr
--enable-mbstring
--enable-mbregex
--enable-sockets
--with-curl=/usr
--with-config-file-path=/etc
--sysconfdir=/private/etc
--with-mysql-sock=/tmp/mysqld.sock
--with-mysqli=/usr/local/mysql/bin/mysql_config
--with-pear=/Library/PHP
--without-iconv
--without-openssl
--with-pdo-mysql=/usr/local/mysql/bin/mysql_config


上に書いたように、MySQL関連のパスはdmgでインストールした場合です。

php.iniの編集

/etc/pho.ini
extension=pdo.so
extension=pdo_mysql.so
を追加

mysql.default_socket = /tmp/mysqld.sock
を指定

これで大丈夫... のはずが
apacheがlibphp5.soを読み込めないとエラーを吐きだす始末。

Apache

Leopard で PHP5 を再構築できなかった話
Custom MAMP on Mac OS 10.5 Leopard

こちらのサイトを参考にapacheも再インストール
ソースをダウンロードして解凍した後apacheのディレクトリに移動してインストールを実行

./configure --enable-layout=Darwin --enable-mods-shared=all
make
sudo make install 


apacheを起動した後phpinfo();で確認して
PDO drivers sqlite2, sqlite, mysqlとなっていればOK