Home > PHP

PHP Archive

PHPのmail()関数で日本語メールを送信するとSubjectの20文字目から文字化けする

  • 2010-01-12 (火)
  • PHP
  • 作成者:hitotsu
PHPのmail()関数に渡すSubjectに漢字をMIMEエンコードしたものを渡すと、長いタイトルの時に20文字目から文字化けすることに気が付いた。
ターゲットはPHP 5.2.1。
問題のメールのSubject(タイトル)を生成する部分
$subject = mb_encode_mimeheader(mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8"),"ISO-2022-JP","B","\r\n");

これだと

「開発者ブログる。投稿者さんからメールテストです」

が20文字目から文字化けして以下のようになる。

「開発者ブログる。投稿者さんからメールテ9%H$G$9」

PHPスクリプトファイルはUTF-8。
mail()関数のバグの可能性もあると思ったが、
そろそろ枯れているはず(と思いたい)なので、調べてみた。
結論を書くと、mail()関数のせいではない。
mail()関数に渡すMIMEエンコードしたSubjectに問題があった。
つまりmb_encode_mimeheader()が原因である。
対処方法は以下のとおり。

次のようにmb_encode_mimeheader()を使う前に、internal_encodingを変更すると
正しくマルチバイト文字をエンコードできるようになった。
$org = mb_internal_encoding();	// 元のエンコーディングを保存
mb_internal_encoding("ISO-2022-JP");// 変換したい文字列のエンコーディングをセット
$subject = mb_encode_mimeheader(mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8"),"ISO-2022-JP","B","\r\n");
mb_internal_encoding($org);// エンコーディングを戻す
問題なくタイトルや長い文字列でもエンコードできるようになった。
以下のブログが参考になった。
どうもありがとう。
PHPのmb_encode_mimeheaderは事前にmb_internal_encodingが必要
[編集履歴]
  • 2010-02-18 修正後のソース中、mb_convert_encoding中のsubjectに$が付いていなかったので付加

hetemlでupload_max_filesizeを変更

  • 2009-06-18 (木)
  • PHP
  • 作成者:hitotsu
仕事でWebページ(ホームページ)の構築のお手伝いをしている。

私はプログラムが関係するところを担当している。

Webページから、自社商品の写真(でっかい写真もある)を登録すると、適切なサイズに縮小して、自動的に新商品ページや、該当カテゴリーページ、特記事項のページなどに掲載される。
商品を登録したら、あとは、システムが画面を作ってくれるので、手間がかからずラクチン。
自分の作ったプログラムが役に立つと思うと何か嬉しいものだ。
ページデザインもシンプルで、わかりやすく、使い勝手もよく、これは使える。(デザインは別の人の仕事だ)

さて、システム開発は社内のLinuxマシンで行ない、ひととおり動くようになってから、外部のレンタルサーバーで動作確認している。
多くの場合、うまくいくのが、そうでない場合もたまにある。そういう時は、思いがけないことだったりするわけだが。(今回の話ではないが、思えば、GD,socket,XMLを使いたいのにライブラリが入ってなかったり、.htaccessが置けなかったり・・・と様々なことがあった。)

さて、話を戻して

今回、レンタルサーバーでの動作確認は自社で契約しているレンタルサーバー ヘテムル(heteml)で行なった。

動作テストをしてみると、大きなファイルサイズがアップロードできない。

小さいサイズは問題ない。他に大きな問題はなさそうだ。

結論を言うと、upload_max_filesizeの値が”5M”と小さかったため、大きなファイルの転送ができなかった。

システムの既定値はこんな感じ。

upload_max_filesize:5M
post_max_size:8M


デジカメで撮影した高画質版の場合には5Mを越えることもあるが、まあ、10Mもあれば十分だろうから、10Mにする。

まずは、php.iniの設定値を変更するため、ファイル「.htaccess」に次の記述を入れ、スクリプトのディレクトリに入れてみた。

php_value upload_max_filesize 10M
php_value post_max_size 16M

スクリプトを起動すると、

500 error
Internal Server Error


エラーページが表示され、プログラムは正常に動作しない。
ページの案内文に「ご利用中のユーザー様は 【 よくある質問 】 をご参照ください。」とあったので、参照してみた。

ふむふむ、きちんと説明がありました。

ヘテムル(heteml)では、.htaccessにphp_flag, php_valueで始まる設定はできない

php.iniの設定をしたい場合は、コントロールパネルから行うようだ。

コントロールパネルにログインしてみてみると、
upload_max_filesize
が5Mから5M刻みで50Mまで設定できる。折角なので^^;、50Mにしてみよう。



さて、PHP4 / PHP5とも最大値の50Mになっているか、設定値を(ini_getで)確認してみた。

upload_max_filesize:50M
post_max_size:50M


ばっちし、きちんと変更が反映されている。

これで、ファイルサイズの問題は解決しそうだ。

他の設定値を確認してみると、アップロードの実行時間(max_input_time)がデフォルトで60秒になっていた。
この値はコントロールパネルには項目がないし、もちろんini_set()でも設定変更ができない。

ADSL回線からアップロードする時は回線状況によっては低速やから、アップロード時間がかかることがある。
時間切れでアップロードできないことがあるかもしれない。
それだけ気になるが、まあよいでしょう。60秒でいったい何Mアップできるんやろ。

今回、調べていて設定値の大きさに関する次の式を見つけた。

memory_limit > post_max_size > upload_max_filesize

もともとの情報がファイルで情報伝送にあたってカプセル化され、カプセルの分だけ情報量が増えるので、その通りだと思う。

ちなみにヘテムル(heteml)の管理画面でいったんupload_max_filesizeを設定して元の値5Mにしてもpost_max_sizeupload_max_filesizeと同じ値(5M)になる。

設定変更前はpost_max_sizeは8Mだったので、なんか少しまずいような気がする・・・

落ち着いたらレンタルサーバーのサポートに確認してみようと思う。

「そういう仕様です」 と言われたら、
「ハイ、そうですね」 としかいいようはないが・・・

ちなみに、スクリプトの実行時間(秒数)はphpスクリプトから

ini_set( ‘max_execution_time’, 60 );

で変更できる。デフォルトは30秒だった。

  • Comments (Close): 0
  • Trackbacks (Close): 0

ホーム > PHP

メタ情報

Return to page top