Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perlに比べてPHPが不便(主観です) ああ…だから僕は…
Search
uzulla
May 21, 2016
Programming
3
4.7k
Perlに比べてPHPが不便(主観です) ああ…だから僕は…
LT at PHP Conference Fukuoka 2016
uzulla
May 21, 2016
Tweet
Share
More Decks by uzulla
See All by uzulla
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
1.5k
似たもの同士のPerlとPHP
uzulla
1
220
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
160
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
250
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
170
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
2.5k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
5
1.2k
PHPerが ISUCONでやるべき事
uzulla
1
1.3k
開発生産性は上がらない - N Ways to Reduce Development Productivity
uzulla
1
300
Other Decks in Programming
See All in Programming
AIと”コードの評価関数”を共有する / Share the "code evaluation function" with AI
euglena1215
1
150
iOS 26にアップデートすると実機でのHot Reloadができない?
umigishiaoi
0
130
すべてのコンテキストを、 ユーザー価値に変える
applism118
3
1.2k
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
920
生成AI時代のコンポーネントライブラリの作り方
touyou
1
180
Google Agent Development Kit でLINE Botを作ってみた
ymd65536
2
240
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
1
360
RailsGirls IZUMO スポンサーLT
16bitidol
0
180
git worktree × Claude Code × MCP ~生成AI時代の並列開発フロー~
hisuzuya
1
550
CursorはMCPを使った方が良いぞ
taigakono
1
250
AI時代のソフトウェア開発を考える(2025/07版) / Agentic Software Engineering Findy 2025-07 Edition
twada
PRO
80
26k
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
360
Featured
See All Featured
For a Future-Friendly Web
brad_frost
179
9.8k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
680
Become a Pro
speakerdeck
PRO
29
5.4k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
48
2.9k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
GitHub's CSS Performance
jonrohan
1031
460k
Bash Introduction
62gerente
613
210k
Designing for humans not robots
tammielis
253
25k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
Transcript
PerlʹൺͯPHP͕ෆศ ʢओ؍Ͱ͢ʣ ͋͋…͔ͩΒ… • date: 20160521 • at: PHPΧϯϑΝϨϯεԬ 2016
• speaker: uzulla
ࣗݾհ • ౦ͷํͷ͏ͣΒ(uzulla)Ͱ͢ • ମܕతʹʮLʢΤϧʣʯͳํ Ͱ͢ • ʢԬͷudzura͞Μମܕ ʮRʢϨΪϡϥʔʣʯͰ͢ Ͷʣ
• Perlք۾ͰPHPͷਓͱ͍Θ Ε·͕͢ɺPHPք۾ͰPerl ͷਓͱ͍ΘΕ͍ͯΔؾ͕͠· ͢
Perlʹൺͯ PHP͕ෆศ ʢओ؍Ͱ͢ʣ
ʮPerlͷΧοίΠΠϠπ ʢओ؍ʣ ΛPHPͰ͔͍͍ͭͨ ͧʂʂʯ
͋͋…͔ͩΒ…
ΠΤʔΠʂ
yay • h#ps:/ /github.com/marcioAlmada/yay • Yay is a high level
PHP preprocessor • Not ready for real world usage yet !
ϓϦϓϩηοαͱʁ • Cͱ͔Ͱ͓ೃછΈ • ίϯύΠϧ࣌ʹίʔυΛಈతʹม • ఆɺϚΫϩஔ • yayPHPίʔυΛม͠ɺPHPίʔυͱͯ͠ग़ྗ ͢ΔτϥϯεύΠϥΈ͍ͨͳͷ
• ࠓճPHPͷߏจΛվ͢Δͷʹ͔͍ͭ·͢
ͱΓ͋͑ͣࢼ͢πʔϧ • github.com/uzulla/yay-tester.php • evalͯ͠ΔͷͰةݥͰ͢!खݩͰ͔͍ͭ·͠ΐ͏ • ʮ҆શͳϨϯαόͳΒ͏͔͍͍ͯ͝͠…ʁʯ ʢԥΒΕͦ͏ͳͷͰࣗॏ͠·ͨ͠ʣ • PHP>=7
ʢevalΛtryʙcatch (\Throwable $e) {}Ͱ ଈࢮճආʣ
say • say "hogehoge"; • sayechoΑΓҰจࣈগͳ͍ʂ • վߦ͕͘ͷ͕࠷ߴʹศརʂ • ʮPerl6͡ΌΜʯ
ʮp5Ͱuse feature 'say'͢Ε…ʯ
<?php # ͜ͷʮmacroʯͱ͍͏ॴΛyay͕ࢀর͢Δ macro { say ·string()·message } >> {
echo ·message; echo PHP_EOL; } # ͜͜·Ͱmacro say "say!"; say "yes!";
say "say!"; say "yes!"; // ↓ echo "say!"; echo PHP_EOL;
echo "yes!"; echo PHP_EOL;
say! yes!
unless • unless($flag){} • if(!$flag){}ͱಉ͡ • ʮ!Λॻ͚͍͍͡Όͳ͍ʯ ʮif( ! isKakin())Έ͍ͨͳͷࢁଓ͘ͱͭΒ͍…ʯ
ʮisHikakin()Λͭ͘Ε͑͑Μʯ ʮͳΔ΄Ͳʁʯ
<?php macro { unless (···expression) { ···body } } >>
{ if (! (···expression)) { ···body } } $isSuccess = true; unless($isSuccess){ echo('failed'); }
$isSuccess = true; unless($isSuccess){ echo('failed'); } // ↓ $isSuccess =
false; if (! ($isSuccess)) { echo('failed'); }
failed
range ԋࢉࢠ • for(1 .. 10){ print $_; } •
ਖ਼͔ͳΓཉ͍͠
<?php macro { foreach ( T_LNUMBER·S .. T_LNUMBER·E as T_VARIABLE·INDEX
) { ···body } } >> { foreach ( range(T_LNUMBER·S , T_LNUMBER·E) as T_VARIABLE·INDEX ) { ···body } } foreach( 1 .. 10 as $_ ){ echo $_; }
foreach( 1 .. 10 as $_ ){ echo $_; }
// ↓ foreach ( range(1 , 10) as $_ ){ echo $_; }
12345678910
range ԋࢉࢠ ͦͷ̎ • ʮrange()Ͱforeachͱ͔μϝͰ͠ΐʯ ʮ͍ʯ • ʢੲͷPerlPHPಉ༷ʹڊେྻ͕Ͱ͖͍ͯͨ ʢΒ͍͠ʣʣ •
ʢࠓճ࣮͠ͳ͍͚Ͳ('a' .. 'z')ͳͲ
<?php macro { foreach ( T_LNUMBER·S .. T_LNUMBER·E as T_VARIABLE·INDEX
) { ···body } } >> { $__itelatorGenerator = itelatorGenerator(T_LNUMBER·S, T_LNUMBER·E); foreach ( $__itelatorGenerator as T_VARIABLE·INDEX ) { ···body } } function itelatorGenerator($init, $fin){ $num = $init; while(1){ if( $fin < $num ) { return $num++; } yield $num++; } } foreach( 1 .. 10 as $_ ){ echo $_; }
function itelatorGenerator($init, $fin){ $num = $init; while(1){ if( $fin <
$num ) { return $num++; } yield $num++; } } // ͜͜·Ͱڞ௨ foreach( 1 .. 10 as $_ ){ echo $_; } // ↓ $__itelatorGenerator·cfcd208495d565ef66e7dff9f98764da = itelatorGenerator(1, 10); foreach ( $__itelatorGenerator·cfcd208495d565ef66e7dff9f98764da as $_ ) { echo $_; }
12345678910
ਖ਼نදݱϚονͱஔ • Ϛον • if( "123" =~ /2/ ){ }
• ஔ • $abc =~ s/a/A/; • ݸਓతʹ݁ߏ͖ • ʮPerlه߸ଟਿʯ ʮperlopͰάάΕʯ
<?php macro { T_VARIABLE·A =~ /T_STRING·B/ } >> { preg_match(
'/'. ··stringify(T_STRING·B) .'/u', T_VARIABLE·A ) } if($abc =~ /a/){ echo 1; }
if($abc =~ /a/){ echo 1; } // ↓ if(preg_match( '/'.
'a' .'/u' ,$abc )){ echo 1; } # օ͞Μ͕͍͍͍ͨ͜ͱղΔ
<?php macro { T_VARIABLE·A =~ s/T_STRING·B/T_STRING·C/ } >> { T_VARIABLE·A
= preg_replace( '/'. ··stringify(T_STRING·B) .'/u', ··stringify(T_STRING·C) , T_VARIABLE·A ) } $abc = 'abc'; $abc =~ s/a/v/; echo $abc;
$abc =~ s/a/v/; // ↓ $abc = preg_replace( '/' .
'a' . '/u', 'v' , $abc );
༨ஊ:JS෩ਖ਼نදݱϚον • if($abc./a/){ ... } • ʮOOPͬΆ͍ʂʯ ʮݩʑΦϒδΣΫτࢦݴޠ͔ͩͧͬ͠Γ͠Ζʯ • ʮPHPͳΒ
−>Ͱʁʯ ʮͤͳʯ
<?php macro { if( T_VARIABLE·A./T_STRING·B/ ){ ···body } } >>
{ if( preg_match( '/'. ··stringify(T_STRING·B) .'/u' , T_VARIABLE·A ) ) { ···body } } $abc = 'abc'; if($abc./a/){ echo 1; }
if($abc./a/){ echo 1; } // ↓ if( preg_match( '/'. 'a'
.'/u' , $abc ) ){ echo 1; }
yadayada • ... • ʮޙͰ࣮͢Δ͔Β...ʯͱ͍͏࣌ͷʮ...ʯ • ౸ୡ͢Δͱɺྫ֎্͕͕Δ • //TODOΑΓΘ͔Γ͍͢…͔…͠Εͳ͍
<?php macro { ... } >> { throw new \Exception
('Unimplemented'); } if(1){ ... }
if(1){ ... } // ↓ if(1){ throw new \Exception ('Unimplemented');
}
block scope • {ʙ} • ϒϩοΫͷதͰείʔϓ͕ग़དྷΔ • ͋ΔҙຯҰ൪ϚΫϩͬΆ͍ • ΊͬͪΌ΄͍͠ʂʂʂ
<?php macro { { ···body } } >> { (
function( $arg ) { extract( $arg ); ···body } ) ( get_defined_vars() ) ; } $abc = 'abc'; { $abc = 'def'; echo $abc, PHP_EOL; } echo $abc, PHP_EOL;
{ $abc = 'def'; } // ↓ ( function( $arg·cfSNIPda
) { extract( $arg·cfSNIPda ); $abc = 'def'; } ) ( get_defined_vars() ) ;
def abc
use • ʮPHPͷuseͬͯͳΜͳͷɺಡΈࠐΜͰ͘Εͳ͍ͷ Α͘Θ͔Βͳ͍Μ͚ͩͲ…ʯʢ༑ਓͷJVMܥϓϩ άϥϚஊʣ ʮͨɺ͔ͨ͠ʹ…ʯ • useͰຊʹrequire_once͢Εղܾ
<?php macro { use ·ns()·type ; } >> { use
·type ; __require( ··stringify(·type) ) ; } function __require($class){ $array = explode('\\', ltrim($class, '\\')); $path = implode('/', $array); $filename = $path.'.php'; require_once($filename); } use \This\Is\Test;
use \This\Is\Test; // ↓ use \This\Is\Test ; __require( '\This\Is\Test' )
;
use strict; use warnings; • ͍ܰΤϥʔͰऴྃ͢Δ • ͍͋͠ॴͰܯࠂ͢Δ • ʢຊ͏ͪΐͬͱҙຯ͕͋Δʣ
• ʢηοτ͍ͯ͠ΔΤϥʔϋϯυϥ࡞๏ݸਓతझ ຯͰ͢ʣ
<?php macro { use strict; } >> { set_error_handler( function($errno,
$errstr, $errfile, $errline){ throw new \Error($errstr); } ); } macro { use warnings; } >> { error_reporting(-1); } use strict; use warnings; echo $a;
use strict; use warnings; // ↓ <?php set_error_handler( function( $errno·cfSNIPda,
$errstr·cfSNIPda, $errfile·cfSNIPda, $errline·cfSNIPda ){ throw new \Error($errstr·cfSNIPda); } ); error_reporting(-1);
·ͱΊ • yayͬͯ݁ߏศརͰʂʢʁʣ • ʮҰਓϓϩδΣΫτझຯͳΒͳʂʯ • ஔͱ͔Ͱͳ͍ͷͰɺ ʢͪΌΜͱॻ͚ʣ͔ͳΓյΕͮΒ͍ • ग़ྗ͞ΕΔͷɺຊͷPHPͳͷͰ҆৺ʢʁʣ
• ୯७ͳϧʔλʔఆٛͷDSLͳΒͭ͘Ε·ͨ͠
ຊʹΔਓͷίϝϯτ • yayɺυΩϡϝϯτ͕ςετίʔυ͔͠ͳ͍ͷͰௐ Δͷ͕େม • τʔΫϯछͷT_VARIABLE github/nikic/PHP-Parser • ύʔαʔͷ·ls github/marcioAlmada/yay/src/
parsers.php • ʮͱʹ͔࣮͘ͱςετίʔυΛݟΔΜͩʯ
• ·ͱ.ͱɾΛؒҧ͑ͯେม • middle dot • ʮ·(00B7)ͬͯɺීஈͲ͏ͬͯೖྗ͢ΔΜ…ʯ • ʮதࠇΛ·(00B7)ʹม͢Δpreprocessor͕ඞཁͰ ʯ
__END__
__halt_compiler();
ʮyapc8oji Ͱάάͬͯ͘ΕཔΉʯ τʔΫԠืͯ͘͠Εʂʂ̍
͓·͚ɿshort closure • ( )->{ }
<?php macro { (···condition) -> { ···body } } >>
{ function ( ···condition ) { ···body } } $a = ($v)->{ echo $v; }; $a('abc');
$a = ($v)->{ echo $v; }; // ↓ $a =
function ( $v ) { echo $v; };
Defined-Or, //= ԋࢉࢠ • $a //= 'default'; • ʢ//??ͱಉ͡ʣ •
ຊؾͰཉ͍͠ • 7.xͰདྷΔʢ͚ͲઌऔΓͱ͍͏͜ͱͰʣ => https://wiki.php.net/rfc/ null_coalesce_equal_operator
<?php macro { T_VARIABLE·A ??= } >> { T_VARIABLE·A =
T_VARIABLE·A ?? } $a ??= 123; echo $a;
$a ??= 123; echo $a; // ↓ $a = $a
?? 123; echo $a;
splitͱjoin • ʮͲ͏ͯ͠Explode/Implode͕׳Εͳ͍ʯ ʮ׳ΕΖʯ ʮͳͥจࣈΛ૿͢ํʹߦͬͨͷ͔ʯ ʮఘΊΖʯ • PHP7Ͱ͍ͭʹফ໓͠·ͨ͠Ͷ
<?php macro { split } >> { mb_split } macro
{ join } >> { implode } print_r( split(",", "a,b,c") ); print_r( join(",", ["a","b","c"]) ); # PHP7Ͱsplit()͕ͳ͘ͳͬͯ # mb_splitͷ͍ͬͯ͜ΔΜͩΑͳ͋…
split(",", "a,b,c"); join(",", ["a","b","c"]); // ↓ mb_split(",", "a,b,c"); implode(",", ["a","b","c"]);