忍者ブログ
[PR]
×

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



2025/05/20 16:08 |
PHP5.5.3 PHPでオブジェクトの強い型付け
前回SplTypeを使って厳密なSplInt型を作りました。
が、用意されているのはint、stringといったスカラー型だけでした。

自作のクラスに対応するためにSplTypeが用意されています。
SplTypeはabstractなクラスです。
何故インターフェイスじゃないんだ。
<?php
	class HOGE extends SplType{}

	$hoge = new HOGE();
	$hoge = 1; // Uncaught exception 'UnexpectedValueException'
あれ、これ全クラスをextends SplTypeってしとけば強い型付け言語PHPの誕生じゃね?
PHPは型付けが~とか言ってる人はいっぱいいるけど、これを紹介してる人がただの一人もいないってのはどういうことですかね。

せっかくなので、runkitで全クラスに強制的にSplTypeを継承させてしまいましょう。
<?php
	class HOGE{}
	
	$classes = get_declared_classes();
	class SplTypeTmp extends SplType{}
	$tmp = error_reporting(0);
	foreach(get_declared_classes() as $key=>$val){
		if(!get_parent_class($val)){
			runkit_class_adopt($val, 'SplTypeTmp');
		}
	}
	error_reporting($tmp);
	
	$x = new HOGE();
	$x = 1; // 普通に入った
あれ?
調べてみたらrunkit_class_adoptは一見親クラスを付け替えているように見えますが、実際は本当に変更しているわけではなくエミュレーション的なことをしているみたいです。
自作クラスでも一部情報が飛んでしまい、SplTypeのような特殊なクラスではその特殊性が失われます。
ということで全自動強い型付け言語PHPの夢は破れてしまいました。
型付けとかは開発時にしか必要のない機能なので、php.iniあたりでSplType強制を設定できるようになってくれれば、とても便利だと思うのですがどうでしょう >開発者

SplTypeを使いこなせば、開発に非常に強力な武器となってくれるでしょう。
あと強い型付け言語使いから大きな顔をされることもなくなるでしょう。
PR


2014/01/13 22:06 | Comments(0) | PHP
買ったものリスト 2014/01/12

ディアボロのスープ3 岡崎 純平
☆☆☆☆☆

2巻まで見て色々考えていたことがあっさり解決してしまった。
よもや作品の根幹にまで仕掛けを入れるとはただものではない。
にしても敵方の彼はどういう氏族扱いされてるんですかね。
つうかあんなに力持ってる味方がいるのに何故助けに行ったりしなかったんだ。
そこらへんきちんと解決するんだろうか。


史上最強の弟子ケンイチ 53 松江名 俊
史上最強の弟子ケンイチ 54
☆☆☆☆

弟子ってなんだったっけ…?
すっかり超人バトルなのですがそれは。

さすがにリミがあっさり退場するとは予想外。
まあ殺人拳とか言いつつわりと死んでなかったし、そろそろ終盤に向けて登場人物の整理が必要な気がしないでもない。


奇食ハンター5 山本 マサユキ
☆☆☆☆

わざとらしく褒めることもなく、大げさに表現することもなく、無駄に地味な評価を下す、妙なもの食道中完結編。
最後まで地味でした。



ラブやん14 田丸浩史
☆☆

そういえばいつのまにか買わなくなってたなこれ。


2014/01/12 21:00 | Comments(0) | 買ったもの
PHP5.5.3 PHPでスカラー型の強い型付け
<?php
	$object = new stdClass();
	$object = '1' + 1;
	
	$boolean = ( '1' == 1 );
$objectはint型の2、$booleanはtrueになり、Java出身者が憤死します。
PHPの型の挙動には色々と論がある人も多いですが、PHPの特徴だと思って諦めましょう。
まあ私はこういうの嫌いではないですが、推移律が成り立たないのはさすがにどうかと思う。

しかし時には、どうしても厳密に型を適用したいんだよ、という場合があるかもしれません。
そんなときのためにSplTypeです。

今のところデフォルトでは入ってないのでPECLから持ってきましょう。
Windows版のDLLも存在します。
<?php
	$int = new SplInt(1);
	
	$int = 2; // 2
	$int++; // 3
	
	$int = 1.0; // Fatal error: Uncaught exception 'UnexpectedValueException'
	$int = 'a'; // Fatal error: Uncaught exception 'UnexpectedValueException'
	
	$a = $int + 10; // 13
	for($i=1; $i<$int; $i++){} // 問題なく動作
PHPがあたかもRubyのような強い型付けに!

$intは、intもしくはSplInt以外を代入しようとするとUnexpectedValueExceptionを発生します。
これで$intの型一意性が保証されることになりました。
逆に$intを演算に使う場合は、ただの整数と同じように扱えます。

型付けの対象としては、int以外にfloat、boolean、stringの各スカラー型、そしてEnum型が用意されています。

ところで、

http://www.php.net/manual/ja/intro.spl-types.php
> スカラー型のタイプヒンティングの代替手段として使用できます。

って書いてあるのですが、あくまで代替のようで完全なタイプヒンティングとしては使えませんでした。
<?php

	class HOGE{
		
		private $int;
		
		// setSplIntは呼び出し側でキャストしないといけない
		public function setSplInt(SplInt $int){
			$this->int = $int;
		}
		
		// setIntは概ね想定した動作だがタイプヒンティングではない
		public function setInt($int){
			$this->int = new SplInt($int);
		}
	}

	$hoge = new HOGE();

	$hoge->setSplInt(new SplInt(1));
	$hoge->setSplInt(1); // Argument 1 must be an instance of SplInt, integer given
	$hoge->setInt(2);
	$hoge->setInt(2.0); // Uncaught exception 'UnexpectedValueException'
まあ後者で作っておけば実質的には困らないと思います。


2014/01/10 23:08 | Comments(0) | PHP
Dust: An Elysian Tail Chapter12
前回の続き。

ガイウス将軍の動静。
兵士「信じがたいことですが、カシウスは銀血の民に協力しています。われわれを裏切った模様です」
ガイウス「カシウス、わが友よ…おまえが生きているかぎり、私はあらゆる手をつくし、おまえの壊れた心を修復してやる…必ずだ」
こっちの関係もどんなんだよ。

さて、スライディングに壁登りに二段ジャンプと、おそらく移動系の技は全部取っただろうと思われるので、これまでやってなかったイベントを回収して回ります。
秘密の入り江でサラヒを助ける。
ここのマップは迷路じみてて少々面倒です。

ブラックムーア山脈でたくさん取れた雪をポポに渡す。
ポポは父のように強くなって母を守る決心を固めたようだ。
かわりに虹の共鳴石をもらう。

6匹の羊をギャッピー爺さんに渡す。
赤ゴケをフロホップに渡す。
全てのサイドクエストをクリアし、「ファラーナの救世主」の称号を得ました。

なお、さらにThe DishwasherやThe Maw、Braidといった別作品の登場人物が捕われているというおまけ要素があります。
前助けた謎のお友達は、Super Meat Boyの主人公だったようです。
おまけ要素ではありますが、助けると最大HPが5%上昇するので助ける価値はあります。

やることをやったので常朝のくぼ地に行く。
チャプター5『伝説』開始。

銀血の民の兵士たちが、最後の戦いの準備をしています。
しかし兵力差は圧倒的で、まともに戦っては到底勝ち目はありません。
ダストはそのために生まれた存在だという。
しかしひとり程度でどうにかなるものなのかね。

かつて銀血の民はシンサクという社会を形成し、「炎なき光の道」という知識を持っていたらしい。
炎なき光は電灯とかでいいとしてシンサクってなんだ?
だがその文明は既に失われ、銀血の民はその技術と共に滅び行くかと思われた。
だがガイウス将軍が使っている武器や装置、光の矢、鳥のように空を翔ける機械は、自然の摂理から逸脱している、シンサクの武器なのではないかという噂があるらしい。

温血の民であろうジンジャーもここにいた。
移動の原因となった水はもう復活したんだから、こんな危ないところじゃなくてオーロラ村に戻ってていいのよ。
という選択肢は出てこない。
残念。
というかジンジャーはヒロインだとばかり思ってたのに、実は妹だったとか今さら言われても色々と困る。

戦闘準備を整えるためにサンジンに話す。
動力発生装置と送水ポンプが先日の地震で壊れたらしい。
修理するために地下に潜ります。
道中はとても短いですが、溶岩でいっぱいなので操作を誤ると危険です。
ここの敵はこっちに近付こうとして勝手に溶岩に落ちて死んだりします。

見張りのキールから連絡がないので見に行ったら倒れていました。
そして半透明…いや9割方透明で非常に見づらい兵士のような敵が襲いかかってきました。
不可視のエンチャントとは卑怯な。
なんとか撃退し、長老に報告。
黄色の共鳴石をもらい、そして最終決戦の準備に赴きます。
村から出ようというところで、実はもうひとつあった移動技、ブーストジャンプを覚えました。
このゲーム、所々下から気流が出ていて空中に浮いたりできるところがあるのですが、浮いてるときにジャンプすると大ジャンプができるようになります。
移動技はさすがにこれで最後でしょう。


Dust: An Elysian Tailのまとめ



2014/01/06 23:33 | Comments(0) | ゲーム
買ったものリスト 2014/01/05

2013年のゲーム・キッズ 渡辺 浩弐
☆☆☆☆☆

1999年、2000年、そして2999年と未来ばかりを描いてきた著者が、その観察眼で2013年という"今"のリアルを切り出す。

というわけでは全く無い。
いつものようにほとんどの話は圧倒的な未来の話で、そしてほぼ全てがバッドエンドなのも相変わらず。
本当にこの著者は私たちと同じ時間軸に住んでいるのか不安になります。

『謎と旅する女』はWeb版とはだいぶ異なる展開になっています。
Web版は正直ただのグロ画像ですが、書籍版はなんつうか狂気じみててやばい。


彼氏ってどこに行ったら買えますの! ? 2 火曜
☆☆☆

1巻の時点で既にネタが毎回同じなんだがどうするんだと思っていたら、まさかの全く同じ内容という。
すぎて逆に斬新かもしれない。



暗殺教室3 松井 優征
暗殺教室6
暗殺教室7
☆☆☆☆

いやあ読んでて実に面白い。
この作者は悪人とか概念の擬人化とかそういうの書くのが本当うまいですよね。
しかし半年程度でプロが認めるほど成長ってのはちょうっとどうなんだという気がしないでもない。

あと毛根には本気でキレて良い。


2014/01/05 21:30 | Comments(0) | 買ったもの
今週の実績 2014/01/05
2014/01/04の実績

地球防衛軍4

レッドカラー・ハンター 15
レッドカラーを150機撃墜する

Brothers

カーテンの裏で 40
君は秘密を見つけだした

2014/01/03の実績

地球防衛軍4

ディロイ・ハンター 15
ディロイを200機倒す

マザーシップ・ハンター 15
マザーシップを6機撃墜する

ギンガフォース

チャプター4 ミッション達成 30
ボスのパーツ破壊数を最高ランクでクリア(ストーリーモードのみ)

2014/01/02の実績

地球防衛軍4

飛行ドローン・ハンター 15
飛行ドローンを5000機撃墜する

2013/12/29の実績

Ascend: Hand of Kul

切り開かれし道 10
各帰属のスペルを 1 つ以上手に入れた

2013/12/26の実績

ギンガフォース

最大警備 10
いずれかのチャプターの初期残機数を最大(30機)まで増やした!(ストーリーモードのみ)

2013/12/24の実績

ギンガフォース

スコアアタック全チャプタープレイ 10
スコアアタックで全てのチャプターをプレイした

2013/12/12の実績

ギンガフォース

ハードクリア 50
ストーリーモード ハードをクリア



2014/01/05 19:42 | Comments(0) | 実績
PHP5.5.3 runkitでprivateな__constructを呼び出す
前回の続き。
runkitにはクラスに対しても色々やっちゃうことが可能です。
<?php
	// クラス
	class A{ public static function getName(){print('A');} }
	class B{ public static function getName(){print('B');} }
	class C extends A{}
	print(C::getName()); // A
	
	runkit_constant_add('C::hoge', 1);
	print(C::hoge); // 1
	
	runkit_class_emancipate('C');
	print(C::getName()); // Fatal error: Call to undefined method C::getName()
	
	runkit_class_adopt('C', 'B');
	print(C::getName()); // B
クラス定数やメソッドの追加削除に留まらず、親クラス入れ替えなんて芸当もできてしまいます。
ここでは前やったprivateな__construct()呼び出しを、runkitを使ってやってみます。

<?php
	class HOGE{
	    public $value = 0;
	    private function __construct(){
	        $this->value = 1;
	    }
	}

	runkit_method_rename('HOGE', '__construct', 'construct');
	runkit_method_add('HOGE', '__construct', '', '$this->construct();', RUNKIT_ACC_PUBLIC);
	$hoge = new HOGE();
	print $hoge->value; // 1
クラスを書き換えた結果、最終的にはこういう形になっていると思われます。
<?php
	class HOGE{
	    public $value = 0;
	    public function __construct(){
	        $this->construct();
	    }
	    private function construct(){
	        $this->value = 1;
	    }
	}
これならごく自然にnewできますね。
いいのかそれ。
なお、最近のPHP関数は引数にクロージャを受け付けてくれるものが多いですが、runkit_method_add()等は文字列しか駄目なようです。

runkitはあまりに強力すぎるため、実環境で使うことはまず無いでしょう。
こんな風に遊んでみるくらいならともかく、仕事でこんなことをやられたらたまったものではありません。


2014/01/03 21:26 | Comments(0) | PHP
PHP5.5.3 PHP5でrunkit
PHP界きっての反則技、runkit
はXAMPPにデフォルトで入っていたのですが、いつのまにか消えていました。
もはやPECLがメンテナンスされてないんですよね。

Windows版runkitをメンテしてる人を見つけたので試してみます。
試したバージョンは「php_runkit-1.0.4-5e179e978a-5.5-vc11.dll」。
TSのほうです。

ダウンロードしたファイルをxampp/php/ext内に入れて、php.iniに
	extension=php_runkit.dll
	runkit.internal_override = true
	runkit.superglobal = _FOO
と書いておきます。
phpinfo()でrunkitの項目が追加されていることを確認しましょう。

runkitを使うと、通常では絶対に有り得ないコーディングが可能になります。
<?php
	// 定数
	define('HOGE', 1);
	print(HOGE); // 1
	
	runkit_constant_redefine('HOGE', 2);
	print(HOGE); // 2
	
	runkit_constant_remove('HOGE');
	print(HOGE); // Notice: Use of undefined constant HOGE
	
	// 関数
	runkit_function_redefine('phpinfo', null, 'print("a");');
	phpinfo(); // "a"と表示される
	
	runkit_function_remove('phpinfo');
	phpinfo(); // Call to undefined function phpinfo()
	
	// 返り値を利用しているか確認
	function foo() {
		var_dump(runkit_return_value_used());
	}
	foo(); // false
	$a = foo(); // true
	
	// スーパーグローバル
	$_FOO = 'foo';
	$_BAR = 'bar';
	function test(){
		print($_FOO); // foo
		print($_BAR); // Notice: Undefined variable: _BAR
	}
	test();
	
	var_dump(runkit_superglobals());
掟破りにも程があるだろ。

見てのとおり、定数も関数も制限?何それってレベルで上書きできてしまいます。

runkit.internal_overrideは組み込み関数のオーバーライドを制御するディレクティブです。
デフォルトはfalseで、ユーザ定義関数しか上書きできません。
trueにすると上記のようにphpinfo()等も上書きできるようになります。
さすがにechoのような言語構造は上書きできません。

runkit.superglobalは、「スーパーグローバル変数として扱う変数を追加する」というこれまた反則なディレクティブです。
今回は"_FOO"を追加しているので、$_FOOが$_REQUEST等と同格のスーパーグローバル変数になります。
runkit_superglobals()は、現在のスーパーグローバル変数一覧を取得します。
$GLOBALS、$_REQUEST、$_SESSIONといった見慣れた変数と一緒に$_FOOが入っているのが確認できます。

runkit_return_value_used()は他と毛色の違う関数で、関数呼び出しが、その返り値を使っているかを確認できるという、どういうときに使うのかよくわからない機能です。
いやほんとこれどういうときに使うんだ?

あとrunkit_lint()でコードチェックとかも可能なはずなのですが、手元環境ではapache毎落ちてしまって確認できませんでした。
理由はよくわかりません。


2013/12/30 20:16 | Comments(0) | PHP
買ったものリスト 2013/12/29

ニンテンドー3DS LL ピンクXホワイト 任天堂
☆☆☆☆☆

前3DSをうっかり落としてから微妙に調子が悪かったのですが、ヨドバシに行ったついでにうっかり衝動買い。
画面がでかい。
ミクもますます可愛い。
ただフレアレッドみたいに内側まで色が付いてると思ってたら内側は白だった。残念。


初音ミク Project mirai 2 アゲアゲ★ファンブック
☆☆☆☆

ゲーム攻略本買うのってずいぶん久々なような気がするな。
前買ったのは何だっけ。
セイクリッド2のビルドマスターズガイドとかそこらへんだった気がするな。
本書はファンブックということで譜面とかはありません。残念。
また作曲者コメントもついてない曲があったりしてそこらへんも残念。
ひとり1ページくらい語ってほしかったぜ。
中心は着せ替えコスチュームで、これがまたとにかくかわいい。
攻略や資料としては物足りませんが、ファンブックとしては素晴らしいできです。
ファミ通のくせに大丈夫だったよ。


カッテ!RPG!! 1 おちR
☆☆☆☆

煽りが「ありそうでなかったゲームの擬人化」
そういうのはディスくんの昔からあってだな。
と思えば、名前こそRPGですが、実際は特定タイトルを表す代名詞として使っているだけでした。
題材のわりにゲームネタはほぼ出てきませんが、4コマとしてそこそこ面白い内容でした。

ところで各キャラに誕生日が設定されています。

RPG 1987/04/02 バンダイ さんまの名探偵(ナムコ)?
ギャルゲ 1994/05/27 コナミ ときめきメモリアル
格ゲー 1994/10/01 SNK KOF94
音ゲー 2012/08/30 SEGA 初音ミク-ProjectDIVA-F
STG 1987/02/01 コナミ グラディウス(X68000)
シミュレーション 2012/11/13 ??? 存在しない?

肝心のRPGさんの設定間違ってるんじゃないですかね。
メーカーが潰れたとか書いてあるし。


生徒会役員共8 氏家 ト全
生徒会役員共9
☆☆☆☆

ああ、もう心の拠り所はスズだけだよ。
他のキャラはどんどんもう酷くなりすぎてですね。


2013/12/29 21:35 | Comments(0) | 買ったもの
PHP5.3.3 blencでPHPソースを暗号化(復号できない)
PHPはソースが平文です。
シェアウェアのMovableTypeや、はてまた糞高いSitePublisですら、ソースさえ手に入れてしまえばどうとでもできてしまいます。

ということでソースを暗号化してしまいましょう。
BlencというBLowfishライブラリを見つけましたが、日本語情報がマニュアルのコピペサイト以外一切ありません。
どうなってんだ。

PECLなのでLinuxであれば適当にpecl installとかしてください。
Windowsはdllが用意されているので拾ってきてphp.iniにextensionを書けばOKです。
extension=php_blenc.dll
blenc.key_file = C:\xampp\blenc.key_file
blenc.key_fileは暗号化キーを保存する場所の設定です。
デフォルトは'/usr/local/etc/blenckeys'になっているので、Windowsでは変更必須です。
ini_set()で変更してもいいです。
<?php
	
	// 暗号化するソース
	$source = file_get_contents('path/to/hoge.php');
	
	// 暗号化して書き込み。返り値は暗号化キー
	$key = blenc_encrypt($source, 'path/to/hoge.encrypt.php');
	
	// 暗号化キーも保存
	file_put_contents($ini_get('blenc.key_file'), $key, FILE_APPEND);
hoge.phpをBlowfishで暗号化した結果がhoge.encrypt.phpとして保存されました。
中を見てみると、全く読むことができない状態になっているのがわかります。

そしてこのhoge.encrypt.php、直接PHPファイルとして取り扱い可能です。

Fatal error: blenc_compile: Module php_blenc was expired. Please buy a new license key or disable the module. in Unknown on line 0

おうふ。

expiredってなんだよ。

Blencのソースを見てみる。

http://svn.php.net/viewvc/pecl/blenc/trunk/blenc.c?view=markup
	// エラーはここで発生
	if(BL_G(expired)) {
		zend_error(E_ERROR, "blenc_compile: Module php_blenc was expired. Please buy a new license key or disable the module.");
		return NULL;
	}
	
	// BL_Gはexpire_charと比較してる
	BL_G(expire_date) = pemalloc(sizeof(expire_char), TRUE);
	
	// expire_charはBLENC_PROTECT_EXPIRE
	char expire_char[] = BLENC_PROTECT_EXPIRE;
http://svn.php.net/viewvc/pecl/blenc/trunk/blenc_protect.h?view=markup
	// BLENC_PROTECT_EXPIREは2013年4月30日
	#define BLENC_PROTECT_EXPIRE "30-04-2013"
なんだこれ。

ということでソースからコンパイルできる人続きを頼んだ。



2013/12/27 19:17 | Comments(0) | PHP

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