From a84908b7e8a0e2423afd6b836eccf27a420270b4 Mon Sep 17 00:00:00 2001
From: nsfisis
#\
+ #\
i\
n\
c\
@@ -245,7 +245,7 @@ c\
また、2文字だと文字列がまともに書けないのも辛い。'' だけで2文字使うので、 「1文字の文字列リテラル」というものを書くことができない。PHP では文字列リテラル中に生の改行が書けるので
- $a
+ $a
='
a'
;;
@@ -267,7 +267,7 @@ a'
まずは普通に書くとしよう。
- <?php
+ <?php
for ($i = 1; $i < 100; $i++) {
echo (($i % 3 ? '' : 'Fizz') . ($i % 5 ? '' : 'Buzz') ?: $i) . "\n";
@@ -284,7 +284,7 @@ a'
for は、3文字もある長いキーワードである。 こんなものは使えない。array_ 系の関数を使って、適当に置き換えるとしよう。
- <?php
+ <?php
$s = range(1, 100);
array_walk(
@@ -304,7 +304,7 @@ fn($i) =>
range、array_walk、printf は長すぎるのでどうにかせねばならない。 ここで、PHP の可変関数を使う。可変関数とは、関数名が文字列として入った変数を経由して、関数を呼び出す機能である。
- <?php
+ <?php
$r = 'range';
$w = 'array_walk';
@@ -340,7 +340,7 @@ fn($i) =>
というルールがない場合、「未定義の定数が評価された場合、その定数の名前が値になる」という PHP 7.x までの仕様が利用できる。 例えば、 Fizz という文字列が欲しければ、次のようにする。
- $f
+ $f
=F
.i
.z
@@ -351,7 +351,7 @@ fn($i) =>
こうして簡単に文字列を作れる。 なお、この仕様は 7.x 時点でも警告を受けるので、@ 演算子を使って抑制してやるとよい。
- $f
+ $f
=@
F.
@i
@@ -376,7 +376,7 @@ F.
ずばり、文字列同士のビット演算を使う。 PHP では、文字列同士でビット演算 (&、|、^) をした場合、 文字列の各バイトごとに指定したビット演算がなされ、それを結合したものが演算結果となる。
- $a = "12345";
+ $a = "12345";
$b = "world";
// $a ^ $b は次のコードと同じ
@@ -392,7 +392,7 @@ F.
これを踏まえ、次のコードを見てみよう。
- $x = "x\nOm\n";
+ $x = "x\nOm\n";
$y = "\nk!\no";
$r = $x ^ $y;
echo "$r\n";
@@ -401,7 +401,7 @@ F.
実行すると、range が表示される。 さて、PHP では文字列リテラル中に生の改行を直接書いてもよいのだった (「主な障害」の節を参照のこと)。 書きかえてみよう。
- $x
+ $x
='x
Om
';
@@ -418,7 +418,7 @@ o'
さらに # を使って適当に調整すると、次のようになる。
- $x
+ $x
=#
'x
Om
@@ -453,7 +453,7 @@ o'
完成したものがこちら。
- <?php
+ <?php
$x
=#
@@ -621,7 +621,7 @@ _!
PHP では、バッククォートを使ってシェルを呼び出せる。 これは shell_exec 関数と等価である。 さて、PHP ではバックスラッシュによる行継続が使えないと書いたが、シェルでは使える (当然だが、呼び出されるシェルに依存する。Bash なら大丈夫だろう。知らんけど)。
- <?php
+ <?php
printf(`
e\
@@ -658,7 +658,7 @@ o\
もうこれ以上は不可能だと思っていたのだが、この記事の執筆中に解決する方法を思いついたので載せておく。
- <?php
+ <?php
$c = 'chr';
@@ -692,7 +692,7 @@ ${
先程と同じく、chr や printf を生成する部分は長くなるので省いた。
- ${
+ ${
'_
'}
@@ -700,7 +700,7 @@ ${
は変数で、中にはスペースとエスケープが入っている (chr(32) . chr(92))。 シェルに渡されている文字列は次のようになる。
- e\
+ e\
c\
h\
o\
@@ -721,7 +721,7 @@ o\
ちなみに、PHP 8.2 からは、この記法で Warning が出るようになるようだ。
- ${
+ ${
'_
'}
--
cgit v1.2.3-70-g09d2