ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

PHPでつくる、仕様書からのプログラム自動生成(その3:雛形ファイルの仕様)

2005-11-28 18:14:01 | PHP

前に書いた仕様書をCSVで書き出し、雛形ファイルを用意すると、仕様書の内容をいれて、プログラムが自動生成するという話。

■■ 手順的にはこんなかんじ
・仕様書をCSV書き出ししたものと、
・雛形を用意して、
   ↓
・このPHPを実行すると、
   ↓
・ブラウザ上に、雛形の指定したところへ、仕様書の値を入れて
 ソースを書き出す。

前のブログで、「このPHPを実行すると」のPHPと、それを呼び出す実行画面について、書いたので、今回は、「雛形を用意して」の雛形ファイルの書き方です




■■ 雛形ファイルのつくりかた

(1)てきとーにプログラムを書いてください
 もちろん、PHPプログラムでなくてもいいです。
 例には、SQLを示しましたが、JavaプログラムでもPHPプログラムでも、
 もちろん、一般的な文章、つまり、「あんたくび!」というドキュメントでもOKです。

(2)半角の< > &を、変換します
 雛形にある、< は <に > は >に & は &に変換したほうがいいです
 (なお、上の行の&は、本当は半角)
  
(3)ここで、あたまとおわりに、じゅもんをつけてください。
 頭に付ける呪文は、こんなかんじ
<?
//==============================//
//	文頭の呪文		//
//==============================//
	session_start();
	$data	=	$_SESSION['data'];
?>
<html>
<BODY>
<pre>

(上記の< >は、実際には半角です)

おわりにつける呪文はこんな感じ
</pre>
</BODY>
</HTML>

(上記の< >は、実際には半角です)

(4)CSVファイルのデータが入るところを指定します

・値が直接入るところには、
  <?=$data[0][1]?>のように
<?=$data[行番号][列番号]?>を指定してください
(どこも空白を空けないでください)

なお、はじめの行は0行目、列も0列目からはじまります
(1スタートでなく、0スタートです)


・繰り返しのところは
<?for($i = 開始行; $i < count($data) ; $i++){ ?>
<?}?>

で囲ってください。開始行のところは、データファイルで、繰り返し部分のところが
はじまる行を指定します。つまり、見出し行の次の行です。
(上記のなかで、実際に指定するのは、開始行だけです)

・繰り返しの中で、ある列の値を表示するには
 <?=$data[$i][列番号]?>
 として、行のところに$iを書きます。

・条件のときは、
<?if (条件文) { ?>
<?}else { ?>
<?}?>
でかきます。そうすると、条件文が成立したときに、かきだします。
(elseの行は、なくてもOK)
 条件式の中で、データファイルの値を利用するときは、$data[行番号][列番号]、繰り返しの中で利用するときは$data[$i][列番号]となります。

基本的にはこうなのですが、実は<? ?>のなかでは、好きにPHPプログラムを書いていただいて問題ありません

(5)そして、このファイルを保存して拡張子をPHPにします。




今、じかんがないので、データファイルの構造と、なぜこれで、自動生成するのかについて、この方法のメリットについては、今度の機会に書きます。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHPでつくる、仕様書からのプログラム自動生成(その2:操作画面の内容と、実行プログラム)

2005-11-28 17:35:07 | PHP

 先ほど書いた、仕様書をCSVで書き出し、雛形ファイルを用意すると、仕様書の内容をいれて、プログラムが自動生成するという話。

■■ 手順的にはこんなかんじ
・仕様書をCSV書き出ししたものと、
・雛形を用意して、
   ↓
・このPHPを実行すると、
   ↓
・ブラウザ上に、雛形の指定したところへ、仕様書の値を入れて
 ソースを書き出す。

ここで、「このPHPを実行すると」のPHPと、それを呼び出す実行画面について、以下に書きます。




■■ 実行画面について
 実行画面の様子は、こんなかんじ。
<form method="POST" action="makepro.php">
CSVファイル名:<input type="text" name="csvfname">  1行のバイト数:<input type="text" name="gyolen" value=1000><BR>
雛形ファイル名:<input type="text" name="hinafname">                
<input type="submit" name="submit" value="実行">
</form>

(上記の < > ¥ は、実際には半角です)

で、画面の様子は、ここの。。。と書こうと思ったら(>_<!!)

gooやってくれるな(^^;)

前のブログの例その1 の実行画面、
 編集画面では、フォームの形になっていたのに、それをエントリしたとたんに、ソースが書かれてる(>_<!) 

 これじゃ、みなさんには、実行画面のイメージがわかんないですよね。。

 具体的には、CSVファイル名、雛形ファイル名 1行のバイト数の入力エリアがあります。

 ここでCSVファイル名は(実際にはタブ区切りですけど)データファイル名、

 雛形ファイル名は、雛形として用意したファイル名を入れてください。

 1行のバイト数は、データファイルの最大の1行のバイト数なのですが、実際のものより、大きい分には問題ありません。




 ということで、実行画面は、入力フォームです。ここで、makepro.phpというのを呼び出しています。
makepro.phpというのは、何をやっているかというと、こんな感じのことをしてます
(といって、以下、ソースプログラムです)

<?
//======================================//
//	コントロール部分		//
//======================================//
	session_start();

		//======================//
		//	処理実行	//
		//======================//
	$VO = shori($VO);

		//======================//
		//	次の画面表示	//
		//======================//
	if ( $VO['nextJob']	==	"ERROR" )
	{	//	エラー時は、エラー画面
		$_SESSION['errmsg'] = $VO['errmsg'];
		header("Location:errmsg.php¥n¥n");
	}
	else
	{	//	正常時、雛形ファイルへ
		$_SESSION['data'] = $VO['data'];
		header("Location:".$VO['hinafname']."¥n¥n");
	}

//=======ここまで:以降は、関数を書いてます===============================//

?>

<?
//======================================//
//	処理部分			//
//======================================//
function shori($VO)
{
		//======================//
		//	データセット	//
		//======================//
	$VO['csvfname']	=	$_POST['csvfname'];
	$VO['gyolen']	=	$_POST['gyolen'];
	$VO['hinafname']=	$_POST['hinafname'];

		//======================//
		//	エラーチェック	//
		//======================//
	$VO['nextJob']	=	"OK";
	if ( $VO['csvfname']	==	"" )
	{
		$VO['nextJob']	=	"ERROR";
		$VO['errmsg']	=	"CSVファイル名の指定がありません";
		return $VO;
	}
	elseif ( $VO['hinafname']	==	"" )
	{
		$VO['nextJob']	=	"ERROR";
		$VO['errmsg']	=	"雛形ファイル名の指定がありません";
		return $VO;
	}
	elseif ( $VO['gyolen']	<=	0 )
	{
		$VO['nextJob']	=	"ERROR";
		$VO['errmsg']	=	"1行のバイト数の指定をしてないか、不正値";
		return $VO;
	}

		//======================//
		//	データ取得	//
		//======================//
	$file = fopen($VO['csvfname'],"r");
	if ( $file == "" )
	{
		$VO['nextJob']	=	"ERROR";
		$VO['errmsg']	=	"CSVファイルのオープンに失敗しました";
		return $VO;
	}

	$i = 0;
	while (($rec =fgetcsv($file,$VO['gyolen'],"¥t") ) != "" )
	{
		if ( count($rec) > 1 )
		{		//	セルが1つよりおおく存在
			$data[$i] = $rec;
			$i ++;
		}
		elseif ( ( count($rec) == 1 ) && ($rec[0] != "" ) )
		{		//	セルが1つだが、そのセルは空でない
			$data[$i] = $rec;
			$i ++;
		} 
	}
	fclose($file);
	$VO['data']	=	$data;

	return $VO;
}
?>

(上記の < > ¥ は、実際には半角です)

 つまり、shoriというところで、CSVファイルを読み込み(fgetcsvのところ、そこでいろいろやってるのは、改行だけの行があったときは、無視する処理)、それを'data'というところにいれて、最終的には、エラーならエラー画面に、そうでなければ、dataをセッションに入れて、雛形ファイル(じつはこのファイル、PHP形式で書くので、呼び出せる)を呼び出しているだけです。

 ??なんで、自動生成するのか?

っていう話ですが、それは、雛形ファイルの仕様について書いた後で、説明します。

 今回は、とりあえずここまで。

 次回、気が向いたら書く内容は、雛形ファイルの仕様についてです。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHPでつくる、仕様書からのプログラム自動生成(その1:操作方法と具体例)

2005-11-28 17:03:45 | PHP

 仕様書から自動生成を行うプログラムについて、前のブログでとりあげましたけど、今回(から?)、具体的に、その内容を書きます。
 今回は、はじめに、操作内容と具体例について。




■■ どういった内容か?
 こんな感じのことをします。

・仕様書をCSV書き出ししたものと、
・雛形を用意して、
   ↓
・このPHPを実行すると、
   ↓
・ブラウザ上に、雛形の指定したところへ、仕様書の値を入れて
 ソースを書き出す。




■■ わけわかんないので、例その1

・こんな、テーブル仕様書(CSVファイル)を用意します
テーブル名	HELLO_WORLD_TABLE	PRIMARY KEY	NO
名前	型	桁数(文字のとき)	NOT NULL
NO	INTEGER		NOT NULL
LANGUAGE	VARCHAR	50
MESSAGE	VARCHAR	100


で、こんな雛形ファイルを用意します。
<?
//==============================//
//	文頭の呪文		//
//==============================//
	session_start();
	$data	=	$_SESSION['data'];
?>
<html>
<BODY>
<pre>
CREATE TABLE <?=$data[0][1]?> (
<? for($i=2 ; $i < count($data);$i++){ ?>
<?	switch($data[$i][1])
	{
	case	"INTEGER":
		print("	" . $data[$i][0] ."	INTEGER	" .  $data[$i][3] . ",");
		break;
	case	"VARCHAR":
		print("	" . $data[$i][0] ."	VARCHAR(" .  $data[$i][2] . ") " . $data[$i][3] . ",");
		break;
	//	今回は、これ以外ないので省略
   	}
?>

<?}?>
	PRIMARY KEY(<?=$data[0][3]?>)

); 
</pre>
</body>
</html>

(上記 < > ¥ は、本当は、半角)

で、これらの雛形ファイルと、CSVファイル(本当はタブ区切りだけど)をサーバーにおきます。

そして、以下の実行画面で

値設定と実行


<form method="POST">
CSVファイル名:<input type="text" name="csvfname">  1行のバイト数:<input type="text" name="gyolen" value=1000>
雛形ファイル名:<input type="text" name="hinafname">                
<input type="submit" name="submit" value="実行">
</form>

で雛形ファイルと、CSVファイルを指定すると、

こんなもんが、画面にあらわれます。
CREATE TABLE HELLO_WORLD_TABLE (
	NO	INTEGER	NOT NULL,
	LANGUAGE	VARCHAR(50) ,
	MESSAGE	VARCHAR(100) ,
	PRIMARY KEY(NO)

); 


あとは、これを貼りこんで実行してください。
仕様書を、上記の形式で書くと、雛形は変えなくても、CREATE文が、同じように自動生成されます。
(つーことは、仕様書が何百もある場合は、「値を設定して、このプログラムを呼び出し、結果を保存する」というJAVAプログラムを書いてしまえば、どんなにあろうとも、ボタン1発、JAVAプログラムをよべばいいということ)




■■ 例その2:

で、こんどは、データをINSERTしましょう。

CSVファイルは、テストデータとして、こんな感じで用意しておきます
テーブル	HELLO_WORLD_TABLE
名称	NO	LANGUAGE	MESSAGE
型	INTEGER	VARCHAR	VARCHAR
1	1	"日本語"	"こんにちわ 世界"
2	2	"英語"	"Hello World"


で、雛形ファイルは、こんなかんじ
<?
//==============================//
//	文頭の呪文		//
//==============================//
	session_start();
	$data	=	$_SESSION['data'];
?>
<html>
<BODY>
<pre>
<? for($i=3 ; $i < count($data);$i++){ ?>
INSERT INTO <?=$data[0][1]?> ( <?
	for($j=1 ; $j < count($data[1]);$j++)
	{ 
		print $data[1][$j];
		if ( $j != count($data[1]) - 1 )
		{
			print ",";
		}
	}
?> ) VALUES( <?
	for($j = 1 ; $j < count($data[$i]) ; $j ++)
	{
		if ( $data[2][$j]	==	"VARCHAR")
		{
			print "'" . $data[$i][$j] . "'" ;
		}
		else
		{
			print $data[$i][$j];
		}
		if ( $j != count($data[1]) - 1 )
		{
			print ",";
		}
	}
?>);
<? } ?>
</pre>
</body>
</html>

(上記 < > ¥ は、本当は、半角)

で、さっきのプログラムを実行すると、こんなかんじで、データができる
INSERT INTO HELLO_WORLD_TABLE ( NO,LANGUAGE,MESSAGE ) VALUES( 1,'日本語','こんにちわ 世界');
INSERT INTO HELLO_WORLD_TABLE ( NO,LANGUAGE,MESSAGE ) VALUES( 2,'英語','Hello World');


あとはいれればいいだけ。
これは、CSVデータ部分を変えると(きまりはあるが)、
・このテーブルの一部のデータの自動生成はもちろんOKだし、
・それ以外のテーブルのデータの自動生成も、OKです。
(雛形は変えなくていい)




■■ 例その3
 じつは、さっきのブログのinsertToTbl($db,$data)、selectTbl($db)は、この方式で、例1のCSVファイル(テーブル定義)と、ある雛形を使って、自動的に作っている。
 ここでは、INSERT文とselect文しかないけど、delete,Update、selectもwhere句を使ったものなども、雛形を作って自動生成できる。




 あとは、同じように、ドライバ部分も雛形を作れば、自動生成して、すぐに、テーブル定義、DBアクセス関数、ドライバができて、テストできる。

 という話で、では、
・その実行画面と、
・そこから呼ばれるPHPプログラムと
・雛形の書き方
は、どーなっているのというのが、ここでのお話。

ただ、話がながくなったので、このへんでおしまい。

気が向いたら、第二話で実行画面と、そこから呼ばれるPHPを公開します。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHPのmysqliを使った、SQL文実行(prepareで)と検索実行(commitの話も)

2005-11-28 16:25:48 | PHP

 この話書きましたっけ?今、調べたら、このブログには引っかかるんだけど、ぜんぜん違うページがひっかかるので、ここに書いておきます。

■■ 前提となるテーブル
ここのテーブルを使わせてもらいます
SQL文を引用すると、こんなかんじ
CREATE TABLE HELLO_WORLD_TABLE (
	NO	INTEGER	NOT NULL,
	LANGUAGE	VARCHAR(50) ,
	MESSAGE	VARCHAR(100) ,
	PRIMARY KEY(NO)
); 


■■ やること
 以下のPHPプログラムを実行します。
 ここでは、
(1)DBをオープンします

(2)データをセットしてINSERTします
 →insertToTblという関数を呼び出します

(3)その結果を取得します
 →selectTblという関数を呼び出します

(4)DBをクローズします

(5)結果を表示します

これらを、PHPで書くと、以下のとおり
<HTML>
<BODY>
<?
	include("hello.php");

	//--------------------------------------//
	//	DB操作部分			//
	//--------------------------------------//

	//	DBのオープン
	//	ユーザー名などは、実際にあわせて、書き換える
	$db = mysqli_connect("localhost", "ユーザー名", "パスワード", "使用DB");
	if (!$db)
	{
		print("接続できませんでした");
		exit();
	}
	
	//	INSERTしてみる
	$data['NO']		=	3;
	$data['LANGUAGE']	=	"テスト語";
	$data['MESSAGE']	=	"Insertのテスト";
	insertToTbl($db,$data);

	//	結果を取得してみる
	$kekka = selectTbl($db);

	//	クローズ
	mysqli_close($db);

	//--------------------------------------//
	//	結果表示部分			//
	//--------------------------------------//
	print "<table border = 1>";
	for($i = 0 ; $i < count($kekka); $i ++ )
	{
		print "<tr>";
		for ($j = 0 ; $j < count($kekka[$i]) ; $j ++ )
		{
			print "<td>" . $kekka[$i][$j] . " </td>";
		}
		print "</tr>";
	}
	print "</table>"; 

?>
</BODY>
</HTML>

(上記中 < > ¥ は実際には、半角です)




■■それらを実現する関数
 prepareステートメントを使って、Insert実行の例が、
 insertToTbl($db,$data);のほう。

 検索のほうが
 selectTbl($db);

どちらも、利用前に、
$db = mysqli_connect(ホスト名, "ユーザー名", "パスワード", "使用DB");
で、DBのハンドルを取得しておく必要有(それを引数$dbとして渡している)
また、最後に
mysqli_close($db);
を行う。

プログラムは、このとおり
<?
	function insertToTbl($db,$data)
	{
		//	ステートメントの設定
		$sql = 'INSERT INTO HELLO_WORLD_TABLE (NO,LANGUAGE,MESSAGE) VALUES(?,?,?)';
		$stmt = mysqli_prepare($db,$sql);
		mysqli_stmt_bind_param( $stmt,"iss",$NO,$LANGUAGE,$MESSAGE);

		//	値設定
		$NO 	=	$data["NO"];
		$LANGUAGE 	=	$data["LANGUAGE"];
		$MESSAGE 	=	$data["MESSAGE"];
	
		//SQL文を実行する
		mysqli_stmt_execute($stmt);

		//ステートメントクローズ
		mysqli_stmt_close($stmt);

	}

	function selectTbl($db)
	{
		//SQL作成
		$sql = 'select * from HELLO_WORLD_TABLE';

		//SQL文を実行する
		$rs = mysqli_query($db, $sql);
		if (!$rs)
		{
			return $kekka;
		}

		$i = 0;
		while($row=mysqli_fetch_array($rs))
		{
			for($j=0;$j < count($row) ; $j++) 
			{
				$kekka[$i][$j] = $row[$j];
			}
			$i++;
		}

		//結果レコードをメモリから開放
		mysqli_free_result($rs);

		return $kekka;
	}
?>

(上記中 < > ¥ は実際には、半角です)




■■ つけたし
今回は、commit処理を行っていない。
する場合は、DBのハンドルを取得したのち

//オートコミットOFF
mysqli_autocommit($db, FALSE);

をして、コミットする場合は、
mysqli_commit($db);
ロールバックのときは
mysqli_rollback($db);
を発行する。




■■ なんで、こんなことをかくのか
 insertToTbl($db,$data);と、selectTbl($db);のテーブルごとの自動生成プログラムを例として、今度書くかもしれないので(このブログに)


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする