Trouble Shooting Record (PHP/Web 関連)


1. include/require 分で読み込んだ関数が Call to unsupported or undefined function. [解決]

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.15-i18n-ja

現象

PHP 関数を定義したファイルを include/require 分で読み込んだページを表示すると、 読み込んだ関数がそのまま表示されてしまう。この時、以下のエラーメッセージ。
Fatal error: Call to unsupported or undefined function foo() in /home/bar/public_html/test.php3 on line 22

解決方法

include/require 分で読み込む関数を <?php 〜 ?> で囲む。
そもそも include/require 分の時点で PHP モードに入っているのだから、読み込む 関数をわざわざ <?php 〜 ?> で囲う必要はないように思えるが、 こういうものらしい。
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

2. HTTP ヘッダーフィールドの終わりは空行 ("\n") !? [解決]

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.15-i18n-ja

現象

以下のソースで HTML 本体のみを取り出そうとしても、ヘッダーフィールドの終わり を示す空行を検出できない。
$fp = fsockopen("www.hoge.com", 80);
fputs($fp, "GET / HTTP/1.0\n\n");
while (!feof($fp)) {
	$line = fgets($fp, 1024);
	if ($line == "\n") {
		// 空行が来たら、ヘッダーフィールドの終わり
		break;
	}

while (!feof($fp)) {
	$line = fgets($fp, 1024);
	print $line;
}
fclose($fp);

解決方法

ヘッダーフィールドの行末は何故か (?) "\n" ではなく "\r\n" になっている。 該当行を以下のように書き換えれば OK 。
(...snip...)
	if ($line == "\r\n") {
                      ~~~~ 修正
		// 空行が来たら、ヘッダーフィールドの終わり
		break;
	}
(...snip...)
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

3. マンモス本 p.316 の日本語 TrueType フォント表示サンプルが動作しない

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.18-i18n-ja
GD 1.7.3
freetype 1.3.1

現象

マンモス本 (PHP4 徹底攻略) p.316 のサンプルを実行すると以下のエラー。 GD や FreeType のインストールに問題はない。phpinfo() でも正しく認識されている。 サンプル通りのパスに wadalab-gothic.ttf はインストールされており、X-TT での 表示にも問題はない。 また、DynaFont や Windows から持って来たフォント (*.ttc) だと問題なし。
Warning: Sorry, but this font doesn't contain any Unicode mapping table in
         /home/foo/public_html/ttf.php3 on line 9

Warning: Cannot add more header information - the header was already sent
         (header information may be added only before any output is generated from the script
         - check for text or whitespace outside PHP tags, or calls to functions that output text) in
         /home/foo/public_html/ttf.php3 on line 11

Warning: Cannot add more header information - the header was already sent
         (header information may be added only before any output is generated from the script
         - check for text or whitespace outside PHP tags, or calls to functions that output text) in
         /home/foo/public_html/ttf.php3 on line 12
臼NG ^Z ~B

解決方法

Help me!

なお、この問題には直接関係ないが、 このサンプルソースの 5 行目、imagerectangle() ではなく imagefilledrectangle() を使用しないと正しく動作しないので要注意 (ことがある...というかあのままだとたまたまうまく動作する) 。;-)
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

4. マンモス本 p.313 の PNG 画像表示サンプルが動作しない [解決]

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.18-i18n-ja
GD 1.7.3

現象

マンモス本 (PHP4 徹底攻略) p.313 のサンプルを実行しても何も表示されない。 (出力された HTML) ソース見ると文字化けした文字列が表示されている。 どうやら PNG ファイルの内容を出力しているようだが...。

解決方法

この時の php3.ini の設定は以下の通り。
; internationalization
i18n.http_output = SJIS
i18n.internal_encoding = EUC-JP
i18n.script_encoding = auto
i18n.http_input = auto
i18n.http_input_default = SJIS

あたなもピンときましたね (^^;。 そう。出力の際に SJIS 変換が行われてしまっているのが原因。
header() の前に i18n_http_output("pass"); を追加することで解決。
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

5. i18n_convert() で正しく変換されない [解決]

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.18-i18n-ja

現象

ファイル/ソケット経由で読み込んだ行 (文字列) を i18n_convert() で変換すると 文字化けしてしまう。
サンプルソースは以下の通り。
<?php
i18n_http_output("SJIS");
(...snip...)
while (!feof($fp)) {
	$line = fgets($fp, 1024);
	echo i18n_convert($line, "SJIS");
}
(...snip...)
?>

この時の php3.ini の設定は以下の通り。
; internationalization
i18n.http_output = SJIS
i18n.internal_encoding = EUC-JP
i18n.script_encoding = auto
i18n.http_input = auto
i18n.http_input_default = SJIS

解決方法

ファイル/ソケット経由で読み込んだ行 ($line) のエンコーディング (ここでは JIS) と、内部エンコーディング (ここでは EUC-JP) が異なっていたのが原因。

この場合、i18n_convert() は $line (JIS コード) を内部コード (EUC-JP コード) と見なして SJIS への変換を行うため、文字化けしてしまう。 変換対象文字列のコードが内部コードと異なる場合には、以下のように変換前のコード を明示する必要がある (auto 指定でもいいのかな? 未確認) 。
echo i18n_convert($line, "SJIS", "JIS");
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

6. NN で画像ファイルのキャッシュを無効にできない [回避]

環境

Kernel 2.2.17 (Slackware 7.0)
Apache 1.3.12
PHP 3.0.18-i18n-ja
Netscape Communicator 4.75

現象

META エレメントでキャッシュを無効にしても Netscape Communicator (Navigator) では有効とならない。逆に IE では META エレメントを指定しなくてもキャッシュ されない。
なお、ここで test.png は一定周期で内容が更新される PNG 画像ファイル。
<HTML>
<HEAD>
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
</HEAD>
<BODY>
    <IMG SRC="./test.png">
</BODY>
</HTML>

解決方法

いろいろ調べてみると (たまによく分からない動作をして ?? な部分もあるのだが (^^;)、 NN では META エレメントでの no-cache 指定、および Refresh 指定をすると キャッシュされず (?) 毎回異なる画像が表示されるようになる。
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Refresh" CONTENT="30">
<META HTTP-EQUIV="Expires" CONTENT="0">

その他、調べた結果をまとめると以下の通り。

ブラウザ META 指定なし no-cache 指定あり no-cache & Refresh 指定あり
画像の自動読込み OFF 画像の自動読込み ON 画像の自動読込み OFF 画像の自動読込み ON 画像の自動読込み OFF 画像の自動読込み ON
IE NG OK NG OK NG OK
NN NG NG NG NG (*1) NG OK

(*1)
「再読み込み」ボタンでもだめ。「画像」ボタンでもダメ。 右メニューから「画像を表示」を選択し、「再読み込み」ボタンを押すと表示されるが、 URL が画像ファイルを指すことになるのでだめだめ。

その他、気付き事項として <IMG SRC="画像ファイル名"> および <IMG SRC="画像出力 CGI ファイル名"> のどちらも NN はダメ。 IE はどちらも OK 。うーむ。SRC タグのファイル名だけを見ているのか??

苦肉の策として、NN で「再読み込み」ボタンの押下だけで画像が更新されるように するために、以下のようにダミーのクエリーコンポーネントを付けるとうまく動作する。 これはキャッシュを抑制するというより、別のファイルとしてキャッシュされている だけだと思うが、そもそもファイル名が同じなだけで内容は異なるのだから、別ファイル としてキャッシュされても特に無駄という訳ではないので、これでよしとする。
# 画像ファイル名そのものを毎回ランダムにしちゃっても可。
<?php
echo "<IMG src=\"./test.png?dummy=" . microtime() . "\">\n";
?>
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

7. PukiWiki で、新たに作成したページを編集できない [回避]

環境

Plamo Linux 2.2.1 (Kernel 2.2.20 + glibc 2.2)
Apache 1.3.27
PHP 4.3.1
PukiWiki 1.3.5

現象

PukiWiki で pukiwiki.ini.php の $defaultpage を次のように変更し、リロード。
$defaultpage = "[[なんとか ABC プロジェクト]]";

トップページの名称が変更されたのを確認した後、編集しようとすると 次のメッセージが表示されて編集できない。
なんとか ABC プロジェクト は編集できません

解決方法

いろいろ試したところ、WikiName に '&', ' ' を含むものは、正しく WikiName として認識されないらしい。
という訳で WikiName を '&', ' ' を含まないものに変更することで解決。
[ 先頭 | 末尾 | 戻る | トップページに戻る ]

8. PukiWiki が生成するリンクを相対パスにするには? [解決]

環境

Plamo Linux 2.2.1 (Kernel 2.2.20 + glibc 2.2)
Apache 1.3.27
PHP 4.3.1
PukiWiki 1.3.5

現象

デュアルホームなサーバで PukiWiki を動作させた場合 (片方のセグメントからは もう片方のセグメントにはアクセスできないという前提) 、PukiWiki が生成する リンク <A href> が絶対パス (ex. https://server.example.co.jp:443/hoge/) なため、片方のセグメントからはアクセスできなくなってしまう。

     server.example.co.jp  +----------+
   ------------------------| PukiWiki |---------------------------
                           +----------+
                      <A href="http://server.example.co.jp/hoge/">

    こちらからは   --->                  <--- こちらのセグメントからは
    アクセス OK                                IP アドレス指定で FrontPage には
                                               アクセスできるのだが、
                                               その先のリンクを辿ろうとすると
                                               server.example.co.jp には
                                               アクセスできないため行けない

両セグメントで別の DNS で名前解決をさせれば可能なことは分かっているのだが、 もっと簡単に実現できないかなぁ。生成されるリンクが相対パスになれば解決 なんだけど...。

解決方法

init.php を次のように編集することで可能 (下記例は、適宜折り返しています) 。
if($script == "") {
        $script = (getenv('SERVER_PORT')==443?'https://':('http://')).getenv('SERVER_NAME').\
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 削除
                  (getenv('SERVER_PORT')==80?'':(':'.getenv('SERVER_PORT'))).getenv('SCRIPT_NAME');
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 削除
}
[ 先頭 | 末尾 | 戻る | トップページに戻る ]