'websql' スクリプト その1

タイトルの通り、「websql.php」と名乗るスクリプトを作ってみました。 これは、SQL文を書いたファイルをWebサーバにアップロードしておき、 そのファイル名を指定してRDBMS上のデータをダウンロードする出来合いの Web画面を実現します。

<?php
$db=strtoupper(addslashes($_GET["db"]));

$query=addslashes($_GET["query"]);
$filename = "/usr/local/apache/htdocs/php4/websql/${query}.sql";
$fin = fopen ($filename, "r");
if(! $fin){
  print "ERROR 120\n";
  exit;
}
$query = "";
while(! feof($fin)){
  $buf = fgets($fin, 256);
  $query = $query . " " . trim($buf);
}
fclose ($fin);

if(! empty($_GET["p1"])){ $p1=addslashes($_GET["p1"]); }
if(! empty($_GET["p2"])){ $p2=addslashes($_GET["p2"]); }
if(! empty($_GET["p3"])){ $p3=addslashes($_GET["p3"]); }
if(! empty($_GET["p4"])){ $p4=addslashes($_GET["p4"]); }
if(! empty($_GET["p5"])){ $p5=addslashes($_GET["p5"]); }

header("Content-Type:text/plain");
if(trim($db) == "" || trim($query) == ""){
  print "ERROR 132\n";
  exit;
}

if($db == "UNYO"){
  $con = OCILogon("uny", "unypass", "unydb");
}
elseif($db == "DEV"){
  $con = OCILogon("dev", "devpass", "devdb");
}
if($con == 0){
  print "ERROR 146\n";
  exit;
}

$stmt = OCIParse($con, $query);
if(! empty($p1)){ OCIBindByName($stmt, ":p1", &$p1, 100); }
if(! empty($p2)){ OCIBindByName($stmt, ":p2", &$p2, 100); }
if(! empty($p3)){ OCIBindByName($stmt, ":p3", &$p3, 100); }
if(! empty($p4)){ OCIBindByName($stmt, ":p4", &$p4, 100); }
if(! empty($p5)){ OCIBindByName($stmt, ":p5", &$p5, 100); }
$r = OCIExecute($stmt, OCI_DEFAULT);
$ncols = OCINumCols($stmt);
for($y=0; OCIFetchInto($stmt, &$arr); $y++){
  $rowdata = "";
  for($i=0; $i<$ncols; $i++){
    if($i>0){ $rowdata .= "\t"; }
    $rowdata .= $arr[$i];
  }
  print $rowdata . "\n";
}
OCIFreeStatement($stmt);
OCILogoff($con);
?>

使い方はこうだ。(←妙に偉そう) まず、検索に使う接続先のデータベースはプログラムの中に書いてあるので、 適当に修正します。

次に、検索を行うSQL文(SELECT文)を書いたテキストファイルを作り、 上のプログラムだと /usr/local/apache/htdocs/php4/websql/ の位置に拡張子.sqlをつけてアップロードしておきます。 例えば、sample.sql と名づけたとします。

さらに、このPHPスクリプトもWebサーバの文書ツリーの下にアップロードします。 ここでは /usr/local/apache/htdocs/php4/websql/websql.php とし、Webブラウザからは http://localhost/php4/websql/websql.php というURLで参照できるものとします。

そして、Webブラウザからは次のようにアクセスします:

http://localhost/php4/websql/websql.php?db=DEV&query=sample
db=DEVが接続先は("dev", "devpass", "devdb")であることを指示し、 query=sampleが使うSQL文をsample.sqlから読むことを指示します。 これで、検索結果がテキストデータとしてWebブラウザに表示されます。

なお、SQL文には「:p1」から「:p5」までのバインド変数を使うことができます。 例えば、

SELECT * FROM USERS WHERE USERNAME = :p1 AND AGE < :p2

というSQL文を書き、検索時にパラメータ「p1」から「p5」で実際の値を指定できます。 例えば
http://localhost/php4/websql/websql.php?db=DEV&query=sample&p1=SAITO&p2=30
のようにパラメータが指定できます。


'websql' スクリプト その2

 上の「その1」スクリプトは便利ですが、表示するレコードが数万件、 という場合にはWebブラウザに表示されるまでがかなり待たされ、 最悪PCがハングする可能性もあります。 そこで、一旦データをWebサーバ上の作業ディレクトリに落とし、 そのファイルへのハイパーリンクを「リンクを名前をつけて保存」 するように改造したのが次のフォーム&スクリプトです。 今度はフォームもちゃんと作りましたよ。ほめて、ほめて(帰れ)

<html>
<body bgcolor="white">
<form action="websql.php" method="POST">
接続先定義の名前:
<input type="text" name="db" maxlength="16">
問合せ定義の名前:
<input type="text" name="query" maxlength="16">
<br>
パラメータがある場合は以下に指定して下さい:<br>
パラメータ1=<input type="text" name="p1" maxlength="32"><br>
パラメータ2=<input type="text" name="p2" maxlength="32"><br>
パラメータ3=<input type="text" name="p3" maxlength="32"><br>
パラメータ4=<input type="text" name="p4" maxlength="32"><br>
パラメータ5=<input type="text" name="p5" maxlength="32"><br>
<br>
<input type="submit" value="実行">
</form>
</body>
</html>

<?php
$db=strtoupper(addslashes($_POST["db"]));

$outputFileName = "/usr/local/apache/htdocs/php4/websql/work/result.txt";
$outputURL = "work/result.txt";

$query=addslashes($_POST["query"]);
$filename = "/usr/local/apache/htdocs/php4/websql/${query}.sql";
$fin = fopen($filename, "r");
if(! $fin){
  print "ERROR 120\n";
  exit;
}
$query = "";
while(! feof($fin)){
  $buf = fgets($fin, 256);
  $query = $query . " " . trim($buf);
}
fclose ($fin);

if(! empty($_POST["p1"])){ $p1=addslashes($_POST["p1"]); }
if(! empty($_POST["p2"])){ $p2=addslashes($_POST["p2"]); }
if(! empty($_POST["p3"])){ $p3=addslashes($_POST["p3"]); }
if(! empty($_POST["p4"])){ $p4=addslashes($_POST["p4"]); }
if(! empty($_POST["p5"])){ $p5=addslashes($_POST["p5"]); }

header("Content-Type:text/html");
if(trim($db) == "" || trim($query) == ""){
  print "ERROR 132\n";
  exit;
}

if($db == "UNYO"){
  $con = OCILogon("uny", "unypass", "unydb");
}
elseif($db == "DEV"){
  $con = OCILogon("dev", "devpass", "devdb");
}
else{
  print "ERROR 143\n"; exit;
}
if($con == 0){
  print "ERROR 146\n"; exit;
}

$stmt = OCIParse($con, $query);
if(! empty($p1)){ OCIBindByName($stmt, ":p1", &$p1, 100); }
if(! empty($p2)){ OCIBindByName($stmt, ":p2", &$p2, 100); }
if(! empty($p3)){ OCIBindByName($stmt, ":p3", &$p3, 100); }
if(! empty($p4)){ OCIBindByName($stmt, ":p4", &$p4, 100); }
if(! empty($p5)){ OCIBindByName($stmt, ":p5", &$p5, 100); }
$r = OCIExecute($stmt, OCI_DEFAULT);
$ncols = OCINumCols($stmt);

$fout = fopen($outputFileName, "w");
if(! $fout){
  print "ERROR 164\n"; exit;
}

for($y=0; OCIFetchInto($stmt, &$arr); $y++){
  $rowdata = "";
  for($i=0; $i<$ncols; $i++){
    if($i>0){ $rowdata .= "\t"; }
    $rowdata .= $arr[$i];
  }
  fwrite($fout, $rowdata . "\n");
}
fclose($fout);
OCIFreeStatement($stmt);
OCILogoff($con);
?>
<html>
<body bgcolor="white">
データの出力に成功しました。
<a href="<?= $outputURL ?>">こちら</a>からダウンロードできます。
</body>
</html>

今度は使い方も何も、フォームに必要項目を入力していけばいいだけですね。 「接続先」というのはPHPからRDBMSに接続する情報に名前をつけたもので、 スクリプトにある「DEV」とか「UNYO」というのを指定すればOKです。

Open Source Web Architecture Top

(first uploaded 2002/11/08 last updated 2002/11/16, URANO398)

Gポイントポイ活 Amazon Yahoo 楽天

無料ホームページ 楽天モバイル[UNLIMITが今なら1円] 海外格安航空券 海外旅行保険が無料!