作成日:2006/06/17
3C.A 付録
3C.A.1 sqlexec_pdb.php
sqlexec_pdb.php
<?php
/* =============================================================================
SQLフォーム
--------------------------------------------------------------------------------
Copyright(C) 2006 Yoshihiro Iwata.
Copyright(C) 2006 Y2Sunlight Office. < http://www.y2sunlight.com >
ソフトウェアの変更の有無に関わらず、以下の条件を満たす場合に限り、再配布及び
利用を許可します。
・本ソフトウェアを再配布する場合は必ずソースコード形式で再配布して下さい。
・再配布する場合に、圧縮、暗号化、または改行を削除するなどして必要以上に
ソースコードを読み難く変更した形式で再配布することはしないで下さい。
但し、回復手段も同時に提供する場合はこの限りではありません。
・再配布する場合は、上記の著作権表示、下記の免責条項、そしてこれら
一連の条件をソースコードに含めて下さい。
本ソフトウェアは無保証です。自己責任で使用してください。
============================================================================= */
require_once("DB.php"); # PEAR
require_once("sql.ini.php");
require_once("sql.inc.php");
#-----------------------------------------------------------
# Main
#-----------------------------------------------------------
# $_REQUEST['dsn' ] : データソース名
# $_REQUEST['text'] : SQLテキスト
#-----------------------------------------------------------
### DSN 設定
if (isset($_REQUEST['dsn'])){
$dsn = $_REQUEST['dsn'];
} else {
ScriptError("URL","Illegal call");
}
### SQLテキスト 設定
if (isset($_REQUEST['text'])) {
$sql_text = GetSqlText($_REQUEST['text']);
CustomSqlText($sql_text,$dsn);
} else {
ScriptError("URL","Illegal call");
}
### データベースへの接続
$opt = array(
'debug' => 2,
'portability' => DB_PORTABILITY_ALL,
);
$db =& DB::connect($dsn, $opt);
if (PEAR::isError($db)) ScriptError("connect", $db->getMessage());
### レスポンス処理
HTML_Begin(); # HTMLの開始
DoSqlScript( $db, $sql_text ); # SQLスクリプトの実行
HTML_End(); # HTMLの終了
### データベースの切断
$db->disconnect();
#-----------------------------------------------------------
# SQLスクリプトの実行
#-----------------------------------------------------------
function DoSqlScript( $db, $sql_text )
{
if (empty($sql_text)) return;
$sqltime = 0;
foreach( $sql_text as $sql )
{
# Error Stop フラグの設定
$bErrStop = true;
if ( $sql{0}=='@' ){
$sql = substr($sql,1);
$bErrStop = false;
}
# SQL文表示
$out = HTML_Escape(
strlen($sql)<60 ? $sql : substr($sql,0,60)." ...");
print "$out<br />\n";
ob_flush(); flush();
if ( !$sql ) continue; # 空行は飛ばす(<br/>出力のみ)
# 特別なEVAL文の実行
if ( preg_match( "/^eval\s+(.+)/i", $sql, $reg ) ) {
eval("{$reg[1]};");
continue;
}
# SELECT文と非SELECT文で処理を分ける
$time1 = microtime_as_float();
if (preg_match("/^(select|show)\s/i", $sql)) {
if(!DoSelect($db, $sql)){
if ($bErrStop) break;
}
}else{
$res =& $db->query($sql);
if(PEAR::isError($res)){
SqlError("DoSqlScript", $res->getMessage());
if ($bErrStop) break;
}
}
$time2 = microtime_as_float();
$sqltime += ($time2-$time1);
ob_flush(); flush();
}
print "time: ".sprintf('%01.03f', $sqltime)." sec.<br />\n";
}
function microtime_as_float() // 時刻のマイクロ秒取得
{
list($usec, $sec) = explode(' ', microtime());
return ((float)$sec + (float)$usec);
}
#-----------------------------------------------------------
# SELECT文の実行
#-----------------------------------------------------------
function DoSelect( $db, $sql )
{
### 検索実行
$sth = $db->prepare($sql);
if(PEAR::isError($sth)){
SqlError("DoSelect", $sth->getMessage());
return false;
}
$res =& $db->execute($sth);
if(PEAR::isError($res)){
SqlError("DoSelect", $res->getMessage());
return false;
}
### 検索結果の表示
# カラム名の取得
$colnum = 0;
if ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)){
print "<table>\n";
print "<tr>\n";
foreach( $row as $key => $value ){
print "<th>$key</th>\n";
}
print "</tr>\n";
$colnum ++;
}
if ( !$colnum ){
print "Not selected.<br />\n";
$db->freePrepared($sth);
$res->free();
return true;
}
# 行のフェッチ
Do {
print "<tr>\n";
foreach( $row as $value ){
$value = HTML_Escape($value);
print "<td>$value</td>\n";
}
print "</tr>\n";
} while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC));
print "</table><br />\n";
$db->freePrepared($sth);
$res->free();
return true;
}
#-----------------------------------------------------------
# SQLスクリプトのカスタマイズ
# DSNに応じたSQLスクリプトのカスタマイズ
#-----------------------------------------------------------
function CustomSqlText(&$sql_text,&$dsn)
{
if ( (strtolower(substr($dsn,0,5))=="mysql") &&
C_MYSQL41 ){
# MySQL 4.1以上の場合は クライアント文字セットを送信
# SHOW CHARACTER SET;
switch(strtolower(C_CHARSET)){
case 'utf-8' : $charset='utf8'; break;
case 'euc-jp' : $charset='ujis'; break;
case 'shift_jis' : $charset='sjis'; break;
default: $charset='';
}
if ($charset) array_unshift($sql_text,"SET NAMES $charset #auto insert");
}
}
#-----------------------------------------------------------
# HTMLの開始と終了
#-----------------------------------------------------------
function HTML_Begin()
{
header('Content-type: text/html; charset='.C_CHARSET);
print <<<EOF
<html>
<head>
<style type="text/css">
body {font:10pt monospace;}
table {font:10pt monospace;border-collapse:collapse;}
th,td {border:solid 1px #000000;}
th {background-color:#eeeeee;}
</style>
</head>
<body>\n
EOF;
}
function HTML_End(){
print "</body></html>\n";
}
#-----------------------------------------------------------
# SQLエラー処理
#-----------------------------------------------------------
function SqlError($title, $msg)
{
print "<span style='color:red'>[Error]$title: $msg</span><br />\n";
}
?>
