2012-06-02

ab(apache bench)コマンド

ab(apache bench)コマンドは、apacheに付属している標準ツール。

ベンチマーク対象のホスト(webサイト)の性能測定ができる。


■コマンド例

例:同時接続数 100 リクエスト総数 1000 対象URL http://www.hoge.jp/

# ab -c 100 -n 1000 http://www.hoge.jp/

これは、http://www.hoge.jp/に対して、同時100接続をリクエスト総数1000になるまで(同時接続100を10回)アクセスするということになる。



テストサイトなどでベーシック認証が必要なサイトに対しては、次のような感じになる。

# ab -c 100 -n 1000 -A user:password http://test.hoge.local/



■GET

URLエンコードしたクエリストリングを付けるだけなので、簡単。

http://test.hoge.local/serach.php?keyword=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a

上は、"あいうえお"をUTF-8でURLエンコードした例。



■POST

ちょっと面倒だができる。

非同期通信オブジェクトを使ってPOSTしたことある方ならわかると思う。

まず、POSTする項目のname属性とvalue値(textareaはタグで囲まれた要素の値)で、GETと同じ要領でクエリストリングを記述し、そいつをファイルとして保存する。

# echo -n "keyword=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a" > postdata


で、次のようにabコマンドを実行する。

# ab -c 100 -n 1000 -p postdata -T "application/x-www-form-urlencoded" http://test.hoge.local

-p オプションでPOSTデータを保存したファイルを指定し、-T オプションで content-type を指定する。



■セッション

abでアクセスしたときにセッションはどうなるか調べてみた。

http://test.hoge.local/sess.php
<?
session_start();


で

ab -c 10 -n 100 http://test.hoge.local/sess.php

を実行すると、セッションファイルが100個できていた。

ということは、100回すべて別セッションでアクセスしているとわかった。

PHPだからと言って

今ね、先行してリリースしたプロジェクトから資産を引き継いで、よく似たシステム作ってる。

LAMPで。



「さーて、.htaccess置いて、エラーメッセージを画面に表示....」



ってやったらさ、


出るわ出るわ...



Notice: Undefined variable

Notice: Undefined index

Notice: Undefined offset


の嵐。



おいぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃぃ



「またやってるよ。ほんとに進歩がない」



変数ないんだろ?

配列の範囲超えてるんだろ?


よくそんな状態で「テストしました。リリースします」って言えるよ....


あきれてものも言えない。



変数を宣言してないとか、範囲チェックしていないとか、キーチェックしていないとか、あり得ない。


PHP使ってんだから、それぐらいやれよ。




明らかに、不正な値を使ってるだろ、これじゃ。




というわけで、こんな文句を他の社員から言われないように、

こんな感じの.htaccess を開発環境ディレクトリの直下において開発しましょう。



■PHP 5.3.x で E_STRICT エラーも表示させる場合の .htaccess

php_flag display_errors On
php_value error_reporting 32767



PHP 5.3.x 以前の E_ALL には E_STRICT は含まれていない。

バージョンE_ALLの値E_STRICTの値
5.3.x307192048
5.2.x61432048
5.1以前20472048

そのため、全てのエラーを表示したければ、各バージョンのE_ALL値とE_STRICT値の合計を error_reporting の値とすればいい。



なお、PHP 5.4.x は、E_ALL (32767) に E_STRICT も含まれているので、PHP 5.3.x 用に作った .htaccess はそのまま使える。


2012-05-30

MySQLでトランザクション

LAMP環境で動いているシステムでレコードロックが発生してしまった。


原因は、処理の途中でブラウザを閉じてしまったこと。


トランザクション制御はきちんとしていた「つもり」だったんだけど、


やっぱり抜けていたところがあったようだ。





所謂「ワークテーブル」がロックしていたので、

とりあえず、


truncate table tablename;



とやって強制的にトランザクションを終了させ、テーブルを空にした。



PHP + MySQL で開発を始めたころに、MySQLの接続が途中で「ブチッ」て切られたときの挙動を調べていたはずだったのだが、そのサイトをブックマークしておくのを忘れ、今日、慌てて探した。



MySQLのAUTOCOMMIT(オートコミット)覚え書き
http://open-groove.net/mysql/autocommit/


お世話になりました。

2012-05-27

PHPで外部サーバーにあるファイルをincludeする

別サーバーにあるPHPソースをinclude()したときに調査した結果を書いておく。

話を簡単にしたいので、ソースはあくまでサンプルで。


呼び出し元
http://www.example.dom/test.php

別サーバー
http://lib.example.dom/

includeしたいファイル
http://lib.example.dom/hoge.php
<?
class person() {
    public $name;
    public $addr;
    public $age;

    function __construct() {
        $this->name = "";
        $this->addr = "";
        $this->age  = "";
    }
}

$o_person = new person();
$o_person->name = "hogehoge"; 
?>

呼び出し元のソース
<?
include 'http://lib.example.dom/hoge.php';
echo "o_person = ";
var_export($o_person);
?>

で、結果はこうなる。



o_person = NULL





外部ファイルを拡張子「.php」のままincludeすると、外部ファイルでphpが「実行」されその「結果」が返される。

そのため、変数$o_personは別サーバー上にしか存在しえない。

PHPのソースとしてincludeしたいため、「結果」として「ソース」が返ってくればよい。

ということで、外部ファイルの拡張子を「.php」から「.inc」に変えたら、見事成功!


呼び出し元のソース
<?
include 'http://lib.example.dom/hoge.inc';  // hoge.php を hoge.inc に変更。これで、呼び出し先の外部サーバーでPHPとして実行されなくなる。
echo "o_person = ";
var_export($o_person);
?>
o_person = person::__set_state(array(
   'name' => 'hogehoge',
   'addr' => '',
   'age' => '',
))


ただし、呼び出し先でさらにincludeしていると、期待した結果にならないので注意。

2012-05-18

照合順序が latin1_swedish_ci なら おれも latin1


PHPが記述されたファイルのエンコード:EUC-JP (CP51932)

MySQLのフィールドの照合順序:latin1_swedish_ci

<?
header("Content-Type: text/html; charset=EUC-JP");

$link = mysql_connect("localhost", "hoge", "hoge");

mysql_select_db("hoge", $link);

mysql_set_charset("latin1", $link);

mysql_query("INSERT INTO `tbl` (`value`) VALUES ('あ')", $link);

$query = mysql_query("SELECT `value` FROM `tbl`", $link);

$row = mysql_fetch_array($query, MYSQL_ASSOC);

echo $row["value"];

mysql_free_result($query);

mysql_close($link);
?>


クライアント側(PHP)が EUC-JP だからといって

mysql_set_charset("ujis", $link);

とすると、MySQLが ujis (EUC-JP) から latin1 へ変換するので文字化けする。


そりゃね、latin1の文字セットに日本語の「あ」なんてないさ。


だから、クライアント側(PHP)も「latin1だよー」って言ってあげると、MySQLは変換しないので文字化けしない。



ということで、このサンプルの出力(echo $row["value"])の結果は


あ


となる。

2012-04-26

charaset=EUC-JP

サンプルコードを張っておくよ。
テキストエディタでEUC-JPで保存してね。

サンプルを確認したサーバー環境:
・PHP Version 5.3.2-1ubuntu4.14

サンプルを確認したOSとブラウザ:
・XP で IE8、Google Chrome
・Ubuntu 10.04 で Google Chrome

<?
$chr = "";
$hex = "";

if (isset($_POST["check_char"])) {
    //  ポストされた文字を16進に変換
    $chr = $_POST["check_char"];
    $arr = unpack("C*", $chr);
    $hex = "";
    for ($j = 1; $j <= count($arr); $j++) {
        $hex.= base_convert($arr[$j], 10, 16);
    }

}
?>
<html>
<head>
<meta http-equiv="content-language" content="ja" />
<meta http-equiv="content-type" content="text/html; charset=EUC-JP" />
<title>EUC-JP</title>
</head>
<body>
<form action="" method="post" accept-charset="EUC-JP">
<p>チェックする文字:<input type="text" name="check_char" value="<?=$chr?>" /></p>
<p>ポストされた文字:<?=$hex?></p>
<p><input type="submit" value="CHECK" /></p>
</form>
</body>
</html>




「チェックする文字」に「№」と入力した結果は


【XP の結果】

ポストされた文字:ade2




【Ubuntu 10.04 の結果】


ポストされた文字:ade2



おや?XPなら「まー、そうかなー」なんだけど、Ubuntuさんまで2バイト文字でポストしちゃってるのね。



ちなみに、PHPで SJIS-win な文字(2バイト文字)を EUC-JP へ変換すると、3バイト文字に変換される。

下のサンプルを Shift_JIS(CP932)で保存して実行してみて。

<?
$chr = "";    
$hex = "";

$chr = mb_convert_encoding("№", "EUC-JP", "SJIS-win");
$arr = unpack("C*", $chr);
$hex = "";
for ($j = 1; $j <= count($arr); $j++) {
    $hex.= base_convert($arr[$j], 10, 16);  //  8fa2f1 に変換される。
}
?>
<html>
<head>
<meta http-equiv="content-language" content="ja" />
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS" />
<title>EUC-JP</title>
</head>
<body>
<p>変換された文字:<?=$hex?></p>
</body>
</html>



理由がわからん。


EUC-JP って言ってるのにさ、2バイト文字として送信されるのは何故?

2012-04-24

Internet Explorer は 3バイトEUC-JP を表示できない

Firefox も Google Chrome も EUC-JP の3バイト文字を表示できるのに対し、

Internet Explorer は表示できない。

Internet Explorer で EUC系の文字をちゃんと表示しようと思ったら、

PHPだと、CP51932でエンコーディングしてあげる。

//  CP932な文字をCP51932へエンコード。"伹" は 0xF9B2
$ecuchar = mb_convert_encoding("伹", "CP51932", "SJIS-win");


//  CP932な文字をEUC-JP、eucJP-winへエンコードすると、
//  3バイト文字にエンコードされる文字があるので注意。
//  CP932な文字をEUC-JPへエンコード。"伹" は 0x8FB0E3
$ecuchar = mb_convert_encoding("伹", "EUC-JP", "SJIS-win");

//  CP932な文字をeucJP-winへエンコード。"伹" は 0x8FB0E3
$ecuchar = mb_convert_encoding("伹", "eucJP-win", "SJIS-win");





2012/05/15 追記
ポストするときは、2バイト文字でポストするのにね。 charset=EUC-JP

Windows 11 インストール / アップグレード 手順

 Microsoftから、Windows 11 の ISO をダウンロード ダウンロードしたISOを右クリックしてマウント コマンドプロンプトを起動してマウントしたドライブ(D:とか)に移動し、setup /product server を実行 あとは指示に従うだけ これだけ。 ...