・ヮ・)あ、おはようございまーす
PHPでセミコロン書いてますか?
PHPはCで実装されていてJavaに強く影響を受けているためか、行末にセミコロンを付けないといけません。
Python、Go、Swift、kotlin、Ruby、JavaScript などセミコロンを書かない(または省略してもいい)言語を使っている方からは
しばしば白い目で見られがちです(諸説あり)
正直、悔しいです…
PHPの真の力(笑) を見せつけます!
【朗報】PHPにはセミコロンを省略できる構文が2つある
if
1つ目は if 文
です
PHPの if文
は、戻り値があるようなものであれば 変数だろうが、関数であろうが、 式でもいれることができます
$var = 0;
if ($var) {} // 変数はもちろんOK
if (fn() => 0) {} // クロージャー、アロー関数ももちろんOK
if ($var = 1) {} // 代入式でもOK
しかし 戻り値が無いような式は入れることができません
if (echo 'は戻り値がないのでだめ!!') {} // ただし print は戻り値があるからOK
if (function hoge() {}) {} // 関数の宣言はだめ
if (use Foo\Baz\Bar) {} // use 式もだめ
// もちろん for 文 はif 文 の条件には入れられません
for ($i = 0; $i < 10; ++$i) {}
?>
2つ目は ?>(閉じタグ)
です
PHPには、?>
の直前のみセミコロンを省略できる仕様があります
<?= 'こういう場合は' ?>
<?php echo '省略可能' ?>
これはHTMLに埋め込むときだけでなく、PHPのコードの中にも埋め込むことができます
<?php
function printLink(string $text, string $href) { ?>
<!-- ここはHTML -->
<a href="<?= $href ?>"><?= $text ?></a>
<?php }
// さらにこういうこともOK
printLink('りんく', 'https://example.com')?><?php
つまり ?><?php
(閉じタグと開始タグのセット) はセミコロンであり、これを使うことでセミコロンを省略できると言えます(省略とは言えない説もあり)
セミコロン書かないでコーディングしてみる
簡単な文法だけだとつまらないので複雑めにFizzBuzz書きました
<?php
namespace FizzBuzz\Handler {
abstract class Handler
{
public static function handle(int $value, callable $next): string
{
return static::isMatched($value) ? static::toString() : $next($value)?><?php
}
abstract public static function isMatched(int $value): bool?><?php // ここら辺IDEがエラー吐きがち
abstract public static function toString(): string?><?php
}
final class FizzHandler extends Handler
{
public static function isMatched(int $value): bool
{
return $value % 3 === 0?><?php
}
public static function toString(): string
{
return 'Fizz'?><?php
}
}
final class BuzzHandler extends Handler
{
public static function isMatched(int $value): bool
{
return $value % 5 === 0?><?php
}
public static function toString(): string
{
return 'Buzz'?><?php
}
}
final class FizzBuzzHandler extends Handler
{
public static function isMatched(int $value): bool
{
return FizzHandler::isMatched($value) && BuzzHandler::isMatched($value)?><?php
}
public static function toString(): string
{
return FizzHandler::toString().BuzzHandler::toString()?><?php
}
}
}
namespace FizzBuzz {
use FizzBuzz\Handler\FizzHandler?><?php
use FizzBuzz\Handler\BuzzHandler?><?php
use FizzBuzz\Handler\FizzBuzzHandler?><?php
use Generator?><?php
class FizzBuzz
{
private $handlerClassList = [
FizzBuzzHandler::class,
FizzHandler::class,
BuzzHandler::class,
]?><?php
public function __invoke(): Generator
{
$handler = fn($i) => (string)$i?><?php
foreach (array_reverse($this->handlerClassList) as $handlerClass) {
$handler = fn(int $i) => $handlerClass::handle($i, $handler)?><?php
}
// for 文の中のセミコロンもばっちり
for ($i = 1?><?php $i <= 100?><?php ++$i) {
yield $handler($i)?><?php
}
}
}
}
namespace Main {
use FizzBuzz\FizzBuzz?><?php
foreach ((new FizzBuzz)() as $v) {
echo $v, PHP_EOL?><?php
}
}
※文法によってはIDEがエラーを吐くかもしれませんが実行できます
PHPは黙ってセミコロン書いたほうがいいですね
なんでこんな物を書こうと思ったのか不明です