SQLの窓

2018年09月01日


各RDBMS の正規表現の実装状況 : MySQL, SQLServer, PostgreSQL, Oracle

今日この日まで、SQL の条件に『正規表現』を使うという発想が無かったのですが(たいていそんな複雑な事はしないし解りにくい)、最近は日本人以外のカタカナ氏名の検索をする事が多くなった事を起因とする要望から、『どうなんだろう』と思って調べた結果です。( 外国人のカタカナ表記では微妙にゆらぎがあるのです )

※ 結果的にウチは、SQLServer なので、or で文字列作っていくよりは楽になりそうです。

SQLServer

検索条件のパターン照合

LIKE で使用される % や _ 以外に、LIKE 対象の文字列に [] と [^] が使用できます。これだけでも文字列作成が格段に楽です。

ただ、他の RDBMS と比べると『正規表現』としては一番未熟です。


MySQL

3.3.4.7 パターンマッチング

12.5.2 正規表現

LIKE では無く REGEXP を使用して、『select * from 社員マスタ where フリガナ REGEXP '.+オ.+'』みたいな書き方ができます。正規表現として使える演算子はそれほど多くはありませんが、逆に単純で使いやすいとは思います。

PostgreSQL

9.7.3. POSIX正規表現

正規表現をそのまま使える記法のようで、~( チルダ ) を使用して、where の中で検索できるようです。

例) select * from テーブル名 where 列名 ~ '[a-zA-Z]'

Oracle

REGEXP_LIKE

どうやら関数のようなものらしく、where の中で利用すると正規表現に一致する行が戻されるようです。
( 第三引数で、関数のパターン一致オプション )







【SQLExpressの最新記事】
posted by lightbox at 2018-09-01 01:31 | SQLExpress | このブログの読者になる | 更新情報をチェックする

2018年08月30日


PHP : 一定時間前のファイルの削除

めったに使わないので忘れがちですが、必要になった時に覚えていない。「あのコードどこに使ったっけ・・・」というコードです。

PATH_SEPARATOR は、検索パスのセパレータで、DIRECTORY_SEPARATOR は、ファイルにアクセスする為のパス内のセパレータです

デモページ
$basedir = realpath("../basic-php");

// ターゲットディレクトリの一覧
$dir_handle = @opendir($basedir);
if ( $dir_handle ) {
	$target = readdir( $dir_handle );
	while( $target !== false ) {
		print $target . "\n";
		$target = readdir( $dir_handle );
	}

	closedir( $dir_handle );
}

print "\n\n";

// 5分以上前に作成されたファイルを削除
$dir_handle = @opendir($basedir);
if ( $dir_handle ) {
	$target = readdir( $dir_handle );
	while( $target !== false ) {
		if ( $target == '.' || $target == '..' ) {
			// 対象外
			$target = readdir( $dir_handle );
			continue;
		}

		$astamp = stat($basedir.DIRECTORY_SEPARATOR.$target);
		$laststamp = $astamp[9];

		$lasttime = (int)((time() - $laststamp) / 60) . "." . ((time() - $laststamp) % 60);

		print "{$target} : {$lasttime}\n";

		// 一番最後の . 以降の文字列
		$ext = strrchr( $target, "." );
		// 全て小文字に変換
		$ext = strtolower($ext);
		// 目的の拡張子 のみ削除
		if ( $ext == ".data" ) {
			if ( $laststamp <= time() - 300 ) {
				@unlink($basedir.DIRECTORY_SEPARATOR.$target);
			}
		}
		$target = readdir( $dir_handle );
	}

	closedir( $dir_handle );
}





タグ:PHP
posted by lightbox at 2018-08-30 15:12 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

GD で画像縮小。『1) 単純縮小、2) 幅にあわす 3) 高さにあわす 4) 任意の幅と高さ』をその他の処理も含めてクラスでまとめ( class GD )

読み出す画像は、短縮 URL で動作確認しています。使用目的としては、画像をアップロードして縮小して保存する事ですが、保存前に必要ならば GD を使って修正をする事も想定しています。

デモページ
<?php
# 新しいオブジェクト
$GD = new GD();

# WEB よりイメージを作成
# 短縮url で動作します
$GD->LoadJpeg( "https://bit.ly/2MCYPI0" );

# 赤のパレットを作成
$red = $GD->CreateColor( 255, 0, 0 );

# 線の太さを設定
$GD->SetLineWidth( 3 );

# パラメータの処理
if ( ctype_digit( $_GET['x'] ) ) {
	$x = $_GET['x'];
}
else {
	$x = 135;
}
if ( ctype_digit( $_GET['y'] ) ) {
	$y = $_GET['y'];
}
else {
	$y = 118;
}

# 楕円を描画
$GD->Arc( $x, $y, 60, 35, $red );

# 黒のパレットを作成
$black = $GD->CreateColor( 0, 0, 0 );

# 白のパレットを作成
$white = $GD->CreateColor( 255, 255, 255 );

# 点線のスタイルを作成
$style = array(
	$black,$black,$black,$black,$black,
	$white,$white,$white,$white,$white
);

# 線の太さを設定
$GD->SetLineWidth( 1 );

# スタイルを使用して斜め線を描画
$GD->Line( 20, 30, 200, 100, $style );

# 指定の大きさで新しいオブジェクトを作成
//@$GD->Copy( $GD2, 0.3 );
//@$GD->CopyW( $GD2, 100 );
//@$GD->CopyH( $GD2, 200 );
@$GD->CopyWH( $GD2, 600, 400 );

# 縮小画像をファイルとして保存
$GD2->SaveJpeg( "uf3_001.jpg" );

# ブラウザに表示
$GD2->Response( );

# 後処理
$GD->DestroyColor( $red );
$GD->Destroy( );
$GD2->Destroy( );


# ***********************
# クラス
# ***********************
class GD {

	var $im;
	var $type;

# ***********************
# コンストラクタ
# ***********************
	function GD( ) {
	}

# ***********************
# キャンバス作成
# ***********************
	function CreateCanvas( $Width, $Height, $Type="PNG" ) {
		$this->type = $Type;
		$this->im = imagecreatetruecolor($Width, $Height);
	}

# ***********************
# PNG ロード
# ***********************
	function LoadPng( $Target ) {
		$this->type = "PNG";
		$this->im = @ImageCreateFromPng($Target);
	}
 
# ***********************
# JPEG ロード
# ***********************
	function LoadJpeg( $Target ) {
		$this->type = "JPEG";
		$this->im = @ImageCreateFromJpeg($Target);
	}

# ***********************
# 色リソース作成
# ***********************
	function CreateColor( $Red, $Green, $Blue ) {
		$ret = ImageColorAllocate (
			$this->im,
			$Red, $Green, $Blue );
		return $ret;
	}

# ***********************
# 線幅設定
# ***********************
	function SetLineWidth( $Width ) {
		ImageSetThickness( $this->im, $Width );
	}

# ***********************
# 直線の描画
# ***********************
	function Line( $x1, $y1, $x2, $y2, $Option ) {
		if ( is_array( $Option ) ) {
			ImageSetStyle( $this->im, $Option );
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED );
		}
		else {
			ImageLine(
				$this->im, $x1, $y1, $x2, $y2, $Option );
		}
	}

# ***********************
# 矩形の描画
# ***********************
	function Box( $x, $y, $w, $h, $Color, $fill=FALSE ) {
		if ( $fill ) {
			imageFilledRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
		else {
			ImageRectAngle(
				$this->im, $x, $y, $x+$w, $y+$h, $Color );
		}
	}

# ***********************
# 楕円の描画
# ***********************
	function Arc( $x, $y, $w, $h, $Color ) {
		ImageArc( $this->im, $x, $y, $w, $h, 0, 359, $Color );
	}

# ***********************
# ブラウザへ出力
# ***********************
	function Response( ) {
		switch( $this->type ) {
			case "PNG":
				header('Content-Type: image/png');
				ImagePng( $this->im );
				break;
			case "JPEG":
				header('Content-Type: image/jpeg');
				ImageJpeg( $this->im );
				break;
		}
	}

# ***********************
# PNG 保存
# ***********************
	function SavePng( $FilePath ) {
		ImagePng( $this->im, $FilePath );
	}

# ***********************
# JPEG 保存
# ***********************
	function SaveJpeg( $FilePath, $Quality=75 ) {
		ImageJpeg( $this->im, $FilePath, $Quality );
	}

# ***********************
# 色リソース開放
# ***********************
	function DestroyColor( $Color ) {
		ImageColorDeallocate( $this->im, $Color );
	}

# ***********************
# イメージの破棄
# ***********************
	function Destroy( ) {
		ImageDestroy ( $this->im );
	}

# ***********************
# 伸縮された新しいイメージの作成
# ***********************
	function Copy( &$New, $rate ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyW( &$New, $w_new ) {
		$w = ImageSx( $this->im );
		$rate = $w_new / $w;
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h * $rate );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyH( &$New, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$rate = $h_new / $h;
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w * $rate, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}

	function CopyWH( &$New, $w_new, $h_new ) {
		$w = ImageSx( $this->im );
		$h = ImageSy( $this->im );
		$New = new GD();
		$New->im = ImageCreateTrueColor( $w_new, $h_new );
		$w2 = ImageSx( $New->im );
		$h2 = ImageSy( $New->im );
		ImageCopyResampled(
			$New->im,
			$this->im,
			0,0,0,0,
			$w2, $h2,
			$w, $h
		);
		$New->type = $this->type;
	}
}




タグ:gd PHP
posted by lightbox at 2018-08-30 12:05 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

PHP : 指定ファイル名でダウンロード 『application/octet-stream』 と 『Content-disposition: attachment』

application/octet-stream を使う事によって、通常はブラウザに表示されてしまうようなファイルをダウンロードさせる事ができます。

また、保存時のファイル名を正しくする為に Content-disposition を使用しています。

PHP のオンラインマニュアル にはそのものズバリのサンプルが readfile のページにあります。

例1 readfile() によるダウンロードの強制
<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>
リンク先のマニュアルでも説明されていますが、readfile はそもそもこのような目的で使われる事を想定しているようで、『メモリに関する問題はなく、 巨大なファイルを送ってもかまいません。』とあります。特殊な目的で出力する為に内容に加工を加えるような場合は、後述のような内容で読み込めばいいはずです。

但し、キャッシュ制御が有効の場合は際限なく読み込んでしまって out of memory エラーが出る場合があるので、ob_end_clean であらかじめキャンセルしておくといいと思います。

システム書き込みバッファの内容を出力したい場合、キャッシュ制御が有効の場合は flash と ob_flush の両方が必要です

ファイルサイズは無くてもダウンロード可能ですが、ただ、存在しないとクライアント側で何パーセント処理済みかの表示が不可能になります。

fread を使用して読み込む
<?
header( "Content-Type: application/octet-stream" );
header( "Content-disposition: attachment; filename={$_GET['download_target']}" );

$path = '../download/' . $_GET['download_target'];

$size = filesize( $path );

header( "Content-Length: $size" );

$fp = fopen( $path, 'rb' );

if ( $fp ) {

	while( TRUE ) {
		if ( feof( $fp ) ) {
			break;
		}
		$ret = fread( $fp, 1024 );
		print $ret;
	}

	fclose( $fp );
}

?>


ファイルの取得方法では、小さいファイルならば、file_get_contents で十分ですが、大きなファイルではメモリが大量に消費させる可能性を考慮する必要があります。さらに、大きなファイルでは PHP 側のタイムアウトの設定も必要になる可能性があります。また、他のサーバーから取り込む場合は、ファイルサイズを取得するのに cURL 関数が必要になります。( PHP 5.0.0 以降 では filesize がそのまま使えるようなニュアンスですが、stat() を http がサポートしていないので使えません )

※ 参考 : max_execution_time (30/PHP_INI_ALL)

▼ PHP マニュアルの投稿の引用
<?php
$remoteFile = 'http://us.php.net/get/php-5.2.10.tar.bz2/from/this/mirror';
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
  echo 'cURL failed';
  exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
  $status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
  $contentLength = (int)$matches[1];
}

echo 'HTTP Status: ' . $status . "\n";
echo 'Content-Length: ' . $contentLength;
?>

Result:

HTTP Status: 302
Content-Length: 8808759
cURL を使ったサンプル

PHP : WEBでもコマンドラインでもHTTPでファイルをダウンロードする



タグ:fread readfile PHP
posted by lightbox at 2018-08-30 04:37 | TrackBack(0) | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする

2018年08月29日


VBScript を使って HTTPプロトコルで PHP へファイルをアップロードする方法


関連する記事

ファイルのアップロード時のデータのダンプ

仕様を確認したわけではありませんが、boundary は、境界識別する為のユニークな文字列であると思われます。http ヘッダで指定した文字列を x とすると --x が境界で、改行コードが付加されます。一番最後の境界は --x-- です。
upload_target.php
<!DOCTYPE html>
<html>
<head>
<title>単純ファイルアップロード</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css">
<style>
#content,#result {
	padding: 20px;
}
#result {
	white-space: pre;
}
</style>
</head>
<body>
<div id="content">
	<form
		enctype="multipart/form-data"
		method="POST">
	
		<p>
			<input name="target" type="file" class="ml-4 btn btn-outline-primary">
			<a
				class="ml-4 btn btn-info btn-sm"
				href="<?= $_SERVER["PHP_SELF"] ?>">GET 再読み込み</a>
		</p>
		<p>
			<input type="submit" name="send" value="アップロード" class="ml-4 btn btn-outline-primary">
		</p>
	 
	</form>
</div>
<div id="result">
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {
 
	$upload = realpath("./");
	$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );

	print "$upload\n";

	if ( move_uploaded_file($_FILES['target']['tmp_name'], $upload ) ) {
		print "<p>アップロードに成功しました</p>\n";
	}

	print_r( $_FILES );
}

?>
</div>
</body>
</html>


upload.wsf
<JOB>
<COMMENT>
************************************************************
 URLEncode用
************************************************************
</COMMENT>
<OBJECT id="Stream" progid="ADODB.Stream" />
<OBJECT id="StreamWorkBin" progid="ADODB.Stream" />
<OBJECT id="StreamBin" progid="ADODB.Stream" />
<COMMENT>
************************************************************
 HTTP通信用
************************************************************
</COMMENT>
<OBJECT id="objHTTP" progid="Msxml2.ServerXMLHTTP" />

<SCRIPT language=VBScript>

' **********************************************************
' アップロード用 URL
' **********************************************************
upload_url = "http://localhost/test/001/upload_target.php"
upload_file = "winofsql.png"
upload_type = "image/png"

' *********************************************************
' 送信準備
' *********************************************************
Call objHTTP.Open( "POST",upload_url, False )
' File Upload 用 HTTP ヘッダ
strBoundary = DateDiff("s", "1970/1/1 0:00:00",DateAdd("h",-9,now))
Call objHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary="&strBoundary)

' バイナリ変換用ストリーム
StreamWorkBin.Open
StreamWorkBin.Type = 1

' 最終バイナリストリーム
StreamBin.Open
StreamBin.Type = 1

' テキストストリーム
Stream.Open
Stream.Charset = "shift_jis"

' 開始セクション
Stream.WriteText "--" & strBoundary & vbLf
Stream.WriteText "Content-Disposition: form-data; name=""target""; filename=""uploadtest.png""" & vbLf
Stream.WriteText "Content-Type: "&upload_type& vbLf
Stream.WriteText vbLf
Stream.Position = 0

' テキストをバイナリに変換
Stream.CopyTo StreamWorkBin

' 第一セクションを書き込み
StreamWorkBin.Position = 0
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' 画像を読み込む
StreamWorkBin.LoadFromFile(upload_file)

' 画像を書き込み
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' バイナリワークをいったん閉じる
StreamWorkBin.Close
StreamWorkBin.Open
StreamWorkBin.Type = 1

' テキストをいったん閉じる
Stream.Close
Stream.Open
Stream.Charset = "shift_jis"

' 終了セクション
Stream.WriteText vbLf & "--" & strBoundary & "--" & vbLf
Stream.Position = 0

' テキストをバイナリに変換
Stream.CopyTo StreamWorkBin

' 終了セクションを書き込み
StreamWorkBin.Position = 0
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' 送信データを取得
nLen = StreamBin.Size
StreamBin.Position = 0
strData = StreamBin.Read(nLen)

Call StreamBin.SaveToFile( "result.dat", 2 )

' *********************************************************
' 投稿データとその長さ
' *********************************************************
Call objHTTP.SetRequestHeader("Content-Length",nLen)

' *********************************************************
' API へ向けて送信
' *********************************************************
Dim lResolve : lResolve = 60 * 1000
Dim lConnect : lConnect = 60 * 1000
Dim lSend : lSend = 60 * 1000
Dim lReceive : lReceive = 60 * 1000
Call objHTTP.setTimeouts(lResolve, lConnect, lSend, lReceive)
Call objHTTP.Send(strData)

Wscript.Echo(objHTTP.responseText)


</SCRIPT>
</JOB>




タグ:Curl
posted by lightbox at 2018-08-29 14:26 | VBS + インターネット | このブログの読者になる | 更新情報をチェックする

PHP : 超簡易ログ

複雑な処理ですと、画面に表示しづらい場合があります。そんな時、その場限りのログです
file_put_contents( uniqid().".log", $vaiue );

// 以下は配列やオブジェクトを出力したい場合

file_put_contents( uniqid().".log", print_r( $_POST, true ) );







posted by lightbox at 2018-08-29 12:56 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする
container 終わり

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

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり