Home > PHP
PHP Archive
CakePHP1.2をベースにしたオープンソースシステム-NoseRub
- 2007-11-11 (日)
- CakePHP
CakePHP1.2はまだpre-betaの状態ですが、既にこれをベースとしたオープンソースシステムが公開されています。
それがNoseRubです。
NoseRubはざっと見た感じ「マイクロブログ」に分類されるシステムです。様々なRSSフィードをアグリゲートできるようでTwitterというよりJaikuに近い印象を受けました。NoseRubの内容については上記サイトにこのシステムを利用したサービスが公開されている(ここなど)のでそちらを参考にして下さい。
ここで大事なのはこのシステムがCakePHP1.2ベースで作られているという事です。
1.2に関してはpre-betaという事もあり、箇所箇所の情報は見られるのですが、これを実際のシステムに組み込むノウハウがまだ共有されていない状態にあります。その中において実際にサービスとして動作するシステムがオープンソースで公開されているのはとても有り難いことです。
実際にダウンロードして中身を見てみました。ソースはわりと丁寧に書かれていて読みやすいです。やはり根本のフレームワークは理解しているので処理を追いやすいですね。まだ導入部分しか読んでいませんが、細かな実装のヒントが見つかり、これはかなり参考になりそうです。
ちなみに最新版であるNoseRub0.5.1はCakePHP1.2.0.5875 pre-betaベースとなっていました。
これから1.2で実装したい方は是非一度ダウンロードして参考にしてみて下さい。
# ホント、オススメです!
ちなみにCakePHPを使ったシステムやサービスなどは以下のサイトに公開されています。
- コメント (Close): 0
- Trackbacks: 0
PHPSpecマニュアルが登場
- 2007-11-07 (水)
- PHP
via: PHPSpec Manual (Work In Progress) – Maugrim The Reaper’s Blog
RSpecのPHP版、PHPSpecのマニュアルが公開されています。
現在はドラフトでこれから順次更新されていくようです。
RSpec自体試したことはないのですが、興味がある分野なので期待しています。
RSpecって何?な方は、Rubyist Magazineが参考になります。
技術の流れとして、以前はJava->PHPなトレンドでしたが、ここ最近はRuby->PHPとなっていますね(Cakeしかりです)。PHP独自のものが少ないのはやはり実用言語だからでしょうか。
# そんなPHP界で異彩を放つPieceFrameworkは面白い試みだと思います。;-)
- コメント (Close): 0
- Trackbacks: 0
PHPでメールの重要度を設定する
- 2007-11-03 (土)
- PHP
システムから配信するメールに重要度を付けたいという話しがあったので調べてみました。
重要度を設定しておくと対応しているMUA(OutlookやらBecky!やら)ではメールの横にマークが付加されます。
分かったことは以下のとおり。
- 重要度はメールヘッダで設定する。
- 以前はX-PriorityやらX-MsMail-Priorityやらの独自ヘッダで設定し、MUAでは各々独自に処理していた。
- RFC1327で重要度を表すPriorityヘッダが用意された。
重要度を設定する値はヘッダによって異なります。
ヘッダ | 重要度高 | 重要度やや高 | 普通 | 重要度やや低 | 重要度低 |
---|---|---|---|---|---|
X-Priotiry | 1 | 2 | 3 | 4 | 5 |
X-MsMail-Priotiry | High | Normal | Low | ||
Priotiry | urgent | normal | non-urgent |
PHPでテストしてみました。mb_send_mail()でメールヘッダを設定しているだけです。
<?php $to = 'hoge@example.com'; $subject = 'subject'; $body = 'body'; // ヘッダで重要度高を設定する $header = 'Priority: urgent'; //$header = 'X-Priority: 1'; //$header = 'X-MsMail-Priority: High'; mb_language('ja'); mb_send_mail($to, $subject, $body, $header); ?>
このコードを実行すると、手元のBecky!では受信したメールに重要度高が設定されているのが確認できました。
どのヘッダを使用するかですが、Becky!では3つの内、どのヘッダを使用しても重要度が設定されていました。RFC1327で定義されているのは「Priority」なので、今後はこれを利用するのが良いでしょう。(対象のMUAが対応していればですが)
ちなみにBecky!自身で重要度を設定すると「X-Priority」と「X-MsMail-Priority」がヘッダに付加されていました。
今回は管理者向けメールなので受信するMUAが限定できました。様々なMUAに対応する際どのヘッダが対応しているかを調査する必要があるでしょう。
私自身はメールに重要度を設定しないので有用かどうかはあまりピンと来ませんが。:-p
- コメント (Close): 5
- Trackbacks: 0
CakePHP 公開する時はデバッグ情報を出さない
CakePHPで作ったシステムを公開する時は、フレームワークが出力するデバッグ情報に気をつけましょう。
1. SQLログ
DEBUG定数の値を2以上に設定すると実行されたSQL文がログとして画面に表示されます。通常本稼働する際はDEBUGを0にしてこの出力は抑制するのですが、たまに本稼働でもSQL文がログが出力されているサイトがあります。
ちなみにSQLログに含まれるキーワードをGoogleで検索すると出力したままのサイトが見つかったりします。
“queries took” “Took (ms)” – Google 検索
対策
[app/config/core.php]にあるDEBUGを0にしておきます。公開サイトでSQL文を確認したい場合はCakePHP SQLをログに記録する方法などを使ってログファイルに出力するのが良いでしょう。
[app/config/core.php]
// define('DEBUG', 2); define('DEBUG', 0);
2. PageControllerへのルーティング
デフォルトのURLルーティングでは[/]と[/pages/*]なURLはPageControllerのdisplayアクションにルーティングされるようになっています。displayアクションでは[/pages/]以降で指定された値をビューテンプレートとして出力します。([/]は/pages/homeとして処理されます)
[/]なURLは大抵アクセスを想定しているのでルーティングを変更すると思うのですが、[/pages/*]なURLは変更を忘れがちです。そのままだと[/pages/home]なURLを指定すると、フレームワークに含まれるhome.thtmlが出力されてしまいます。
http://example.com/pages/home
対策
[app/config/routes.php]にあるPageControllerへのルーティングを削除します。
[app/config/routes.php]
// [/]のURLルーティングを変更 // $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); $Route->connect('/', array('controller' => 'top', 'action' => 'index')); (snip) // [/pages/*]のURLルーティングを変更 // $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
3. 存在しないコントローラ、アクション
これもDEBUG定数の値によって出力されます。DEBUGの値が1以上の場合、存在しないコントローラやアクションがURLで指定されるとエラーメッセージが表示されてしまいます。
例えばそこで[/a/a]のように存在しないであろうコントローラやアクションを指定すると「Missing Controller」や「Missing Method」が表示されます。
対策
1.と同様にDEBUGの値を0にします。
対策-さらに
フレームワークは[/foo(/bar)?]なURLであればコントローラとアクション(/barがなければ/indexが存在するとみなす)を探そうとします。ですのでリバースプロキシなどで外部からCakePHPシステムへアクセスされるURLを限定してしまうのもアリです。
こうしておけば予期せぬURLからのアクセスを防ぐことができるので、URLルーティングにおける想定外の動作を防ぐことができます。(この手法は結構好きなので良く使用します。;-))
便利機能には注意を
CakePHPに限らず各種フレームワークには開発に有用なデバッグ情報出力などの機能が用意されています。これらの情報は開発には役立ちますが、一般に公開すると攻撃者へヒントを与えることにもなりますし、何より見た目が宜しくありません。
特にURLルーティングに関しては今時のフレームワークでは実装されている機能だと思います。外部に公開するシステムでは、あらかじめ想定外のURLが指定された場合、どのような動作をするかを確認しておきましょう。
- コメント (Close): 0
- Trackbacks: 0
CakePHPガイドブック登場
先日ご案内したCakePHP本がいよいよ登場します。タイトルは「CakePHPガイドブック」です。
ベタな名前ですが、あえて奇をてらわず、定番となる本になって欲しい!という執筆陣の思いが詰まっています。またカバーもシンプルなデザインになっているのでオフィスに置いて頂いても違和感無いかと思います。
10月末頃には書店に並ぶそうです。見かけたら一度手に取って頂ければ嬉しいです。
# 私自身も初めての書籍なのでとても楽しみです。;-)
出版元のマイコミさんのサイト [MYCOM BOOKS – CakePHPガイドブック]
- コメント (Close): 4
- Trackbacks: 0
PHPソースからドキュメントを生成するツール
PHPソースからドキュメントを生成する主要な3ツールを試してみました。どのツールもそれほど深くは調べていないのでインストール+アルファ程度の設定変更で試しています。
環境はCentOS4.4+PHP5.2.3です。
phpDocumentor
PHPでできたツールです。pearコマンドでインストールできることもあって、PHPのドキュメントジェネレータとして人気があります。
- インストール
pearコマンドでインストールできます。
$ pear install --alldeps phpdocumentor
- ドキュメント生成
phpdocコマンドで生成します。とりあえずドキュメントを生成するだけなら設定ファイルの変更は不要です。
./src 以下のPHPファイルを対象に ./doc 以下にドキュメントを生成 $ phpdoc -t ./doc -d ./src
[参考サイト]
- phpDocumentor: The complete documentation solution for PHP[本家]
- Do You PHP? – phpDocumentor – PHPDocに代わるAPIドキュメント自動生成ツール
Doxygen
C++でできたツールです。DoxygenはC/C++、Javaをはじめ様々な言語についてドキュメントを生成することができます。どちらかと言うと、C/C++、Java、Pythonがメインのツールですが、PHPでも十分なドキュメントを生成することができます。
- インストール
CentOS4用はRPMがあるのでyumコマンドでインストールできます。
$ sudo yum install Doxygen
ただRPMは1.3.9ですので、最新版(1.5.3)がよければソースからインストールします。
$ tar zxvf doxygen-1.5.3.src.tar.gz $ cd doxygen-1.5.3 $ ./configure $ make $ sudo make install
- ドキュメント生成
まず設定ファイルを生成します。-gで生成する設定ファイルのファイル名を指定します。ファイル名を指定しなければDoxyfileという設定ファイルがカレントディレクトリに生成されます。
$ doxygen -g [config]
次に設定ファイルを編集します。下記は最低限変更した方が良いと思う項目です。
$ vi Doxyfile
# ドキュメント出力ディレクトリ(省略すればカレントディレクトリに出力) # => doc ディレクトリに出力 #OUTPUT_DIRECTORY = OUTPUT_DIRECTORY = doc # ソースディレクトリ(省略すればカレントディレクトリ) # => src ディレクトリ以下のファイルを解析 #INPUT = INPUT = src # 再帰的にソースディレクトリを解析する # => 再帰する(YESにしないとINPUTで指定したディレクトリのみ解析する) #RECURSIVE = NO RECURSIVE = YES # ソースコードページを生成する # => ソースコードページを生成 #SOURCE_BROWSER = NO SOURCE_BROWSER = YES # ソースコードページにてコメントを削除する # => ソースコードページにコメント出力 #STRIP_CODE_COMMENTS = YES STRIP_CODE_COMMENTS = NO
ドキュメント生成コマンドを実行するとドキュメントが生成されます。
$ doxygen Doxyfile
[参考サイト]
PHPXRef
Perlでできたツールです。phpDocumentorやDoxygenとは少し毛色が異なり、クラス図などは表示されません。上記2ツールはクラス構造などをドキュメント化しますが、PHPXRefはソースコード自体をドキュメント化するのを目的としています。
- インストール
PHPXref – The PHP Cross Referencing Documentation Utilityから最新版ソース(0.7)をダウンロードして展開するだけでokです。
$ tar zxvf phpxref-0.7.tar.gz $ cd phpxref-0.7
- ドキュメント生成
設定ファイルを編集します。展開したディレクトリ内にあるphpxref.cfgが設定ファイルになります。
$ vi phpxref.cfg
# ソースディレクトリ(省略すればカレントディレクトリ) SOURCE=src # ドキュメント出力ディレクトリ(省略すればカレントディレクトリに出力) OUTPUT=doc
ドキュメント生成コマンドを実行するとドキュメントが生成されます。
$ ./phpxref.pl
[参考サイト]
- PHPXref – The PHP Cross Referencing Documentation Utility[本家]
- Do You PHP? – PHPXref – クロスリファレンスドキュメントの自動生成
出力サンプル
CakePHP1.1.17.5612のソースを各ツールで出力してみました。
クラス構造を確認するならDoxygenが、ファイル構造を確認するならPHPXRefが良さそうです。ただDoxygenにはクセがあるようで、PEARパッケージのようにファイル名とクラス名が異なる場合は上手く生成ができませんでした。(良い方法があればどなたかヘルプを・・・;-))
- コメント (Close): 4
- Trackbacks: 0
モバイル向けGoogle AdSenseをPHPで使う
Google AdSenseにモバイル版が登場しました。
通常のAdSenseではJavaScriptを使って広告を表示するのですが、携帯ではJavaScriptが使えないので、PHPやPerlなどサーバ側で実行する言語で記述します。AdSenceサイトではPHP/Perl/JSP/ASPのコードが用意されており、モバイル向けAdSense設定を行うとそれぞれのコードが表示されます。
PHP用コードを確認したところ、コードの流れは単純で、AdSense IDや広告フォーマット、HTTPリクエスト(HTTP_USER_AGENT等)などを専用変数に設定して、最後にリモートにあるPHPコードをrequire()しているだけです。
コードを見て気になる点があったのでメモしておきます。
$_SERVERにキーが無いことを想定していない
$_SERVER[‘HTTPS’]や$_SERVER[‘HTTP_REFERER’]など値が存在しない可能性があるものをそのまま参照しています。これらの値が存在しない場合は「Notice: Undefined index」が発生します。
[対応策]
isset()やempty()で連想配列にキーが存在するかどうかを確認します。単純に回避するなら[@]をつけてエラーメッセージの出力を抑制する方法もあります。
require()でリモートスクリプトをインクルード
PHP5.2.3でコードを実行したところ、以下のメッセージが表示されました。
Warning: require() [function.require]: URL file-access is disabled in the server configuration in /home/www/xxxx/ad.php on line 17
これはallow_url_includeディレクティブがoffになっているために発生します。allow_url_includeはPHP5.2.0からは追加されたもので、これがoffになっているとリモートにあるスクリプトをinclude()やrequire()でインクルードすることができません。
allow_url_includeはデフォルトはoffとなっているので、そのままだとこのコードは動作しません。
対応策としては3通りの方法があります。
[対応策1] allow_url_includeをonにする
allow_url_includeをonにすればこのコードは動作します。しかしこのディレクティブはセキュリティリスク(RFI等)を回避するためにoffにされているものなので、できればこの方法は取らない方が良いです。
またallow_url_includeはphp.iniやhttpd.confでのみ設定が可能なので、共用サーバなどでは設定が変更できないかもしれません。
[対応策2] file_get_contents()でリモートスクリプトを読む
file_get_contents()でリモートスクリプトを読み込む方法です。file_get_contents()は単にファイルを読み込んでその内容を返すだけなので、allow_url_includeの影響は受けません。
あとは読み込んだスクリプトをeval()で実行しようと思いました。が、eval()でエラーが発生しました。「<&php」「&>」が引っかかっているようです。対応しても良いのですが、これはこのまま放置。
[対応策3] リモートスクリプトをローカルに置く
require()で読み込んでいるスクリプトをローカルに置いてしまいます。そしてrequire()でローカルのファイルをインクルードするようにします。こうすればallow_url_includeの設定に関わらずスクリプトを実行できます。
ちなみにリモートスクリプトは以下のようになっています。
<?php /** * Copyright (C) 2007 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * @license http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ $google_dt = time(); function google_append_url(&$url, $param, $value) { $url .= "&" . $param . "=" . urlencode($value); } function google_append_globals(&$url, $param) { google_append_url($url, $param, $GLOBALS["google"][$param]); } function google_append_color(&$url, $param) { global $google_dt; $color_array = split(",", $GLOBALS["google"][$param]); google_append_url($url, $param, $color_array[$google_dt % sizeof($color_array)]); } function google_get_ad_url() { $google_ad_url = "http://pagead2.googlesyndication.com/pagead/ads?"; $google_scheme = ($GLOBALS["google"]["https"] == "on") ? "https://" : "http://"; foreach ($GLOBALS["google"] as $param => $value) { if ($param == "client") { google_append_url($google_ad_url, $param, "ca-mb-" . $GLOBALS["google"][$param]); } else if (strpos($param, "color_") === 0) { google_append_color($google_ad_url, $param); } else if ((strpos($param, "host") === 0) || (strpos($param, "url") === 0)) { google_append_url($google_ad_url, $param, $google_scheme . $GLOBALS["google"][$param]); } else { google_append_globals($google_ad_url, $param); } } google_append_url($google_ad_url, "dt", round(1000 * array_sum(explode(" ", microtime())))); return $google_ad_url; } $google_ad_handle = fopen(google_get_ad_url(), "r"); if ($google_ad_handle) { while (!feof($google_ad_handle)) { echo fread($google_ad_handle, 8192); } fclose($google_ad_handle); } ?>
[おまけ] require()よりinclude()
require()は読込に失敗した場合、Fatal errorが発生してスクリプトの実行が止まってしまいます。一方include()は読込ができなくてもWarningが出るのみです。広告は最悪表示されなくとも問題無いので、include()(もしくは@include())を使った方がより良いでしょう。
allow_url_fopenをonにしておく
最後に大事なこと。どのような対策を取るにせよallow_url_fopenはonである必要があります。これはリモートスクリプト自体がfopen()でリモートファイルを読みに行っているためです。またallow_url_includeをonにしたところでallow_url_fopenがoffだとリモートファイルのインクルードは動作しません。
allow_url_fopenはデフォルトではonになっているので問題無いかと思いますが、上手く動作しない場合はご確認を。
まとめ
モバイル向けGoogle AdSenseのPHPでの使用法について見てきました。各言語用にコードが用意されているのは素晴らしいことなのですが、つまづきそうな点が幾つかあるので注意が必要です。
あとデザインですが、シングル広告でもかなり画面幅を取ります。もう少し控えめなパターンがあると嬉しいです。
- コメント (Close): 1
- Trackbacks: 4
デザイナー向けPHPチュートリアルビデオ
- 2007-09-27 (木)
- PHP
KILLER PHP – FOR WEB DESIGNERS
20以上のPHPチュートリアルビデオが公開されています。サイトではデザイナー向けと謳っているだけに基本的な内容から解説されているようです。
チュートリアルの内容は全て英語になるのですが、インストール方法やソースコードの説明などは映像もあるので何となく理解できます。個人的には解説されている内容自体は知っているので英語の勉強になって良いです。;-)
これからPHPを触れる方には参考になるのではないでしょうか。
- コメント (Close): 1
- Trackbacks: 0
楽天API PEAR::Services_Rakuten-0.2.1リリース
- 2007-09-19 (水)
- PHP
楽天ウェブサービスをPHPで利用するPEARライブラリ「PEAR::Services_Rakuten-0.2.1」をリリースしました。
本リリースでは以下の内容を修正しています。(nekolifeさん、ご指摘ありがとうございました。)
- 商品検索等でgenreIdに0を指定すると「keyword or genreId have not been set.」が表示される
インストール・アンインストール
インストール方法は以下です。
$ pear install --alldeps /blog/download/Services_Rakuten-0.2.1.tgz
インストール時に「Failed to download pear/XML_Serializer within preferred state “stable”」といったエラーが発生した場合は以下のコマンドでXML_Serializerをインストール後、Services_Rakutenをインストールして下さい。
$ pear install --alldeps XML_Serializer-beta
アンインストール方法は以下です。
$ pear uninstall __uri/Services_Rakuten
使用方法はこちらをご参考下さい。
- コメント (Close): 0
- Trackbacks: 0
PHP 5.2.4 の新機能
- 2007-09-06 (木)
- PHP
PHP5.2.4がリリースされています。
基本バグフィックス&セキュリティアップデートのようなので大きな変更はありませんが、ChangeLogから興味を引いた変更点をメモしておきます。
–enable-versioningの廃止
追加機能では無いですが。
PHP3/PHP4を同時にApacheモジュールとして実行できるオプションでしたが、今回廃止されました。まあ昨今ではさすがに使っている人はいないでしょうけど、PHP3->PHP4の移行期には必須とも言えるオプションだったので、感慨深いものがあります。
PHPエラーをstderrに出力可能に
CGI/CLI版では、display_errors=stderrに設定することにより、PHPエラーをstderr(標準エラー)に出力することができるようになりました。なおデフォルトではこれまでどおりstdoutに出力されます。
stderrにPHPエラーを出力
$ php -d 'display_errors=stderr' -r 'a' > stdout 2> stderr $ cat stdout $ cat stderr PHP Parse error: syntax error, unexpected $end in Command line code on line 1 Parse error: syntax error, unexpected $end in Command line code on line 1
PHPエラーでHTTP 500を返す
PHP5.2.4ではPHPエラーでHTTP 500を返す参照
前項のPHPエラーをstderrに出力するのと同じノリですね。
PCRE_VERSION定数を追加
正規表現ライブラリであるPCREのバージョンを表す定数が追加されています。
$ php -r 'echo PCRE_VERSION . PHP_EOL;' 7.2 2007-06-19
あとGDでもバージョンを表す定数が追加されています。(GD_MAJOR_VERSION, GD_MINOR_VERSION GD_RELEASE_VERSION, GD_EXTRA_VERSION, GD_VERSION_STRING)
php_ini_loaded_file()追加
現在読み込んでいるphp.iniファイルの絶対パスを返す関数です。
CLIで何か挙動がおかしいなあと思ったら、読み込んでいるphp.iniを確認するのも良いかもしれません。
$ php -r 'var_dump(php_ini_loaded_file());' string(29) "/home/hoge/php524/lib/php.ini" $ php -c . -r 'var_dump(php_ini_loaded_file());' string(18) "/home/home/php.ini"
ReflectionExtensionクラスにinfo()を追加
extensionをリフレクションするReflectionExtensionクラスにinfo()が追加されました。
$ php -r '$obj = new ReflectionExtension("mbstring"); $obj->info();' mbstring Multibyte Support => enabled Multibyte string engine => libmbfl Multibyte (japanese) regex support => enabled Multibyte regex (oniguruma) version => 4.4.4 Multibyte regex (oniguruma) backtrack check => On mbstring extension makes use of "streamable kanji code filter and converter", which is distributed under the GNU Lesser General Public License version 2.1. Directive => Local Value => Master Value mbstring.language => neutral => neutral mbstring.detect_order => no value => no value mbstring.http_input => pass => pass mbstring.http_output => pass => pass mbstring.internal_encoding => ISO-8859-1 => no value mbstring.substitute_character => no value => no value mbstring.func_overload => 0 => 0 mbstring.encoding_translation => Off => Off mbstring.strict_detection => Off => Off
ReflectionClass::getDefaultProperties()でstaticクラス変数が取得可能に
ReflectionClass::getDefaultProperties()でstaticクラス変数が取得できるようになっています。
<?php class Foo { public static $fooStatic = 'foo'; protected $foo = 'foo'; } $class = new ReflectionClass('Foo'); print_r($class->getDefaultProperties());
$ /home/hoge/php523/bin/php ref.php Array ( [foo] => foo ) $ /home/hoge/php524/bin/php ref.php Array ( [fooStatic] => foo [foo] => foo )
- コメント (Close): 1
- Trackbacks: 0
ホーム > PHP
- 検索
- フィード
- メタ情報