diff options
Diffstat (limited to 'content/posts/2023-01-10')
| -rw-r--r-- | content/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3.xml | 176 |
1 files changed, 88 insertions, 88 deletions
diff --git a/content/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3.xml b/content/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3.xml index 6356597..e3eb845 100644 --- a/content/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3.xml +++ b/content/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3.xml @@ -44,24 +44,24 @@ </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - <?php + <?php + try { + f(g() / __LINE__); + } catch (Throwable $e) { + while ($e = $e->getPrevious()) printf('%c', $e->getLine() + 23); + echo "\n"; + } + function f(int $i) { + if ($i < 0) f(); try { - f(g() / __LINE__); - } catch (Throwable $e) { - while ($e = $e->getPrevious()) printf('%c', $e->getLine() + 23); - echo "\n"; - } - function f(int $i) { - if ($i < 0) f(); - try { - match ($i) { - 0 => 0 / 0, + match ($i) { + 0 => 0 / 0, - 15, 36 => 0 / 0, - 14 => 0 / 0, - 37 => 0 / 0, + 15, 36 => 0 / 0, + 14 => 0 / 0, + 37 => 0 / 0, @@ -72,16 +72,16 @@ - 6 => 0 / 0, + 6 => 0 / 0, - 5 => 0 / 0, + 5 => 0 / 0, - 22 => 0 / 0, + 22 => 0 / 0, - 34, 35 => 0 / 0, + 34, 35 => 0 / 0, @@ -90,10 +90,10 @@ - 25 => 0 / 0, - 17, 21 => 0 / 0, + 25 => 0 / 0, + 17, 21 => 0 / 0, - 24, 32 => 0 / 0, + 24, 32 => 0 / 0, @@ -101,12 +101,12 @@ - 33 => 0 / 0, + 33 => 0 / 0, - 16 => 0 / 0, + 16 => 0 / 0, - 18 => 0 / 0, + 18 => 0 / 0, @@ -115,37 +115,37 @@ - 7 => 0 / 0, + 7 => 0 / 0, - 2 => 0 / 0, - 1, 20 => 0 / 0, - 10, 28 => 0 / 0, - 8, 12, 26 => 0 / 0, - 4, 9, 13 => 0 / 0, + 2 => 0 / 0, + 1, 20 => 0 / 0, + 10, 28 => 0 / 0, + 8, 12, 26 => 0 / 0, + 4, 9, 13 => 0 / 0, - 31 => 0 / 0, + 31 => 0 / 0, - 29 => 0 / 0, + 29 => 0 / 0, - 11 => 0 / 0, + 11 => 0 / 0, - 3, 19, 23 => 0 / 0, + 3, 19, 23 => 0 / 0, - 27 => 0 / 0, + 27 => 0 / 0, - 30 => 0 / 0, - }; - } finally { - f($i - 1); - } + 30 => 0 / 0, + }; + } finally { + f($i - 1); } + } @@ -153,9 +153,9 @@ - function g() { - return __LINE__; - } + function g() { + return __LINE__; + } ]]> </programlisting> <simpara> @@ -165,15 +165,15 @@ トークンは PHP の式になっていて、評価すると <literal>Hello, World!</literal> という文字列になる。PHPer チャレンジのトークンには空白を含められないという制約があるが、こういった形でトークンにすれば回避できる。 </simpara> </section> - <section xml:id="_解説"> + <section xml:id="commentary"> <title>解説</title> - <section xml:id="_概要"> + <section xml:id="commentary--summary"> <title>概要</title> <simpara> 例外が発生した行数にデータをエンコードし、それを <literal>catch</literal> で捕まえて表示している。 </simpara> </section> - <section xml:id="_例外オブジェクトの連鎖"> + <section xml:id="commentary--chain-of-exceptions"> <title>例外オブジェクトの連鎖</title> <simpara> <link xl:href="https://www.php.net/class.Exception"><literal>Exception</literal></link> や <link xl:href="https://www.php.net/class.Error"><literal>Error</literal></link> には <literal>$previous</literal> というプロパティがあり、コンストラクタの第3引数から渡すことができる。主に 2つの用法がある: @@ -187,42 +187,42 @@ </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - <?php + <?php + try { try { - try { - throw new Exception("Error 1"); - } finally { - throw new Exception("Error 2"); - } - } catch (Exception $e) { - echo $e->getMessage() . PHP_EOL; - // => Error 2 - echo $e->getPrevious()->getMessage() . PHP_EOL; - // => Error 1 + throw new Exception("Error 1"); + } finally { + throw new Exception("Error 2"); } + } catch (Exception $e) { + echo $e->getMessage() . PHP_EOL; + // => Error 2 + echo $e->getPrevious()->getMessage() . PHP_EOL; + // => Error 1 + } ]]> </programlisting> <simpara> この知識を元に、トークンの出力部を解析してみる。 </simpara> </section> - <section xml:id="_出力部の解析"> + <section xml:id="commentary--output"> <title>出力部の解析</title> <simpara> 出力部をコメントや改行を追加して再掲する: </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - <?php - try { - f(g() / __LINE__); - } catch (Throwable $e) { - while ($e = $e->getPrevious()) { - printf('%c', $e->getLine() + 23); - } - echo "\n"; + <?php + try { + f(g() / __LINE__); + } catch (Throwable $e) { + while ($e = $e->getPrevious()) { + printf('%c', $e->getLine() + 23); } + echo "\n"; + } ]]> </programlisting> <simpara> @@ -233,7 +233,7 @@ </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - 1, 20 => 0 / 0, + 1, 20 => 0 / 0, ]]> </programlisting> <simpara> @@ -243,33 +243,33 @@ それでは、エラーチェインを作る箇所、関数 <literal>f()</literal> を見ていく。 </simpara> </section> - <section xml:id="_データ構成部の解析"> + <section xml:id="commentary--data-construction"> <title>データ構成部の解析</title> <simpara> <literal>f()</literal> の定義を再掲する (エラーオブジェクトの行数を利用しているので、一部分だけ抜き出すと値が変わることに注意): </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - function f(int $i) { - if ($i < 0) f(); - try { - match ($i) { - 0 => 0 / 0, // 12 行目 + function f(int $i) { + if ($i < 0) f(); + try { + match ($i) { + 0 => 0 / 0, // 12 行目 - 15, 36 => 0 / 0, - 14 => 0 / 0, - 37 => 0 / 0, + 15, 36 => 0 / 0, + 14 => 0 / 0, + 37 => 0 / 0, - // (略) + // (略) - 30 => 0 / 0, // 97 行目 - }; - } finally { - f($i - 1); - } + 30 => 0 / 0, // 97 行目 + }; + } finally { + f($i - 1); } + } ]]> </programlisting> <simpara> @@ -277,16 +277,16 @@ </simpara> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - <?php - try { - f(g() / __LINE__); // 3 行目 + <?php + try { + f(g() / __LINE__); // 3 行目 ]]> </programlisting> <programlisting language="php" linenumbering="unnumbered"> <![CDATA[ - function g() { - return __LINE__; // 111 行目 - } + function g() { + return __LINE__; // 111 行目 + } ]]> </programlisting> <simpara> |
