[PHP]: You don't have permission to access /php/php.exe/index.php on this server. => Windowsで、PHP4のCGIモードが動かないのは、Apacheのバージョン

2008/08/27 20:05:19
カテゴリ:Web > PHP

結論から言うと、Windows上にインストールした「Apache2.2 + PHP4.4.9」では、"CGIモード"はおろか"モジュールモード"でも動きませんでした。
で、Apacheを、「2.2」から「2.0」にバージョンダウンさせたら、"CGIモード" も "モジュールモード" も、難なく動作しました。

PHP5では「php5apache2_2.dll」があるんでモジュールモードのときは"httpd.conf"からこいつをロードしてあげればいいわけですが、PHP4.4.9には「php4apache2_2.dll」がありません。
「php4apache2_2.dll」をダウンロードできるサイトを紹介しているブログもいくつかありましたが、該当するファイルは削除されてしまったようでしたので、「Apache2.0」へのバージョンダウンで対応。

なんでこんなことで、今日一日はまってたか、と言うと・・・

普通、PHPでシステム組むときに共有サーバなんて使いませんよね。
でも今回はお客さんの都合(稟議がどうたら、とか、決済がどうたら、とか)で「どうしても現在借りてるホスティングサーバで」と押し切られ、 当然と言えば当然ですが共有サーバのPHPはCGIモードで、モード切り換えも不可。
しかもPHPは、「PHP4」とのこと。

んで、CGIモードで動くテスト環境を作ろう、として「はまった」わけです。

具体的には、

Apache 2.2.9 (apache_2.2.9-win32-x86-no_ssl-r2.msi)
PHP 4.4.9 (Windows Binaries)

で普通にXPにインストール。
で、Apacheまでは普通に動作確認して、PHPの設定をCGIモード用に、httpd.confで、

ScriptAlias /php/ "c:/php4/"
AddType application/x-httpd-php .php .html
Action application/x-httpd-php "/php/php.exe"

として、Apache再起動して、"http://localhost/index.php"にアクセスしたら、

Forbidden
    You don't have permission to 
        access /php/php.exe/index.php on this server.

になっちゃいました。

ちゃんと、「php.exe/index.php」で実行しようとしてる、ってことは"CGIモード"で動こうとはしてるってこと?
と思いながらも、「環境変数が~!」とか、「MIMEタイプが~!」とか、「ディレクトリは"/"か"¥"か~!」とか、さんざっぱら試行錯誤したあげく、 ググってるうちに前述の「php4apache2_2.dllじゃないと動かないっぽい」という情報にたどりつき、 「要するに、Windows上でApache2.2にPHP4.4.9を入れなければいいだけじゃん?」という結論に達したわけです。

あ~、めんどかった。
他にも共有サーバの落とし穴がありそうで怖いです。
頼むからうちで借りてるサーバに引越してくれ~!

[PHP]: 404で、リダイレクトPHP

2008/07/28 11:48:37
カテゴリ:Web > PHP

とあるウェブサイトのリニューアルで、次のような問題がありました。

  1. リニューアル後、リニューアルするページと、しないページがある。
  2. リニューアルしないページの中には、ディレクトリ構成だけが変わる箇所がある。
  3. ということは、各ページからのリンク付けで、「旧ページのままなのに、ディレクトリ(URL)だけ変わるところがある、ということ。

みたいな、整理するだけで面倒だなぁ、という問題です。
で、こういう時って.htaccessで、

Redirect permanent /old/ http://www.example.com/new/

とかやる訳ですが、これだと、ディレクトリ配下の全ファイルがリダイレクトされてしまいます。
今回は、リダイレクトさせたいファイルと、させたくないファイルが有るわけです。
(諸般の事情により・・・。まぁ、色々ありますよね。)
じゃあ.htaccessで、個別のファイルに指定すればいいじゃん、と言われそうですが、これがまた大量で。。。
しかも動的なページも有ったりして。

で、1時間考えた末、PHP、5行で解決しました。
どうしたか、と言うと、

  1. リンク付けは古いまま維持
  2. 古いリンク付けで飛んでくるディレクトリに、「404 Not Found」向けのページを設定し、そのページをPHPで作る。
    具体的には、
    ErrorDocument 404 /404.php
    
    みたいにする。
  3. 404.php 内で、どんな古いURLでアクセスしようとしているかを取得
  4. 新しいURLに変換。
  5. 新しいURLのHTMLファイルが存在するかチェック。
  6. 存在したら、そのページへリダイレクト。存在しなかったら、404のメッセージ(「見つかりません」、とか)を表示。

としました。
404.php内で書いたPHPの内容は、

<?
//どこのURLにアクセスしようとして404になったかを取得
$redURL = htmlspecialchars($_SERVER["REDIRECT_URL"]);

//新しいURLに変換
$path = str_replace( '/old/', '/new/', $redURL );

//該当するパスのファイルが有ったらリダイレクト
if ( file_exists( $path ) ) {
   header("Location: ".$path);
   exit;
}
?>
<html>
・・・
以下、「見つかりません」のHTML文書。
</html>

これで、
・旧リンクのまま維持するページは、そのまんま。
・ディレクトリ構成を変更しちゃったページは、404経由で、リダイレクト。
と、処理を分けることができました。

こんな、意味不明なソースは残したくないんですが、完全リニューアルまでの暫定処置として採用しました。
これで、泣いてたデザイナー兼コーダーの子の作業が、3日分は節約できたんじゃないか、と。

1時間、本気でPHPを書けば数十行~数百行は書けるんでしょうが、
1時間悩んで、PHP5行で解決して、手間を数日分省けた、ってのが、
「ああ、プログラムって、こういうことのために有るんだよな」と感慨にふけった日でした。

[PHP]: JavaScriptで「escape」された文字列をデコードする関数「unescape」

2008/07/22 15:42:47
カテゴリ:Web > PHP

と言いつつ、実はJavaScript、というよりActionScript関連です。

最近 Adobe Airの、とあるツールを作ってます。
ASは、Flashのオーサリング専門でやってる人間に任せてるんですが、
自分は彼の作ったAirアプリから、サーバーサイド(PHP)に送信されるデータの処理を担当してます。

で、そのAirアプリから送信されるデータの取り合いをXMLにしたんですが、
文字化け防止のために、エンコードして送ってくれました。
それ自体は問題ないんですが、何に変換してくれたかというと、JavaScriptにしかない「escape」関数を使ってくれました。 (やっぱりASの関数は、基本JavaScriptなんですよね。)

うぅ、PHPには「unescape」無いんだよー、「encodeURI」使って欲しかったよー、
つっても彼は本当にFlashしか知らないので、仕方がありません。
このままでどーにかならないものか、と調べてたら、ちゃんとデコーダを作ってくれた人が居ました。

「unescape(PHP)関数 Javascript版escape日本語POST対応」で紹介されてる、
PHPマニュアルの、「utf8_encode」のページの「User Contributed Notes」の中の1人 。

おぉ、すばらしい!
なんか、

文字列に"-"(ダッシュ)が含まれると、それ以降が抜けるらしい。

Lupin's Weblog: PHP: Javascriptのescapeに対応したunescape関数のバグ

というバグもあるらしいので、こちらも参照してみて下さい。

何にせよ助かりました。

使い方も簡単ですね。
記載されてるfunctionを定義して、

$str = unescape($str);

で、デコードされます。

[PHP]:PHPファイルを保存に行っちゃうのは、Firefoxのキャッシュでした

2008/07/22 11:06:16
カテゴリ:Web > PHP

ローカルで開発して、サーバにアップすると動かない、ってことは良くあります。
今回は、「.htaccess」で、

AddType application/x-httpd-php .php .html

な設定のサイトだったんですが、最初にアップした時、「.htaccess」をアップし忘れて、
HTML(実体はPHP)ファイルをブラウザがダウンロード(保存)しに行きました。
(Firefoxでは、「Firefox Document」として保存しようとします。)

んで、忘れてた「.htaccess」をアップしたんですが、一向にPHPとして処理されません。
そこで格闘1時間。
Apacheの設定変えたり、PHPのバージョンやら環境やらチェックしたり・・・

もういい加減いやになってきたころに、他のブラウザで見てみたら、普通に動いてました。
なんじゃこりゃ、ってんで、Firefoxの該当するページのキャッシュを消したら、無事解決。

ちゃんと動いてないページでも、キャッシュってされてるんですねぇ。あぁ、脱力。。。

[PHP]:Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent

2008/06/21 13:06:13
カテゴリ:Web > PHP

またもや、PHPのWarning 「header already sent by (...)」 ネタです。

今度は別の個人で受けた案件で、「超特急で、メール送信フォームをお願いします!」というのがありました。
まぁ、メールフォームくらいならすぐ出来ますよ、ってなもんで、
既存でサーバに上がってたHTMLをダウンロードしてきて、PHP化して、
ちゃちゃっと終わらせようとしたら、またもや Warningで、 「header already sent by (...)」が!

詳細はこれ。

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at hoge.php:1) in hoge.php on line 5

line 5 に書かれているのは「 session_start(); 」。

むむむ?
前回の記事のように、ファイルの頭に、余分な改行も、空白もありません。

で、今回の「超特急」でお願いされた仕事でもあり、いろいろ確認をすっとばしてたところを、
真面目に再確認。

おお!UTF-8 だ!これか?!
普段、PHPはEUCで書いてて、UTFなんかで書かないですもん。

でも、content の宣言もUTF-8で、ファイル保存形式も・・・、「UTF-8」!
これか?
日本語、使ってるぞ!?

で、「UTF-8N」に保存し直して、一件落着。

でも、なぜ「 SESSION 」についてのエラーなんでしょう?
2行目から4行目は、なんでエラーにならないんでしょう?
(行数が違うってことは、当然、改行コードも入ってるし。)

あぁ、そうか。処理の中で一番最初に日本語が出てくるのは、セッション内に
格納された、日本語文字列か orz

なるほど。焦点が間違ってましたね。
「なぜ、セッションでのエラーなのか」、じゃなかったんだ。
「スクリプトの中で、セッションが、一番最初に扱うものにエラーがある。」、だったんだ。

森博嗣が、書いてました。

人は、どう答えるかではなく、何を問うかで評価される。
臨機応答・変問自在

デバッグの基本、ですね。

[PHP]:Warning: Cannot modify header information - headers already sent by

2008/06/17 21:46:24
カテゴリ:Web > PHP

先日、会社をやめちゃったプログラマ(初心者)からある案件を引き継ぎました。
PHP + MySQL(+ JavaScript使いまくり!)。
そしたら、バグの雨あられ。

で、今日はまったのが、このエラー。

Warning: Cannot modify header information - headers already sent by (output started at hogehoge.php:7) in unyaunya.php on line 28

う~ん、header情報がすでに出力されてるって言っても、「hogehoge.php」に相当するファイルのどこでも「header("Content-Type:・・・);」みたいなことはやってる形跡がありません。

しかし、やっぱりヒントは、「header」なのでした。
「hogehoge.php」で定義されてるfunctionの前に、改行やら、タブやらが転がってました。
つまり、改行やら、タブやらが「出力」されてしまっていて、「unyaunya.php」で吐きたいheader情報が上書きできてなかったみたいです。

↓これは駄目。

<?
	
	function hoge(){
	}
?>

↓当然これはOK。

<?
function hoge(){
}
?>

普段、いきなりファイルの冒頭でインデントなんてしたことなかったので、分かりませんでした。
これも勉強!、ですかね?

[Smarty]:Linux へのインストール メモ

2008/06/17 13:55:25
カテゴリ:Web > PHP
  1. 解凍したファイルを全部アップロードするのは面倒なので、「tar.gz」版をダウンロード。
    2008年6月17日現在の最新版は、2.6.19。
    ダウンロードサイト:http://www.smarty.net/download.php
  2. ダウンロードしたファイル(Smarty-2.6.19.tar.gz)をライブラリディレクトリへアップロード。
    今回は、「/usr/local/lib/」。
  3. Telnetして、アップしたディレクトリへ移動して、解凍。
    # cd /usr/local/lib/
    # tar xvzf Smarty-2.6.19.tar.gz
    
  4. 解凍できたか確認。
    # ls
    # Smarty-2.6.19  Smarty-2.6.19.tar.gz
    
  5. インストールは以上で完了。
    あとは、Smartyを利用するPHPファイルから、
    define('SMARTY_DIR', '/usr/local/lib/Smarty-2.6.19/libs/');
    require_once(SMARTY_DIR . 'Smarty.class.php');
    $hoge = new MySmarty();
    
    でOK。

[Smarty]:Smarty のソースをDreamWeaverで

2008/06/13 19:37:04
カテゴリ:Web > PHP

とある新規のお客さんから、
「Webデザイン会社にサイトを作ってもらったけど、管理が大変で仕方がないので、テンプレート化&管理画面化して欲しい。」
とのお仕事を頂きました。

お客さんとしては、若干PHPの知識があるようなので、PHP+Smartyに決定。
だけど、普段の更新作業はDreamWeaverを使っている模様。

自分は全くと言っていい程DreamWeaverを使わない(コーディングからプログラムまで、何でもかんでもTerapadです)ので、DreamWeaver上でSmartyのソースがどうなるやら想像も付きませんでした。

で、Google先生に教えて頂いたのが、こちらのページ。
SmartyをよりスマートにDreamweaverで編集する (Nega Diary)

その発展版ソリューションがこちら↓
Smarty×Smarty (Nega Diary)

PhotoshopのJavaScriptプラグイン書く人とか、Firefoxのアドオン作る人とかもそうですが、こういう風に、アプリケーションに突入して行けるってすごく羨ましいです。