Home

Shin x blog

CakePHP 公開する時はデバッグ情報を出さない

この記事の所要時間: 351

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が指定された場合、どのような動作をするかを確認しておきましょう。

PostgreSQL VACUUM FULLせずに不要領域を削除する

この記事の所要時間: 41

PostgreSQLではDELETEしたレコードは物理的には削除されずそのまま残り続けます。テーブル自体のサイズ(容量)を削減するにはDELETEした後にVACUUM FULLを行う必要があります。

このVACUUM FULLはテーブルへの書き込みロックがかかります。また数GクラスのテーブルへのVACUUM FULLは数時間かかることがあるので、常時書き込みがあるテーブルへは処理を行うタイミングが難しいです。

そこでVACUUM FULLを行わずに不要領域を削除(テーブルサイズを減らす)する方法を考えました。

方法は単純で「テーブルを新たに作って、そちらにデータを移行する」だけです。流れとしては以下のようになります。

  1. 不要領域を削除するテーブル(移行元テーブル)と同じレイアウトのテーブルを作成する(移行先テーブル)
  2. 移行先テーブルにレコードを移行する
  3. 移行先テーブルにインデックスを設定する
  4. 移行元テーブル名を変更する
  5. 移行先テーブル名を移行元テーブル名に変更する

ここでは不要領域を削除するテーブル(移行元)をitems、移行先をitems_newとします。

1. items_newテーブルを作る

create table as文でitems_newテーブルを作成します。「limit 0」を指定することによりレコードを移行することなくitemsと同じレイアウトのテーブルを生成します。但しこの方法では制約等は受け継がれないので別途作成する必要があります。

create table items_new as select * from items limit 0;

2. レコードを移行する

insert into select文でitemsテーブルからitems_newテーブルにレコードを格納します。ポイントは全レコードを一度に移す必要が無く、select文のwhere句で条件を指定して序々に移行することができる点です。ログのような時系列で並ぶレコードでは一度登録されたレコードを変更されることが無いので、この方法で少しづつ移行することができます。

逆に各レコードがランダムに変更されるようなテーブルだとこのアプローチは使えません。

order by句を指定することにより任意の順序でレコードを格納することができます。

insert into items_new select * from items where created between '2007/1/1 00:00:00' and '2007/1/31 23:59:59' order by created;

3. items_newテーブルにインデックスを設定する

items_newテーブルにインデックスを設定します。インデックス設定はロックがかかるのでこの段階で行います。

create index items_new on ...;

● itemsテーブルへの書き込みを停止する

常時itemsテーブルへの書き込みがある場合は、このタイミングで書き込みを一旦停止します。停止の方法には、サービスを一時停止する、テンポラリテーブルに書き出す、ファイルに書き出す等が考えられます。

4. itemsテーブルのテーブル名を変更する

itemsテーブルのテーブル名を適当な名前に変更します。

alter table items rename to items_old;

5. itemsテーブルのテーブル名を変更する

items_newテーブルのテーブル名をitemsに変更します。

alter table items_new rename to items;

● itemsテーブルへの書き込みを再開する

itemsテーブルへの書き込みを再開して完了です。もし停止期間に書き込むデータがあればitemsに書き戻します。またこの方法では外部制約は設定していないので、もしitemsやそれに関連するテーブルに外部参照制約があるならそちらも設定します。(そもそも外部参照がからむようなテーブルにはこの方法自体が不向きですね。)

VACUUM FULLは意外とやっかい

テーブルサイズが巨大化するとVACUUM FULLは意外とヘビーです。通常はコンカレントVACUUMで用が済むかもしれませんが、テーブルサイズを小さくしたい場合などは、今回のようにちょっとした工夫が必要となります。

ちなみにこの方法を取ると当然ながらレコードのoidが変わります。oidに依存しているシステムでは適用できませんのでご注意を。

CakePHPガイドブック登場

この記事の所要時間: 032

先日ご案内したCakePHP本がいよいよ登場します。タイトルは「CakePHPガイドブック」です。

ベタな名前ですが、あえて奇をてらわず、定番となる本になって欲しい!という執筆陣の思いが詰まっています。またカバーもシンプルなデザインになっているのでオフィスに置いて頂いても違和感無いかと思います。

10月末頃には書店に並ぶそうです。見かけたら一度手に取って頂ければ嬉しいです。

# 私自身も初めての書籍なのでとても楽しみです。;-)

出版元のマイコミさんのサイト [MYCOM BOOKS – CakePHPガイドブック]

PHPソースからドキュメントを生成するツール

この記事の所要時間: 524

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 

[参考サイト]

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

[参考サイト]

出力サンプル

CakePHP1.1.17.5612のソースを各ツールで出力してみました。

クラス構造を確認するならDoxygenが、ファイル構造を確認するならPHPXRefが良さそうです。ただDoxygenにはクセがあるようで、PEARパッケージのようにファイル名とクラス名が異なる場合は上手く生成ができませんでした。(良い方法があればどなたかヘルプを・・・;-))

モバイル向けGoogle AdSenseをPHPで使う

この記事の所要時間: 436

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&#91;"google"&#93;&#91;$param&#93;);
}

function google_append_color(&$url, $param) {
  global $google_dt;

  $color_array = split(",", $GLOBALS&#91;"google"&#93;&#91;$param&#93;);
  google_append_url($url, $param,
                    $color_array&#91;$google_dt % sizeof($color_array)&#93;);
}

function google_get_ad_url() {
  $google_ad_url = "http://pagead2.googlesyndication.com/pagead/ads?";
  $google_scheme = ($GLOBALS&#91;"google"&#93;&#91;"https"&#93; == "on")
      ? "https://" : "http://";
  foreach ($GLOBALS&#91;"google"&#93; 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での使用法について見てきました。各言語用にコードが用意されているのは素晴らしいことなのですが、つまづきそうな点が幾つかあるので注意が必要です。

あとデザインですが、シングル広告でもかなり画面幅を取ります。もう少し控えめなパターンがあると嬉しいです。

デザイナー向けPHPチュートリアルビデオ

  • 2007-09-27 (木)
  • PHP
この記事の所要時間: 034

KILLER PHP – FOR WEB DESIGNERS

PHP VIDEO TUTORIALS FOR WEB DESIGNERS

20以上のPHPチュートリアルビデオが公開されています。サイトではデザイナー向けと謳っているだけに基本的な内容から解説されているようです。

チュートリアルの内容は全て英語になるのですが、インストール方法やソースコードの説明などは映像もあるので何となく理解できます。個人的には解説されている内容自体は知っているので英語の勉強になって良いです。;-)

これからPHPを触れる方には参考になるのではないでしょうか。

楽天API PEAR::Services_Rakuten-0.2.1リリース

  • 2007-09-19 (水)
  • PHP
この記事の所要時間: 116

楽天ウェブサービスを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

使用方法はこちらをご参考下さい。

人気のTwitterクライアントは?

この記事の所要時間: 55

いつからかTwitterのfeedに投稿元を示すが含まれるようになりました。(情報ありがとうございました。>@fjkktkysさん)

そこで投稿数からTwitterクライアントのランキングを出してみました。

集計期間は[9/10 00:00:00 ~23:59:59]、対象はprotectをかけていない投稿(public_timelineに表示される投稿)です。

Twitterクライアントランキング [日本ユーザ]

まず日本ユーザでのランキングです。

1位はWindows用クライアントのTwitです。私も使っていますが、必要十分な機能が上手くまとまっており良いツールです。2位はim、3位はMac用ツールのtwitterrificとなっています。Mac用ツールでは5位にTwitterPodが入っており、Macでの専用クライアントでは人気を二分しているようです

なお[web]はランキングに含めてませんが、投稿数はダントツのトップです(全クライアントの投稿数を合計してさらにN倍)。ただこの数にはモバツイやtwitterMobileのようにに対応していないものも含まれているので、純粋なtwitter.comからの投稿はもっと少ないと思われます。

モバツイやtwitterMobileはユーザ数も多いでしょうから、どのあたりにランクインするか見てみたいですね。(是非ご対応を;-))

rank client entries
1 Twit 4913
2 im 1879
3 twitterrific 1737
4 TwitterFox 1484
5 TwitterPod 736
6 TwitterIrcGateway 438
7 Twippera 149
8 tmitter 145
9 foxytunes 141
10 Twitter Line 105
11 tokotto 94
12 TwitBin 87
13 Chirrup 82
14 TwitKu 81
15 Netvibes 62
16 twitte.rb 23
17 txt 18
18 Twitter Tools 17
19 Tweetr 16
20 Twitter4J 16
21 m2m 14
22 TwitterMail 12
23 Twitter4R 9
24 GtkTwitter 8
25 Facebook 7
26 twigadge 6
27 fring 5
28 Twitter Opera widget 2
28 Twimp 2
28 bookey 2
28 PocketTweets 2
29 Snitter 1

Twitterクライアントランキング [全体]

次は全体のランキングです。

まず目に付くのがクライアント数の多さです。日本ユーザでは32だったクライアント数は65となっています。中には掘り出し物のツールかも。

1位はtwitterrificで、2位に続く[im]と2つで投稿数の約半数を占めています。あと特徴的なのが3位の[txt](twitter.comが提供するモバイル版)です。日本では携帯電話からの投稿はモバツイやtwitterMobileなどツールを使用することが多く、[txt]はほとんど利用されていないようです(日本では17位)。

なお[web]については日本ランキングと同じくランキングには含めていませんが、こちらも圧倒的に1位となっています。

rank client entries
1 twitterrific 11651
2 im 9272
3 txt 6916
4 Twit 4932
5 TwitterFox 2465
6 TwitBin 1624
7 Tweetr 1255
8 Netvibes 918
9 yedda 876
10 TwitterPod 784
11 Facebook 645
12 Twitter Tools 531
13 PocketTweets 450
14 TwitterIrcGateway 449
15 foxytunes 354
16 TwitKu 243
17 Twippera 182
18 iTweet 173
19 tmitter 145
20 InnerTwitter 118
21 Snitter 115
22 TwitterMSN 111
23 Twitter Line 105
24 CTwitter 96
25 Twadget 95
26 tokotto 94
27 TwitterMail 86
28 Spaz 85
29 Chirrup 83
30 the ORG 74
31 TTYtter 56
32 Twitter Opera widget 40
33 fring 38
34 Numpa 32
35 twibble 29
36 twitte.rb 24
37 ThinCloud 21
38 brabblr 20
39 TinyTwitter 17
40 Twitter4J 16
41 Twitter4R 15
42 m2m 14
43 Hahlo 11
43 Mobypicture 11
44 blt 10
44 Pwytter 10
44 cellity 10
44 mobile with WidSets 10
45 GtkTwitter 8
45 TwitterGram 8
46 SKTwitter 6
46 twigadge 6
47 30 Boxes 5
48 twitterAIR 4
48 BlogRovr 4
49 哀Twitter 3
50 Whirrl 2
50 twit.el 2
50 mobile with WidSets China 2
50 Twimp 2
50 Auto Tweet 2
50 bookey 2
51 1stat.us 1
51 blogTV.com 1
51 Whisher 1

日本ユーザが1/3

このランキングを作成するのに投稿数を集計したのですが、日本ユーザの投稿数が全体の1/3となっていました。

他の言語・地域については個別に集計していないので分かりませんが、日本ユーザが大きな勢力となっているのは間違い無いと思います。

PHP 5.2.4 の新機能

  • 2007-09-06 (木)
  • PHP
この記事の所要時間: 453

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
)

CakePHP解説本を書きました

この記事の所要時間: 046

先日のPHPカンファレンス2007で安藤さんが発表されたとおりCakePHPの解説本が出版されます。

この本の執筆にcakephp.jp管理人である堂園さん、そしてPHP勉強会やカンファレンスでお馴染みの安藤さん、と共に参加させて頂きました。

原稿はほぼ書き終えた状況で、現在は10月出版を目指して諸々の作業を行っています。

これまでもCakePHPを扱った書籍はあったのですが、単独での解説本としては(世界?)初となります。基本的な使い方から実践的な内容までカバーしているので、CakePHPユーザはもちろんの事、フレームワークは初めてという方にもおすすめの一冊となっています。

現段階ではamazon等で予約はできませんが、正式な発売日など決まりましたら、またお知らせ致します。

お楽しみに!

via: CakePHP のおいしい食べ方: 間もなくCake本登場!!

Home

検索
フィード
メタ情報

Return to page top