SQLの窓

2017年04月15日


PHP で MySQLをテストする為のソースコード


※ $_GET['text'] で入力された SQL が引き渡されます。
※ GET コマンドなので、内容はアドレスバーで確認する事ができます
※ Form を使わずにアドレスバーから直接 SQL を実行できます。

MySQL 改良版拡張モジュール
<?php
session_cache_limiter('nocache');
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SQL実行結果</title> 
</head>
<body style='white-space:pre;'>
<?php
print $_GET['text'] . "\n";

$server = 'localhost';
$dbname = 'lightbox';
$user = 'root';
$password = 'パスワード';

// ***************************
// 接続
// ***************************
$mysqli = @ new mysqli($server, $user, $password, $dbname);
if ($mysqli->connect_error) {
	print "接続エラーです : ({$mysqli->connect_errno}) ({$mysqli->connect_error})";
	exit();
}

// ***************************
// クライアントの文字セット
// ***************************
$mysqli->set_charset("utf8"); 

// ***************************
// クエリ
// ***************************
$result = $mysqli->query($_GET['text']);
if ( !$result ) {
	print "\n";
	print "<span style='color:#f00'>" . $mysqli->error . "</span>";
}

// ***************************
// 列数
// ***************************
$nfield = $result->field_count;
if ( $nfield ) {
	$ncount = 0;
	print "<table style='border:solid 1px #000;border-collapse:collapse;'>\n";

	print "\t<th style='border:solid 1px #000;padding:5px;'></th>\n";

	$field = $result->fetch_fields( );
	for( $i = 0; $i < $nfield; $i++ ) {
		print "\t<th style='border:solid 1px #000;padding:5px;'>{$field[$i]->name}</th>\n";
	}

	while ($row = $result->fetch_row()) {
		print "<tr>\n";
		print "\t<td style='border:solid 1px #000;padding:5px;'>" . ($ncount + 1) . "</td>\n";
		for( $i = 0; $i < $nfield; $i++ ) {

			print "\t<td style='border:solid 1px #000;padding:5px;'>{$row[$i]}</td>\n";
		}
		print "</tr>\n";
		$ncount++;
	}
	print "</table>";
}

// ***************************
// 接続解除
// ***************************
$mysqli->close();
?>

</body>
</html>


PHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除
<?php
session_cache_limiter('nocache');
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SQL実行結果</title> 
</head>
<body style='white-space:pre;'>
<?php
print $_GET['text'] . "\n";

$server = 'localhost';
$dbname = 'lightbox';
$user = 'root';
$password = 'パスワード';

// ***************************
// 接続
// ***************************
$connect = @mysql_connect( $server, $user, $password );
if ( !$connect ) {
	print "接続エラーです";
	exit();
}

// ***************************
// DB選択
// ***************************
mysql_select_db( $dbname, $connect );
mysql_set_charset("utf8", $connect); 

// ***************************
// クエリ
// ***************************
$result = mysql_query($_GET['text'], $connect);
if ( !$result ) {
	print "\n";
	print "<span style='color:#f00'>" . mysql_error() . "</span>";
}

// ***************************
// 列数
// ***************************
$nfield = @mysql_num_fields( $result );
if ( $nfield ) {
	$ncount = 0;
	print "<table style='border:solid 1px #000;border-collapse:collapse;'>\n";

	print "\t<th style='border:solid 1px #000;padding:5px;'></th>\n";
	for( $i = 0; $i < $nfield; $i++ ) {
		$field = mysql_fetch_field( $result, $i );

		print "\t<th style='border:solid 1px #000;padding:5px;'>{$field->name}</th>\n";
	}

	while ($row = mysql_fetch_row($result)) {
		print "<tr>\n";
		print "\t<td style='border:solid 1px #000;padding:5px;'>" . ($ncount + 1) . "</td>\n";
		for( $i = 0; $i < $nfield; $i++ ) {
			print "\t<td style='border:solid 1px #000;padding:5px;'>{$row[$i]}</td>\n";
		}
		print "</tr>\n";
		$ncount++;
	}
	print "</table>";
}

// ***************************
// 接続解除
// ***************************
mysql_close($connect);
?>

</body>
</html>

※ このコードではセキュリティ上の考慮はされていません。



posted by lightbox at 2017-04-15 19:47 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2016年05月30日


PHP で 自家製 API を作成して jQuery の簡単なコードで更新処理を行うサンプル

以下のような『社員マスタ』を使って、まず PHP のコードを用意します。
create table `社員マスタ` (
	`社員コード` varchar(4)
	,`氏名` varchar(50)
	,`フリガナ` varchar(50)
	,`所属` varchar(4)
	,`性別` int
	,`作成日` datetime
	,`更新日` datetime
	,`給与` int
	,`手当` int
	,`管理者` varchar(4)
	,`生年月日` datetime
	,primary key(`社員コード`)
)


全てのデータが空でも、SQL 的にはエラーは起こりません。但し、エラーが発生した場合は、kj にエラーメッセージをセットし、furi に 更新 SQL をセットします。

dbdata_update_json.php
<?php
header( "Content-Type: application/json; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );
header( "Access-Control-Allow-Origin: *" );

// ***********************************************
// 初期設定
// ***********************************************
if ( $_GET["sdata"] == "" ) {
	$_GET["sdata"] = "{}";
}
$data = json_decode($_GET["sdata"]);
$data->type = "UPDATE";

// ***********************************************
// 利用変数設定
// ***********************************************
$json_type =  JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT;
$db_data_type = MYSQLI_ASSOC;
$_GET["sdata"] = str_replace("'","''",$_GET["sdata"]);
// -----------------------------------------------


// ***********************************************
// 接続情報
// ***********************************************
$server = 'localhost';
$db_name = 'lightbox';
$user = 'root';
$password = 'trustno1';
// -----------------------------------------------


// ***********************************************
// 接続
// ***********************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	$data->status = "ERROR";
	$data->kj = "接続エラーです";
	print json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
	exit();
}
$connect->set_charset("utf8"); 
// -----------------------------------------------


// ***********************************************
// NULL 項目の対応
// ***********************************************
if ($data->kyuyo == '') {
	$data->kyuyo = "null";
}
if ($data->teate == '') {
	$data->teate = "null";
}
if ($data->seibetu == '') {
	$data->seibetu = "0";
}
if ($data->birth == '') {
	$data->birth = "null";
}
else {
	$data->birth = "'{$data->birth}'";
}
// -----------------------------------------------


// ***********************************************
// 更新 SQL
// ***********************************************
$query = <<< QUERY
update `社員マスタ` set 
	`氏名` = '{$data->kj}'
	,`フリガナ` = '{$data->furi}'
	,`性別` = {$data->seibetu}
	,`給与` = {$data->kyuyo}
	,`手当` = {$data->teate}
	,`所属` = '{$data->syozoku}'
	,`管理者` = '{$data->kanri}'
	,`生年月日` = $data->birth
 where
 `社員コード` = '{$data->scode}'
QUERY;
// -----------------------------------------------


// ***********************************************
// クエリ実行
// ***********************************************
$result = $connect->query($query); 
if ( !$result ) {
	$data->status = "ERROR";
	$data->kj = "クエリに誤りがあります";
	$data->furi = $query;
	print json_encode( $data, $json_type );
	exit();
}
else {
	$data->status = "SUCCESS";
}
// -----------------------------------------------


// ***********************************************
// 接続解除
// ***********************************************
$connect->close();
// -----------------------------------------------


// ***********************************************
// 結果
// ***********************************************
print json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);

// -----------------------------------------------

?>


PHP で Access-Control-Allow-Origin: * をセットしているので、どこに置いても JavaScript から呼び出し可能です。

以下のような簡単なコードで更新のテストが可能です。
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
$(function(){
	var sdata = {};
	$("#build").on("click", function(){
		$(".entry").find("input").each(function(idx){
			sdata[$(this).prop("id")] = $(this).val();
		});
		$("#result").text( JSON.stringify(sdata,null,"    ") );
	});
	$("#send").on("click", function(){
		var sdata = encodeURIComponent( $("#result").text() );
		$.get("http://localhost/log/easy_board/dbdata_update_json.php?sdata="+sdata ,function(data){
			console.dir(data);
		});
	});
});
</script>
<input id="build" type="button" value="JSON 文字列作成">
<input id="send" type="button" value="サーバ送信">
<pre class="entry">
<input id="scode"> scode
<input id="kj"> kj
<input id="furi"> furi
<input id="seibetu"> seibetu
<input id="kyuyo"> kyuyo
<input id="teate"> teate
<input id="syozoku"> syozoku
<input id="kanri"> kanri
<input id="birth"> birth
</pre>
<pre id="result">
</pre>



posted by lightbox at 2016-05-30 21:17 | Comment(0) | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2015年08月06日


PHP : PIPES_AS_CONCAT を使用して、CSV 作成処理をサーバの負荷にして高速に WrodPress のデータを Excel で読み込める CSV として保存する処理

まず、set sql_mode = 'PIPES_AS_CONCAT' を同一セッション内で実行しておく事によって、Oracle と同様に文字列連結に || を使用できるようになります。

そこで、CSV としての 文字列の仕様を SELECT 構文上でほぼ完成させておいて、クライアントでは一つの列を取得して、改行コードの処理のみを加えてファイルに出力するようにしています。ファイルの出力も、ここでは file_put_contents を使っている為、効率は良くありません。大量のデータを処理したい場合ならば、ファイルへの出力は一行単位で行うべきです。

この方法は十数年前の Oracle でレスポンスが顕著で、天と地ほどの処理時間の差が出ていました。現在では、クライアントの処理能力も上がったので差は無いかもしれませんが、一つのテクニックとして利用可能だと思います。

出来上がった SQL
select ID||','||post_author||','||'"'||replace(post_date,'"','""')||'"'||','||'"'||replace(post_date_gmt,'"','""')||'"'||','||'"'||replace(post_content,'"','""')||'"'||','||'"'||replace(post_title,'"','""')||'"'||','||'"'||replace(post_excerpt,'"','""')||'"'||','||'"'||replace(post_status,'"','""')||'"'||','||'"'||replace(comment_status,'"','""')||'"'||','||'"'||replace(ping_status,'"','""')||'"'||','||'"'||replace(post_password,'"','""')||'"'||','||'"'||replace(post_name,'"','""')||'"'||','||'"'||replace(to_ping,'"','""')||'"'||','||'"'||replace(pinged,'"','""')||'"'||','||'"'||replace(post_modified,'"','""')||'"'||','||'"'||replace(post_modified_gmt,'"','""')||'"'||','||'"'||replace(post_content_filtered,'"','""')||'"'||','||post_parent||','||'"'||replace(guid,'"','""')||'"'||','||menu_order||','||'"'||replace(post_type,'"','""')||'"'||','||'"'||replace(post_mime_type,'"','""')||'"'||','||comment_count from wp_posts

<?php
// **************************************
// MIME と キャラクタセットを設定
// **************************************
header( "Content-Type: text/html; Charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダ
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **************************************
// グローバル変数
// **************************************
$server = 'データベースサーバー';
$db_name = 'データーベース';
$user = 'ユーザー';
$password = 'パスワード';

print "処理開始<br>";
// **************************************
// データベース接続
// **************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	die('Connect Error (' . $connect->connect_errno . ') '
	. $connect->connect_error);
}

// **************************************
// クライアントのキャラクタセット
// **************************************
$connect->set_charset("cp932");

// セッション(接続)中有効
$query = "set sql_mode = 'PIPES_AS_CONCAT'";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

// **************************************
// WordPress の投稿データ
// **************************************
$query = "select * from wp_posts";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

// **************************************
// 列名とデータ型を取得
// **************************************
$finfo = $result->fetch_fields();

$name = array();
$type = array();
foreach ($finfo as $val) {
	$name[] = $val->name;
	$type[] = $val->type;
}

// **************************************
// フィールド数
// **************************************
$field_count = $connect->field_count;

$csv = "";
for( $i = 0; $i < $field_count; $i++ ) {
	if ( $i != 0 ) {
		$csv .= "||','||";
	}
	// 数値型
	// TIMESTAMP型(7) を使用している場合は変更が必要です
	if ( $type[$i] < 10 || $type[$i] == 246 || $type[$i] == 16 ) {
		$csv .= $name[$i];
	}
	else {
		$csv .= "'\"'||replace({$name[$i]},'\"','\"\"')||'\"'";
	}

}

$query = "select {$csv} from wp_posts";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

file_put_contents("query.txt", $query);

$file = "";
while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// データ内の改行コード
	$row[0] = str_replace("\r\n", "\\r\\n", $row[0]);
	$row[0] = str_replace("\r", "\\r", $row[0]);
	$row[0] = str_replace("\n", "\\n", $row[0]);

	// insert としての一行を追加
	$file .= "{$row[0]}\r\n";

}

// **************************************
// ファイルに出力
// **************************************
file_put_contents("easy.csv", $file);

?>

関連する記事



タグ:PHP MySQL WordPress
posted by lightbox at 2015-08-06 20:05 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2015年08月04日


PHP : WrodPress のデータを insert SQL で保存する処理

前回の Excel とは違い、SQL のクォートがシングルクォートなので、データ中の ' は '' に変換しています。キャラクタセットも本来の utf8 を指定していますがこれは省略してもいいでしょう。

実際にローカルの MySQL に wp_posts を作成して 作成された insert 文を2つ実行してみましたが、エラー無く登録されました。
<?php
// **************************************
// MIME と キャラクタセットを設定
// **************************************
header( "Content-Type: text/html; Charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダ
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **************************************
// グローバル変数
// **************************************
$server = 'データベースサーバー';
$db_name = 'データーベース';
$user = 'ユーザー';
$password = 'パスワード';

print "処理開始<br>";
// **************************************
// データベース接続
// **************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	die('Connect Error (' . $connect->connect_errno . ') '
	. $connect->connect_error);
}

// **************************************
// クライアントのキャラクタセット
// **************************************
$connect->set_charset("utf8");

// **************************************
// WordPress の投稿データ
// **************************************
$query = "select * from wp_posts";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

// **************************************
// 列名とデータ型を取得
// **************************************
$finfo = $result->fetch_fields();

$name = array();
$type = array();
foreach ($finfo as $val) {
	$name[] = $val->name;
	$type[] = $val->type;
}

// **************************************
// フィールド数
// **************************************
$field_count = $connect->field_count;

$fld_list = "(" . implode(",",$name ) . ")";

$file = "";

while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// CSV の一行の作成
	$insert = "insert into wp_posts {$fld_list} values(";
	for( $i = 0; $i < $field_count; $i++ ) {
		if ( $i != 0 ) {
			$insert .= ",";
		}
		// 数値型
		// TIMESTAMP型(7) を使用している場合は変更が必要です
		if ( $type[$i] < 10 || $type[$i] == 246 || $type[$i] == 16 ) {
			if ( $row[$i] == "" ) {
				$insert .= "0";
			}
			else {
				$insert .= $row[$i];
			}
		}
		else {
			// データ内のダブルクォートとフィールドを囲むダブルクォート
			if ( $row[$i] == "" ) {
				$insert .= "''";
			}
			else {
				$insert .= "'" . str_replace("'", "''","$row[$i]") . "'";
			}
		}
	}

	// データ内の改行コード
	$insert = str_replace("\r\n", "\\r\\n", $insert);
	$insert = str_replace("\r", "\\r", $insert);
	$insert = str_replace("\n", "\\n", $insert);

	// insert としての一行を追加
	$file .= "{$insert});\r\n";

}

// **************************************
// ファイルに出力
// **************************************
file_put_contents("insert.sql", $file);

?>


関連する記事

参考

MySQL TIMESTAMP / MySQLTutorial



posted by lightbox at 2015-08-04 20:30 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2015年08月03日


PHP : WrodPress のデータを Excel で読み込める CSV として保存する処理

結果の確認として、Excel が簡単なので、SHIFT_JIS その他を最適化していますが、利用先に合わせて変更すればいいと思います。最初1行目に列名リストを出力していたのですが、Excel の仕様で最初に ID という文字があるとエラーになるので省いています。
<?php
// **************************************
// MIME と キャラクタセットを設定
// **************************************
header( "Content-Type: text/html; Charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダ
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **************************************
// グローバル変数
// **************************************
$server = 'データベースサーバー';
$db_name = 'データーベース';
$user = 'ユーザー';
$password = 'パスワード';

print "処理開始<br>";
// **************************************
// データベース接続
// **************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	die('Connect Error (' . $connect->connect_errno . ') '
	. $connect->connect_error);
}

// **************************************
// クライアントのキャラクタセット
// **************************************
$connect->set_charset("cp932");

// **************************************
// WordPress の投稿データ
// **************************************
$query = "select * from wp_posts";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

// **************************************
// 列名とデータ型を取得
// **************************************
$finfo = $result->fetch_fields();

$name = array();
$type = array();
foreach ($finfo as $val) {
	$name[] = $val->name;
	$type[] = $val->type;
}

// **************************************
// フィールド数
// **************************************
$field_count = $connect->field_count;

$file = "";

while ($row = $result->fetch_array(MYSQLI_BOTH)) {

	// CSV の一行の作成
	$csv = "";
	for( $i = 0; $i < $field_count; $i++ ) {
		if ( $csv != "" ) {
			$csv .= ",";
		}
		// 数値型
		// TIMESTAMP型(7) を使用している場合は変更が必要です
		if ( $type[$i] < 10 || $type[$i] == 246 || $type[$i] == 16 ) {
			$csv .= $row[$i];
		}
		else {
			// データ内のダブルクォートとフィールドを囲むダブルクォート
			$csv .= "\"" . str_replace('"', '""',"$row[$i]") . "\"";
		}
	}

	// データ内の改行コード
	$csv = str_replace("\r\n", "\\r\\n", $csv);
	$csv = str_replace("\r", "\\r", $csv);
	$csv = str_replace("\n", "\\n", $csv);

	// CSV としての一行を追加
	$file .= "{$csv}\r\n";

}

// **************************************
// ファイルに出力
// **************************************
file_put_contents("table.csv", $file);

?>


関連する記事

参考

MySQL TIMESTAMP / MySQLTutorial



posted by lightbox at 2015-08-03 20:41 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

PHP で MySQLi 使用時の データ型定数( MYSQLI_TYPE_ ) の詳細 ( バックアップ用 insert 文を作る為 )

テーブルのデータから insert 文を自動的に作成する場合、列が数値かそれ以外かで処理を分ける必要がありますが、データ型は数値で取得されるので、定数の意味を確認する必要があります。

その結果、基本的には 0 〜 9 が数値型であり(6と7は特殊なので対応が必要です)、MySQL 5.0.3 以降という条件付で 246 と 16 が数値として扱われます。
※ 6 は DEFAULT NULL と言う意味として書かれていますが、だとしたら使われる事は無いはずです。
※ 7 は TIMESTAMP なので、INSERT の時は再現必要で、DATETIME と同様に扱うべきものと思われます。

BIT 型は特殊ですが、値のセット方法としては数値でいいようです

▼ PHP マニュアルの参照リンク

定義済み定数
mysqli_result::fetch_field_direct
mysqli_result::fetch_fields

▼ 定数の実際の値と意味
DECIMAL 0
NEWDECIMAL 246 DECIMAL or NUMERIC(MySQL 5.0.3 以降)
BIT 16 (MySQL 5.0.3 以降)
TINY 1 TINYINT
SHORT 2 SMALLINT
LONG 3 INT
FLOAT 4
DOUBLE 5
NULL 6
TIMESTAMP 7
LONGLONG 8 BIGINT
INT24 9 MEDIUMINT
DATE 10
TIME 11
DATETIME 12
YEAR 13
NEWDATE 14 DATE
INTERVAL 247
ENUM 247
SET 248
TINY_BLOB 249
MEDIUM_BLOB 250
LONG_BLOB 251
BLOB 252
VAR_STRING 253 VARCHAR or BINARY
STRING 254
CHAR 1 TINYINT
GEOMETRY 255

関連する記事

参考

MySQL TIMESTAMP / MySQLTutorial



タグ:PHP MySQL
posted by lightbox at 2015-08-03 10:12 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2015年08月01日


PHP から MySQL の簡易的なバックアップを取得する( 但し、DBサーバがディスクへの書き込み権限を持っている必要があります )

実際には、ローカルの MySQL にしか使えなさそうですが、ビューとテーブルの CREATE 文を取得して、TABLE からは CSV 形式のデータを取るコードです。
<?php
// **************************************
// MIME と キャラクタセットを設定
// **************************************
header( "Content-Type: text/html; Charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダ
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// ***********************************************
// グローバル変数
// ***********************************************
$server = 'データベースサーバー';
$db_name = 'データベース名';
$user = 'ユーザ名';
$password = 'パスワード';

print "処理開始<br>";
// ***********************************************
// データベース接続
// ***********************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	die('Connect Error (' . $connect->connect_errno . ') '
	. $connect->connect_error);
}


$query = "show full tables";
// クエリ
$result = $connect->query($query); 
if ( !$result ) {
	die('クエリーに誤りがあります : ' . $connect->error );
}

$table = array();
$view = array();

while ($row = $result->fetch_array(MYSQLI_BOTH)) {
	if ( $row[1] == "BASE TABLE" ) {
		$table[] = $row[0];
	}
	if ( $row[1] == "VIEW" ) {
		$view[] = $row[0];
	}
}

$create_view = "";

for( $i = 0; $i < count( $view ); $i++ ) {
	$query = "show create view {$view[$i]}";
	$result = $connect->query($query);
	while ($row = $result->fetch_array(MYSQLI_BOTH)) {
		$create_view .= $row[1] . ";\n\n";
	}
}

print "view 定義出力<br>";
file_put_contents("./create_view.sql", $create_view );


$create_table = "";

for( $i = 0; $i < count( $table ); $i++ ) {
	$query = "show create table {$table[$i]}";
	$result = $connect->query($query);
	while ($row = $result->fetch_array(MYSQLI_BOTH)) {
		$create_table .= "// [{$i}] {$table[$i]}" . "\n";
		$create_table .= $row[1] . ";\n\n";
	}
}

print "table 定義出力<br>";
file_put_contents("./create_table.sql", $create_table );


print "データ出力開始<br>";
for( $i = 0; $i < count( $table ); $i++ ) {
	$path = realpath("./");
	$path .= DIRECTORY_SEPARATOR ."file_{$i}.csv";
	@unlink($path);
	$path = str_replace("\\", "\\\\", $path );
	$query = "SELECT * INTO OUTFILE '{$path}' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\\n' FROM `{$table[$i]}`";
	$connect->query($query);

}
print "データ出力終了<br>";

?>

レンタルサーバでは、phpmyadmin をインストールしたほうが速いですね。(実際そうしました)

ただ、phpmyadmin は、最新では PHP 5.3+ を要求するので注意です。

インストールと言うほどの処理は無く、アップロードして config フォルダを作って、setup フォルダにアクセスして特別な設定があればそこで入力して設定ファイルを作成し、ファイルを phpmyadmin があるフォルダに移動して config フォルダを削除すれば出来上がりです。


関連する記事



posted by lightbox at 2015-08-01 22:15 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2015年07月02日


PHP : JSON 文字列で定義されたフォーマットを元に、そのフォーマットにセットされた配列を使って insert と update の SQL 文を自動作成。

以下のような簡単な定義は、データベースのテーブルの列定義と同期していますが、全ての列を定義する必要はありません。二つ目の定義は、where で使用される条件を作成する為に必要となるので、必ずしも実際の定義上の主キーである必要はありません。

num は、SQL 内で ' を使用しない事を意味します。よって、num 列の場合はデータベースの関数を直接記述する事ができます。

' を使用する列では、1文字目に @ を指定すると ' を使いませんので、@関数名() や @null といった文字列が使用できます。

syain.json
{
    "社員コード": "",
    "氏名": "",
    "フリガナ": "",
    "所属": "num",
    "性別": "num",
    "作成日": "",
    "更新日": "",
    "給与": "num",
    "手当": "num",
    "管理者": "",
    "生年月日": ""
}

syain_keys.json
{
    "所属": "num",
    "社員コード": ""
}

▼ 実行結果

insert into 社員マスタ (社員コード,氏名,フリガナ,所属,性別,作成日,更新日,給与,手当,管理者,生年月日) values('0001','山田 太郎',null,1,null,null,NOW(),null,null,null,null)
update 社員マスタ set 氏名 = '山田 太郎',フリガナ = null,性別 = null,作成日 = null,更新日 = NOW(),給与 = null,手当 = null,管理者 = null,生年月日 = null where 所属 = 1 and 社員コード = '0001'
insert into 社員マスタ (社員コード,氏名,所属) values('0001','山田 太郎',1)
update 社員マスタ set 氏名 = '山田 太郎' where 所属 = 1 and 社員コード = '0001'
所属 = 1 and 社員コード = '0001'
Run code で実行 type が 1、2 または 3 の場合、第三引数になんらかの配列データが無い場合は、内部で type = 0 で配列を取得して使うようにしました type = 0 : JSON 上で定義されたフォーマットを全て持つ連想配列の取得です。 つまり、全ての列での insert や update を作成する時に使用します。部分的ならば、キー列を含んだ列名の一致する連想配列で問題ありません。 type = 0 を使用せずとも、MySQL であれば、$result->fetch_array(MYSQLI_ASSOC) の結果の連想配列をそのまま使用できます。( 但し、フォーマットとデータ型や列名やキーが一致している必要はあります ) type = 1 : insert を作成します。 type = 2 : update を作成します。 type = 3 : 条件部分のみ取得します。 get_sql.php( 関数とテストコード )
<?php
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );



// **************************************
// 列一覧配列の取得
// **************************************
$row = build_sql( 0, "syain" );
// 値のセット
$row["所属"] = 1;
$row["社員コード"] = "0001";
$row["氏名"] = "山田 太郎";
$row["更新日"] = "@NOW()";

print "<hr>";
// insert 取得
print build_sql( 1, "syain", $row, "社員マスタ" );

print "<hr>";
// update 取得
print build_sql( 2, "syain", $row, "社員マスタ" );


// **************************************
// 必要な列だけの処理
// **************************************
$row = array();
$row["所属"] = 1;
$row["社員コード"] = "0001";
$row["氏名"] = "山田 太郎";

print "<hr>";
// insert 取得
print build_sql( 1, "syain", $row, "社員マスタ" );

print "<hr>";
// update 取得
print build_sql( 2, "syain", $row, "社員マスタ" );


// **************************************
// 条件のみ
// **************************************
print "<hr>";
print build_sql( 3, "syain", $row );


// **************************************
// SQL更新文字列 ビルド関数
// **************************************
function build_sql( $type, $file_name, $row=null, $table_name="" ) {

	global $build_sql_error;

	// 更新列一覧情報の取得
	$format1 = @file_get_contents( "{$file_name}.json " );
	if ( $format1 === false ) {
		$build_sql_error = "{$file_name}.json not found.";
		return false;
	}

	$format2 = @file_get_contents( "{$file_name}_keys.json " );
	if ( $format2 === false ) {
		$build_sql_error = "{$file_name}_keys.json not found.";
		return false;
	}

	// insert sql 文字列作成
	if ( $type == 1 ) {
		if ( $row == null || !is_array( $row ) || count($row) == 0 ) {
			$row = build_sql( 0, $file_name );
		}

		$obj1 = json_decode($format1);
		$array1 = get_object_vars( $obj1 );
		$insert = "insert into @TABLE (@FIELDS) values(@VALUES)";

		$fields = "";
		foreach( $array1 as $k => $v ) {
			if ( array_key_exists($k,$row) ) {
				if ( $fields != "" ) {
					$fields .= ",";
				}
				$fields .= $k;
			}
		}
		$insert = str_replace("@FIELDS", $fields, $insert );

		$values = "";
		foreach( $array1 as $k => $v ) {

			if ( array_key_exists($k,$row) ) {
				if ( $values != "" ) {
					$values .= ",";
				}
				if ( $row[$k] == NULL ) {
						$values .= "null";
				}
				else {
					if ( $v == "num" ) {
						$values .= $row[$k];
					}
					else {
						if ( substr( $row[$k], 0, 1 ) == "@" ) {
							$values .= str_replace( "@", "", $row[$k] );
						}
						else {
							$values .= "'{$row[$k]}'";
						}
					}
				}
			}

		}
		$insert = str_replace("@VALUES", $values, $insert );
		$insert = str_replace("@TABLE", $table_name, $insert );
		return $insert;
	}

	// update sql 文字列作成
	if ( $type == 2 ) {
		if ( $row == null || !is_array( $row ) || count($row) == 0 ) {
			$row = build_sql( 0, $file_name );
		}

		$obj1 = json_decode($format1);
		$array1 = get_object_vars( $obj1 );
		$obj2 = json_decode($format2);
		$array2 = get_object_vars( $obj2 );

		$update = "update @TABLE set @SETS where @KEYS";
		$sets = "";
		foreach( $array1 as $k => $v ) {

			if ( array_key_exists($k,$row) ) {
				// キー項目以外の代入を作成します
				if ( !array_key_exists($k,$array2) ) {

					if ( $sets != "" ) {
						$sets .= ",";
					}

					if ( $row[$k] == NULL ) {
							$sets .= "{$k} = null";
					}
					else {
						if ( $v == "num" ) {
							$sets .= "{$k} = {$row[$k]}";
						}
						else {
							if ( substr( $row[$k], 0, 1 ) == "@" ) {
								$sets .= "{$k} = " . str_replace( "@", "", $row[$k] );
							}
							else {
								$sets .= "{$k} = '{$row[$k]}'";
							}
						}
					}

				}
			}

		}

		// where 以降の条件を作成します
		$update = str_replace("@SETS", $sets, $update );
		$keys = "";
		foreach( $array2 as $k => $v ) {

			if ( $keys != "" ) {
				$keys .= " and ";
			}
			if ( $v == "num" ) {
				$keys .= "{$k} = {$row[$k]}";
			}
			else {
				if ( substr( $row[$k], 0, 1 ) == "@" ) {
					$keys .= "{$k} = " . str_replace( "@", "", $row[$k] );
				}
				else {
					$keys .= "{$k} = '{$row[$k]}'";
				}
			}

		}

		$update = str_replace("@KEYS", $keys, $update );
		$update = str_replace("@TABLE", $table_name, $update );
		return $update;
	}

	// where 以降のみ作成
	if ( $type == 3 ) {
		if ( $row == null || !is_array( $row ) || count($row) == 0 ) {
			$row = build_sql( 0, $file_name );
		}

		$obj2 = json_decode($format2);
		$array2 = get_object_vars( $obj2 );

		$keys = "";
		foreach( $array2 as $k => $v ) {

			if ( $keys != "" ) {
				$keys .= " and ";
			}
			if ( $v == "num" ) {
				$keys .= "{$k} = {$row[$k]}";
			}
			else {
				if ( substr( $row[$k], 0, 1 ) == "@" ) {
					$keys .= "{$k} = " . str_replace( "@", "", $row[$k] );
				}
				else {
					$keys .= "{$k} = '{$row[$k]}'";
				}
			}

		}

		return $keys;
	}


	// 一覧より $row の作成
	if ( $type == 0 ) {
		$obj1 = json_decode($format1);
		$array1 = get_object_vars( $obj1 );
		$obj2 = json_decode($format2);
		$array2 = get_object_vars( $obj2 );
		foreach( $array1 as $k => $v ) {
			$array1[$k] = null;
			if ( array_key_exists($k,$array2) ) {
				$array1[$k] = "key";
			}
		}

		return $array1;
	}

}

?>


関連する記事

PHP : unset によるオブジェクトのプロパティの削除と配列の要素の削除の検証


タグ:PHP SQL JSON
posted by lightbox at 2015-07-02 18:31 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2014年05月27日


PHP : PDO のエラー処理

概要

PDO エラー処理には3通りあります。

(1) DO::ERRMODE_SILENT
最初はその名の通り、エラーが起きてもなにも起こりません。そのまま実行されますが、エラー情報は設定されていますし、戻り値も正しく返ります。一番簡単でバグさえなければ問題は発生しにくいですが、複雑な問題を確認する為には戻り値とメッセージを常に確認して正しいエラー処理を行う必要があります

(2) PDO::ERRMODE_WARNING
二つ目は、さらにPHPの通常のエラーメッセージを出力させるようにしたバージョンです。初期段階のデバッグに有効です

(3) PDO::ERRMODE_EXCEPTION
三つ目は、try 〜 catch を使うようにしたものですが、慣れていないと扱いは少し難しくなります。しかし、例外によりスクリプトが終了した際には、トランザクションは自動的に ロールバックされるそうです。

前者でどうなるかは未確認ですが、業務アプリケーションならばこちらを選択したほうが良いでしょう。個人の一般の WEB アプリならばそこまで神経質になる必要は無いと思いますので、デフォルトの ERRMODE_SILENT で良いと思います
<?php
$strDriver = "{SQL Native Client}";
$strTarget = "NIGHT_TCP";	// 別名
$strDB = "lightbox";
$strUser = "sa";
$strPass = "passwordpassword";

// **********************************************************
// 接続
// **********************************************************
$Cn = new PDO(
	"odbc:Driver=$strDriver;Server=$strTarget;" .
	"Database=$strDB;Uid=$strUser;Pwd=$strPass;");

	// デフォルトエラーモード
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	$ret = $Cn->exec( $Query );
	if ($ret===false) {
		print_r( $Cn->errorInfo() );
	}


	// エラー表示( デバッグに有効 )
	// 抑制する場合は、@$Cn->exec( $Query );
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	$ret = $Cn->exec( $Query );
	if ($ret===false) {
		print_r( $Cn->errorInfo() );
	}

	// try catch 用
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	try {
		$ret = $Cn->exec( $Query );
	}
	catch( PDOException $e ) {
		print $e->getMessage();
	}

$Cn = null;

?>



タグ:PDO PHP
posted by lightbox at 2014-05-27 17:25 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2014年04月01日


PHP : 5.3(以上) / 5.2.11 で sqlite3 作成

概要

PHP 5.3 から、SQLite3 クラスが使用できます。それ以前では、PDO で、SQLLite3 を扱う事ができます。

▼ PHP Version 5.2.17


SQLite3 の空ファイルは、接続しただけでは作成されず、ダミーでテーブルを作成して削除した後に VACUUM を実行しています。

▼ dl 関数を使うのは今時では無いので、php.ini できちんと指定します。( extension=php_mysql.dll と extension=php_pdo_sqlite.dll )
あと、きちんと検証していませんが、dl 関数の扱いが厳密になっているようで、マルチスレッド Web サーバ上では サポートされないそうです。※ Call to undefined function dl() となってしまいました / cli では機能するので、条件を加えています

▼ 実際は 1024 バイトになりますが、残りは 0x00 です。
          0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
--------------------------------------------------------------------------
00000000 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00  SQLite format 3.
00000010 04 00 01 01 00 40 20 20 00 00 00 03 00 00 00 01  .....@  ........
00000020 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00  ................
00000030 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00  ................
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03  ................
00000060 00 2D E2 1F 0D 00 00 00 00 04 00 00 00 00 00 00  .-・............
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
※ 最初の16バイトは、仕様としては固定です
<?
// **********************************************************
// PHP 5.3 / 5.2.11 用 sqlite3 作成
// **********************************************************

if ( PHP_SAPI == 'cgi' ) {
	$strDB1 = realpath("./newdb.sqlite3" );
	$strDB2 = realpath("./newdb.sqlite3_pdo" );
}
else {
	$strDB1 = getcwd()."/newdb.sqlite3";
	$strDB2 = getcwd()."/newdb.sqlite3_pdo";
}

// **********************************************************
// 処理
// www.php.net/manual/ja/sqlite3.construct.php
// www.php.net/manual/ja/ref.pdo-sqlite.connection.php( PDO )
// **********************************************************

$Cn = new SQLite3( $strDB1, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE );
$Cn->exec('CREATE TABLE bar (bar STRING)');
$Cn->exec('DROP TABLE bar');
$Cn->exec('VACUUM');
$Cn->close();

$Cn = new PDO( "sqlite:{$strDB2}" );
$Cn->exec('CREATE TABLE bar (bar STRING)');
$Cn->exec('DROP TABLE bar');
$Cn->exec('VACUUM');
$Cn = null;	// close


?>
処理が終了しました

関連するリンク

Query Language Understood by SQLite
Datatypes In SQLite Version 3

関連する記事

タグ:PHP sqlite3
posted by lightbox at 2014-04-01 15:56 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2013年09月27日


PHP で、ODBC 関数を使って結果を JSON 文字列に変換する

SkyDrive へ移動


db.php は、簡単なクラスで、一般的な利用が可能ですが、さらに JSON 用にメソッドを用意して json_encode でうまく使えるようにデータを返しています。

db.php(クラス)
<?php
# **********************************************************
# データベースクラス
# **********************************************************
class DB {
 
	public $connect;
	public $result;
 
# **********************************************************
# コンストラクタ
# **********************************************************
	function DB( $connect ) {

		$this->connect = odbc_connect($connect, "", "");

	}
 
# **********************************************************
# 接続解除
# **********************************************************
	function close( ) {
		odbc_close( $this->connect );
	}
 
# **********************************************************
# クエリー
# **********************************************************
	function query( $sql_query ) {

		$ret = odbc_exec( $this->connect, $sql_query );
		return $ret;
	}
 
# **********************************************************
# フェッチ
# **********************************************************
	function fetch( $result ) {

		$ret = odbc_fetch_array( $result );
		$ret2 = $ret;
		$cnt = 0;
		while (list($_key, $_value) = @each($ret)) {
			$ret2[$cnt] = $_value;
			$cnt++;
		}
		return $ret2;
	}
 
# **********************************************************
# クエリーとフェッチ
# **********************************************************
	function query_ex( $sql_query='' ) {
 
		if ( $sql_query != '' ) {
			$this->result = $this->query( $sql_query );
			if ( !$this->result ) {
				return false;
			}
			return $this->fetch( $this->result );
		}
		else {
			return $this->fetch( $this->result );
		}
 
	}

# **********************************************************
# フェッチ
# **********************************************************
	function fetch_json( $result ) {

		$ret = odbc_fetch_array( $result );
		$ret2 = array();
		$cnt = 0;
		while (list($_key, $_value) = @each($ret)) {
			if (preg_match("/[^0-9a-zA-Z_\-]+/", $_key)) {
				$_key = "item_" . ($cnt+1);
			}
			$ret2[$_key] = mb_convert_encoding( $_value, "UTF-8", "SHIFT_JIS" );
			$cnt++;
		}
		return $ret2;
	}

# **********************************************************
# クエリーとフェッチ
# **********************************************************
	function query_ex_json( $sql_query='' ) {
 
		if ( $sql_query != '' ) {
			$this->result = $this->query( $sql_query );
			if ( !$this->result ) {
				return false;
			}
			return $this->fetch_json( $this->result );
		}
		else {
			return $this->fetch_json( $this->result );
		}
 
	}

# **********************************************************
# 実行
# **********************************************************
	function Execute( $sql_exec ) {
		$ret = odbc_exec( $this->connect, $sql_exec );
		return $ret;
	}
 
 
}
?>


以下は、mdb を使ってデータを JSON として出力しています。mdb は SHIFT_JIS なので、このソースコードは SHIFT_JIS で書かれています。出力時には、日本語は使われませんが、UTF-8 で出力しています。
mdb2json.php
<?php
header( "Content-Type: text/plain; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

require_once("db.php");

mb_language( "ja" );
mb_internal_encoding("UTF-8");

$connect_string = "Provider=MSDASQL;";
$connect_string .= "Driver={Microsoft Access Driver (*.mdb)};";
$dbpath = realpath("販売管理B.mdb");
$connect_string .= "dbq={$dbpath};";

$db = new DB( $connect_string );

$query = "select [社員マスタ].*,[社員マスタ].[社員コード] as scode from [社員マスタ]";

$json = array();

$column = $db->query_ex_json( $query );

$cnt = 0;
$max = 20;
while ( $column ) {

	$json['items'][] = $column;

	$cnt++;
	if ( $cnt >= $max ) {
		break;
	}

	$column = $db->query_ex_json( );
};

$db->close();

print json_encode($json);

?>




posted by lightbox at 2013-09-27 21:37 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2013年08月31日


PHP に GET で SQL の select 構文(UTF8 で urlencode)を与えて JSON 文字列を返す簡単な処理

eval を使って、動的に配列を作成する文字列を作って(データを埋め込む)、さらに eval で実際の配列を作成してから json_encode します。

データベースは、Windows の MySQL で、PHP も Windows なので、PDO の ODBC を使って処理しています。ですから、MySQL は utf-8 ですが、クライアントアプリは SHIFT_JIS を前提に環境作成しているので、ちょっと変則な文字列変換が行われています。

ただ、そこは本筋とは関係無いので差し替えて考えて下さい。

json_encode が、utf-8 前提なので、『?q=select構文』の日本語部分は utf-8 で urlencode が前提です。

テーブルの列名が日本語の場合は、自動的に item_連番 という形式に列名を変更して JSON に渡します。もし、意図的にその文字列を定義したい場合は、select 構文の列名に英数字(_と-は可)別名を与えて下さい。
<?php
header( "Content-Type: application/json; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

mb_language( "ja" );
mb_internal_encoding("utf-8");

// *********************************************************
// extension=php_pdo_odbc.dll ( php.ini )
// *********************************************************
$conf = array(
	"dns_driver" => "{MySQL ODBC 5.2w Driver}",
	"dns_server" => "localhost",
	"dns_db" => "lightbox",
	"dns_user" => "root",
	"dns_pass" => "パスワード",
	"dns_charset" => "cp932"
);

// **********************************************************
// 接続
// **********************************************************
try {
	$cn1 = new PDO(
		"odbc:Driver={$conf['dns_driver']};Server={$conf['dns_server']};" .
		"Database={$conf['dns_db']};Uid={$conf['dns_user']};Pwd={$conf['dns_pass']};".
		"charset={$conf['dns_charset']}");
}
catch ( Exception $ex ) {
	print '{"error": "接続できませんでした: ' . $ex->getMessage() . '"}';
	exit();
}

//print "<pre>";
//print "接続されました\n";
//print_r($conf);

//print_r($cn1);

// **********************************************************
// SQL
// **********************************************************
$query = mb_convert_encoding( $_GET["q"], "sjis", "utf8" );

// **********************************************************
// 結果セット
// **********************************************************
$rs = $cn1->query( $query );
if ( $rs === false ) {
	$er = $cn1->errorInfo();
	print '{ "error" : "' . $er[2] . '" }';
	exit();
}

// フィールド数
$field_cnt = $rs->columnCount();
// 文字列バッファ
$buffer = "";
$update_cnt = 0;
while( $result = $rs->fetch(PDO::FETCH_ASSOC) ) {
	// ループの最初で列名一覧を作成する
	if ( $buffer == "" ) {
		// 配列に列名を取得
		$field_names = array_keys($result);
		$entry = build_field( $field_names );
		for( $i = 0; $i < $field_cnt; $i++ ) {
			if ( $buffer != "" ) {
				$buffer .= ",";
			}
			$buffer .= $field_names[$i];
		}
	}

	// ***************************************************************
	// 最終 eval に埋め込む為の変数セット( フィールド個々の内容 )
	// $myfield(n) という変数に実際の値をセットしておいて、
	// $myfield(n) という変数を最終文字列に埋め込んで eval する
	// ***************************************************************
	for( $i = 0; $i < $field_cnt; $i++ ) {
		$wk = "$" . "myfield" . ($i+1) . ' = "' . mb_convert_encoding( $result[$field_names[$i]], "utf8", "sjis" ) . '";';
		eval($wk);
	}

	// JSON 文字列に変換する為の配列を作成する文字列
	$x = '$my_json["items"][] = array( ' . $entry  .  ');';
	// eval で $my_json["items"] を作成
	eval($x);
}

// JSON 文字列化
$my_json_string =json_encode($my_json);
print $my_json_string;


// *********************************************************
// フィールド文字列( 連想配列部分作成 )
// 列名が日本語の場合は、item_(n) に変更する
// 指定したい場合は select の 列名記述を as で作成する
// *********************************************************
function build_field( $fields ) {

	$buffer = "";

	$field_cnt = count( $fields );

	for( $i = 0; $i < $field_cnt; $i++ ) {
		if (preg_match("/[^0-9a-zA-Z_\-]+/", $fields[$i])) {
			$field_name = "item_" . ($i+1);
		}
		else {
			$field_name = $fields[$i];
		}
		if ( $buffer != "" ) {
			$buffer .= ",";
		}
		$buffer .= '"' . $field_name . '" => "' . "$" . "myfield" . ($i+1) .  '"';
	}

	return $buffer;

}
?>

関連する記事

PHP : PDO : SQLExpress(SQLServer)の読み込みと同時更新
VB.net 2008 : System.Data.Odbc 接続テスト( MySQL 5.1 )


▼ 『?q=select+%2A+from+%E7%A4%BE%E5%93%A1%E3%83%9E%E3%82%B9%E3%82%BF
+limit+4』で出力したもの 
{"items":[{"item_1":"0001","item_2":"\u6d66\u5ca1 \u53cb\u4e5f","item_3":"\u30a6\u30e9\u30aa\u30ab \u30c8\u30e2\u30e4","item_4":"0003","item_5":"0","item_6":"2013-05-04 00:00:00","item_7":"2013-07-20 00:00:00","item_8":"270000","item_9":"9000","item_10":""},{"item_1":"0002","item_2":"\u5c71\u6751 \u6d0b\u4ee3","item_3":"\u30e4\u30de\u30e0\u30e9 \u30d2\u30ed\u30e8","item_4":"0003","item_5":"1","item_6":"2013-02-06 00:00:00","item_7":"2013-05-10 00:00:00","item_8":"300000","item_9":"","item_10":""},{"item_1":"0003","item_2":"\u591a\u5ca1 \u51ac\u884c","item_3":"\u30bf\u30aa\u30ab \u30d5\u30e6\u30e6\u30ad","item_4":"0002","item_5":"0","item_6":"2013-04-05 00:00:00","item_7":"2013-07-06 00:00:00","item_8":"250000","item_9":"","item_10":""},{"item_1":"0004","item_2":"\u9ad8\u7530 \u51ac\u7f8e","item_3":"\u30bf\u30ab\u30bf \u30d5\u30e6\u30df","item_4":"0003","item_5":"1","item_6":"2013-02-02 00:00:00","item_7":"2013-05-27 00:00:00","item_8":"250000","item_9":"","item_10":""}]}

▼ 以下は整形したもの
{
    "items": [
        {
            "item_1": "0001",
            "item_2": "浦岡 友也",
            "item_3": "ウラオカ トモヤ",
            "item_4": "0003",
            "item_5": "0",
            "item_6": "2013-05-04 00:00:00",
            "item_7": "2013-07-20 00:00:00",
            "item_8": "270000",
            "item_9": "9000",
            "item_10": ""
        },
        {
            "item_1": "0002",
            "item_2": "山村 洋代",
            "item_3": "ヤマムラ ヒロヨ",
            "item_4": "0003",
            "item_5": "1",
            "item_6": "2013-02-06 00:00:00",
            "item_7": "2013-05-10 00:00:00",
            "item_8": "300000",
            "item_9": "",
            "item_10": ""
        },
        {
            "item_1": "0003",
            "item_2": "多岡 冬行",
            "item_3": "タオカ フユユキ",
            "item_4": "0002",
            "item_5": "0",
            "item_6": "2013-04-05 00:00:00",
            "item_7": "2013-07-06 00:00:00",
            "item_8": "250000",
            "item_9": "",
            "item_10": ""
        },
        {
            "item_1": "0004",
            "item_2": "高田 冬美",
            "item_3": "タカタ フユミ",
            "item_4": "0003",
            "item_5": "1",
            "item_6": "2013-02-02 00:00:00",
            "item_7": "2013-05-27 00:00:00",
            "item_8": "250000",
            "item_9": "",
            "item_10": ""
        }
    ]
}



posted by lightbox at 2013-08-31 22:55 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2012年12月03日


PHP で mdb(古い形式) の(架空の)ユーザデータを取得する ODBC クラス

通常の DB アクセスはそのまま Windows のあらゆる ODBC で可能ですが、JSON のデータを作成する為に機能を少し追加してあります。

print_r 関数は、そのままでもすでに整形されているので、str_replace で JSON に改造しました。日本語部分を unicode 表現には変換していませんが、このほうがテストには向いていると思います。

この為に mdb のデータは作成しました。ランダムに存在しないような名前を合成しています。

SkyDrive へ移動


<?
# **********************************************************
# データベースクラス
# **********************************************************
class DB {
 
	var $connect;
	var $result;
	var $json;
 
# **********************************************************
# コンストラクタ
# **********************************************************
	function DB( $server='127.0.0.1', $db_name='lightbox', $user='', $password='' ) {

		$this->connect = odbc_connect($db_name, $user, $password);
		$this->json = false;
	}
 
# **********************************************************
# 接続解除
# **********************************************************
	function close( ) {
		odbc_close( $this->connect );
	}
 
# **********************************************************
# クエリー
# **********************************************************
	function query( $sql_query ) {

		$ret = odbc_exec( $this->connect, $sql_query );
		return $ret;
	}
 
# **********************************************************
# フェッチ
# **********************************************************
	function fetch( $result ) {

		$ret = odbc_fetch_array( $result );
		$ret2 = $ret;
		$cnt = 0;
		while (list($_key, $_value) = @each($ret)) {
			$ret2[$cnt] = $_value;
			$cnt++;
		}
		return $ret2;
	}
 
# **********************************************************
# クエリーとフェッチ
# **********************************************************
	function query_ex( $sql_query='' ) {
 
		if ( $this->json ) {
			if ( $sql_query != '' ) {
				$sql_query = mb_convert_encoding( $sql_query, "shift_jis", "UTF-8" );
				$this->result = $this->query( $sql_query );
				if ( !$this->result ) {
					return false;
				}
			}
			$ret = odbc_fetch_array( $this->result );
			while (list($_key, $_value) = @each($ret)) {
				$ret[$_key] = mb_convert_encoding( $ret[$_key], "UTF-8", "shift_jis" );
			}

			$ret = print_r($ret,true);

			$ret = str_replace( "Array\n(\n", "{", $ret );
			$ret = str_replace( ")\n", "}", $ret );
			$ret = str_replace( "    [", "    \"", $ret );
			$ret = str_replace( "] => ", "\" : \"", $ret );
			$ret = str_replace( "\n    \"", "\",\n    \"", $ret );
			$ret = str_replace( "\n}", "\"\n}", $ret );
			$ret = str_replace( "{    ", "{\n    ", $ret );

			return $ret;
		}
		else {
			if ( $sql_query != '' ) {
				$this->result = $this->query( $sql_query );
				if ( !$this->result ) {
					return false;
				}
				return $this->fetch( $this->result );
			}
			else {
				return $this->fetch( $this->result );
			}
		}
 
	}
 
# **********************************************************
# 実行
# **********************************************************
	function Execute( $sql_exec ) {
		$ret = odbc_exec( $this->connect, $sql_exec );
		return $ret;
	}
 
 
}
?>
以下は実際のテスト出力ですが、全体の出力はこちらから参照して下さい。
<?
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

require_once("db.php");

$db_path = "C:\\httpd142p\\lightbox\\work\\api\\api.mdb";

$connect_string = "Provider=MSDASQL;";
$connect_string .= "Driver={Microsoft Access Driver (*.mdb)};";
$connect_string .= "dbq={$db_path}";

$db = new DB( "", $connect_string );
$db->json = true;

$query = "select * from [user_data] order by [id]";

$column = $db->query_ex( $query );

print "<pre>";
print "{ \"items\" : [\n";
$flg = false;
while ( $column ) {

	if ( !$flg ) {
		$flg = true;
	}
	else {
		print ",\n";
	}
	print( $column );
	$column = $db->query_ex( );
};
print "\n]\n}";
print "</pre>";

$db->close();

?>


以下は5件のみ表示しています
{
    "items": [
        {
            "id": "0001",
            "user_name": "浦岡 孫准",
            "name_f": "ウラオカ ソンジュン",
            "class_code": "0003",
            "h_type": "0",
            "create_date": "2012-12-02 00:00:00",
            "update_date": "2013-02-17 00:00:00"
        },
        {
            "id": "0002",
            "user_name": "蘭村 瑠璃",
            "name_f": "ランムラ ルリ",
            "class_code": "0003",
            "h_type": "1",
            "create_date": "2012-09-06 00:00:00",
            "update_date": "2012-12-08 00:00:00"
        },
        {
            "id": "0003",
            "user_name": "多岡 愛葛",
            "name_f": "タオカ アイカツ",
            "class_code": "0002",
            "h_type": "0",
            "create_date": "2012-11-03 00:00:00",
            "update_date": "2013-02-03 00:00:00"
        },
        {
            "id": "0004",
            "user_name": "高田 愛魅",
            "name_f": "タカタ アイミ",
            "class_code": "0003",
            "h_type": "1",
            "create_date": "2012-09-02 00:00:00",
            "update_date": "2012-12-25 00:00:00"
        },
        {
            "id": "0005",
            "user_name": "内高 孫之",
            "name_f": "ウチタカ ソンユキ",
            "class_code": "0003",
            "h_type": "0",
            "create_date": "2012-12-02 00:00:00",
            "update_date": "2013-01-30 00:00:00"
        }
    ]
}
関連する記事

ログイン画面からリダイレクトしてアクセストークンを取得するまでの簡単な PHP コード

※ JSON のチェックおよび最終整形にはこちらを使っています

タグ:PHP MDB ODBC
posted by lightbox at 2012-12-03 18:50 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2011年09月18日


PHP + ADO + Oracle : ADO の オブジェクトを使った更新

あまり一般的ではありませんが、Windows 環境で簡単に Oracle にアクセスするには
COM 経由で ADO を使うのが最も有効です。特に更新では、INSERT 文や UPDATE 文を
作成する必要があります。

※ 以下は、10g の Express で実行している為、列名を使ったアクセスはできていません
※ 11g では最後の AddNew から Update の間で原因不明なエラーが出ます。

結局 Field オブジェクトを使った操作は、PHP からは少し無理があるようです。
( Execute を使った更新は以前よりずっと問題は出ていません )
<?
header( "Content-Type: text/html; Charset=shift_jis" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

$Cn = new COM( "ADODB.Connection" );
$Cn->CursorLocation = 3;
$Rs = new COM( "ADODB.Recordset" );
$Rs->LockType = 3;	// オブジェクトを使った更新に必要

$ConnectionString = "Provider=MSDASQL;";	// ODBC ドライバ用
$ConnectionString .= "Driver={Microsoft ODBC for Oracle};";
$ConnectionString .= "SERVER=LIGHT/XE;";
$ConnectionString .= "UID=LIGHTBOX;";
$ConnectionString .= "PWD=LIGHTBOX;";

print $ConnectionString . "\n<br />";

// 接続
$Cn->Open( $ConnectionString );

$Query = "select * from 社員マスタ";

// Query の実行
$Rs->Open( $Query, $Cn );

// 列数
$rec_cnt = $Rs->Fields->Count;
// 列名一覧
for( $i = 0; $i < $rec_cnt; $i++ ) {
	print $Rs->Fields($i)->Name . "\n<br>";
}

// データの扱い
while( !$Rs->EOF ) {

	// 内容の読み出し
	for( $i = 0; $i < $rec_cnt; $i++ ) {
		print $Rs->Fields($i)->Value . " ";
	}

	// オブジェクトを使った更新
	$Rs->Fields(7)->Value += 1;
	$Rs->Update();

	print "\n<br>";

	// SQL を使った更新
	$Query = "update 社員マスタ set";
	$Query .= " 更新日 = TO_DATE('2011/09/18 00:00:00','RRRR/MM/DD HH24:MI:SS')";
	$Query .= " where 社員コード = '{$Rs->Fields(0)->Value}'";
	$Cn->Execute($Query);

	$Rs->MoveNext();
}

// 新規行の作成
$Rs->AddNew();
$Rs->Fields(0)->Value = "9001";
$Rs->Fields(1)->Value = "社員名";
$Rs->Fields(2)->Value = "フリガナ";
$Rs->Fields(5)->Value = "2011/09/18 00:00:00";
$Rs->Fields(6)->Value = NULL;
$Rs->Fields(7)->Value = 1000;
$Rs->Update();

$Cn->Close();

?>

Oracle ユーザ作成 SQL サンプル


posted by lightbox at 2011-09-18 22:55 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2010年12月24日


PHP : MySQLリモートカウンタ

使い方はいろいろですが、ローカルの PC から HTTP で呼び出して使う
事もできますし、別のサイトから呼びだして使ってもいいわけです。

※ Ruby でデータベース処理書くのが面倒なのでこうして使っています。
FieldTypeNullKeyDefaultExtra
1ページvarchar(25)PRI
2カウンタint(11)YES0
3備考varchar(100)YES
<?
// *********************************************************
// データベース接続情報
// *********************************************************
$server = 'xxxxxxxx';
$db_name = 'xxxxxxxx';
$user = 'xxxxxxxx';
$password = 'xxxxxxxx';

// *********************************************************
// ヘッダ
// *********************************************************
header( "Content-Type: text/html; Charset=euc-jp" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// *********************************************************
// 内部初期処理
// *********************************************************
foreach( $_GET as $Key => $Value ) {
	$_POST[$Key] = $_GET[$Key];
}
foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = str_replace("\\\\", "\\", $Value );
	$_POST[$Key] = str_replace("\\'", "'", $_POST[$Key] );
	$_POST[$Key] = str_replace("\\\"", "\"", $_POST[$Key] );
}
mb_language( "ja" );
mb_internal_encoding("EUC-JP");


// *********************************************************
// 接続
// *********************************************************
$connect = @mysql_connect( $server, $user, $password );
if ( !$connect ) {
	print "接続エラーです";
	exit();
}

// *********************************************************
// DB選択
// *********************************************************
mysql_select_db( $db_name, $connect );

// *********************************************************
// クエリ( カウントアップ )
// *********************************************************
$query = "update `カウンタ表示` set `カウンタ` = `カウンタ` + 1";
$query .= " where ページ = '_cron'";
mysql_query($query, $connect);

// *********************************************************
// クエリ( カウント取得 )
// *********************************************************
$query = "select `カウンタ` from `カウンタ表示`";
$query .= " where ページ = '_cron'";
$result = mysql_query($query, $connect);
$row = mysql_fetch_row($result);

// *********************************************************
// 現在のカウンタ
// *********************************************************
print $row[0];

// *********************************************************
// カウンタのリセット( 1001 を 0 )
// *********************************************************
if ( ($row[0]+0) > 1000 ) {
	$query = "update `カウンタ表示` set `カウンタ` = 0";
	$query .= " where ページ = '_cron'";
	mysql_query($query, $connect);
}

// *********************************************************
// メモリを開放ですが、通常は必要ありません
// *********************************************************
mysql_free_result($result);

// *********************************************************
// 接続解除
// *********************************************************
mysql_close($connect);

?>



posted by lightbox at 2010-12-24 23:35 | PHP + データベース | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します


Windows
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり