php[world] in Washington, D.C.

PHP の使いかた

このセクションにはPHPスクリプトを書くにあたってよく問題となる事柄が 集められています。

  1. PHP の関数のパラメータの順番を覚えられません。だって関数によってばらばらなんだもん。
  2. あらゆるフォームから送信されたデータを扱うことができる汎用的な PHPスクリプトを書きたいのですが、POSTメソッドでどのようなデータ が送信されたかを知るにはどうするのですか?
  3. シングルクオート(')をバックスラッシュでエスケープされた シングルクオート(\')に変換しなければならないのですが、 正規表現を用いてこれを行うにはどの様にするのですか? 同様に " を \" に、\ を \\ に変換したいのです。
  4. " は \" に、また ' は \' に全て変換されているのですが、 これら無用なバックスラッシュを除去するにはどうしたらよいですか? どうやって、そしてなぜ、こんなことになっているのでしょう?
  5. PHP の設定項目 register_globals はどんな影響があるの?
  6. 次のようなコードを実行すると、思った通りの順番で出力が表示されません。 function myfunc($argument) { echo $argument + 10; } $variable = 10; echo "myfunc($variable) = " . myfunc($variable); なぜですか?
  7. 改行されないのですが? <pre> <?php echo "これは1行目"; ?> <?php echo "この行は改行に続いて出力されるはず"; ?> </pre>
  8. 'Warning: Cannot send session cookie - headers already sent...'や 'Cannot add header information - headers already set...'といった メッセージが出力されるのですが。 sent...'.
  9. リクエストヘッダに直接アクセスしたいのですが、どうすればよいですか?
  10. IISで認証を行おうとすると'No Input file specified'というエラーが 発生します。
  11. Windows: 他のコンピュータと共有しているファイルに、IIS でアクセスできません。
  12. どうすればXMLとPHPは共存することが出来るのですか?XMLの <?xml>タグがPHPでエラーになります。
  13. あらかじめ設定されている変数を全て網羅したリストはどこにあるので すか?なぜPHPのドキュメントにはその一覧がないのですか?
  14. フリーではない商用ライブラリである PDFLibを使わずに PDFファイルを生成するにはどうしたらよいでしょうか? フリーのもので、外部のPDFライブラリを必要としない ものがいいのです。
  15. ユーザー定義関数の中で、標準的な ($DOCUMENT_ROOT や $HTTP_REFERER のような) CGI変数にアクセスしたいのですが、PHPはそれらの変数を見つけること ができていないようです。何がおかしいのですか?
  16. いくつかの PHP ディレクティブでは、バイト値を integer ではなく省略形で設定できます。この省略形で使えるオプションを教えてください。 また、これは php.ini 以外でも使えるのですか ?
  17. Windows で、 "127.0.0.1" だと動作するのに localhost を使うと接続がタイムアウトします。
PHP の関数のパラメータの順番を覚えられません。だって関数によってばらばらなんだもん。

PHP は、さまざまな外部ライブラリの間を取り持つ糊のような存在です。 そのため、時にはちょっとごちゃごちゃすることもあります。 しかし、経験上、以下のような規則があるようです。

配列関数 のパラメータは "needle, haystack" の順だけれども、 文字列関数 はその逆で "haystack, needle" の順となります。

あらゆるフォームから送信されたデータを扱うことができる汎用的な PHPスクリプトを書きたいのですが、POSTメソッドでどのようなデータ が送信されたかを知るにはどうするのですか?

PHPは$_POSTのような 定義済みの変数 を沢山提供しています。$_POSTを連想配列として ループすることでPOSTされた全ての値にアクセスできます。例えば、 foreach で単純にループして empty() で値をチェックし、 結果を出力します。

<?php
$empty 
$post = array();
foreach (
$_POST as $varname => $varvalue) {
    if (empty(
$varvalue)) {
        
$empty[$varname] = $varvalue;
    } else {
        
$post[$varname] = $varvalue;
    }
}

print 
"<pre>";
if (empty(
$empty)) {
    print 
"None of the POSTed values are empty, posted:\n";
    
var_dump($post);
} else {
    print 
"We have " count($empty) . " empty values\n";
    print 
"Posted:\n"var_dump($post);
    print 
"Empty:\n";  var_dump($empty);
    exit;
}
?>

注意: スーパーグローバル: 使用可能なバージョンに関する注意

PHP 4.1.0 以降、 $_GET, $_POST, $_SERVER 等のスーパーグローバル配列が使用可能となっています。 詳細な情報については、マニュアルの superglobals のセクションを参照してください。

シングルクオート(')をバックスラッシュでエスケープされた シングルクオート(\')に変換しなければならないのですが、 正規表現を用いてこれを行うにはどの様にするのですか? 同様に " を \" に、\ を \\ に変換したいのです。

もしデータベースに格納するためにそんなことをしようとしているのなら、 データベース自身が持つエスケープの仕組みを使うようにしましょう。 MySQL なら mysql_real_escape_string()、 PostgreSQL なら pg_escape_string() などです。 汎用的な関数 addslashes()stripslashes() もありますが、 これはさらに古い時代の PHP コードで使われていたものです。

注意: ディレクティブに関する注意: magic_quotes_gpc

PHP ディレクティブmagic_quotes_gpc のデフォルトは on です。この場合、すべての GET, POST, COOKIE データに ついて addslashes() が実行されます。 これらを取り除くため stripslashes() を使用することが できます。

" は \" に、また ' は \' に全て変換されているのですが、 これら無用なバックスラッシュを除去するにはどうしたらよいですか? どうやって、そしてなぜ、こんなことになっているのでしょう?

なぜかバックスラッシュがついてしまう、という現象の原因のほとんどは、PHP の magic_quotes_gpc ディレクティブが On になっていることです。これは古い時代の PHP の機能であり、現在は無効にしておくべきものです。この仕組みに頼ってはいけません。 文字列からバックスラッシュを取り除くために、PHP の stripslashes() を使うことができます。

注意: ディレクティブに関する注意: magic_quotes_gpc

PHP ディレクティブmagic_quotes_gpc のデフォルトは on です。この場合、すべての GET, POST, COOKIE データに ついて addslashes() が実行されます。 これらを取り除くため stripslashes() を使用することが できます。

PHP の設定項目 register_globals はどんな影響があるの?
警告

この機能は PHP 5.3.0 で 非推奨となり、 PHP 5.4.0 で削除されました。

まずはじめに、この ini 設定がどういうはたらきをするのかを説明します。 例として、次のような URL を使用します。 http://example.com/foo.php?animal=cat そして foo.php の中身は次のようなコードが書かれているものとします。

<?php
// ここでは $_GET を使うことを推奨します
echo $_GET['animal'];

// $animal を使用するには register_globals が on でなければなりませんが
// こんなことはしないでください
echo $animal;

// これはすべての変数について当てはまります。たとえば $_SERVER についても同じで、
echo $_SERVER['PHP_SELF'];

// $PHP_SELF を使用するには register_globals が on でなければなりません
// 改めて言いますが、こんなことはしないでください
echo $PHP_SELF;
?>

上のコードでおわかりのように、register_globals を使用すると数多くの変数が作成されます。 長年にわたってこの手のコーディングは問題視されており、 ここ数年 register_globals のデフォルト設定は無効になっています。 大半のウェブサーバーは register_globals を無効にしていますが、 いまだに register_globals が on であることを前提とした記事や書籍が存在します。 注意しましょう。

詳しい情報は、以下のリソースを参照ください。

注意:

上の例では、クエリ文字列を含む URL を使用しています。 このように情報を渡す場合には GET HTTP リクエストを使用するので、 この場合はスーパーグローバル $_GET を使用します。

次のようなコードを実行すると、思った通りの順番で出力が表示されません。
function myfunc($argument)
{
    echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
なぜですか?

式の中で関数の実行結果を使用する(例えば上の例の様に他の文字列と 連結する)ためには、echo するのではなく、その 値を return しなければいけません。

改行されないのですが?
<pre>
<?php echo "これは1行目"?>
<?php 
echo "この行は改行に続いて出力されるはず"?>
</pre>

PHPでは、"?>"か"?>\n"(\nは改行を表します)をPHPのコードブロッ クの終端と見なします。このため、コードブロック終端の改行記号は省 略され、表示される文は1行になります。つまり、改行をさせるために は、PHPのコードブロックの終端の後にもう1つ改行を挿入する必要があ るということです。

なぜPHPはこのようなことをするのでしょうか?なぜならHTMLを出力する 場合にはこの方が都合のよいことが多いからです。もしとても長い1行を 出力しなければならない場合に、改行が解釈されてしまうとしたらどう でしょう。ソースコードの1行もとても読めないくらい長いものになって しまいます。

'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();
foreach ($headers as $name => $content) {
    echo "headers[$name] = $content<br />\n";
}

apache_lookup_uri(), apache_response_headers(), fsockopen()も参照してください。

IISで認証を行おうとすると'No Input file specified'というエラーが 発生します。

これはIISのセキュリティモデルの欠点で、IISで動作するCGIに共通する 問題です。これを回避策するには、認証のかかったディレクトリに(PHP が解釈しない)HTMLファイルを作成します。そしてMETAタグを使ってPHP を使用したページにリダイレクトするか、リンクを張ります。こうすれ ばPHPは認証済みかどうかを正しく認識することが出来ます。ISAPIモジュー ルの場合はこの問題は起きません。また、これは他のNTウェブサーバーに は影響ありません。詳しくは» http://support.microsoft.com/kb/q160422/HTTP 認証を 参照してください。

Windows: 他のコンピュータと共有しているファイルに、IIS でアクセスできません。

Go to Internet Information Services を変更する必要があります。PHP ファイルを選択して プロパティを開き、セキュリティ タブに移動し、 Edit -< Anonymous access and authentication control

この問題を解決するには Anonymous Access のチェックをはずして Integrated Window Authentication をチェックしたままにしておきか、 あるいは Anonymous Access をチェックしてアクセスできないユーザーを別途指定します。

どうすればXMLとPHPは共存することが出来るのですか?XMLの <?xml>タグがPHPでエラーになります。

<?xml を直接PHPコードに埋め込むには、 PHPディレクティブのshort_tags0 に設定しなければなりません。 このディレクティブはini_set()でセットすることは できません。short_open_tags のオン/オフに関わらず、次のようにもできます: <?php echo '<?xml'; ?> このディレクティブはデフォルトでオンです。

あらかじめ設定されている変数を全て網羅したリストはどこにあるので すか?なぜPHPのドキュメントにはその一覧がないのですか?

マニュアルの 定義済みの変数 のページを読んでください。スクリプト上で有効な定義済み変数のリストの 一部があります。有効な変数の完全なリスト(とその詳しい情報)は phpinfo()をコールすることで見ることができます。 マニュアルの PHPの外部から来る変数 のセクションも読んでください。HTMLフォームやCookie、URL等から 来る外部変数に関するシナリオが説明されています。

注意: register_globals: 重要な注意

PHP 4.2.0 以降、PHP ディレクティブ register_globals のデフォルト値は off となっています。 PHP コミュニティは、ユーザーがこのディレクティブの設定に依存せず、 superglobals のような他の手段を使用することを推奨します。

フリーではない商用ライブラリである PDFLibを使わずに PDFファイルを生成するにはどうしたらよいでしょうか? フリーのもので、外部のPDFライブラリを必要としない ものがいいのです。

PHPで書かれている代替手段がいくつかあります。 » FPDF» TCPDF などです。

また、Haru 拡張モジュールもあります。 これは、フリーな外部ライブラリ libHaru を使用しています。

ユーザー定義関数の中で、標準的な ($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 のセクションを参照してください。

いくつかの PHP ディレクティブでは、バイト値を integer ではなく省略形で設定できます。この省略形で使えるオプションを教えてください。 また、これは php.ini 以外でも使えるのですか ?

有効なオプションは K(キロバイト)、M(メガバイト)および G(ギガバイト: PHP 5.1.0 以降で有効)です。大文字小文字は区別しません。これ以外の文字は バイト値と判断されます。 1M は、1 メガバイトあるいは 1048576 バイトと等しくなります。1K は、1 キロバイトあるいは 1024 バイトです。この表記法を php.ini 以外では使用 しないでください。かわりに integer のバイト値を設定します。 これらの値を数値に変換する例は ini_get() のドキュメントを 参照ください。

注意: キロバイト? キビバイト?

PHP の記法では 1 キロバイト = 1024 バイトとしていますが、 IEC の標準規格では 1024 バイトのことを 1 キビバイト (kibibyte) と呼ぶことになっています。 まとめ: PHP での k および K = 1024 バイト。

Windows で、 "127.0.0.1" だと動作するのに localhost を使うと接続がタイムアウトします。

PHP 5.3.4 を使っている場合、その原因は PHP のネットワーク解決に関するコードのバグです。 IPv6 が有効になっている環境では、ストリーム関連のすべての場面で localhost への接続に失敗していました。 回避策は、 "127.0.0.1" を使うようにするか IPv6 の名前解決を hosts ファイルで無効にするかのいずれかです。

add a note add a note

User Contributed Notes 3 notes

up
2
greenie2600 at yahoo dot com
6 years ago
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;
    }
}
?>
up
2
kjn
7 years ago
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).
up
0
info at zankmusic dot com
5 years ago
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.
To Top