第 55章PHPを使う
このセクションにはPHPスクリプトを書くにあたってよく問題となる事柄が 集められています。
- 1. あらゆるフォームから送信されたデータを扱うことができる汎用的な PHPスクリプトを書きたいのですが、POSTメソッドでどのようなデータ が送信されたかを知るにはどうするのですか?
- 2. シングルクオート(')をバックスラッシュでエスケープされた シングルクオート(\')に変換しなければならないのですが、 正規表現を用いてこれを行うにはどの様にするのですか? 同様に " を \" に、\ を \\ に変換したいのです。
- 3. " は \" に、また ' は \' に全て変換されているのですが、 これら無用なバックスラッシュを除去するにはどうしたらよいですか? どうやって、そしてなぜ、こんなことになっているのでしょう?
-
4.
次のようなコードを実行すると、思った通りの順番で出力が表示されま せん。
なぜですか?function myfunc($argument)
{
echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable); -
5.
改行されないのですが?
<pre>
<?php echo "これは1行目" ; ?>
<?php echo "この行は改行に続いて出力されるはず" ; ?>
</pre> - 6. 'Warning: Cannot send session cookie - headers already sent...'や 'Cannot add header information - headers already set...'といった メッセージが出力されるのですが。 sent...'.
- 7. リクエストヘッダに直接アクセスしたいのですが、どうすればよいですか?
- 8. IISで認証を行おうとすると'No Input file specified'というエラーが 発生します。
- 9. Windows: 他のコンピュータと共有しているファイルに、IIS でアクセスできません。
- 10. 私が書いたPHPスクリプトはIEとLynxでは動作するのですが、Netscapeを 使うと出力の一部が失われてしまいます。"ソースの表示"をするとIEには あるがNetscapeにはない内容があります。
- 11. どうすればXMLとPHPは共存することが出来るのですか?XMLの <?xml>タグがPHPでエラーになります。
- 12. FrontPageやその他のHTMLエディタを使うと、書いたPHPのコードが勝手 にあちこちに移動されてしまいます。どうしたらいいですか?
- 13. あらかじめ設定されている変数を全て網羅したリストはどこにあるので すか?なぜPHPのドキュメントにはその一覧がないのですか?
- 14. フリーではない商用ライブラリである ClibPDF や PDFLib を使わずに PDFファイルを生成するにはどうしたらよいでしょうか? フリーのもので、外部のPDFライブラリを必要としない ものがいいのです。
- 15. ユーザ定義関数の中で、標準的な($DOCUMENT_ROOTや$HTTP_REFERER等の) CGI変数にアクセスしたいのですが、PHPはそれらの変数を見つけること ができていないようです。何がおかしいのですか?
- 16. いくつかの PHP ディレクティブでは、バイト値を integer ではなく省略形で設定できます。この省略形で使えるオプションを教えてください。 また、これは php.ini 以外でも使えるのですか ?
PHPは
$_POST
のような
定義済みの変数
を沢山提供しています。
$_POST
を連想配列として ループすることでPOSTされた全ての値にアクセスできます。例えば、
foreach
で 単純にループして
empty()
で値をチェックし、 結果を出力します。
<?php
|
スーパーグローバル: 使用可能なバージョンに関する注意: PHP 4.1.0 以降、
$_GET,$_POST,$_SERVER等のスーパーグローバル配列が使用可能となっています。 詳細な情報については、マニュアルの superglobals のセクションを参照してください。
2. シングルクオート(')をバックスラッシュでエスケープされた シングルクオート(\')に変換しなければならないのですが、 正規表現を用いてこれを行うにはどの様にするのですか? 同様に " を \" に、\ を \\ に変換したいのです。
addslashes() がこれを行ってくれます。 mysql_escape_string() も見てください。 stripslashes() によって バックスラッシュを除去することもできます。
ディレクティブに関する注意: magic_quotes_gpc: PHP ディレクティブ magic_quotes_gpc のデフォルトは on です。この場合、すべての GET, POST, COOKIE データに ついて addslashes() が実行されます。 これらを取り除くため stripslashes() を使用することが できます。
3. " は \" に、また ' は \' に全て変換されているのですが、 これら無用なバックスラッシュを除去するにはどうしたらよいですか? どうやって、そしてなぜ、こんなことになっているのでしょう?
stripslashes() 関数によって string から バックスラッシュを取り除くことができます。 このような奇妙なバックスラッシュは、ほとんどの場合、PHPの magic_quotes_gpc ディレクティブがオンになっていることによって付加されています。
ディレクティブに関する注意: magic_quotes_gpc: PHP ディレクティブ magic_quotes_gpc のデフォルトは on です。この場合、すべての GET, POST, COOKIE データに ついて addslashes() が実行されます。 これらを取り除くため stripslashes() を使用することが できます。
4. 次のようなコードを実行すると、思った通りの順番で出力が表示されま せん。
function myfunc($argument)
|
式の中で関数の実行結果を使用する(例えば上の例の様に他の文字列と 連結する)ためには、 echo() するのではなく、その 値を return しなければいけません。
PHPでは、"?>"か"?>\n"(\nは改行を表します)をPHPのコードブロッ クの終端と見なします。このため、コードブロック終端の改行記号は省 略され、表示される文は1行になります。つまり、改行をさせるために は、PHPのコードブロックの終端の後にもう1つ改行を挿入する必要があ るということです。
なぜPHPはこのようなことをするのでしょうか?なぜならHTMLを出力する 場合にはこの方が都合のよいことが多いからです。もしとても長い1行を 出力しなければならない場合に、改行が解釈されてしまうとしたらどう でしょう。ソースコードの1行もとても読めないくらい長いものになって しまいます。
6. 'Warning: Cannot send session cookie - headers already sent...'や 'Cannot add header information - headers already set...'といった メッセージが出力されるのですが。 sent...'.
header() , set_cookie() や セッション関数 は出力ストリームに ヘッダを付加する関数で、ヘッダを送信できるのは本文の出力を 開始する前のみです。 headers_sent() を使って 既にヘッダが送信済みでないかチェックすることができます。 出力制御関数 もご覧ください。
もしPHPがApacheモジュールとして動作しているなら、 getallheaders() を使えば全てのヘッダを取得する ことができます。下のちょっとしたコードで全てのリクエストヘッダを 表示することができます。
$headers = getallheaders();
|
apache_lookup_uri() , apache_response_headers() , fsockopen() も参照してください。
これはIISのセキュリティモデルの欠点で、IISで動作するCGIに共通する 問題です。これを回避策するには、認証のかかったディレクトリに(PHP が解釈しない)HTMLファイルを作成します。そしてMETAタグを使ってPHP を使用したページにリダイレクトするか、リンクを張ります。こうすれ ばPHPは認証済みかどうかを正しく認識することが出来ます。ISAPIモジュー ルの場合はこの問題は起きません。また、これは他のNTウェブサーバに は影響ありません。詳しくは http://support.microsoft.com/kb/q160422/ と HTTP 認証 を 参照してください。
Go to Internet Information Services を変更する必要があります。PHP ファイルを選択して プロパティを開き、 セキュリティ タブに移動し、 Edit -< Anonymous access and authentication control 。
この問題を解決するには Anonymous Access のチェックをはずして Integrated Window Authentication をチェックしたままにしておきか、 あるいは Anonymous Access をチェックしてアクセスできないユーザを別途指定します。
10. 私が書いたPHPスクリプトはIEとLynxでは動作するのですが、Netscapeを 使うと出力の一部が失われてしまいます。"ソースの表示"をするとIEには あるがNetscapeにはない内容があります。
NetscapeはHTMLタグの扱いがIEに比べて厳密になっています(テーブル等)。 スクリプトが出力したHTMLを validator.w3.org などのHTMLバリデータに掛けてみると良いでしょう。 例えば</table>が無いとこのような現象が発生します。
また、IEとLynxは共にHTMLストリーム中のNULL文字( \0 )を 無視しますがNetscapeは無視しません。この問題をチェックする一番の方法 は コマンドライン版 の PHP(つまりCGIバージョン)をコンパイルして、コマンドラインからその スクリプトを実行することです。*nix上では、その出力を od -c にパイプして \0 があるかどうかを チェックしてください。もしWindowsを使っている場合は、バイナリファ イルを扱えるエディタかそれに類するソフトウェアが必要です。IEや Lynxと異なりNetscapeはNULL文字を見つけるとその行の文字を一切出力 しません。
<?xml を直接PHPコードに埋め込むには、 PHPディレクティブの short_tags を0に設定しなければなりません。 このディレクティブは ini_set() でセットすることは できません。 short_open_tags のオン/オフに関わらず、次のようにもできます: <?php echo '<?xml'; ?> このディレクティブはデフォルトでオンです。
最も簡単なのはASPタグを使う方法です。こうすればASPの様に<%と %>をコード区切りとして使用することが出来ます。有名なHTMLエディ タは(今のところ)ASPタグを賢く扱ってくれます。ASPスタイルのタグを 有効にするには php.ini ファイルで asp_tags を設定するか、適切なApacheディレ クティブを使用します。
マニュアルの 定義済みの変数 のページを読んでください。スクリプト上で有効な定義済み変数のリストの 一部があります。有効な変数の完全なリスト(とその詳しい情報)は phpinfo() をコールすることで見ることができます。 マニュアルの PHPの外部から来る変数 のセクションも読んでください。HTMLフォームやCookie、URL等から 来る外部変数に関するシナリオが説明されています。
register_globals: 重要な注意: PHP 4.2.0 以降、PHP ディレクティブ register_globals のデフォルト値は off となっています。 また、このディレクティブは PHP 6.0.0 で完全に削除される予定です。 PHP コミュニティは、ユーザがこのディレクティブの設定に依存せず、 superglobals のような他の手段を使用することを推奨します。
14. フリーではない商用ライブラリである ClibPDF や PDFLib を使わずに PDFファイルを生成するにはどうしたらよいでしょうか? フリーのもので、外部のPDFライブラリを必要としない ものがいいのです。
PHPで書かれている代替手段がいくつかあります。 http://www.ros.co.nz/pdf/ , http://www.fpdf.org/ , http://www.gnuvox.com/pdf4php/ , http://www.potentialtech.com/ppl.php 等です。 Panda モジュールもあります。
15. ユーザ定義関数の中で、標準的な($DOCUMENT_ROOTや$HTTP_REFERER等の) CGI変数にアクセスしたいのですが、PHPはそれらの変数を見つけること ができていないようです。何がおかしいのですか?
PHPディレクティブの
register_globals
がサーバと環境変数に与える影響を認識することは重要なことです。 register_globals = off (PHP4.2.0以降デフォルトでoff)の場合、
$DOCUMENT_ROOT
は存在しません。代わりに
$_SERVER['DOCUMENT_ROOT']
を使用してください。 register_globals = on の場合は
$DOCUMENT_ROOT
も
$GLOBALS['DOCUMENT_ROOT']
も存在します。
スーパーグローバル: 使用可能なバージョンに関する注意: PHP 4.1.0 以降、
$_GET,$_POST,$_SERVER等のスーパーグローバル配列が使用可能となっています。 詳細な情報については、マニュアルの superglobals のセクションを参照してください。
16. いくつかの PHP ディレクティブでは、バイト値を integer ではなく省略形で設定できます。この省略形で使えるオプションを教えてください。 また、これは php.ini 以外でも使えるのですか ?