PHPの変数をJavaScriptの変数(のコード)に変換する関数

こんにちは。

JavaScriptが全然動かないとおもっていたら、
type="test/javascript"と書いているような人間です。


DBから取得したデータをJavaScriptプラグインに渡すときは、PHPの変数をJSコードに変換してで出力しなければなりませんよね?
ネットで探しても適度なものがなかったので簡単なの作りました。配列と文字列、数値が変換できます。オブジェクトや連想配列を変換したい場合は土台に使ってください。
誰か他に便利な方法知ってたら教えてください。

関数

<?php
function getArrayToJSArray($element) {
	$js = "";
	if (is_array($element)) {
		$js .= "[";
		$count = 0;
		foreach($element as $key => $value) {
			$js .= getArrayToJSArray($value);
			$count++;
			if ($count != count($element)) {
				$js .= ",";
			}
		}
		$js .= "]";
	} else {
		if (is_numeric($element)) {
			$js .= $element;
		} else if (is_string($element)) {
			$js .= "'" . $element . "'";
		}
	}
	return $js;
}
?>

使い方

  • 実行
<?php
$test = array();
$test[0] = array('2010-12-25 10:00', '100');
$test[1] = array('2010-12-25 10:05', '200');
$test[2] = array('2010-12-25 10:10', '300');

echo 'var data = ' . getArrayToJSArray($test) . ';';
?>
  • 結果
var data = [['2010-12-25 10:00',100],['2010-12-25 10:05',200],['2010-12-25 10:10',300]];

ちなみに文字列のエスケープ処理はしてないです。


ColdFusionにはToScript()という関数がありますね!でも高い。。。


誰かのお役に立てば幸いです。

LEAST()とARRAY_AGG()

こんにちは。


プログラムがいつまでたっても直らないとおもったら、実は引数が間違っているような人間です。
PostgreSQLを5年使っていても、知らない関数というのはいっぱい出てくるものです。

LEAST/GREATEST (8.1以上)

たとえば、表のような「5列あるカラムの最小値を使って」といわれた場合、1回取得したレコードをプログラム側で最小値をとることになるかと思いますが、クールにバチッとSQL1発で取得したいものです。
CASE文?いやいや、横にMINみたいなことできないの?ってときにこのLEAST。

  • examinationテーブル
japanese mathematics english chemistry history
60 40 70 60 30
SELECT LEAST(japanese, mathematics, english, chemistry, history) AS result 
FROM examination;
  • 結果
result
30

逆に最大値を使いたいときはGREATEST。

ARRAY_AGG (8.4以上)

下の表のようなテーブルをなんとか3行に集約したいというとき。
GROUP BYを使ってもうまくいきません。サブクエリ?んーなんか違うと。
プログラムでループだよねって感じでしたいままでは。
はいありました、集約関数ARRAY_AGG。

  • mycolorテーブル
category color
1 Red
1 Pink
1 Wine Red
2 Green
2 Cobalt Green
2 Emerald Green
3 Blue
3 Sky Blue
3 Sax Blue
SELECT
	category,
	ARRAY_AGG(color) AS color
FROM mycolor
GROUP BY category;
  • 結果
category color
1 "{Red,Pink,"Wine Red"}"
2 "{Green,"Cobalt Green","Emerald Green"}"
3 "{Blue,"Sky Blue","Sax Blue"}"

結果がVARCHARの配列型で帰ってくるので、好き嫌いは分かれそうですが。
ARRAY_AGGの引数に渡すカラムはGROUP BYしないことに注意してください。
新しいバージョンなのが難点ですね。


何かのお役に立てば幸いです。

GoogleMapでシンプルなボタンコントローラを

こんにちは。

GoogleMap用に作ったボタンが例によってお蔵入りなので涙目で書きます。
ちなみにGoogleMapAPIのバージョンは2.sで動作を確認しています。


ボタン作成

コントロールを作成するにはGControlクラスを継承したクラスを作成します。
引数は左px、上px、ID、ボタンテキスト、クリック時の実行関数となっています。

/**
 * コンストラクタ
 */
function GSimpleButton(_left, _top, _id, _text, _click) {
	this.left = _left || 0;
	this.top = _top || 0;
	this.id = _id || "";
	this.text = _text || "";
	this.click = _click || function(){};
}

/**
 * 継承
 */
GSimpleButton.prototype = new GControl();
/**
 * 初期化
 */
GSimpleButton.prototype.initialize = function(_map) {
	// コンテナ作成
	var container = document.createElement("div");
	var buttonFrame = document.createElement("div");
	buttonFrame.style.backgroundColor = "#FFFFFF";
	buttonFrame.style.borderColor = "#000000";
	buttonFrame.style.borderStyle = "solid";
	buttonFrame.style.borderWidth = "1px";

	// ボタン作成
	var button = document.createElement("div");
	button.style.backgroundColor = "#FFFFFF";
	button.style.color = "#000000";
	button.style.borderColor = "#FFFFFF #B0B0B0 #B0B0B0 #FFFFFF";
	button.style.borderStyle = "solid";
	button.style.borderWidth = "1px";
	button.style.fontSize = "12px";
	button.style.cursor = "pointer";
	button.style.textAlign = "center";
	button.style.width = "65px";
	button.style.height = "14px";
	button.style.zIndex = "20";

	// ID
	button.id = this.id;

	// コンテナの中にボタン枠を追加
	container.appendChild(buttonFrame);

	// ボタン枠の中にボタンを追加
	buttonFrame.appendChild(button);

	// ボタンの中に文字を追加
	button.appendChild(document.createTextNode(this.text));

	// 地図上に追加
	_map.getContainer().appendChild(container);

	var obj = this;

	// イベントリスナ
	GEvent.addDomListener(button, "click", function() {
		if (obj.click instanceof Function) {
			obj.click();
		}
	});

	// コンテナを返す
	return container;
}
/**
 * 印刷
 */
GSimpleButton.prototype.printable = function() {
	return false;
}
/**
 * 選択
 */
GSimpleButton.prototype.selectable = function() {
	return false;
}
/**
 * 表示位置
 */
GSimpleButton.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(this.left, this.top));
}

使い方

GMAP_CTRL_TEST_BUTTON = new GSimpleButton(100, 7, "gbtn_test", "TEST", function() {console.debug("test")});

上のような感じでインスタンスを生成したら、addControlしてください。
地図をボタンだらけに出来ますね!
誰かのお役に立てば幸いです。

ファイルを非同期での読み書きするメモ

こんにちは

Flexを始めて1ヶ月、ファイルの非同期での書き込みで泣きそうなくらいハマったので書きます。

非同期のポイント

読み込みのときは以下のイベントをリッスンする。

  • ProgressEvent.PROGRESS
  • Event.COMPLETE
  • IOErrorEvent.IO_ERROR

書き込みのときは以下のイベントをリッスンする。

  • OutputProgressEvent.OUTPUT_PROGRESS
  • Event.CLOSE
  • IOErrorEvent.IO_ERROR

読み書きでイベントが違うんですねー。
私は読み込みと書き込み同じイベントをリッスンしていました。。。
こんなアホは私だけでしょうか。

ファイル読み込み(非同期)

function readFileAsync(path:String):void {
	// ファイル
	var file:File = new File(path);
	var fileStream:FileStream = new FileStream();
	// イベントリスナ
	fileStream.addEventListener(ProgressEvent.PROGRESS, onEventProgress);
	fileStream.addEventListener(Event.COMPLETE, onEventComplete);
	fileStream.addEventListener(IOErrorEvent.IO_ERROR, onEventIOError);
	// 読み込み開始
	fileStream.openAsync(file, FileMode.READ);
	
	// イベントハンドラ
	function onEventProgress(e:ProgressEvent):void {
	}
	function onEventComplete(e:Event):void {
		// ファイルストリーム終了
		fileStream.close();
	}
	function onEventIOError(e:IOErrorEvent):void {
		fileStream.close();
	}
}

ファイル書き込み(非同期)

public function writeFileAsync(path:String, data:Object):void
	// ファイル
	var file:File = new File(path);
	var fileStream:FileStream = new FileStream();
	// イベントリスナ
	fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, onEventOutputProgress);
	fileStream.addEventListener(Event.CLOSE, onEventClose);
	fileStream.addEventListener(IOErrorEvent.IO_ERROR, onEventIOError);
	// 書き込み開始
	fileStream.openAsync(file, FileMode.WRITE);
	fileStream.writeObject(data);

	// イベントハンドラ
	function onEventOutputProgress(e:OutputProgressEvent):void {
		// ファイルストリーム終了
		if (e.bytesPending == 0) {
			fileStream.close();
		}
	}
	function onEventClose(e:Event):void {
	}
	function onEventIOError(e:IOErrorEvent):void {
		fileStream.close();
	}
}

※ちなみにこのコードは動いていたものを一部切り抜き変更しているので、そのままだと動かないかもしれないです。
※FileStream.openAsyncをopenのままにしてしまうのも意外によくやるミスですね(私だけ?(笑))

書籍OS自作入門で作ったイメージをVMwareで起動する

バイナリエディタで作成したhelloos.imgをVMwareで起動します。


起動画面


前提
WindowsVmware Server 1.0.4
(※尚、下記手順はすべて自己責任でお願いします)


まずはOS自作入門用の最小構成のバーチャルマシンを作成します。

  • [ File ] -> [ New ] -> [ Virtual Machine... ]

New Virtual Machine Wizard手順

  • Virtual machine configuration - Typical
  • Guest operating system - Other
  • Version - Other
  • Virtual machine name - (好きな名前)
  • Network connection - Do not use a network connection
  • Disk capacity - 0.1GB
  • Allocate add disk space now - チェックを外す


テキストエディタでバーチャルマシンのフォルダ内のvmxファイルを開きます。

1   |config.version = "8"
2   |virtualHW.version = "4"
3   |scsi0.present = "TRUE"
4   |memsize = "32"
5   |ide0:0.present = "TRUE"
6   |ide0:0.fileName = "Other.vmdk"
7   |ide1:0.present = "TRUE"
8   |ide1:0.fileName = "auto detect"
9   |ide1:0.deviceType = "cdrom-raw"
10  |floppy0.present = "FALSE"
11  |floppy0.startConnected = "TRUE"
12  |floppy0.fileName = "E:\Documents and Settings\foo\My Documents\source\OS自作入門\tolset\helloos0\helloos.img"
13  |floppy0.fileType = "file"
14  |displayName = "os-30days"
15  |guestOS = "other"
16  |priority.grabbed = "normal"
17  |priority.ungrabbed = "normal"
  • 4行目 192→32(メモリは最低限の32で起動)
  • 10行目 FALSE→TRUEに変更
  • 11行目〜13行目 追加


VMwareでPower Onで起動


OSが起動できて感動、さらにVMwareで起動したことで感動2倍ですね!!


参考
VMware まとめ Wiki

EmEditor用の構文ファイルを公開してみます

最近、RPMのspecファイルを書くことがあったのですが、
皆さんはどんなツールを使っているのでしょうか?


僕はEmEditorを使っているんですが、
spec用の構文ファイルが探してもなかったので作ってみました。


シンタックス適用前

シンタックス適用後

ついでに使い捨てのマクロも作ってみました。
(汚いJavaScriptですいません。。。配列のところ変更すれば自分使用に簡単に変更できると思います。)


マクロ実行画面


構文ファイルのインストール方法


誰かのお役に立てれば幸いです。

(すでに同様のファイルがあったら削除します。)