Pseudo Block

2,494 views
2,378 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,494
On SlideShare
0
From Embeds
0
Number of Embeds
34
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Pseudo Block

  1. 1. eval() と create_function() の ミニレシピ 坂本昌彦 msakamoto-sf@users.sourceforge.net
  2. 2. 自己紹介 ● PHP, Java プログラマー ● 404 Blog Not Found の影響で Perl に浮気中。 ● はてなダイアリ: ● http://d.hatena.ne.jp/msakamoto-sf/ ● PukiWiki : ● http://www.glamenv-septzen.net/pukiwiki/inde x.php
  3. 3. eval() って? ● 文字列を PHP コードとして評価する ● http://jp.php.net/manual/ja/function.eval.php ● サンプルは後で。 ● フレームワークなどで、動的な処理を行わせた い場合に使われているらしい。 ● ● 但し、著者は現場では一度も使ったことがな い。・・・ ( ; ´Д ` ) ウウッ…
  4. 4. create_function() って? ● 匿名関数 ( ラムダ形式 ) を作成する ● http://jp.php.net/manual/ja/function.create-fun ction.php ● array_map などで callback に使う関数を、一々定 義するのが面倒なときに使ったりするらしい。 ● ● 但し、これも著者は現場での使用経験は無 し。・・・ ( ; ´Д ` ) ウウッ…
  5. 5. eval() の例 eval01.php: <?php $a = “xyz”; eval('$b = “abc”; $c = '123'; $result = $a . $b . $c;'); echo $result; ?> > php eval01.php xyzabc123 >
  6. 6. create_function() の例 create_function01.php: <?php $lambda = create_function('$a, $b', 'static $c; $c++; return $a + $b + $c;'); echo $lambda(1, 2) . PHP_EOL; echo $lambda(3, 4) . PHP_EOL; ?> > php create_function01.php 4 // 1 + 2 + 1 ($c) 9 // 3 + 4 + 2 ($c) >
  7. 7. イケテナイ。
  8. 8. エスケープが 面倒くさい。
  9. 9. Perl なら・・・ !! (eval の場合 ) #!/usr/bin/perl use strict; use warnings; my $a = “xyz”; my $result; eval { my $b = “abc”; my $c = '123'; $result = $a . $b . $c; }; print $result;
  10. 10. Perl なら・・・ !! ( 匿名関数の場合 ) #!/usr/bin/perl use strict; use warnings; my $c = 0; my $lambda = sub() { my ($a, $b) = @_; $c++; return $a + $b + $c; }; print $lambda->(1, 2), “n”; print $lambda->(3, 4), “n”;
  11. 11. PHP でこうできれば・・・!! <?php ... eval { $a = ... } $lambda = function($a, $b) { ... return ...; } $result = $lambda(1, 2); ... ?>
  12. 12. 匿名関数については、挑戦者がいた。 パッチも作成され、 ML でも議論された。 [PHP-DEV] PATCH: anonymous functions in PHP http://marc.info/?l=php-internals&m=1174261219 11550&w=2
  13. 13. が・・・。 忘れ去られたっぽい。 Σ (゚ д ゚ lll ) ↓ ML のスレッドも 2007 年 3 月一杯で終了。 ↓ PHP 5.3 Suggested Feature List にも無し。 (http://d.hatena.ne.jp/shimooka/20070910/11893 59199)
  14. 14. 駄目元で PHP のソースを見る。 訳わかんねぇ 。゚ ( ゚ ´Д `゚ ) ゚。 yacc? lex? ZTS ってなーに? “ 小泉守義の PHP ソースコードウォッチ” https://www.codeblog.org/blog/moriyoshi/ “ZeroMemory” http://ido.nu/kuma/ でも読んで勉強してみようか知らん・・・。
  15. 15. 以上が前置き。 手っ取り早く PHP の現状の文法の範囲内で、何と か抜け道を見つけ、エスケープメントの縛りから 逃れる方法は無いのか・・・。 (ヒアドキュメントも目的を達し得ない)
  16. 16. とにかく、 PHP のコードが「そのまま」 べた書きできればイイ!! それが最優先!! とにかくエスケープメントから逃げたい!!!
  17. 17. あった。 電波受信成功 !!! キタ─wwヘ√レvv~ ( ゚∀゚ )─ wwヘ√レvv~─ !!  
  18. 18. 出力バッファリングを使え!! ● PHP では” <?php” - “?>” の「外」はそのまま出 力される。 (HTML 埋め込み型言語だから ) ● つまり、「外」では何を書こうがエスケープの心配 は要らない。 ● → わざと「外」に PHP のコードを書き、それを ob _*() で取得すればどうにかできるのでは?
  19. 19. Proof of Concept hoge1.php : <?php $i = 0; ob_start(); ?> global $i; 普通なら HTML が入る箇所に、わざ $i++; と PHP コードを入れる。 return quot;Hello, World! + [$i]quot;; → エスケープの必要が無くなる。 <?php $_code = ob_get_contents(); ob_end_clean(); echo eval($_code).quot;nquot;; // out : Hello, World! + [1] echo eval($_code).quot;nquot;; // out : Hello, World! + [2] echo eval($_code).quot;nquot;; // out : Hello, World! + [3] ?>
  20. 20. Pseudo_Block 「疑似」コードブロックをサポート http://xhwlay.sourceforge.net/Pseudo_Block/ ・ Apache Software License 2 ・ PHP4/5 ・ PEAR パッケージ
  21. 21. Usage 1 : Pseudo_Eval <?php require_once('Pseudo/Eval.php'); $pe =& new Pseudo_Eval(); $pe->start(); // start pseudo block ?> $a = quot;ABC.quot;; $b = 'xyz.'; ここが疑似ブロック return $a . $b . $c; <?php $pe->end(); // end pseudo block $val = 30; $pe->bind('c', $val); // eval() された時のコードブロックに、変数をコピーする。 $result = $pe->act(); echo $result . PHP_EOL; // out : quot;ABC.xyz.30quot; ?>
  22. 22. Usage 2 : Pseudo_Lambda <?php require_once('Pseudo/Lambda.php'); $pl =& new Pseudo_Lambda('$a, $b'); $pl->start(); // start pseudo block ?> static $c = 0; $c++; return $a + $b + $c + $d; ここが疑似ブロック <?php $pl->end(); // end pseudo block $val = 30; $pl->bind('d', $val); // 匿名関数のスコープに外部変数をコピーする。 $func = $pl->create(); echo $func(1, 2) . PHP_EOL; // out : 34 (1 + 2 + 1($c) + 30($d)) echo $func(3, 4) . PHP_EOL; // out : 39 (3 + 4 + 2($c) + 30($d)) ?>
  23. 23. Usage 3 : Pseudo_Block <?php require_once('Pseudo/Block.php'); $pb =& new Pseudo_Block(); $pb->start(); // start pseudo block ?> Name|Age|Hobbies Masahiko|26|Programming ここが疑似ブロック Sakamoto|62|Cooking FengJing|-|Walking <?php $pb->end(); // end pseudo block $text = $pb->getText(); // 疑似ブロック内のテキストを取得 $rows = array_map('trim', explode(quot;nquot;, $text)); foreach($rows as $row) { echo strtr($row, quot;|quot;, quot;,quot;) . PHP_EOL; } ?>
  24. 24. ご意見募集中。 ● http://sourceforge.net/projects/xhwlay/ – ↑ の Tracker 、あるいは msakamoto-sf のはて なダイアリへ。 ● コードブロック中でクラスや関数を定義したり、 外部と参照をやりとりし始めるとヤバイかも・・・。 – →tokenizer を通して conflict なコードは除去す る? ● あまりいぢめないで下さい。 (*´д ` *) – 泣いちゃいます。 – PHP の文法としてサポートする議論のとば口 になれば・・・。
  25. 25. で。 ・・・使うのか? ↓ 「別に、 eval() とか匿名関数とか使わなくても Web は作れるよね。」 「何でもかんでも {Perl|Ruby|JavaScript|Python} マ ンセーっておかしくね?」 ・・・ビミョー・・・。
  26. 26. おしまい。 ( ゚ Д ゚ )y─┛~~ ウマー。
  27. 27. おまけ:無責任な Proposal C のソースを埋め込み、 PHP の Extension として 実行時にコンパイル ,dl() しちゃうとかどうだろう? (CPAN の Inline モジュールみたく ) 埋め込まれたテキストのハッシュ値を取っておいて 上手く cache, expire の仕掛けを作れば・・・? Pseudo_{C|Java|Ruby|Perl|Python|Lisp|e.t.c}

×