前回\SplPriorityQueueを紹介しましたが、今回のZend\Stdlib\SplPriorityQueueはZendFrameworkによる\SplPriorityQueueの拡張です。
使いやすいように、配列出力やシリアライズする機能が追加されています。
結果。
件数:5
一番目:最優先
キー:4 値:最優先
キー:3 値:にばんめその1
キー:2 値:にばんめその2
キー:1 値:低い
キー:0 値:一番低い
件数:0
結果が前回と微妙に違います。
配列のキーが0スタートになっているのと、同プライオリティのデータが順不同ではなくinsertした順に整列されるのが主な違いです。
また、toArray()、serialize()といった便利なメソッドが増えています。
配列にした場合は優先度が消えるため、配列から元に戻すことはできません。
シリアライズした場合は全情報が保存されるため、完全に元の状態に戻すことができます。
これらのためにわざわざ入れるほどの内容でもありませんが、ZFを使っているならついでにZend\Stdlib\SplPriorityQueueを使ってみてもいいかもしれません。
どうでもいいけどZend\Stdlib\SplPriorityQueue::insert()のソース中で、\SplPriorityQueue::insert()の第二引数priorityに配列を突っ込んでいました。
この使い方、\SplPriorityQueue::insert()には全く書かれていません。
何故かSplPriorityQueue::compare()のノートにしれっと書いてあるだけで、他に何処にも情報が見当たりませんでした。
その結果どうなるかというと、配列の複数の要素で優先順位を判断してくれるようです。
使いやすいように、配列出力やシリアライズする機能が追加されています。
<?php require_once('path/to/channel/vendor/autoload.php'); $queue = new Zend\Stdlib\SplPriorityQueue(); $queue->insert('低い', 10); $queue->insert('最優先', 100); $queue->insert('にばんめその1', 50); $queue->insert('にばんめその2', 50); $queue->insert('一番低い', 1); // 個数 → 5 print($queue->count()); // 配列に取り出す $array = $queue->toArray(); // シリアライズも可能 $serial = $queue->serialize(); // 優先順位の高い順になる foreach($queue as $key=>$val){ print('キー:' . $key . ' 値:' . $val); } // 一度使うとやっぱり消える → 0 print($queue->count()); // シリアライズから元に戻せる $queue2 = new Zend\Stdlib\SplPriorityQueue(); $queue2->unserialize($serial);
結果。
件数:5
一番目:最優先
キー:4 値:最優先
キー:3 値:にばんめその1
キー:2 値:にばんめその2
キー:1 値:低い
キー:0 値:一番低い
件数:0
結果が前回と微妙に違います。
配列のキーが0スタートになっているのと、同プライオリティのデータが順不同ではなくinsertした順に整列されるのが主な違いです。
また、toArray()、serialize()といった便利なメソッドが増えています。
配列にした場合は優先度が消えるため、配列から元に戻すことはできません。
シリアライズした場合は全情報が保存されるため、完全に元の状態に戻すことができます。
これらのためにわざわざ入れるほどの内容でもありませんが、ZFを使っているならついでにZend\Stdlib\SplPriorityQueueを使ってみてもいいかもしれません。
どうでもいいけどZend\Stdlib\SplPriorityQueue::insert()のソース中で、\SplPriorityQueue::insert()の第二引数priorityに配列を突っ込んでいました。
この使い方、\SplPriorityQueue::insert()には全く書かれていません。
何故かSplPriorityQueue::compare()のノートにしれっと書いてあるだけで、他に何処にも情報が見当たりませんでした。
その結果どうなるかというと、配列の複数の要素で優先順位を判断してくれるようです。
PR
前回の続き。
http://bloggdgd.blog28.fc2.com/blog-entry-272.html
> 「Recursive」って入ってるけど
なんてこった、Recursiveは再帰って発想はなかった。
いや、皮肉とかじゃなくて素で気付いてなかった。
さて、せっかくなので色々見つけたarray_flatten関数のパフォーマンスを測定してみます。
似てるっぽいのは除いて、6種類を適当に試してみました。
array_flatten1()は前回作ったやつで、自力では一切何もせずSPLに任せっきりです。
array_flatten2()はCertaiN氏の「再帰を使わないものでは最も美しい」関数です。
array_splice()なんて初めて見たよ。
array_flatten3()も再帰を使わないパターンですが、array_flatten2()よりは平易に書かれています。
まあループ中で自分自身を更新しててややこしいのはかわらないのですが。
array_flatten4()は、典型的な再帰パターンです。
私が何も参考にせず一から書いたらこうなっていたと思います。
array_flatten5()は再帰にarray_walk_recursive()を用いたパターン。
正直array_walk_recursive()難しいです。
array_flatten6()はおまけです。
中身はarray_flatten1()とほぼ同じで、一番外側のiterator_to_array()だけを手動でやってるわけですが、ビルトイン関数とどちらが早いでしょうか。
展開後の個数は動作確認用です。
最大10階層のランダム構造、変数の個数の合計は見てのとおり68228個の多重配列を1次元に展開しています。
一発取りなので多少の誤差はありますが、何回かやっても時間が逆転するほどの違いはありませんでした。
1位はarray_flatten5。
array_walk_recursive()ちょっぱや!
2位はarray_flatten1。
簡潔で美しい上に速度も速い。
素晴らしい。
--0.1秒の壁--
3位はarray_flatten6。
foreachを手動で回したぶんだけ遅くなっているのでしょうか。
こーゆーのはビルトイン使っとけば基本問題無いんですよ。
4位はarray_flatten3。
array_flatten2とあまり変わらないように見えるのですが早いですね。
やはりarray_shift()やarray_merge()のようなよく使われる関数は最適化も進んでいるのでしょうか。
--0.2秒の壁--
5位はarray_flatten4。
再帰はやはり何度も関数呼び出しが入るぶん遅くなってしまうのでしょうか。
やってることはそんなに変わらないはずのarray_walk_recursive()に比べて4倍近い時間がかかっていますね。
--0.4秒の壁--
残念ながらarray_flatten2は問題外という結果になりました。
幾ら美しくても実用に耐えなくては役に立ちません。
ちなみに計測に用いた配列は以下で生成しました。
2013/05/29追記
http://bloggdgd.blog28.fc2.com/blog-entry-278.html
CertaiN氏の検証によりますと、array_merge()とarray_splice()そのものについてはarray_splice()のほうが早いようです。
Cのソース読めないので本当はどういう実装になっているのかは知らないのですが、マニュアルのコメント欄などでも「array_splice()の方がはえーよ」との声が多いようです。
http://php.net/manual/ja/function.array-splice.php
http://php.net/manual/ja/function.array-merge.php
従ってarray_flatten2()がタイムアウトでarray_flatten4()がそれなりに早い理由は、それ以外の部分(おそらくforeachとwhile)にあるであろうということです。
2013/05/30追記
http://yuubiseiharukana.blog.shinobi.jp/Entry/1174/
array_flatten3()にarray_splice()やったらarray_flatten3()より早くなりました。
クッソってほどではないのでなんか間違ってる気もしますが。
http://bloggdgd.blog28.fc2.com/blog-entry-272.html
> 「Recursive」って入ってるけど
なんてこった、Recursiveは再帰って発想はなかった。
いや、皮肉とかじゃなくて素で気付いてなかった。
さて、せっかくなので色々見つけたarray_flatten関数のパフォーマンスを測定してみます。
<?php // by NurseAngel // http://yuubiseiharukana.blog.shinobi.jp/Entry/1155/ function array_flatten1($arr) { return iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)), false); } // by CertaiN // http://bloggdgd.blog28.fc2.com/blog-entry-272.html function array_flatten2($arr) { $arr = array_values($arr); while (list($k,$v)=each($arr)) { if (is_array($v)) { array_splice($arr,$k,1,$v); next($arr); } } return $arr; } // by Happy Programming // http://blog.beanz-net.jp/happy_programming/2008/11/phparray-flatten.html function array_flatten3($array) { $tmp = array(); while (($val = array_shift($array)) !== null) { if (is_array($val)) $array = array_merge($val, $array); else $tmp[] = $val; } return $tmp; } // by wellandpower at hotmail.com // http://www.php.net/manual/en/function.array-values.php#77542 function array_flatten4($array) { $flat = array(); foreach ($array as $value) { if (is_array($value)) $flat = array_merge($flat, array_flatten4($value)); else $flat[] = $value; } return $flat; } // by might // http://might1976.doorblog.jp/archives/51164023.html#more function array_flatten5($array){ $result = array(); array_walk_recursive($array, function($v) use (&$result){ $result[] = $v; }); return $result; } // by crashrox at gmail dot com // http://www.php.net/manual/ja/class.recursiveiteratoriterator.php#87757 function array_flatten6($array) { if($array) { $flat = array(); foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST) as $key=>$value) { if(!is_array($value)) { $flat[] = $value; } } return $flat; } else { return false; } }
似てるっぽいのは除いて、6種類を適当に試してみました。
array_flatten1()は前回作ったやつで、自力では一切何もせずSPLに任せっきりです。
array_flatten2()はCertaiN氏の「再帰を使わないものでは最も美しい」関数です。
array_splice()なんて初めて見たよ。
array_flatten3()も再帰を使わないパターンですが、array_flatten2()よりは平易に書かれています。
まあループ中で自分自身を更新しててややこしいのはかわらないのですが。
array_flatten4()は、典型的な再帰パターンです。
私が何も参考にせず一から書いたらこうなっていたと思います。
array_flatten5()は再帰にarray_walk_recursive()を用いたパターン。
正直array_walk_recursive()難しいです。
array_flatten6()はおまけです。
中身はarray_flatten1()とほぼ同じで、一番外側のiterator_to_array()だけを手動でやってるわけですが、ビルトイン関数とどちらが早いでしょうか。
関数 | 処理時間 | 展開後の個数 |
---|---|---|
array_flatten1 | 0.08642秒 | 68228 |
array_flatten2 | Maximum execution time of 30 seconds exceeded | |
array_flatten3 | 0.19846秒 | 68228 |
array_flatten4 | 0.32668秒 | 68228 |
array_flatten5 | 0.06959秒 | 68228 |
array_flatten6 | 0.11780秒 | 68228 |
展開後の個数は動作確認用です。
最大10階層のランダム構造、変数の個数の合計は見てのとおり68228個の多重配列を1次元に展開しています。
一発取りなので多少の誤差はありますが、何回かやっても時間が逆転するほどの違いはありませんでした。
1位はarray_flatten5。
array_walk_recursive()ちょっぱや!
2位はarray_flatten1。
簡潔で美しい上に速度も速い。
素晴らしい。
--0.1秒の壁--
3位はarray_flatten6。
foreachを手動で回したぶんだけ遅くなっているのでしょうか。
こーゆーのはビルトイン使っとけば基本問題無いんですよ。
4位はarray_flatten3。
array_flatten2とあまり変わらないように見えるのですが早いですね。
--0.2秒の壁--
5位はarray_flatten4。
再帰はやはり何度も関数呼び出しが入るぶん遅くなってしまうのでしょうか。
やってることはそんなに変わらないはずのarray_walk_recursive()に比べて4倍近い時間がかかっていますね。
--0.4秒の壁--
残念ながらarray_flatten2は問題外という結果になりました。
幾ら美しくても実用に耐えなくては役に立ちません。
ちなみに計測に用いた配列は以下で生成しました。
function mkarray($depth = 0, $stop = 0){ if($depth <= 0 || $stop !== 0){ return mt_rand(1, 10); }else{ $ret = array_fill(0, mt_rand(1, 10), '1'); foreach($ret as $key=>$val){ $ret[$key] = mkarray(($depth-1), mt_rand(0, 2)); } return $ret; } } $arr = mkarray(10);何度かvar_export()して、大きめの配列が生成されたときにそれを保存して使用しました。
2013/05/29追記
http://bloggdgd.blog28.fc2.com/blog-entry-278.html
CertaiN氏の検証によりますと、array_merge()とarray_splice()そのものについてはarray_splice()のほうが早いようです。
Cのソース読めないので本当はどういう実装になっているのかは知らないのですが、マニュアルのコメント欄などでも「array_splice()の方がはえーよ」との声が多いようです。
http://php.net/manual/ja/function.array-splice.php
http://php.net/manual/ja/function.array-merge.php
従ってarray_flatten2()がタイムアウトでarray_flatten4()がそれなりに早い理由は、それ以外の部分(おそらくforeachとwhile)にあるであろうということです。
2013/05/30追記
http://yuubiseiharukana.blog.shinobi.jp/Entry/1174/
array_flatten3()にarray_splice()やったらarray_flatten3()より早くなりました。
クッソってほどではないのでなんか間違ってる気もしますが。
http://bloggdgd.blog28.fc2.com/blog-entry-272.html
> これより美しいコード書いた奴いたら名乗り出てこい!!11
個人的には、リンク先にあるこれが一番美しいと思うんですよね。
というわけで上記を関数に仕立て上げた、自称最も美しいarray_flatten。
iterator_to_array()が微妙だ…
RecursiveIteratorIteratorは値を突っ込んだ時点ではそのままの構造が保持されており、foreach()で取り出さないとフラットになってくれません。
とか書いても元の値が戻ってくるだけです。
こっちみたいに書ければ自称を外していいほど最強だったのにまったくもって非常に残念。
ていうか、せっかく自分で調べたのにAdil Baig @ AIdezignsって人がとっくに回答済だった。
> これより美しいコード書いた奴いたら名乗り出てこい!!11
function array_flatten($arr) { $arr = array_values($arr); while (list($k,$v)=each($arr)) { if (is_array($v)) { array_splice($arr,$k,1,$v); next($arr); } } return $arr; }
個人的には、リンク先にあるこれが一番美しいと思うんですよね。
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($a)); foreach($it as $v) { echo $v, " "; }array_splice()みたいなややこしい関数も使ってなくて圧倒的に見やすいですし。
というわけで上記を関数に仕立て上げた、自称最も美しいarray_flatten。
function array_flatten($arr) { return iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)), false); }
iterator_to_array()が微妙だ…
RecursiveIteratorIteratorは値を突っ込んだ時点ではそのままの構造が保持されており、foreach()で取り出さないとフラットになってくれません。
function array_flatten_fail($arr) { return (new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)))->getArrayCopy(); }
とか書いても元の値が戻ってくるだけです。
こっちみたいに書ければ自称を外していいほど最強だったのにまったくもって非常に残念。
ていうか、せっかく自分で調べたのにAdil Baig @ AIdezignsって人がとっくに回答済だった。
PHP5.3でSplPriorityQueue、優先度つきキューが実装されました。
取得時、第二引数の値が高いものから順に並べ替えられます。
出力
件数:5
一番目:最優先
キー:5 値:最優先
キー:4 値:にばんめその2
キー:3 値:にばんめその1
キー:2 値:低い
キー:1 値:一番低い
件数:0
優先したいデータから順に表示することができました。
なお、同じ優先度内での順番がどうなるかは保証されていません。
実用としてはわりと困ることに、Wikipediaの定義通りの実装がなされています。
どういうことって一度使ったら無くなってしまうんですよね。
具体的にはSplPriorityQueue::next()したときに、イテレータを進めるかわりにshiftするので値が消滅します。
なので繰り返し使う場合はcloneするか、配列に取り出すなどしてから扱う必要があります。
取得時、第二引数の値が高いものから順に並べ替えられます。
<?php $queue = new SplPriorityQueue(); $queue->insert('低い', 10); $queue->insert('最優先', 100); $queue->insert('にばんめその1', 50); $queue->insert('にばんめその2', 50); $queue->insert('一番低い', 1); // 個数 → 5 print('件数:' . $queue->count()); // 一番目を閲覧。これは使っても無くならない。 print('一番目:' . $queue->top()); // 優先順位の高い順に取り出す foreach($queue as $key=>$val){ print('キー:' . $key . ' 値:' . $val); } // 一度使うと無くなる → 0 print('件数:' . $queue->count()); // rewindは意味がない $queue->rewind();
出力
件数:5
一番目:最優先
キー:5 値:最優先
キー:4 値:にばんめその2
キー:3 値:にばんめその1
キー:2 値:低い
キー:1 値:一番低い
件数:0
優先したいデータから順に表示することができました。
なお、同じ優先度内での順番がどうなるかは保証されていません。
実用としてはわりと困ることに、Wikipediaの定義通りの実装がなされています。
どういうことって一度使ったら無くなってしまうんですよね。
具体的にはSplPriorityQueue::next()したときに、イテレータを進めるかわりにshiftするので値が消滅します。
なので繰り返し使う場合はcloneするか、配列に取り出すなどしてから扱う必要があります。
GoWJ、3回目のレベル50達成。
これで取れる実績は取り尽くしたので終了ですかね。
ストーリーが短いとか対戦マップがやたら少ないとか色々言いたいこともありますが、映像は相変わらず素晴らしいし対戦自体はやっぱり面白いしで、十分満足できる作品でした。
あ、インセインスターとかSURVIVALクリアとかは無理です、はい。
あとDLCはどうしよう。
魔法少女チキチキ 新装版 上 小池 定路
魔法少女チキチキ 新装版 下
☆☆☆☆
魔法少女で4コマってどうせありがちなドタバタコメディだろうと思ってたら全然違った。
コメディこそ多少あるものの、基本はハートフルでとても優しい作品でした。
魔法という非日常極まりない要素が主役にもかかわらず派手さの全く無い、地味で、でも安心した空気の流れるよい作品でした。
迷宮街クロニクル1 生還まで何マイル? 林 亮介
☆☆☆☆
あれ、なんか物凄く見覚えがあるぞ。
しかもプロローグは全く覚えがないのに第一週から部分部分はっきり覚えてるぞ。
なんだこれ。
と思ったらWeb小説からの出版だったようです。
きっと覚えがあるのはそこで読んだからで、覚えがないところは加筆修正部分でしょう。
読んだ記憶そのものは全く無いのですがね。
内容を一言で表すと現代ウィザードリィ。
現代日本にいきなり穴が空いて怪物が現れたらどうなるか、というシミュレーション的考察は、たいしてありません。
基本的に主人公および他キャラクターの一人称視点から語られるからで、そのあたりはスルーです。
自衛隊が入らないのはどうこうと理由付けはありますが、実際日本で発生したらどう考えても自衛隊に封鎖されるだろ。
OL進化論33
OL進化論34
☆☆☆
OLってすっかり聞かなくなったような気がするがまだ生きてるのか?
昔と全く変わらない、変わらなすぎる安定のOL4コマ。
秋月りすさんの周りでは時間が止まっているのだろうか。
特筆するような長辺はないが、といって特筆する欠点があるわけでもない、非常に安定したいつまでも日常が続くナイスまんが。
新刊でありながら既にノスタルジックな雰囲気まで醸し出している気がしないでもない。
ただ、35歳で独身は既に珍しくも何ともなくなっているような。
これで取れる実績は取り尽くしたので終了ですかね。
ストーリーが短いとか対戦マップがやたら少ないとか色々言いたいこともありますが、映像は相変わらず素晴らしいし対戦自体はやっぱり面白いしで、十分満足できる作品でした。
あ、インセインスターとかSURVIVALクリアとかは無理です、はい。
あとDLCはどうしよう。
魔法少女チキチキ 新装版 上 小池 定路
魔法少女チキチキ 新装版 下
☆☆☆☆
魔法少女で4コマってどうせありがちなドタバタコメディだろうと思ってたら全然違った。
コメディこそ多少あるものの、基本はハートフルでとても優しい作品でした。
魔法という非日常極まりない要素が主役にもかかわらず派手さの全く無い、地味で、でも安心した空気の流れるよい作品でした。
迷宮街クロニクル1 生還まで何マイル? 林 亮介
☆☆☆☆
あれ、なんか物凄く見覚えがあるぞ。
しかもプロローグは全く覚えがないのに第一週から部分部分はっきり覚えてるぞ。
なんだこれ。
と思ったらWeb小説からの出版だったようです。
きっと覚えがあるのはそこで読んだからで、覚えがないところは加筆修正部分でしょう。
読んだ記憶そのものは全く無いのですがね。
内容を一言で表すと現代ウィザードリィ。
現代日本にいきなり穴が空いて怪物が現れたらどうなるか、というシミュレーション的考察は、たいしてありません。
基本的に主人公および他キャラクターの一人称視点から語られるからで、そのあたりはスルーです。
自衛隊が入らないのはどうこうと理由付けはありますが、実際日本で発生したらどう考えても自衛隊に封鎖されるだろ。
OL進化論33
OL進化論34
☆☆☆
OLってすっかり聞かなくなったような気がするがまだ生きてるのか?
昔と全く変わらない、変わらなすぎる安定のOL4コマ。
秋月りすさんの周りでは時間が止まっているのだろうか。
特筆するような長辺はないが、といって特筆する欠点があるわけでもない、非常に安定したいつまでも日常が続くナイスまんが。
新刊でありながら既にノスタルジックな雰囲気まで醸し出している気がしないでもない。
ただ、35歳で独身は既に珍しくも何ともなくなっているような。
http://memocarilog.info/wordpress/5278
まず思ったこと。
「はてなブックマークのタイトルにスクリプトって入れられるかな。」
はてなを一切使用したことがないので仕様とか知らないんですけどね。
なお参照先のWEB Drawer『JavaScriptを使って、自サイトでの「はてなブックマーク」の人気記事一覧を表示する』でも、無邪気に$().append()で追加してますね。
まあタイトルが長ければ途中で切られてしまうようですし、実質的に意味のあるインジェクションを行うのは難しいでしょうけど、外部からの変数を利用する場合は必ずhtmlspecialchars()を使用しましょう。
JavaScriptであれば、文字列連結ではなくinnerTextなどを使うのが安全でしょう。
まあレスポンスはJSONPなくらいだし、この場合はリンク先を完全に信用するのが前提なのかもしれませんが、だからといって今回は信用できる、こっちは信用できない、なんてやってたら間違いなく事故ります。
外部からの値は常に信用できないものとして取り扱うべきです。
ちなみにリンク先のことくらいであれば、わざわざCURL使わなくても@file_get_contents($url)の一行で終わるのは秘密。
まず思ったこと。
「はてなブックマークのタイトルにスクリプトって入れられるかな。」
はてなを一切使用したことがないので仕様とか知らないんですけどね。
なお参照先のWEB Drawer『JavaScriptを使って、自サイトでの「はてなブックマーク」の人気記事一覧を表示する』でも、無邪気に$().append()で追加してますね。
まあタイトルが長ければ途中で切られてしまうようですし、実質的に意味のあるインジェクションを行うのは難しいでしょうけど、外部からの変数を利用する場合は必ずhtmlspecialchars()を使用しましょう。
JavaScriptであれば、文字列連結ではなくinnerTextなどを使うのが安全でしょう。
まあレスポンスはJSONPなくらいだし、この場合はリンク先を完全に信用するのが前提なのかもしれませんが、だからといって今回は信用できる、こっちは信用できない、なんてやってたら間違いなく事故ります。
外部からの値は常に信用できないものとして取り扱うべきです。
ちなみにリンク先のことくらいであれば、わざわざCURL使わなくても@file_get_contents($url)の一行で終わるのは秘密。
Aura.Uriは、URLなどを論理的に作成・分析できますよというクラスです。
ってつい先日やった気がするな。
さて、どちらが優秀か試してみましょう。
Factory::getInstance($http)みたいなstaticメソッドが無く、いちいち無意味なインスタンス化をしないといけないのがよくわかりません。
基本的にZend\Uri\Uriと同等のことができますが、is**の検証系メソッドはありません。
AuraはtoString()のようなメソッドをあまり持たず、マジックメソッド__toString()で文字列変換を実装しています。
なので文字列にしたい場合はStringにキャストしましょう。
プロパティは概ねStringですが、pathとqueryだけクラスになっています。
そしてこのAura\Uri\Queryには問題があります。
まずQuery::buildString()が何故かprotectedなので、Zend\Uri\Uri::setQueryのような配列形式での投入ができません。
そしてヘルプでは$url->query->baz = 'zab';とか書いてありますが、実はこれが正しく動作しません。
Aura\Uri\Queryは\ArrayObjectをextendsしているのですが、呼び出しの引数に\ArrayObject::ARRAY_AS_PROPSを記述していないせいで、プロパティと配列が別の値として扱われます。
Aura\Uri\Queryは内部値を配列形式で取り扱っているため、プロパティで指定した値は反映されません。
思いっきりバグじゃねーかこれ。
指定するときは配列形式で指定するか、setFromString()を使いましょう。
なおsetFromString()は他の値を全部消して上書きするので、上記例ではaとbが消えています。
AuraPHPの記事
ってつい先日やった気がするな。
さて、どちらが優秀か試してみましょう。
<?php require_once('path/to/channel/vendor/autoload.php'); // Aura.Uri $http = 'http://example.com/foo/../bar.php?a=1&b=2#hoge'; $factory = new Aura\Uri\Url\Factory($_SERVER); $uri = $factory->newInstance($http); // 分析 // スキーマを取得 $uri->scheme; // http // ユーザ名/パスワードを取得 $uri->user; // NULL $uri->pass; // NULL // ホスト名を取得 $uri->host; // example.com // ポート番号を取得 $uri->port; // NULL // パスを取得 (string)$uri->path; // /foo/../bar.php (string)$uri->query; // a=1&b=2 $uri->query->getArrayCopy(); // array('a'=>'1', 'b'=>'2') $uri->fragment; // hoge // 参照を解消 $uri->get(); // /fuga.php?c=3&d=4 // 作成 $uri->setScheme('https'); $uri->setUser('user'); $uri->setPass('pass'); $uri->setHost('example.jp'); $uri->setPort(443); $uri->path->setFromString('/fuga.php'); $uri->setFragment(''); // $uri->query->buildString(array('c'=>3, 'd'=>4)); // Fatal error:Call to protected method $uri->query->a = 5; // 正しく動作しない $uri->query['b'] = 6; // OK $uri->query->setFromString('c=3&d=4'); // OK (string)$uri; // https://user:pass@example.jp:443/fuga.php?c=3&d=4
Factory::getInstance($http)みたいなstaticメソッドが無く、いちいち無意味なインスタンス化をしないといけないのがよくわかりません。
基本的にZend\Uri\Uriと同等のことができますが、is**の検証系メソッドはありません。
AuraはtoString()のようなメソッドをあまり持たず、マジックメソッド__toString()で文字列変換を実装しています。
なので文字列にしたい場合はStringにキャストしましょう。
プロパティは概ねStringですが、pathとqueryだけクラスになっています。
そしてこのAura\Uri\Queryには問題があります。
まずQuery::buildString()が何故かprotectedなので、Zend\Uri\Uri::setQueryのような配列形式での投入ができません。
そしてヘルプでは$url->query->baz = 'zab';とか書いてありますが、実はこれが正しく動作しません。
Aura\Uri\Queryは\ArrayObjectをextendsしているのですが、呼び出しの引数に\ArrayObject::ARRAY_AS_PROPSを記述していないせいで、プロパティと配列が別の値として扱われます。
Aura\Uri\Queryは内部値を配列形式で取り扱っているため、プロパティで指定した値は反映されません。
思いっきりバグじゃねーかこれ。
指定するときは配列形式で指定するか、setFromString()を使いましょう。
なおsetFromString()は他の値を全部消して上書きするので、上記例ではaとbが消えています。
AuraPHPの記事
Zend\Uri\Uriは、URLなどを論理的に作成・分析できますよというクラスです。
APIを呼び出す際のURLを論理的に作成したり、ユーザ入力値の検証などに使えるでしょう。
今回は'http'なのでZend\Uri\Httpクラスのインスタンスとなります。
他にも色々あるかと思いきや、実は'mailto'のZend\Uri\Mailto、'file'のZend\Uri\Fileしかありません。
FTPすら無いとはびっくりだ。
ところでこれがDIなんですかね、いまいちわかりません。
normalize()やmakeRelative()はsetという名前は付いていませんがオブジェクトを直接書き換えるので、以後getScheme()やgetPath()などの値が変わる可能性があります。
少しだけ気をつけましょう。
このようにZend\Uri\Uriを使うことで、URLの論理的な組み立て、分解が可能になりました。
APIを呼び出す際のURLを論理的に作成したり、ユーザ入力値の検証などに使えるでしょう。
<?php require_once('path/to/channel/vendor/autoload.php'); // HTTP $http = 'http://example.com/foo/../bar.php?a=1&b=2#hoge'; $uri = Zend\Uri\UriFactory::factory($http); // 分析 // 正しいURLか $uri->isValid(); // true // 正しい相対パスか $uri->isValidRelative(); // false // 絶対パスか $uri->isAbsolute(); // true // スキーマを取得 $uri->getScheme(); // http // ユーザ名/パスワードを取得 $uri->getUserInfo(); // NULL // ホスト名を取得 $uri->getHost(); // example.com // ポート番号を取得 $uri->getPort(); // 80 // パスを取得 $uri->getPath(); // /foo/../bar.php $uri->getQuery(); // a=1&b=2 $uri->getQueryAsArray(); // array('a'=>'1', 'b'=>'2') $uri->getFragment(); // hoge // 参照を解消 $uri->normalize()->toString(); // http://example.com/bar.php?a=1&b=2#hoge // ベースURIからの相対パスにする $uri->makeRelative('http://example.com/foo/')->toString(); // bar.php?a=1&b=2#hoge /* ../bar.php?a=1&b=2#hogeにならないのはバグな気がする */ // 作成 $uri->setScheme('https'); $uri->setUserInfo('user:pass'); $uri->setHost('example.jp'); $uri->setPort(443); $uri->setPath('/fuga.php'); $uri->setQuery(array('c'=>'3', 'd'=>'4')); $uri->setFragment(''); $uri->toString(); // https://user:pass@example.jp:443/fuga.php?c=3&d=4Zend\Uri\UriFactory::factoryにチェックしたいURLを突っ込むと、適切なZend\Uri\UriInterface実装クラスが帰ってきます。
今回は'http'なのでZend\Uri\Httpクラスのインスタンスとなります。
他にも色々あるかと思いきや、実は'mailto'のZend\Uri\Mailto、'file'のZend\Uri\Fileしかありません。
FTPすら無いとはびっくりだ。
ところでこれがDIなんですかね、いまいちわかりません。
normalize()やmakeRelative()はsetという名前は付いていませんがオブジェクトを直接書き換えるので、以後getScheme()やgetPath()などの値が変わる可能性があります。
少しだけ気をつけましょう。
このようにZend\Uri\Uriを使うことで、URLの論理的な組み立て、分解が可能になりました。
ドラクエ7、とりあえずクリア。
クリアタイムは50時間程度。
なんかラスダンまで来たところで経験値稼ぎモードに入ってしまい、10時間ほど口笛を吹き続けてしまった。
おかげでラスボスに楽勝。
というかラスボス、こんな残念な性格だったっけ。
不思議なくらい全く覚えてないや。
あとは裏ダンジョンとDLCシナリオをクリアしたら終了かな。
さすがにモンスター図鑑コンプとかはやる気にならない。
鬱ごはん1 施川 ユウキ
☆☆☆☆☆
言葉の魔術師施川ユウキの最新刊、一挙三冊発売。
なんと素晴らしい。
三冊とも傑作なので買え。
鬱ごはんは就職浪人、鬱野タケシがごはんを食べる話。
第一話から「思うにベジタリアンの前世はハエトリソウに食われたハエだ。奴らは植物に復讐心を燃やし執拗にサラダを食らう」と素敵フレーズが炸裂します。
グルメ漫画といえば美食。
> ・料理がつくられる
> ・過程が描かれている
> ・美味しさが表現されている
どれも無え!
ご飯を食べたくなる気力が全く湧かない異次元のグルメ漫画です。
しかし嫌々言いながら、腹が減ってもないのに年越し蕎麦を律儀に食べたり、わりとこまめに自炊していたりなど、意外とその境遇を楽しんでいたり。
バーナード嬢曰く1 施川 ユウキ
☆☆☆☆☆
バーナード嬢こと町田さわ子は文学少女。
…のふりをしているが実際本は全然読まない残念少女。
既存の本のタイトルやあらすじ、格言などについて、施川ユウキ的な異次元の解釈によって新たな切り口を見せつけてくれます。
問題は、そんな切り口本来は存在しないってところですが。
これほど読んだこと無い本を読みたくなってしまう紹介文も珍しいです。
というか作中に出てくる『三びきのやぎのがらがらどん』『合成怪物』とか絶対ネタだろうと思っていたら実在するのかよ。
びっくりだ。
ちなみに参考文献で読んだことあるのは以下だけでした。少ない。
ジェイムズ・ティプトリー・ジュニア『たったひとつの冴えたやり方』
ジューヌ・ヴェルヌ『海底二万里』
テッド・チャン『あなたの人生の物語』
シドニィ・シェルダン『真夜中は別の顔』
フランツ・カフカ『変身』
サイモン・シン『フェルマーの最終定理』
ロバート・A・ハインライン『夏への扉』
ロバート・A・ハインライン『月は無慈悲な夜の女王』
山田真哉『さおだけ屋はなぜ潰れないのか? 身近な疑問からはじめる会計学』
スペンサー・ジョンソン『チーズはどこへ消えた?』
しかし中身を覚えていない本もあるので、そういうのはもしかしたら読破したっぽいフンイキになっているだけかもしれません。
チーズはどこへ消えた?は物凄く下らない内容だったというのだけは覚えている。
罪と罰は昔持ってたが1ページも読まずに挫折した。
いずれ再挑戦してみるかのう。
オンノジ 施川 ユウキ
☆☆☆☆☆
ある日突然人や動物が完全にいなくなってしまった世界、そこにたった一人残されてしまった女の子ミヤコは毎日町を彷徨う。
やがて自分以外の何かが存在していることに気付いたミヤコは、それをオンノジと名付けた。
やばい、あらすじだけだと死ぬほどつまらなそうだ。
もちろんそんなことはなく、施川ユウキ独特の空気が全編に漂うシュールでハートフルな傑作となっています。
酢めし疑獄ほどの理不尽さはないながらも初期の作風に最も近く、それでいて初期には全く無かった恋愛要素も一番多めで、これまでの集大成的な作品かもしれません。
3冊中で一番よかったのを挙げるとしたらオンノジです。
まあ、これだけ完結しているからかもしれませんが。
お約束とはいえあの最終回は反則だろー。
サクラテツ対話編上巻 藤崎 竜
サクラテツ対話編下巻
☆☆☆
い、意味が、意味がわかりません。
さすがに新刊では入手できないので古本で発掘。
と思いきや復刻版出てたのか。
なんてこった。まあいいや。
毎話毎話異次元かつ明後日の世界が繰り広げられます。
しかしそもそも根本的に全く対話していないのはどうなんだ。
各作者の元ネタ作品を読めば何か理解の通じるところもあるかもしれませんが、今の私では無理でした。
クリアタイムは50時間程度。
なんかラスダンまで来たところで経験値稼ぎモードに入ってしまい、10時間ほど口笛を吹き続けてしまった。
おかげでラスボスに楽勝。
というかラスボス、こんな残念な性格だったっけ。
不思議なくらい全く覚えてないや。
あとは裏ダンジョンとDLCシナリオをクリアしたら終了かな。
さすがにモンスター図鑑コンプとかはやる気にならない。
鬱ごはん1 施川 ユウキ
☆☆☆☆☆
言葉の魔術師施川ユウキの最新刊、一挙三冊発売。
なんと素晴らしい。
三冊とも傑作なので買え。
鬱ごはんは就職浪人、鬱野タケシがごはんを食べる話。
第一話から「思うにベジタリアンの前世はハエトリソウに食われたハエだ。奴らは植物に復讐心を燃やし執拗にサラダを食らう」と素敵フレーズが炸裂します。
グルメ漫画といえば美食。
> ・料理がつくられる
> ・過程が描かれている
> ・美味しさが表現されている
どれも無え!
ご飯を食べたくなる気力が全く湧かない異次元のグルメ漫画です。
しかし嫌々言いながら、腹が減ってもないのに年越し蕎麦を律儀に食べたり、わりとこまめに自炊していたりなど、意外とその境遇を楽しんでいたり。
バーナード嬢曰く1 施川 ユウキ
☆☆☆☆☆
バーナード嬢こと町田さわ子は文学少女。
…のふりをしているが実際本は全然読まない残念少女。
既存の本のタイトルやあらすじ、格言などについて、施川ユウキ的な異次元の解釈によって新たな切り口を見せつけてくれます。
問題は、そんな切り口本来は存在しないってところですが。
これほど読んだこと無い本を読みたくなってしまう紹介文も珍しいです。
というか作中に出てくる『三びきのやぎのがらがらどん』『合成怪物』とか絶対ネタだろうと思っていたら実在するのかよ。
びっくりだ。
ちなみに参考文献で読んだことあるのは以下だけでした。少ない。
ジェイムズ・ティプトリー・ジュニア『たったひとつの冴えたやり方』
ジューヌ・ヴェルヌ『海底二万里』
テッド・チャン『あなたの人生の物語』
シドニィ・シェルダン『真夜中は別の顔』
フランツ・カフカ『変身』
サイモン・シン『フェルマーの最終定理』
ロバート・A・ハインライン『夏への扉』
ロバート・A・ハインライン『月は無慈悲な夜の女王』
山田真哉『さおだけ屋はなぜ潰れないのか? 身近な疑問からはじめる会計学』
スペンサー・ジョンソン『チーズはどこへ消えた?』
しかし中身を覚えていない本もあるので、そういうのはもしかしたら読破したっぽいフンイキになっているだけかもしれません。
チーズはどこへ消えた?は物凄く下らない内容だったというのだけは覚えている。
罪と罰は昔持ってたが1ページも読まずに挫折した。
いずれ再挑戦してみるかのう。
オンノジ 施川 ユウキ
☆☆☆☆☆
ある日突然人や動物が完全にいなくなってしまった世界、そこにたった一人残されてしまった女の子ミヤコは毎日町を彷徨う。
やがて自分以外の何かが存在していることに気付いたミヤコは、それをオンノジと名付けた。
やばい、あらすじだけだと死ぬほどつまらなそうだ。
もちろんそんなことはなく、施川ユウキ独特の空気が全編に漂うシュールでハートフルな傑作となっています。
酢めし疑獄ほどの理不尽さはないながらも初期の作風に最も近く、それでいて初期には全く無かった恋愛要素も一番多めで、これまでの集大成的な作品かもしれません。
3冊中で一番よかったのを挙げるとしたらオンノジです。
まあ、これだけ完結しているからかもしれませんが。
お約束とはいえあの最終回は反則だろー。
サクラテツ対話編上巻 藤崎 竜
サクラテツ対話編下巻
☆☆☆
い、意味が、意味がわかりません。
さすがに新刊では入手できないので古本で発掘。
と思いきや復刻版出てたのか。
なんてこった。まあいいや。
毎話毎話異次元かつ明後日の世界が繰り広げられます。
しかしそもそも根本的に全く対話していないのはどうなんだ。
各作者の元ネタ作品を読めば何か理解の通じるところもあるかもしれませんが、今の私では無理でした。