2008.03.24 Mon

Zend Frameworkをインストール PHP

Zend Frameworkを使ってみようということで、インストールしたときに参考にしたサイトの覚書

2008.03.19 Wed

日付の整合性チェック checkdate PHP

指定した日付が存在するのか、書式はあっているのかなど、日付のチェックを行ってくれる関数。

 checkdate

参考サイト

2008.03.03 Mon

PHPを使ってHTMLのコメントを削除

HTMLをコーディングする際に<!--〜-->でコメントを入れながら作ることが多いです。

ただ、ソースを見ているときには見やすくていいのですが、ウェブで公開するときに表示させたくない場合があります。

HTMLのコメントを一括で削除する方法の覚書。

$data = preg_replace('/<!--[\s\S]*?-->/','',$data));

$data にHTMLのソースを格納しておき、preg_replaceでコメントの部分をマッチングさせて削除しています。

PHPで独自テンプレートを使っている場合などは有効ではないでしょうか?

参考サイト

2008.03.03 Mon

PHP共通関数(クラス)を公開・紹介しているサイト

公開・紹介しているクラス

クラスについて説明しているサイト

2008.02.28 Thu

PHP 月末の日付を取得する方法

PHPを使っていると日付の処理で月末を求めることがあります。
月末の取得方法の覚書。

前提として$year $month には今年と今月を設定

今月末

$day = date("d", mktime(0, 0, 0, $month + 1, 0, $year));

先月末

$day = date("d", mktime(0, 0, 0, $month , 0, $year));

来月末

$day = date("d", mktime(0, 0, 0, $month - 1 , 0, $year));

2008.02.28 Thu

PHPでタイムアウトの設定

負荷の高い処理を制限するために、PHPでタイムアウトの設定(php.ini)を行ったときの覚書。

# vi /etc/php.ini
max_execution_time = 30
max_input_time = 60
※デフォルト値


max_execution_time

スクリプトが強制終了されるまでの最大時間を秒単位で指定します。
無限ループなど、時間のかかるスクリプトを制限し、負荷を上げること防止することができます。

max_input_time

スクリプトがデータを送信する場合の最大時間を秒単位で指定します。
ファイルのアップロード、GET、POSTなどを行った場合に、時間のかかる処理を行った場合に有効です。



あえて重たい処理をさせる場合は、このタイムアウト時間の設定を長くしましょう。
また、負荷を考慮する場合は、タイムアウトの時間を短くしましょう。

2008.02.20 Wed

ZendOptimizer 3.3 インストール

ZendOptimizer 3.3 インストール

Zend Optimizerとは、無償で使えるPHPアプリケーションの実行速度を高速化させるソフトウェアです。

※ダウンロードするにはユーザー登録が必要になります。(無料)

ZendOptimizer 3.3 インストール

# tar zvfx ZendOptimizer-3.3.0a-linux-glibc21-i386.tar.gz
# cd ZendOptimizer-3.3.0a-linux-glibc21-i386
# ./install
後はOKを押し続ける

設定ファイルの確認

# vi /etc/php.ini

以下の記述がphp.iniに追加されていることを確認

[Zend]
zend_extension_manager.optimizer=/usr/local/Zend/lib/Optimizer-3.3.0
zend_extension_manager.optimizer_ts=/usr/local/Zend/lib/Optimizer_TS-3.3.0
zend_optimizer.version=3.3.0a
zend_extension=/usr/local/Zend/lib/ZendExtensionManager.so
zend_extension_ts=/usr/local/Zend/lib/ZendExtensionManager_TS.so

2008.02.14 Thu

QRコードをPHPで簡単に作成する方法

QRコードをPHPで簡単に作成する方法

QRコードをPHPで簡単に作成する方法を探していたところクラス化されたPHPのプログラムを見つけたので紹介

このクラスを使えば、以下のサイトのような感じで使うことができます。

2008.02.12 Tue

PHP.iniの2種類のテンプレートの違い

php.ini のテンプレートファイルは2種類用意されており、

php.ini-dist(開発用)
php.ini-recommended(運用用)

の設定になっています。

詳細は参考サイトを確認してみてください。

参考サイト

2008.02.05 Tue

PHP でグラフを作成するには

最近では様々な情報をグラフ化して視覚的にみれるようになっています。PHPでグラフを作成しているサイトも多く、どうやって作成しているのだろうということでサイトを調べてみました。

配布サイト

参考サイト

2008.01.25 Fri

PHPでエラーログが表示されない・記録されないときの対応

PHPのエラーをブラウザに表示、ログファイルに記録するための設定

エラーをブラウザに表示

# vi /etc/php.ini (※環境によって異なる)

error_reporting = E_ALL & ~E_NOTICE
display_errors = On

apacheを再起動する

# service httpd restart

これでエラーが発生した場合はブラウザ上に表示されるようになります。
運用時にエラーを表示するのはセキュリティーの面でも好ましくないので、display_errors を Off にして運用することをオススメします。

エラーをログに記録する

ブラウザにエラーを表示させずに運用を行うとどこでどんなエラーが発生しているのか確認できないため、ログファイルに記録するようにします。

# vi /etc/php.ini (※環境によって異なる)

display_errors = Off
log_errors = On
error_log = /usr/local/apache2/logs/php_erro.log

apacheを再起動する

# service httpd restart

これでブラウザにエラーを表示させず、指定したファイルにログが残るようになります。

参考サイト

2008.01.24 Thu

エックスサーバーでPHPにて文字化けせずにメール送信する設定

PHPよりメール送信処理を行ったときに文字化けが発生することがあります。
実際に文字化けが発生してしまったエックスサーバーでの対応方法の記録

環境

  • エックスサーバー
  • PHP文字コードSJIS
  • 他のサーバーでは正常に動くがエックスサーバーだと文字化けしてしまう場合

PHP 設定の変更

php.ini というファイルを作成し、

HTTP input encoding translation = on
mbstring.detect_order = auto
mbstring.encoding_translation = on
mbstring.http_input = auto
mbstring.http_output = SJIS
mbstring.internal_encoding = SJIS
mbstring.language = Japanese

を記述して設定を反映させたいディレクトリにアップロードします。

php.iniの設定が有効になっていれば文字化けすることなくSJISでメール送信できるようになりました。

参考サイト

2008.01.17 Thu

メール関数の使えないサーバーでメール送信 php

レンタルサーバーなので、サイトを作成していると、サーバーの設定でメールが使えなくなっていることがあります。それでもメールは必要になることがあると思います。

そんなときに使うと便利な外部サーバー経由SOCKETタイプのメール送信 PHP ※文字コード Shift-jis

<?php
function Send_Mail_Socket($subject, $body, $from, $to) {
//各種設定
$body = mb_convert_encoding($body, 'ISO-2022-JP', 'SJIS');
$body = str_replace("\\n", "\n", $body);
$body = str_replace("&", "&", $body);
$subject = 'Subject: =?ISO-2022-JP?B?' . base64_encode(mb_convert_encoding($subject, 'ISO-2022-JP', 'SJIS')) . '?=';
$server = "example.com"; //外部SMTPサーバー指定

$sock = fsockopen($server,25);
fputs($sock,"HELO $server\r\n");
fputs($sock,"MAIL FROM:<$from>\r\n");
fputs($sock,"RCPT TO:<$to>\r\n");
fputs($sock,"DATA\r\n");
fputs($sock,"$subject\r\n");
fputs($sock,"$body\r\n");
fputs($sock,"\r\n.\r\n");
fclose($sock);
}
?>

上記関数を

<?php
Send_Mail_Socket('タイトル', '内容', 'info@from.com', 'test@to.com');
?>

のような感じで使うと外部サーバーを使用してメール送信することができます。

参考サイト

2007.12.12 Wed

PHP safe_mode セーフモードの設定

PHP のセーフモードは、共有サーバでのセキュリティの問題を解決するための設定です。ということで、一体どういう状態になるのか?何が制限されるのかを調べてみました。

PHP をsafe_mode セーフモードに変更

# vi /etc/php.ini

safe_mode = Off

safe_mode = On

# /etc/rc.d/init.d/httpd restart

セーフモードの詳細

共有サーバーでメール関数も制限したい場合

# vi /etc/php.ini

disable_functions =

disable_functions = mail

# /etc/rc.d/init.d/httpd restart

とすることで mail() 関数の使用を禁止することができます。

safe_modeの動作確認

#vi info.php

<?php phpinfo(); ?>

上記で作成したinfo.phpにアクセスすし、safe_modeの項目がOnになっていれば正常にsafe_modeで動作しています。

2007.11.29 Thu

Cookieが使えない場合のSessionの使用方法

Sessionの使えないブラウザでアクセスしてくる端末に対して、Sessionを使用するには session.use_trans_sid を有効にしてあげましょう。

URLに自動的に

index.php?ssid=xxxxxxxxxxxxxxxxxxxxx

といったSessionIDをつけてくれます。

# vi /etc/php.ini
session.use_trans_sid = 0

session.use_trans_sid = 1

さてここまではごくごく一般的なSessionの持ち回りの話ですが、本日大きなカン違いに気づかされました。

今まで全てのアドレス、フォームに自動でSessionIDをつけてくれるものだと思っていたのですが、

session.use_trans_sid が有効な場合、相対URIは自動的にセッションIDを含むように変換されます。

という仕様をしりませんでした。

よく考えてみればそりゃそうですよね、外部リンクにもセッションをつけてしまうことになるので、それはそれで大問題です。

つまり絶対パスで記述しているアドレスにはSessionIDがつきません。
このおかげで全てのパスをチェックするはめになりました・・・

参考サイト

2007.11.28 Wed

mysql_fetch_array VS mysql_fetch_assoc

mysql_fetch_array と mysql_fetch_assoc 添え字がつくかつかないかでどの程度速度に違いがでるのだろう・・・結果を見ないと夜も眠れないのでレッツチャレンジ

以下で実行したプログラムは単純にデータベースの値をselectして変数に格納するという処理を1万回ループさせた結果を比較してみました。

1回目

1.10664892197 秒 mysql_fetch_array
1.09572291374 秒 mysql_fetch_assoc

2回目

1.11120200157 秒 mysql_fetch_array
1.09469890594 秒 mysql_fetch_assoc

3回目

1.11140799522 秒 mysql_fetch_array
1.10241794586 秒 mysql_fetch_assoc

めっちゃ微妙ですが、mysql_fetch_assocがやはり早そうです。といっても誤差程度の速度差でした。

単純に配列に入るデータが多い分遅くなるということなんでしょうね。

var_dumpで表示した結果
mysql_fetch_array

array(2) {
[0]=> string(1) "1"
["KEY"]=> string(1) "1"
}

mysql_fetch_assoc

array(1) {
["KEY"]=> string(1) "1"
}

2007.11.26 Mon

PHP5.1.6でeAcceleratorのインストール 2倍高速化

PHP5.1.6でeAcceleratorのインストール 2倍高速化

eAcceleratorについて

アクセラレータはスクリプトを解析した結果を中間コードの状態で共有メモリ上にキャッシュし、スクリプトの2回目以降の実行は構文解析を行わずに, キャッシュされた中間コードをダイレクトに読み込むことで処理を高速化しています。

巨大なソースファイルや多数のファイルをインクルードしているサイトなどでアクセラレータは絶大な威力を発揮します。

インストール環境

Centos 5
PHP 5.1.6 パッケージインストール版

php-develパッケージのインストール

# yum install php-devel
※パッケージインストールの場合のみ必要

eAcceleratorのインストール

# wget http://bart.eaccelerator.net/source/0.9.5.2/eaccelerator-0.9.5.2.tar.bz2
# tar jxvf eaccelerator-0.9.5.2.tar.bz2
# cd eaccelerator-0.9.5.2

※yumでphp-develを入れた場合

# /usr/bin/phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20050922
Zend Extension Api No: 220051025
# ./configure --enable-eaccelerator=shared --with-php-config=/usr/bin/php-config

※phpをソースからインストールしている場合

# /usr/local/bin/phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20050922
Zend Extension Api No: 220051025
# ./configure --enable-eaccelerator=shared --with-php-config=/usr/local/bin/php-config

# make
# make install

phpの設定変更

# vi /etc/php.ini

最終行に追加

[eAccelerator]
zend_extension = "/usr/lib/php/modules/eaccelerator.so"
eaccelerator.shm_size = "16"
eaccelerator.cache_dir = "/tmp/eaccelerator"
eaccelerator.enable = "1"
eaccelerator.optimizer = "1"
eaccelerator.check_mtime = "1"
eaccelerator.debug = "0"
eaccelerator.filter = ""
eaccelerator.shm_max = "0"
eaccelerator.shm_ttl = "0"
eaccelerator.shm_prune_period = "0"
eaccelerator.shm_only = "0"
eaccelerator.compress = "1"
eaccelerator.compress_level = "9"
eaccelerator.keys = "shm_and_disk"
eaccelerator.sessions = "shm_and_disk"
eaccelerator.content = "shm_and_disk"

キャッシュディレクトリの作成

# mkdir /tmp/eaccelerator
# chmod 0777 /tmp/eaccelerator

Apacheの再起動

# service httpd restart


動作確認・導入結果

<?php phpinfo(); ?> にてeAcceleratorの項目が表示されていることを確認する。

動作していることが確認できたらadベンチマークにて結果を確認


eAccelerator導入前

# ab -n 1000 -c 10 http://localhost/index.html

Concurrency Level: 10
Time taken for tests: 13.77777 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 23102000 bytes
HTML transferred: 22927000 bytes
Requests per second: 76.47 [#/sec] (mean)
Time per request: 130.778 [ms] (mean)
Time per request: 13.078 [ms] (mean, across all concurrent requests)
Transfer rate: 1725.06 [Kbytes/sec] received

eAccelerator導入後

# ab -n 1000 -c 10 http://localhost/index.html

Concurrency Level: 10
Time taken for tests: 6.798706 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 23102000 bytes
HTML transferred: 22927000 bytes
Requests per second: 147.09 [#/sec] (mean)
Time per request: 67.987 [ms] (mean)
Time per request: 6.799 [ms] (mean, across all concurrent requests)
Transfer rate: 3318.28 [Kbytes/sec] received

Requests per second: 1秒間に処理されたリクエスト数。


はまったところ・・・

/var/lib/php/session

ディレクトリに設定していた所有者の設定がrootに戻ってしまっていた。apacheを実行しているユーザーの権限を与えてやらないとsessionファイルが作れなくなりセッション変数が使えない状態ではまりました。

参考サイト

2007.11.14 Wed

コピーライトの表示が簡単に変更できるちょっとした工夫

ホームページでは一番下にコピーライトを入れるのが常識ですが、運用年月を入れている場合、年が変わるたびに全ページ更新するのは大変ですよね?そんな人のためにコピーライトの簡単な表示方法を紹介します。

外部ファイルからコピーライトの文章を表示させる方法

<?php include('外部ファイル); ?>

外部ファイルに 「 Copyright &copy; 2004-2007 All Right Reserved. 」を記述しておき、表示させるだけ。年が変わるたびに外部ファイルの記述を変更すれば、最新のコピーライトが表示されるようになります。

phpで動的に表示させる場合

Copyright &copy; 2004- <?php echo date(Y); ?> All Right Reserved.

この方法で記述しておけば自動的に表示が変わるので、手間いらずです。

実際に表示されるコピーライト

Copyright &copy; 2004-2007 All Right Reserved.

2007.11.08 Thu

phpinfoの色々な使い方

絶対パスがわからないときに・・・

レンタルサーバーなど自分で構築した環境でないサーバーにシステムを設置する場合、絶対パスがわからないことがあります。

そんな時便利なのが

<?php phpinfo(); ?>

phpinfo()を表示させたファイルまでの絶対パスがブラウザ上で確認できるので、非常に便利です。

パラメーターのチェックに

通常 <?php phpinfo(); ?> としてシステムの状態をチェックすることに使うことが多いと思いますが、phpinfo に引数を設定することで、パラメーターを表示してくれるようになります。

<?php phpinfo(32); ?>

環境変数・GET・POST・クッキー・サーバ変数から すべての 定義済みの変数を表示してくれます


 phpinfo

定数表示 関連サイト

 var_dump

2007.10.29 Mon

Wiki書式からHTMLへの変換について調べた内容

Wiki書式からHTMLへの変換機能をWiki以外のサイトに導入できないかと思い、調査した内容のログ

Wiki書式って??という人のためにWiki書式についてまとめてくれているサイトがあったので、こちらを参考にしてみてください。

オープンソース PHP Markdown

Wikiとはまた違った感じの入力書式

オープンソース Markdownの入力補助「wmd」

JavaScriptを使ったWiki変換


CGIを使ったWiki変換


HTMLからWiki書式へ変換

調べていたら希望する処理の反対の処理も見つかりました。

2007.10.29 Mon

mysql_query() のカン違い

mysql_query()を使ってPHPからqueryを実行する場合 処理が実行されたかを判定するために

$query = mysql_query($sql);
if($query == true){
/* 正常に実行 */
}

と今までしていたのですが、 === で比較したほうが早いということを知り

$query = mysql_query($sql);
if($query === true){
/* 正常に実行 */
}

としてみたらエラー連発・・・・
何でだろうと思ったリファレンスに書いてあるじゃないですか・・・

SELECT, SHOW, DESCRIBE や EXPLAIN 文では、 mysql_query() は成功した場合に resource を返します。エラー時には FALSE を返します。
それ以外の SQL 文 UPDATE, DELETE, DROP などでは、 mysql_query() は成功した場合に TRUE 、エラー時に FALSE を返します。

== のときは気づかなかったのですが、SELECT, SHOW, DESCRIBE や EXPLAIN 文では処理が正常に実行できた場合は resource を戻り値として返してくれていたのね・・・。

なるほど。戻り値の型が違うからエラーになっていたということですね。

全て true false で帰ってくると思っていました。危ない危ない・・・


 mysql_query

2007.10.29 Mon

ライブラリーなど直接アクセスされたときの対応は?

ライブラリーなどphpからincludeして使うファイルを隠蔽するにはどうしたら?

以下のような記述をファイルの上部に書いておけば、直接ファイルにアクセスした場合でも、処理を実行させずにエラー表示をして処理を停止します。

また、このスクリプトが実行された場合にメール通知するようにしておけば、不正を早期発見できるかもしれません。

/* 不正アクセス処理 */
if (!isset($_SERVER["argv"][0]) || isset($_SERVER['REQUEST_METHOD']) || isset($_SERVER['REMOTE_ADDR'])) {
die("<strong>不正アクセスです。</strong>");
}



 isset
 die

システム構築に関する覚書トップページへ