PHPでYahoo!知恵袋APIを叩く

2011-08-10
このエントリーをはてなブックマークに追加

なんの脈絡もなくPHPで、しかもYahoo!のAPIなんですけど、知人と話しているときにふとそんな話になりまして。以前RubyやPythonでYahoo!の形態素解析API叩いたことはあったんですけど、PHPで、しかもYahoo!知恵袋APIってなかったなーと思って書いてみました。

結論、超簡単。自分の慣れもあるんだろうけど、一番あっさりかけた。Rubyで書いたときはその時使ったXMLパーサの仕様だったと思うのですがxmlnsの扱いにひどく手間取った記憶があります。

が、PHPの場合XML文書をオブジェクトに変換してくれる便利な関数があったので一発で完了。正直、拍子抜けなレベルでした。

<?
$req = “http://chiebukuro.yahooapis.jp/Chiebukuro/V1/questionSearch?appid=「自分で取得するアプリID」&query=”.urlencode(‘焼肉’);
$xml = simplexml_load_file($req);

foreach($xml->Result->Question as $item){
echo “質問:”.$item->Content.”rn”;
echo “質問ID:”.$item->Id.”rn”;
echo “ベストアンサー:”.$item->BestAnswer.”rnrn”;
}
?>

これだけで「焼肉」で検索して質問と質問IDとベストアンサーを取得できます。まぁ参照だけならこんなもんですよね。

API経由で質問したり回答したりもできるんですけど、その場合はOAuthでの認証が必要みたいですね。まぁOAuthなんてTwitterAPI叩いたことある人なら楽勝でしょ。

PHPはささっと書けてささっと動いてくれるので好きです。いいフレームワークがあればPHPをメインにしてもいいかと思うくらい。

うーん、PHP用のマイクロフレームワーク、作っちゃおうかなぁ。

Tags:

MacOSXでPHPの開発環境を構築する

2011-06-15
このエントリーをはてなブックマークに追加

MacOSX、SnowLeopardでのお話です。

WindowsでPHP使って開発してたときはApacheのインストールからやってましたが、MacOSXの場合はApacheはインストール済み、PHPもインストール済みでして、それらを「有効」にしてあげるだけですぐに使えます。

まぁ、そこをあえてソースからコンパイルしたい人とかもいるかもしれませんが、今回はそういうケースではなく、バンドルされているものをそのまま使う方法です。

まず、Apacheを使えるようにする

「システム環境設定」→「共有」→「Web共有」にチェックを入れるだけです。いれたあと、ブラウザを開いて「http://localhost/」を開いてみると、「It works.」と表示されていると思います。これでApacheは起動しました。

Apacheの再起動は

sudo apachectl restart

でOK。設定ファイルは「/etc/apache2/httpd.conf」にあります。編集するときは

sudo vi /etc/apache2/httpd.conf

で開いてください。

コンテンツを置く場所、DocumentRootはデフォルトでは「/Library/WebServer/Documents」の中になっているはずです。

 

PHPモジュールを読み込むように設定する

つぎはPHPの設定です。httpd.confを開いて、116行目あたり。PHPモジュールの読み込みがコメントアウトされていると思います。そこの#を消してあげてください。

#LoadModule php5_module        libexec/apache2/libphp5.so
↑この#を消す。

さらに、

<IfModule mod_php5.c>
AddType application/x-httpd-php .php
<IfModule mod_dir.c>
DirectoryIndex index.html index.php
</IfModule>
</IfModule>

を追記。場所はどこでいいのだとは思いますが、273行目あたりからモジュールの設定等が続くので、ハセテツはそのへんに書きました。

保存して閉じたらApacheの再起動。動作の確認に恒例のphpinfoでも書きましょう。

 

最近PHPがdisられているのを目にすることがたまにあるのですが、僕個人はPHP好きです。あの手軽さはいいですよね。PHPを否定する人の大半って、「マジョリティを否定することでちょっと俺はそのへんの連中と違うぜへへん」って、マイノリティ気取ってるだけちゃうんかなと。

ただ、PHPerにはとりあえずコーディングできるだけ、っていうひとが多いのも事実で、セキュリティもなんも考慮されていない、どうしようもなくスパゲッティになっているコードがあるのも事実です。それでPHPが悪く観られたりもしてんのかなと。けど、そんなのPHPが悪いわけじゃないしね。Javaで全部のロジックがJSPに記述されてるアプリケーションとかもあったよ。けっこう有名な会社だったけど。

まぁ、なにが言いたいかって、改善を伴わない否定は無駄なのでやる意味なし。そんなヒマあったらスキルアップに時間を費やしましょう、ってことでした。

 

Tags: ,

ハセテツがPython、というかDjangoを選んだ理由

2011-04-29
このエントリーをはてなブックマークに追加

思いっきり個人的な見解です。無知であるが故の部分も大きいと思います。

「そんなことねーぞ、こういうのもあるぞ」

っていうのがあると、教えて欲しかったりしてます。

正直、国内でのRuby人気は気になるのです。Rubyというか、RubyonRailsですよね。

2年位前は「Rubyすげえ!Railsすげえ!」だったんです。その前はPHPばっかり書いてました。

でも、RoR使うようになってフルスタックのフレームワークの便利さに魅了され、RoR一本でいくつもりでした。

まぁPHPの前はC#(ASP.NET)ばっかり書いてた頃もあったのですが。ちなみにその前はaspでした。

そんななか、Googleが導入し、GAEでも使えるPythonにも興味がありました。もともといろんな言語を使えるようになりたいとも思っていたので、新規プロジェクトの際にちと手を出してみたんですね。Python+Djangoに。

当時、Apacheにpassengerを組み合わせてRoRを走らせていたハセテツには一定時間ごとにインスタンスが終了されてしまうのが「なんだかなー」でした。アクセス数の多いサイトであれば気にならないのでしょうが、少ないサイトのだったのでリクエスト時に多少のタイムラグがあることが気になってしまっていました。

Python+Django、mod_wsgiはそれを解決してくれました。まぁmongrelでもよかったのかもしれませんが、当時は開発が止まっていた時期だったと。今はthinとかもあるから問題ないのかもしれませんね。

CakePHPやsymfonyは選択肢に入りませんでした。ステップ数が多くてリクエストごとのレスポンスが遅すぎました。APCとか使えばそれなりらしいのですが、そもそもPHPは手軽に書けるのが魅力だと思っていたので、フレームワークのお作法に従うのは違うなーと。

実際、Pythonがよかったのではなく、Djangoがよかったのかもしれません。それくらいDjangoはよくできていました。RoRのfind_by_sqlに匹敵するものがないのは残念ですが。

Djangoだとurlディスパッチャーは自分で設定というか、urlとコントローラを紐付けてやらないといけません。Railsのようにcontrollerが自動的にurlと紐付かれたりはしません。が、それが自由自在で便利でした。

フレームワークを経由しないでApacheから直接レスポンスを返す静的コンテンツを置くディレクトリの指定も簡単です。フレームワークから「ここに置け」って指定されることもありません。

Railsはループ処理のときは一件ごとにsqlを発行しましたが、結合して一気に取ってきてくれます。ちゃんとO/Rマッパーが外部結合してくれます。

Djangoも、syncdbした後にmodelの設計を変えると面倒くさいという不満はあります。まぁそれは事前にきちんと設計しておけばいいだけの話なのですが。

モジュールの多さという点では、PythonもRubyもPHPも必要なものはそろっているという印象です。「RubyにはあるけどPythonにはない」っていうのはなかったかと。

あ、PHP版のMeCabバインディングはなかったか。

あ、あとRoRってひとつのプロジェクトで複数のWebアプリって作れませんよね。

実際こうやって書き出してみると、たいした理由じゃないですね。ちっさな「うーん、なんだかなー」の積み重ねだったりしてますね。

でも、そういう小さな積み重ねって技術者にとっては大事だったりすると思います。不満だった点も、当時はそうだっただけで今はとっくに改善されているのかもしれません。

結局、Python書けるようになってもGAEのアプリは一本も書いてません。それでも、Python+Djangoを選択してよかったと思っています。

うまい感じにオチをつけられないのですが、いろいろ試した結果、もうしばらくはPython+Djangoでいってみようと思います。

メインの言語を持った上で、いろいろな言語、環境のプロジェクトがこなせるように勉強だけは欠かさずにしないといけませんね。

技術者は死ぬまで追いかけ続けるんだろうな。下りのエスカレーターを上っていくように。

立ち止まったらどんどん落ちていくんでしょうね。

SmartyでArrayの内容を出力する

2010-07-13
このエントリーをはてなブックマークに追加

PHPではprint_rでArrayの内容を出力できますが、smartyの場合どうしたらよいものかと。まぁループして書き出せばよいのですが、それは面倒だなと。

{$array|@debug_print_var}

これで出力できます。簡単ですね。

最近ものすごく久しぶりにPHPを書いていますが、Array関連のメソッドが非常に豊富で、便利だなぁと。

Tags: ,

PHPとRubyとPythonのパフォーマンスを比較してみました

2010-05-11
このエントリーをはてなブックマークに追加

前回のエントリが結局フレームワークの話になってしまったため、新しいエントリを書きました。

同じような処理をさせた場合、どの言語が一番早いのか。非常に気になるところでありますが、試したことがありませんでした。今回試してみたところ、意外な結果が出たのです。

下の方に書いたそれぞれのプログラムを実行した結果の、プログラム内部で計測したミリ秒を比較してます。

PHP Ruby Python
2.80秒 0.36秒 0.93秒

3回計測した平均です。同じ処理をさせるプログラムを書いたつもりですが、本当にフェアなものになっているのか正直自信がありません。そもそもPHPはWebアプリを主な目的としているとのことなので、こういう処理は得意としていないのかもしれない。

また、それぞれのプログラムのループ内2行目、文字列連結の部分をコメントアウトして実行してみると、これまた意外な結果が出ました。

PHP Ruby Python
0.07秒 0.06秒 0.39秒

PHPは文字列連結が苦手なんだろうか。暗黙的な型変換にコストがかかるのだろうか、等々考えてしまいます。それとも秒を求める部分がネックなんですかね。その辺は今後追っていきます。

ただ、これまでPythonの方がRubyより早い、と思っていたために自分の無知さに猛烈に恥ずかしい思いをしています。

実際にMySQLと連携するバッチを書いたときにはRubyの方が遅かったり、Railsアプリがもっさりだったり、「速い」という印象がまったくありませんでした。が、それはある特定の面しかみていない上での思い込みだったのかもしれません。

これはRailsが遅いのか、もしくはMySQL/Rubyが遅いのか。当時の書き方がマズかったのか。今後、いろんなケースでこういった比較をしてみようかと。

今回の検証がすべてではないし、これが答えだとも思っていません。また、そういう意図を含んだエントリではありません。今回の検証だって、特定の面しか見ていません。が、あまりに意外な結果だったため、自戒の念を含めてブログに書きました。

「こう書くともっとフェアだよ」「こういうテストの方がいいんじゃない」等、アドバイスいただけるとうれしいです。

フレームワークまで含めた検証した方が現実的なのだろうか。。。


PHP

#!/usr/bin/php
<?
function microtime_float()
{

list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);

}
$_start = microtime_float();
$_sec = date(‘s’);

for($i=1;$i<100000;$i++)
{

$_val = (mt_rand(0, 100) + $i) / $i;
$_str = $_val.date(‘s’);

}

echo microtime_float() – $_start;
?>

Ruby

#! /usr/local/bin/ruby

i=1
_start = Time.now

99999.times do

_val = rand(100) / i
_str = _val.to_s + Time.now.sec.to_s
i += 1

end

p (Time.now – _start).to_f

Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
import datetime
import random

_start = datetime.datetime.now()

for i in range(1, 100000):

_val = random.randint(0, 100) / i
_str = str(_val) + str(datetime.datetime.now().second)

print datetime.datetime.now() – _start


検証環境

CPU:Xeon 1.86GHz
メモリ:2GB
OS: CentOS5.4 32bit
PHP:5.2.11
Ruby:1.8.7
Python:2.5.2

Tags: , ,

PHPの三項演算子

2009-11-16
このエントリーをはてなブックマークに追加

よく「スパゲッティの元だ」みたいな扱われ方をしますが、三項演算子はスパゲッティとは関係ないんじゃないかなぁと個人的には思うわけですよ。

確かに多用し過ぎると可読性が著しく下がりますが、それがイコールスパゲッティになるとは思っていません。

やっぱり書く人に依存、っていうことですよね。

$_page = (is_numeric($_GET[“page”]))? $_GET[“page”]: 1;

このまま使ってはいけない例ですが、

「pageっていうGETのパラメータが数値なら$_pageにはその値、数値じゃないなら$_pageには1を代入しなさい」

っていう内容です。

if(is_numeric($_GET[“page”])){
    $_page = $_GET[“page”];
}else{
    $_page = 1;
}

と同じ結果ですね。

Tags:

PHPでMySQLのload data infileを実行する

2009-08-20
このエントリーをはてなブックマークに追加

クエリで

load data local infile ‘ファイルパス’ into table テーブル名;

を実行するだけなのですが、「local」をつけないと動いてくれなかったのでメモ。SSHでログインしていたときは「load data infile」だけでインポートできていたので、気がつかずに苦労しました。

Tags: ,

Rubyで書くか、PHPで書くか、それが問題だ

2009-07-06
このエントリーをはてなブックマークに追加

はっきりいって、やっぱりRubyは遅いです。Railsじゃなくて、Rubyが遅いです。Rubyでループしまくってデータをインポートするバッチを書いたら、C#で同じ処理をさせたときの倍近くかかりました。(正確に計測していないので倍は言いすぎだと思うが、体感できるぐらい遅かった。今度PHPで同じコードを書いてみよう)

いわれてみれば書いてて気持ちいいし、Railsはらくちんです。しかし、ここまで遅いとは思っていなかった。ただ、遅いといってもフツーのWebアプリを開発する分にはそれほど大差は出ないのかもしれません。それでもやっぱりループ処理は遅いなぁ。イテレータのおかげでらくちんではあるのですが。

ORマッパーは、便利ですがやはり不安を常に感じてしまいます。ループ処理するときにはORマッパー任せにしないでfind_by_sqlで自分でSQLを書いちゃいます。そうしないと、100回のループで100件の問い合わせをされちゃいます。ここは外部結合使ってごっそり取ってきて欲しかった。まぁ、MySQLは外部結合するよりクエリ連打した方が早いからいいのかな。

ただし、ルーテイングは便利です。コントローラとアクションの管理がラクなので、あとからソースを追うときに非常にラクです。さらに、MVCの管理がすっきりしてます。

「それだけならCakePHPでもいいじゃないか」といわれそうですが、CakePHPはRubyonRailsより遅いというベンチを誰かのブログで拝見しました。いやー、アレ以上遅いのはさすがにパスかな。symfonyも同様みたいです。

小規模サイトで開発メンバーの入れ替わりがあるなら、フレームワークは必須でしょう。中規模以上になってもハードウェアに予算投入で解決できるならそれほど問題にはならないと思います。

予算が限られ、自社内コンテンツみたいに開発メンバーが限定されるのであれば、ピュアなPHPとSmarty、URLをきれいにしたければ(GETにだらだらつけたくなければ)mod_rewriteを使えばよいかと。

自社内コンテンツであっても、メンテナンスなどを考えるとフレームワークを導入した方がいい気もするのですが、サイトの成長計画と相談ですかねぇ。

あ、言語の話じゃなくてフレームワークの話になってきちゃった。

Tags: ,

PHPで複数ページのPDFを分割して1ページごとの複数ファイルにする

2009-04-15
このエントリーをはてなブックマークに追加

FPDIを利用します。「フリーで使っていいよ」と書いてあるのにPayPalのボタンが置いてあるのは、寄付はしてねっていうことですよね。会社のプロジェクトで利用することになったら経費で寄付してみようかと。

require ‘../var/fpdf/fpdi.php’;

$temp_pdf= new FPDI();
$_page = $temp_pdf->setSourceFile(‘../var/hoge.pdf’);
unset($temp_pdf);

for($i=1;$i<=$_page;$i++)
{
    $_write_pdf = new FPDI();
    $_write_pdf->setSourceFile(‘../var/hoge.pdf’);
    $_tmp_info = $_write_pdf->importPage($i);
    $_write_pdf->addPage();
    $_write_pdf->useTemplate($_tmp_info);
    $_write_pdf->Output(“hoge_”.$i.”.pdf”,”F”);
    unset ($_write_pdf);
}

unsetにはあまり意味はない、というかムダかもしれません。closeやdisposeが見当たらなかったので微妙に気持ち悪かったから入れただけです。解放してくれているのかなぁ。

ページ数の取得のために一度テンプレートとして読み込み、それからページ数分でループしてます。ループ処理の中で「テンプレートファイルのiページ目だけ読み込んでファイル書き出し」を繰り返しています。

これでやりたいことはできたのですが、なんかメソッド一発で分割してくれるのがありそうで怖い。あったらどなたか教えてください。

FPDIは1.2、FPDFは1.53、PHPは5.2、WindowsXP上のApache2.0で動作確認しました。

Tags:

PHPで文字列の桁埋め

2008-09-30
このエントリーをはてなブックマークに追加

「sprintf」を使うか「str_pad」を使うかが悩みどころです。今までは大して気にしてなかったのですが、どうやら「str_pad」の方が早いらしい。

ということで検証したのですが、あんまり変わんない。。。

まぁ所詮20万回程度のループだと大して差は出ないかな。とはいえ、実開発でそこまで大きな処理させるとも思えないし、ここはどっち使っても差はないということにしておきましょう。

使いやすい方でいいや。

str_pad使って「$_counter」という文字列を10桁に「0」で桁埋め。左側を埋める。

str_pad($_counter,10,’0′,STR_PAD_LEFT)

sprintfを使って「$_counter」という文字列を10桁に「0」で桁埋め。

sprintf(“%010d”,$_counter)

Tags: