Just spent a couple days on this one...
As previously posted, if you set
upload_max_filesize = 0.25M, the value reads correctly in phpinfo(), BUT it is effectively ZERO when implemented.
Note that the following also give ZERO bytes:
upload_max_filesize = 10M (note the two white spaces before 10M), but the phpinfo() reads '10M' and everything looks ok.
I removed all white spaces in my php.ini file and viola...working fine again.
第 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 以外でも使えるのですか ?
Here's a simple function that will convert the shorthand values described in point 64.16 to a number of bytes.
I use this to display the maximum size of file uploads to the user, so they don't waste time uploading a huge file only to find that it's too big. (I've been unable to find any browsers that actually support the MAX_FILE_SIZE technique described in chapter 38, and it's certainly not part of any W3C spec, so this is the next best thing.)
Here's how you'd use my function for that purpose (though you might want to abstract this to a function of its own):
<?php
echo 'Maximum file size: ' . convertBytes( ini_get( 'upload_max_filesize' ) ) / 1048576 . 'MB';
?>
And here's the function:
<?php
/**
* Convert a shorthand byte value from a PHP configuration directive to an integer value
* @param string $value
* @return int
*/
function convertBytes( $value ) {
if ( is_numeric( $value ) ) {
return $value;
} else {
$value_length = strlen( $value );
$qty = substr( $value, 0, $value_length - 1 );
$unit = strtolower( substr( $value, $value_length - 1 ) );
switch ( $unit ) {
case 'k':
$qty *= 1024;
break;
case 'm':
$qty *= 1048576;
break;
case 'g':
$qty *= 1073741824;
break;
}
return $qty;
}
}
?>
64.16 Byte Values
The number that precedes K, M, or G should be an integer.
E.g. this php.ini directive:
post_max_size = 0.25M
is interpreted as 0, and thus prevents all POSTs.
It is particularly unhelpful that phpinfo() reports the string value assigned to post_max_size (0.25M), and not the numerical value that PHP extracts from that string (0M).
In reference to faq.using:
6. I get the message 'Warning: Cannot send session cookie - headers already sent...' or 'Cannot add header information - headers already sent...'.
This can be caused by starting a session and then calling a class function in a php file that has any whitespace either before the very first or after the very last php tags <?php and ?>.
Make sure there is NO whitespace before the initial tag and after the closing tag.
