忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2025/11/24 12:52 |
ZF1.11 Zend_Loader
Zend_ValidateZend_Filterで静的呼び出しを行った際、該当のファイルを自力でインクルードしなくても勝手に対応するクラスがインクルードされていました。

そのインクルードを行っている実体がZend_Loaderです。
まあやってることは_を/にしてインクルードしてるだけです。
<?php
	//Zend_Loader
	require_once('Zend/Loader.php');
	
	//任意のクラスをロード
	Zend_Loader::loadClass('Zend_Cloud_QueueService_Adapter_ZendQueue');
	Zend_Loader::loadClass('Spreadsheet_Excel_Writer_Worksheet');
	
	//インクルードパスを指定してロード
	Zend_Loader::loadClass('Hoge_Fuga_FooBar', '../');
	$hogeFugaFooBar = new Hoge_Fuga_FooBar();
ファイル名およびクラス名はPearの命名規約に沿っている必要があります。
例えば引数として'Zend_Cloud_QueueService_Adapter_ZendQueue'を与えると、'Zend/Cloud/QueueService/Adapter/ZendQueue.php'をインクルードしてクラス名'Zend_Cloud_QueueService_Adapter_ZendQueue'が存在するかまでをチェックします。
従って、ZendライブラリだけではなくPearライブラリもZend_Loaderでインクルード可能ですが、SymfonyのライブラリはPearの命名規則に沿っていないので読み出し不可能です。
また第二引数にパスを与えると、指定された場所からの相対ディレクトリのみをチェックします。

このファイル名の変換は先日やったZend_Filter_Word_UnderscoreToSeparator('/')そのままなのでこれを使っているのかと思いきや、全く使わずZend_Loader内で普通に自力で実装していました。
なんだそれ。


まあともかく、このようにZend_Loader::loadClass()にはクラス名をファイル名に変換する仕組みが備わっているのですが、実際このZend_Loaderを使用しているクラスを見てみると、

Zend_Validate
	$className  = ucfirst($classBaseName);
	$class = $namespace . '_' . $className;
	$file  = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
	if (Zend_Loader::isReadable($file)) {
		Zend_Loader::loadClass($class);
	}
Zend_Filter
	$className = $namespace . '_' . ucfirst($classBaseName);
	$file = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
	if (Zend_Loader::isReadable($file)) {
		Zend_Loader::loadClass($className);
	}
まずZend_Loader::isReadableでファイルが存在するか確認してからZend_Loader::loadClassでクラスを呼び出しています。
で、このZend_Loader::isReadableが引数として何故かクラス名ではなくファイル名を必要とするので、結局呼び出し側でも自力でクラス名→ファイル名の変換という同じ処理を行わないといけない果てしなく微妙な作り。
PR


2011/09/09 23:09 | Comments(0) | TrackBack() | PHP
ZF1.11 Zend_Filterで命名規則変換
前回前々回Zend_Filterを紹介しましたが、実はリファレンスにはフィルタクラス群のリストに載っていない謎のクラス群が存在します。
Zend_Filter_Word_UnderscoreToDash、Zend_Filter_Word_CamelCaseToSeparatorなどZend_Filter_Word配下に属するクラス群です。

まあ謎と言っても実はインフレクタのほうに載ってるんですが。

しかしこの解説、何言ってるのか全然わからないのですが、簡単に言うと文字列変換を行うフィルタのようです。
で、インフレクタと文字列変換は実際は微妙に違う機能なのですが、リファレンスではまとめて解説されているせいでわかりにくくなっています。
ここではとりあえず文字列変換フィルタだけ使ってみます。

Zend_Filter_Wordクラス群は、キャメルケースやスネークケースといった命名規則を変換する専用のフィルタです。
<?php
	
	//キャメルケース
        $string='fooBarBazHogeFuga';
	
	//Zend_Filter
		require_once('Zend/Filter.php');
	
	//静的にフィルタを実行
		//キャメルケースからアンダースコアに
		Zend_Filter::filterStatic($string, 'Word_CamelCaseToUnderscore'); //「foo_Bar_Baz_Hoge_Fuga」になる
	
	//フィルタチェイン
		require_once('Zend/Filter/Word/CamelCaseToDash.php');
		require_once('Zend/Filter/Word/DashToSeparator.php');
		
		//フィルタチェインを作成
		$filterChain = new Zend_Filter();
		$filterChain
			->addFilter(new Zend_Filter_Word_CamelCaseToDash())	//キャメルケースから-に
			->appendFilter(new Zend_Filter_Word_DashToSeparator('/'));//-から任意のセパレータに
		
		$filterChain->filter($string);	//「foo/Bar/Baz/Hoge/Fuga」になる
やってることははZend_Filter::filterStatic($string, 'PregReplace', array('match'=>'#(?<=(?:[a-z0-9]))([A-Z])#','replace'=>'_\1'));なので不要といえばそのとおりですが、正規表現などをいちいち考えずに使用できるので楽です。

Zend_Filter_Wordクラス群には全部で12のクラスがあるので、使用目的によって使い分けるとよいでしょう。
変換内容はだいたいクラス名のとおりです。
・CamelCaseToDash
・CamelCaseToSeparator
・CamelCaseToUnderscore
・DashToCamelCase
・DashToSeparator
・DashToUnderscore
・SeparatorToCamelCase
・SeparatorToDash
・SeparatorToSeparator
・UnderscoreToCamelCase
・UnderscoreToDash
・UnderscoreToSeparator

ところでこのZend_Filter_Wordクラス群は抽象クラスZend_Filter_Word_Separator_Abstractを継承しているのですが、この抽象クラスZend_Filter_Word_Separator_Abstractクラスはなんと具象クラスZend_Filter_PregReplaceを継承しています。
こりゃ面白い、と思って試してみたらJavaでも普通に継承できました。


2011/09/05 22:45 | Comments(0) | TrackBack() | PHP
買ったものリスト 2011/09/04
ものすごく今更ですが、2011/07/15オープンの、ヤマダ電機LABI新宿西口館に行ってきました。

感想。

狭い。

鏡張りでごまかしていますが敷地面積が非常に狭いです。
その面積のわりに非常に余裕を持った陳列を行っているので、当然の帰結として品揃えもたいしたことがありません。
すぐ近くにあるヨドバシのほうが無難に豊富です。
まあヨドバシは店舗が分散していて、また天井が低く通路も狭いせいで圧迫感があってこちらも広いとは感じられないのですがね。

結論としては、ヨドバシ秋葉とかに行った方がいいんじゃない。


ソードワールド2.0リプレイ 新米女神の勇者たち8 秋田 みやび
ソードワールド2.0リプレイ 新米女神の勇者たち9
ソードワールド2.0リプレイ 新米女神の勇者たち10
ソードワールド2.0リプレイ 新米女神の勇者たち11
☆☆☆☆

2.0のリプレイはたのだん魔封マージナルライダーとどうも微妙なのが多いのですが、その中でも最初に始まっておきながら最も安定した面白さで長編となった新米女神の勇者たち、ついにシリーズ完結。
歴史の積み重ねによってNPCや舞台背景の厚みが増し、ただのリプレイという枠を超えて英雄叙事詩になりつつある、といったらさすがに言い過ぎかも。
あと最近下品なのが多いリプレイの中にあって、安心して読める長編ということでも貴重です。
口は悪いですが。


ファミ通XBOX360 2011年10月号

表紙はマーカスですが、中身はADV特集多めです。
特にEver17好きにとっては狂喜乱舞の内容。
メーカーの壁を越え、Infinityシリーズのクリエイター、若林健、市川和弘、中澤工の共同インタビューを掲載!
って肝心の打越鋼太郎が居ないじゃない。
なんか知らんがInfinityの血を引く作品がcode_18、DUNAMIS15、ルートダブル、そしてEver17のリメイクと大量発生して一体なんなんだこのハード。
無論ADVばかりではなく、FPSにRPGにゾンビにシムにパーティゲーム、そして最大の話題作GoW3と読み応えたっぷりです。

あと箱通は関係ないけど2011年9月14日いよいよレイディアントシルバーガン配信決定!


2011/09/04 19:22 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/09/04
2011/09/03の実績

コール オブ デューティ ブラックオプス

VIP 10
ランサーから命令を受領する。

抑圧からの解放 10
ヴォルクタから脱出する。

自己犠牲 10
自分の分隊をキューバから安全に脱出させる。

独裁者に死を 15
ヘッドショットでカストロを倒す。

STEINS;GATE 比翼恋理のだーりん

CGの達成率75% 25
CGを75%見た

根源のアガペー 50
鈴羽のエンディングを見た

破滅と終焉のフーガ 10
「破滅と終焉のフーガ」をクリアした

迷走螺旋のアルケー 10
「迷走螺旋のアルケー」をクリアした

CGの達成率50% 25
CGを50%見た

楼閣都市のネフシュタン 50
フェイリスのエンディングを見た

猫耳乙女のドメイン 10
「猫耳乙女のドメイン」をクリアした

Sacred 2 Fallen Angel

Scrooge 30
Any Hero has completed the main quest without buying anything.

Dedicated 30
Any Hero completed the main quest without exploring more than 20 % of the map.

Survivalist 30
Any Hero completed the main quest in Bronze or Silver difficulty without dying.

Ancaria's Dark Lord 40
Any Hero completing the Shadow Campaign.

Medicine Man 20
Any Hero has consumed 1,000 healing potions.

2011/08/30の実績

Sacred 2 Fallen Angel

Tyr Lysia's Hero 20
Your High Elf attaining Level 15.

2011/08/30の実績

Sacred 2 Fallen Angel

Toughness 30
Any Hero reaching difficulty level Gold.

Dreadnought 30
Any Hero slayed 25 boss monsters.

Lone Ranger 25
Any Hero traveled a distance of 200 miles on his special mount.

Butcher 30
Any Hero slayed 1,337 elite monsters.


2011/09/04 19:19 | Comments(0) | TrackBack() | 実績
ZF1.11 Zend_Filterで既存の関数を利用
前回Zend_Filterでhtmlspecialchars()できるとか言いましたが、実はZend_Filter_HtmlEntitiesはあってもZend_Filter_HtmlSpecialcharsはありませんでした。
あれれ。

このような場合、Zend_Filterでは簡単にフィルタを追加することができます。

が、htmlspecialchars()のように既存の関数を呼ぶだけであればもっと手っ取り早い方法があります。
<?php
	//フィルタリングする文字列
        $string='<script>alert();</script>';
	
	//Zend_Filter
		require_once('Zend/Filter.php');
		require_once('Zend/Filter/Callback.php');
	
	//関数でフィルタを呼ぶ
		$filter = new Zend_Filter_Callback('htmlspecialchars',array(ENT_QUOTES, 'UTF-8'));
		$filter->filter($string);
	
	//静的にフィルタを実行
		Zend_Filter::filterStatic($string, 'Callback', array('htmlspecialchars',array(ENT_QUOTES, 'UTF-8')));
	
	//フィルタチェイン
		$filterChain = new Zend_Filter();
		$filterChain->addFilter(new Zend_Filter_Callback('htmlspecialchars',array(ENT_QUOTES, 'UTF-8')));
		$filterChain->filter($string);
Zend_Filter_Callbackは、引数に関数名もしくはクラス+メソッド名を与えることで、その関数を実行してくれます。
http://framework.zend.com/manual/1.9/ja/zend.filter.set.html#zend.filter.set.callback
上記例では3種類の呼び出し方を試していますが、いずれも最終的にhtmlspecialchars($string, ENT_QUOTES, 'UTF-8')が実行され、返り値は'&lt;script&gt;alert();&lt;/script&gt;'となります。

まあ関数ひとつで実行可能な変換をわざわざZend_Filterを通して実行する意味があるのかどうかわかりませんが。


2011/09/02 22:39 | Comments(0) | TrackBack() | PHP
ZF1.11 Zend_Filter
Zend_Filterは値のフィルタリングを行います。

Zend_Validateと違うのは、あちらはあくまで値のチェックを行うだけなのに対し、こちらは実際に値を処理するという点です。
まあ、htmlspecialchars()とかtrim()とか数値に変換したりといった操作を一元的に行えるクラスです。

使い方もZend_Validateとほぼ同じです。
filterStatic()メソッドで静的に実行できたり、フィルタチェインにはインクルードが必要なところまで同じです。
http://framework.zend.com/manual/ja/zend.filter.introduction.html
<?php
	
	//フィルタリングする文字列
        $string='ABC012<script>alert();</script>';
	
	//Zend_Filter
		require_once('Zend/Filter.php');
	
	//静的にフィルタを実行
		Zend_Filter::filterStatic($string, 'Alnum'); //「ABC012scriptalertscript」になる
		Zend_Filter::filterStatic($string, 'PregReplace', array('match'=>'/<script>/', 'replace'=>'script'));//「ABC012scriptalert();</script>」になる
	
	//フィルタチェイン
		//フィルタチェインはインクルードが必要
		require_once('Zend/Filter/Alpha.php');
		require_once('Zend/Filter/StringToLower.php');
		
		//フィルタチェインを作成
		$filterChain = new Zend_Filter();
		$filterChain
			->addFilter(new Zend_Filter_Alpha())
			->addFilter(new Zend_Filter_StringToLower());
		//実行
		$filterChain->filter($string);	//「abcscriptalertscript」になる
簡単にフィルタリングできました。

ちなみにfilterStaticの第三引数、'match''replace'には全然意味がなくて、配列の順番だけしか見ていません。
array('replace'=>'/<script>/', 'match'=>'script')って書いても全く同じ動作になります。
Zend_Filter_PregReplace自体にはif (array_key_exists('match', $options))みたいなことが書いてあるので直接呼び出せば連想配列が考慮されるのですが、Zend_Filter::filterStaticの呼び出し側がそこらへんを気にしないのでうっかり逆順に書いてたりすると事故ります。
微妙に残念。


2011/08/29 22:41 | Comments(0) | TrackBack() | PHP
買ったものリスト 2011/08/28
クラブニンテンドーオリジナルグッズ、タオルハンカチを入手しました。
20110828-mario.jpg
こういう実用性のあるプレゼントはいいですね。

左のは先週のゼルダサントラです。


皇帝のかぎ煙草入れ ディクスン・カー
☆☆☆

日本人って根本的に「かぎ煙草入れ」に親近感がないわけですよ。
なので肝心の現場がイメージしにくくて、ネタ晴らしの部分で、え?どういうこと?となってしまいます。
その点だけが残念。
もっと日本にも存在するようなものに差し替えてくれれば。

しかしこのイヴ、ちょっと脇が甘すぎるんじゃね。


ソード・ワールド2.0リプレイ 滅びのサーペント 清松 みゆき
☆☆☆

ゲームシステム上最高レベルであるところのレベル15パーティ。
オーガバーサーカー1ダースを軽く蹴散らし、ゲルダムが泣いて逃げ出す彼らに対し、GMが用意するは"黒の封印"。
果たして彼らの運命やいかに、という世紀末設定のリプレイ。
単純なパワープレイに陥らないようにと多少の工夫も凝らされていて、「魔晶石で拡大だにゅう、どっかーん」とはひと味違う展開が待ち受けており…あんまり変わらないかも。

残念なのはオリジナルモンスターのモンスターデータがわからないこと。
1のころのリプレイはモンスターデータが載っているのが普通だったので残念。

ところで「退かぬこともなく」って変じゃないか。
あとせっかくなんで流星落ちるときのテストプレイのリプレイを出してくれんかのう。


のうりん 白鳥 士郎
☆☆

「たまにギャグが滑ることがありますが、品質には全く問題ございません」
いや、問題あるだろう。
消化不良起こすわ。
一部の文体が激しく非常にウザい。

しかしどこかで見覚えのあるウザさだと思えばバカとテストと召還獣だった。
よりによってあんな底辺を見習わなくてもいいものを。
素の部分は比較的そこそこ良い感じなので、余計な装飾を入れずにやってくれれば多少は良くなるかも。

あと非常によくわからないのが、何故初っぱなから何の伏線もなく唐突に好意全開なのかと。
この部分はかなり納得がいかない。

農業についてはかなり詳しく調べた形跡があって、そこだけは頭のからっぽな他のラノベとは一線を画していて評価できます。


それゆけ! 宇宙戦艦ヤマモト・ヨーコ【完全版】5 庄司 卓
それゆけ! 宇宙戦艦ヤマモト・ヨーコ【完全版】6
☆☆☆

ダンディライオンってフィッシュチームより先だったっけか。
なんか旧版はダンディライオンで終わったっていうイメージがあるんだよな。何故か。
だいぶ記憶が薄らいでるようだ。

全体的にネタが古いのはまあ仕方がないので、あー当時はこんなんだったなあ、と懐かしみながら読むのが正しいスタイルですかね。


2011/08/28 18:19 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/08/28
2011/08/27の実績

HALF-MINUTE HERO SMNC

称号マスター 30
すべての称号を獲得した

Sacred 2 Fallen Angel

Butcher 30
Any Hero slayed 1,337 elite monsters.

Slaughterer 30
Any Hero slayed 10,000 opponents.

2011/08/23の実績

Sacred 2 Fallen Angel

Millionaire 20
Any Hero owning 1,000,000 gold.

Junior Cartographer 20
Any Hero has explored 30 % of the map.

2011/08/21の実績

Sacred 2 Fallen Angel

Extremely Diligent 30
Any Hero completed 40% of all sidequests.

Ancaria's Lightbringer 40
Any Hero completing the Light Campaign.

Discoverer 10
Any Hero reaching the Wastelands and accepting a quest there.

Legendary 25
Any Hero attaining Level 35.

Bookworm 30
Any Hero has read 33 Books.


2011/08/28 18:11 | Comments(0) | TrackBack() | 実績
Dojo1.6.1 dojo Dojox.chartingでテーマの一部だけを変更する
Dojox.chartingには、themesディレクトリにたくさんのテーマが格納されています。

なので、用意されているテーマを使用するだけであれば、
	dojo.require("dojox.charting.themes.BlueDusk");
	myChart.setTheme(dojox.charting.themes.BlueDusk);
とするだけで簡単に利用できます。

このテーマは自作することも可能で、実際にDojo道場ではテーマをひとつ作成して実装しています。

ただこちらは一から全部作っているので大がかりです。
基本的には元々あるテーマでいいんだけど少しだけ変更したい、などという場合は、
	dojo.require("dojox.charting.themes.BlueDusk");
	dojox.charting.themes.BlueDusk.chart.stroke = "#ff0000";
	myChart.setTheme(dojox.charting.themes.BlueDusk);
です。
楽ですね。


2011/08/26 22:36 | Comments(0) | TrackBack() | JavaScript
JavaScript prettyPrintでvar_dump()
alert(hoge)すると[object Object]って言われてどういうことだよとなりますが、var_dump()みたいに配列やオブジェクトの中身を出力してくれるライブラリがないかと探してみたらprettyPrint.jsというものがみつかりました。
https://github.com/jamespadolsey/prettyPrint.js

変数とDOMに対して使ってみます。
なお、変数の例はこちらのをそのまま借りています。
<html>
<head>
    <script src="prettyprint.js"></script>
</head>
<body>
	<div id="hoge" title="title">text<span>inner</span></div>
	<div id="output"></div>
	<div id="output2"></div>

	<script type="text/javascript">
		var hoge =document.getElementById('hoge');
		document.getElementById('output').appendChild(prettyPrint(hoge));
		
		var config = {
			expanded :true,
			forceObject: true,
			maxDepth: 2,
			styles: {
				'default': {
					th: {
						backgroundImage:false
					}
				}
			}
		};
		var test = {
			_arr 	: ["pretty","print"],
			_rear	: [["pretty","print"]],
			_reobj	: {	"a":"pretty",
					"b":{"b1" : "print"}},
			_func 	: function(_str){
				alert(_str);
				return;
			}
		};
		
		document.getElementById('output2').appendChild(prettyPrint(test, config));
		
	</script>
</body>
</html>
出力は以下。

DOMElement
tag <div>
id hoge
innerHTML text<span>inner</span>

Object
key value
_arr
Array(2)
index value
0 "pretty"
1 "print"
_rear
Array(1)
index value
0 [DEPTH REACHED] [+]
_reobj
Object
key value
a "pretty"
b [DEPTH REACHED] [+]
_func
Function
arguments _str
body alert(_str); return;

prettyってわりにソースはちょっとあれなかんじですが、見事に出力できました。
なお、[DEPTH REACHED]ってなってるところは本来ならクリックすると更に詳細を表示することが出来ます。

さて、prettyPrintの解説記事を見て回ったのですがオプションについて書いてる記事がついぞひとつも見つかりませんでした。
第二引数を渡すことで挙動の変更が可能です。

forceObjectは返り値を強制的にObjectにするみたいなんですが意味がよくわかりませんでした。

expandedはfalseにすると詳細を表示しません。
maxDepthで内部構造を掘り下げる深度を調整できます。
いずれも初期状態では隠れているだけで、各値をクリックすることで詳細を見ることができます。

stylesは出力されるテーブルのスタイルを変更することができます。
例でやってるbackgroundImageは、デフォルトだといちいちインライン画像を作ってしまうためキャンセルさせています。

まあ、所詮開発時にしか使わないはずなのであんまりオプションを指定してもしょうがないんですがね。
ちなみにconsole.dir()のことは秘密だぞ。


2011/08/22 21:24 | Comments(0) | TrackBack() | JavaScript

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]