備忘録(PHP)」カテゴリーアーカイブ

PHP 別ウィンドウ(window.open)でマルチプロセスの実現

以前、PHP マルチスレッド処理(並行処理)を実行する方法という記事を書きましたが、別ウィンドウを開いてマルチプロセスを実現する方法が分かりました。

それは、ほんと単純なことでした。

セッションを使わない、開始しないだけでした。

セッションを開始すると、セッション情報が保持されるため別ウィンドウを開いたとしても、同じセッションIDを利用する。(たぶん)
その同じセッションIDというのが曲者で、同じセッションIDだと別ウィンドウを開いても同一プロセスとして扱われてしまい、片方のプロセスが終わらないともう一方のプロセスが開始されない。

気づいたときには、「なんだ、そんなことか」と思いました。

PHP mail関数を使って日本語ファイル名を添付する

PHPのmail関数を使って、日本語(マルチバイト)のファイル名を添付するしてメールを送信する方法を紹介します。

方法はいたって簡単でした。

普通に日本語ファイル名をそのまま記述すると、拡張子が外れた状態で受信してしまいます。

そこで、一つおまじないをかけます。

日本語ファイル名に対して、mb_encode_mimeheader()関数を使ってエンコードするだけです。

例:$mail_body .= “Content-Disposition: attachment; filename=\””.mb_encode_mimeheader(“ファイル名”).”.【拡張子】\”;\n”;

もしかしたら、間違っているかもしれませんが、私の環境下では正常に送信・受信できました。

PHP mail関数を使って複数のファイルを添付する

PHPのmail関数を使って、複数のファイルを添付してメールを送信する方法を紹介します。

// メールヘッダ部
$header=”From:”.【メール送信元】.”\n”.
       ”MIME-Version: 1.0\n”.
       ”Content-Type: multipart/mixed;”.
       ” boundary=\”__BOUNDARY__\”\n\n”.
       ”Mime-Version: 1.0\n”.
       ”Content-Type: text/plain; charset=ISO-2022-JP\n”.
       ”Content-Transfer-Encoding: 7bit”;

// メール本文部
$mail_body=”メール本文\n”.
“–__BOUNDARY__\n”;

// 添付ファイル部
$temp_file_body =””;

// 添付ファイル1
$file1_name=”【添付ファイルパス】”;
$file = fopen($file1_name,”r”);
$file1_contents=file_get_contents($file1_name);
fclose($file);
// 添付ファイル2
$file2_name=”【添付ファイルパス】”;
$file = fopen($file2_name,”r”);
$file2_contents=file_get_contents($file2_name);
fclose($file);
// 添付ファイル3
$file3_name=”【添付ファイルパス】”;
$file = fopen($file3_name,”r”);
$file3_contents=file_get_contents($file3_name);
fclose($file);

// 添付ファイル1の記述
$temp_file_body .=”Content-Type: application/octet-stream;name=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Disposition: attachment; filename=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Transfer-Encoding: base64\n\n”;
$temp_file_body .= chunk_split(base64_encode($file1_contents)) . “\n”;

// 区切り
$temp_file_body .= “–__BOUNDARY__\n”;

// 添付ファイル2の記述
$temp_file_body .=”Content-Type: application/octet-stream;name=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Disposition: attachment; filename=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Transfer-Encoding: base64\n\n”;
$temp_file_body .= chunk_split(base64_encode($file2_contents)) . “\n”;

// 区切り
$temp_file_body .= “–__BOUNDARY__\n”;

// 添付ファイル3の記述
$temp_file_body .=”Content-Type: application/octet-stream;name=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Disposition: attachment; filename=\”【添付ファイル1名】\”;\n”;
$temp_file_body .= “Content-Transfer-Encoding: base64\n\n”;
$temp_file_body .= chunk_split(base64_encode($file3_contents)) . “\n”;

// 結合
$send_mail_body=$header.$mail_body.$temp_file_body;

// 文字エンコードをJISに変換
$send_mail_body=mb_convert_encoding($send_mail_body,’JIS’);

// 文字エンコードをJISに変換
$subject=mb_convert_encoding(“メール件名”,’JIS’);

// メール送信
mail(【メール宛先】,$subject,$send_mail_body,$header);

PHP マルチスレッド処理(並行処理)を実行する方法

PHPで複数の処理を実行したい場合、どうしても逐次処理となってしまいます。
例えば、5秒かかる処理が10個あった場合、5×10=50秒必要です。
それを、マルチスレッド(並列処理)で行えば5秒ですみます。
その方法を紹介します。情報元はこちらです。

PHPでマルチスレッド(バックグラウンド処理)を実現する方法 – EC studio 技術ブログ

続きを読む

PHP 処理が遅くなる原因

とあるシステムである特定の処理が遅いと指摘をうけていました。
ある条件になると、処理時間が超過してしまいブラウザタイムアウトとなってしまい、処理が終了しないという状況になります。

さて、原因についてですが、まず条件というのが、処理件数が多くなってしまうということなのですが、処理件数が多いと処理に時間がかかるのはしょうがない。

処理の概要ですが、データベースから条件を指定して抽出を行い、その抽出したデータにさらにPHP側で処理を行うというものです。

ここで時間がかかっていたのは、データベース側ではなくPHP側です。
当初、データベース側で複雑な条件を指定すると時間がかかるため、PHP側の処理に変更したのですがどうもPHP側にすると遅いという状況でした。
この遅くなるという部分の処理ですが、チェック用の配列Arrayの中にデータベースから取り出した値が存在するかチェックを行ってTRUEならば、チェック用の配列に値を格納。これを繰り返すという内容なのですが、このチェック用の配列が1000件近くになると極端に遅くなるんです。

では、どうすればいいか。
方法としては、二つあります。

  • 1つは、この配列がある程度、例えば100件程度になれば別の配列に格納する。ただ、この方法だと配列の全件チェックはできないのでNG.
  • 2つ目は、配列ではなくデータベースに格納する。
    この方法だと、処理件数が少ないと遅くなるのですが、処理件数が多くなると全件チェックはSELECT文一つで完結するので、早くなる。
    データベースはMySQLなので、ストレージエンジンはHEAPを選択しようと思ったのですが、HEAPはメモリ上にデータを格納する性質上、MySQL終了時にクリアされる。
    しかし、クリアされるのはレコードのみで、テーブルは残ってしまう。
    将来的に、件数が肥大してメモリ圧迫も困るので結局MyISAMを選択しました。

さてさて、結果はまず150秒ほどかかっていた処理が30秒ほどになりました。
そして、タイムアウトになっていた処理も200秒程度で処理が完了します。

今回のことで、データが多く大きくなると格納する変数、配列も考慮しておかないといけないのだなと実感しました。
たぶん、Cを経験されている方はメモリの管理も含めて開発しているのでしょうから、今回のようなトラブルは開発時点で分かっていることなんでしょう。
まだまだ、未熟だと実感しましたOTL

PHPでファイルをダウンロードするには

PHPを使ってユーザにファイルをダウンロードしてもらいたい場合は、header関数を使ってContent-Disposition:ヘッダを送信すれば簡単に構築できます。
今回はその方法を簡単に紹介しましょう。

まずは基本的なContent-Disposition構文は次のとおりです。
Content-Disposition: attachment; filename=”<ファイル名>”
Content-Type:<ファイル形式>

Content-Disipositionフィールドを「attachment」とすることで、ユーザに表示するか保存するかを選択させることができます。よくある開くか保存するかのダイアログボックスが表示されます。

Content-typeを設定すればファイル形式を指定できます。

ファイル形式 対応するContent-Type
HTML text/html
テキスト text/plan
CSS text/css
JPEG画像 image/jpeg
GIF画像 image/gif
PNG画像 image/x-png
PDF application/pdf
tar形式圧縮ファイル application/x-tar
zip形式圧縮ファイル application/zip
CSVファイル application/x-csv
Excelファイル application/vnd.ms-excel
その他のファイル application/octet-stream

次は、簡単なプログラムを書いてみます。

続きを読む

PHP mb_send_mainでHTMLファイルを添付すると・・・・

とあるシステムで自動的にHTMLファイルを添付してメールを送信するシステムにしているのですが、メール本文中のhttp://で始まるURLやメールがリンクされていないとの指摘があっていろいろとヘッダを調べてみました。

しかし、どんなにヘッダを設定してもNG。
最悪は添付のHTMLファイルのソースがメール本文に表示されたり。

もともとのメール本文中のURLも重要度としては低いんですが。

とりあえず、OutlookExpressで単純に同じ文章をコピペして、HTMLファイルを添付して送ってみた。
すると、やはり結果はリンクが表示されていない。
HTMLファイルを添付しないと、正常にリンクされる。
と、言うことはHTMLファイルを添付するとダメなのだろうか???

もう少し調べてみます。

未解決ですいませんm(__)m 解決したら、また書きます・・orz   

分かっているのに、エラーが出て先に進めない

プログラムを構築していて、どーしてもエラーが出る箇所ってないですか?
エラーが出るのは分かっているんだけど、別に無視できるエラーだったり。
でも、PHPの仕様で絶対発生するエラー。

こんなときには、「@」を使います。
エラーが出る箇所の先頭に@をつけてあげるだけで、エラーを無視できます。

ちなみにこの「@」はエラー制御演算子と言います。
エラー制御できないのは、関数の定義、クラスの定義、条件構造などです。

エラーが発生しないのが、一番いいですけどね。

書いたスクリプトが@だらけにならないよーに注意しましょう。  

PHPでのSEO対策 その2

PHPでとある携帯サイトを構築していたときのことです。
携帯ではCookieが使える端末と使えない端末があるので、SESSIONIDを持ちまわればセッションの維持はできます。そして、SESSIONを有効にするにはphp.ini内の【session.use_trans_sid】をONにすればリンクのURLに自動的にSIDを付与してくれます。
ここまでは、先日書いたとおりです。

しかし、これではSEO的には不利です。
検索エンジンのクローラがアクセスするたびにSIDは違いますから、いつまでも違うページとして認識されてしまいます。
ここで、一つPHPスクリプトの先頭に付け加えることで対応できます。

続きを読む

PHPのSEO対策

PHPでWEBサイトを構築したときに一番頭を抱えるのがSEO対策についてです。
システムとして成立しないといけない上に、SEO的に有利なサイトを構築しないと無意味です。
特にショッピングカートシステムなんかは、集客の為にSEO対策が必須なのでかなり頭を悩まされます。

PHPでWEBサイトを構築したらURLにhttp://www.sample.com/sample.php?a=100&b=abcとなってしまうことがありますよね。
これは、SEO的には不利だと言われています。
なので、一般的にはhttp://www.sample.com/100/abc/sample.htmlのURLからrewriteしていることが多いのではないかと思います。

しかし、調べてみると事実は違っていました。

「動的URLも静的URLと同様に扱う」 – Google Matt Cutts氏

まさに、目からうろこと言った状態。
果たしてこの真意がどうなのかは知る術がないので、一概にURLをそのままにするはどうかと思いましたが、とりあえずこういうこともあるのだと頭に置いておくと気休めにはなるのではないかと思います。