こんにちはゲストさん    
腑に落ちない現象・・・

ある日突然クライアント様からの連絡がありました

内容は「午後から突然エラーが発生しシステムが使えない」と言った内容でした。

午後から急にとは・・・あり得ないと思いつつアクセスしてみると・・・

確かに「Internal Server Error 500」で停止してしまいます。

CGIではこのような現象は良く出ますが、今回はPHPですのである意味初めてです。

PHPコードを変更したりしていませんので当然原因はほぼサーバ側だとは察しがつくのですが、サポートに電話したところ当然

当社のサーバは特に変更を行っておりません、お客様のスクリプトに何らかの原因があるのでは」とのいつもの模範的な回答でした。

サーバのエラーログを診ても結局ヘッダーが出力する前に終了(Error 500)で終了してしまっているのでエラー情報が全く判りません。

何せ今回は開発用のLOCALサーバでは全く問題無く動作するためにサーバ側でしか動作テストが出来ないのが非常に手間取りました

それから様々な動作テストをした結果、次のような事が判明しました・・・

  • データを入力してアップ(POST)した段階でエラーが発生
  • POSTするデータ数(内容の有無に関わらず)がある一定数以上になるとエラーにな

恐らくPHP動作環境の何かが影響してると考え次のようなような内容をチェック(php.ini)

  • upload_max_filesize
  • memory_limit
  • post_max_size

しかし、何れも計算上到底影響するようなサイズにはならないために上記の設定では無いこと断定

でもこれ以上POSTに関係する設定は無いはずと思いながらいろいろ調べてみたら関係するような設定を発見

それは「max_input_vars」を発見・・・

※上記3つ(upload_max_filesize、memory_limit、post_max_size)は全体的なサイズを制限するものに対してmax_input_varsはPOSTする数に対して制限するものです。

でもmax_input_varsphp-5.3.9からの対応では?(今回はphp-5.2なので設定は出来ないはずでは?

でも「ものは試し」と設定してみる・・・

max_input_varsの初期値は1000ですが、一気に5000程にしおてみるとエラーは発生しなくなりました。

エラーは回避出来ましたが次のような疑問点は残りました

  • php-5.3.9以降の設定機能が何故php-5.2に影響を及ぼすのか
  • 本来であれば「Input variables exceeded 1000」などと言うエラーになるはずだが何故Internal Server Error 500と言ったエラーで止まってしまうのか?
  • 以前は無視?されていたmax_input_varsが何故突然有効になったのいか?

 

ここからは推測です・・・

そもそもmax_input_varshashdos 対策用の設定ですので、セキュリティー対策としてphp-5.2にもこの設定用のパッチを当てたのではないかと思われます。

確かに通常のスクリプトにおいてPOSTする変数の数が1000もあれば十分と考えるのは当然かと思いますが、今回のシステムはこの数値を遙かに越える情報のやり取りを行いますのでこのような結果になったものと思われます。

尚、通常のシステム(スクリプト)においてmax_input_vars=1000を越える事は無いと思いますのでデフォルトにて大丈夫かと思います。

レンタルサーバに於いてセキュリティー対策を行って頂けるのは大変助かりますが、せめてエラー情報を出して頂けると助かります。(Internal Server Error 500で止めてしまうのはいけませんネ

 一般的には一度に1000個以上のデータをアップ(POST)するシステムはシステム(スクリプト)が悪いと言う事になるのでしょうが(私も同意見です)、どうしようもないシステムもあるのですよ

メールでの問合せ
意見を書込む
HTML形式のメルマガ

HTML形式のメルマガと云うと面倒な感じがしますが、HTMLと云えども所詮中身はテキスト形式ですので、テキスト形式と抜本的に異なる訳ではありませんが・・・
これが、携帯に送ろうとすると少し勝手が違ってきます。
勿論、携帯とパソコンでは使えるタグも違っていますが、これはそれほど大きな問題ではありません。(通常理解出来ないタグは無視されますので)
所が、画像を貼り付けて送るとパソコンと携帯では全く?違います。

◇パソコンの場合
<IMG src=”画像への絶対パス/画像名”>
でパソコンは大凡OKですが、携帯の場合、この絶対パスは表示出来ません。
確かに相対パスが使えないのは判りますが、この絶対パスが使えないのは結構痛い違いです。

では携帯へはどうすれば良いの?となりますが・・・

◇携帯の場合

<IMG src=”CID:画像名”> ←添付した画像ファイルを表示と云う意味です。

文章で書くと“たったこれだけ”と思ってしまいますが、この両者には大きな違いがあります・・・
その違いとは、携帯で画像を表示する為には単にパスを表記するだけではダメで、実際にその表示する画像を添付ファイルとしてパッケージして送らなくては行けないと云う事です。

つまりパソコンだとHTML形式で記述されたテキストを送ればOKだったものが、携帯に送る場合にはHTML形式テキスト+表示画像添付を送らなくてはなりません。
HTML形式のテキストを作成する方法は沢山存在するとは思いますが、問題はこの辺りを自動変換して添付ファイル化しないと携帯ではXマークが表示されるだけです。

メールでの問合せ
意見を書込む
スパーグローバル変数

スーパーグローバル変数の挙動の設定はphp.iniの中のregister_globals で操作出来る事を書き込みましたが・・・

最近、こんな問題が・・・
当然、開発用のローカルのサーバは、register_globals  off にして開発しておりますが、うっかりWEBサーバの設定を忘れていたようで、ON になっていた
一見サーバのphp.iniの設定を変更すれば良いだけかと思ってしまうのですが。。。事はそう簡単には行かないのです。

なぜなら、サーバ内では他のプログラムも多数動作中の為、うっかりこの設定を変更すると、動かなくなるスクリプトが出る可能性があります。
ホント最悪です。 結局現在作成中のスクリプトを再デバックするしか無いようです。

サーバ設定は一度設定すると簡単には変更出来ませんので、出来限りローカルの開発環境と同一にしておきましょうね? しかし、register_globalsは最悪ですね
忘れていた私が悪いので、八つ当たりはしないでガンバです。

でもやはり$_POST[’key_name’]$key_nameは別で良いですよね?

 

メールでの問合せ
意見を書込む
文字化け・・・@

phpの場合、その挙動の殆どはphp.iniで制御可能ですが(勿論、全てのレンタルサーバがphp.iniの編集を許しているわけではありません。)

以下の記事は、php.iniの編集が可能で、文字コードがShift-JISの場合の対策の一つです。
スクリプトとデータベースの文字コードが全てShif-JISの場合でも、「@」、「」と云った文字が「?」と化けることがあります。

php.iniはうっかり書き換えると、挙動が全く変わってしまう場合がありますので、あまりやたらといじらないことをお勧めします。
また、編集する前には、以前の常態に戻せるようにバックアップを取っておくことをお勧めします。

phpを使って、POSTやGETで文字の送信を行った場合に、「@」、「」が「?」となってしまうことがあります。

対策(この対策が絶対ではありません
mbstring.http_input = auto になっている場合
     ↓
  mbstring.http_input = pass (文字エンコーディングを自動では行わない)

同じようにoutputも変更
   mbstring.http_output = auto になっている場合
     ↓
   mbstring.http_output = pass

で改善される場合があります。
尚、mbstring.http_input = auto の場合は、mbstring.detect_order なども絡んで来ますのでここでは省きます。

PHPにしてもMySqlにしても、このようなマルチバイト環境は文字化けの元ですので、出来るだけスクリプト側で処理を行い、PHP側では何もやらない方が、問題が少ないように思います。
少なくても、悪さはすれど恩恵を感じたことは無いです

メールでの問合せ
意見を書込む
文字化け・・・A

度々遭遇するもいつも躓いてしまうため、メモっておきます。

例えばプログラム(スクリプト)が、SJISでコーディングを行っていて、データベースの文字コードがUTF-8の場合、当然書き込み時に文字コードの変換を行って書き込むが、ここで、「@」、「」と云った特殊な文字が文字化けする。

当然、書き込み時のエンコードは mb_convert_encoding($data,"UTF-8", "sjis") のように変換して書き込むが、前記の特殊な文字は文字化けを起こして「」と云った具合になってしまう。

サーバ環境にも影響を受けますが、こんな時は変換部分を mb_convert_encoding($data,"UTF-8", "sjis-win") としてみると改善される。

このようなWinの特有の文字には度々悩まされますが、ユーザがWinを使っている以上仕方ないですね 

当然SJISに戻す場合(読み込んで表示する場合)は、mb_convert_encoding($data,"sjis-win", "UTF-8") としないとイケマセン。 

メールでの問合せ
意見を書込む
PHPのバグ?(変数名による混同)

PHPでコーディングしていてたまーに引っかかる部分なので、メモっておきます。
PHPなどではデータの受け渡しなどでPOSTGETのメソッドは多用するのであるが、このデータの受け取りにはスーパーグローバル変数の$_POST[’key_name’]($_GET[’key_name’])で受け取る場合が多いと思うが、ここに大きな落とし穴があります
$_POST[’key_name’]($_GET[’key_name’])は文字通りスパーグローバル変数であるが、うっかりこの’key_name’と同じ名前のローカル変数($key_name)を使ったりすると$key_nameの内容が不安定になります。
基本的に、プログラム上$_POST[’key_name’]$key_nameは別の変数と捉えられると考えるが、PHPでは明確に区別が付かずに混同して解釈されてしまうことが多々発生します。
この事は$_SESSION['key_name’]などでも同じような現象が発生します。

以前からこのような現象は起きていましたが、今回少し調べて見ました

その結果、次のような事が判明・・・
この、スパーグローバル変数の取り扱いは、php.iniの中のregister_globals の設定で変わる事が判明。これはPHP 4.2.0以降にデフォルトがOffに設定されているようで、この設定をOnにすると、$_POST[’key_name’]$key_nameとして扱うことが可能になるようである。
わざわざデフォルトをOffにしたのはやはりセキュリティ的な問題からのようで、個人的にはOffのままがお勧めかと思いますし、やはりスーパーグローバル変数とローカル変数は明示的(意識してプログラムする)に動作して欲しいのでOffの方がプログラム上良いような気がします。

セキュリティに関する参考記事・・・
http://itpro.nikkeibp.co.jp/article/NEWS/20051102/223939/?ST=security

メールでの問合せ
意見を書込む
■ 1〜6件 全7件中