一体いつから PHPがセミコロン省略できないと錯覚していた？

・ヮ・）あ、おはようございまーす
PHPでセミコロン書いてますか？

PHPはCで実装されていてJavaに強く影響を受けているためか、行末にセミコロンを付けないといけません。

Python、Go、Swift、kotlin、Ruby、JavaScript などセミコロンを書かない(または省略してもいい)言語を使っている方からは
しばしば白い目で見られがちです(諸説あり):sob: 

正直、悔しいです…:rage: 

**PHPの真の力(笑)** を見せつけます！

## 【朗報】PHPにはセミコロンを省略できる構文が2つある:tada: 

### `if`
1つ目は `if 文` です
PHPの `if文` は、戻り値があるようなものであれば 変数だろうが、関数であろうが、 式でもいれることができます

```php
$var = 0;
if ($var) {} // 変数はもちろんOK
if (fn() => 0) {} // クロージャー、アロー関数ももちろんOK
if ($var = 1) {} // 代入式でもOK
```

しかし 戻り値が無いような式は入れることができません:joy: 

```php
if (echo 'は戻り値がないのでだめ！！') {} // ただし print は戻り値があるからOK

if (function hoge() {}) {} // 関数の宣言はだめ

if (use Foo\Baz\Bar) {} // use 式もだめ

// もちろん for 文 はif 文 の条件には入れられません
for ($i = 0; $i < 10; ++$i) {}
```

### `?>`
2つ目は `?>(閉じタグ)` です
PHPには、`?>` の直前のみセミコロンを省略できる仕様があります

```php
<?= 'こういう場合は' ?>
<?php echo '省略可能' ?>
```

これはHTMLに埋め込むときだけでなく、PHPのコードの中にも埋め込むことができます:clap: 

```php
<?php
function printLink(string $text, string $href) { ?>
    <!-- ここはHTML -->
    <a href="<?= $href ?>"><?= $text ?></a>
<?php }

// さらにこういうこともOK
printLink('りんく', 'https://example.com')?><?php
```

つまり `?><?php` (閉じタグと開始タグのセット) はセミコロンであり、これを使うことでセミコロンを省略できると言えます(省略とは言えない説もあり)

## セミコロン書かないでコーディングしてみる

簡単な文法だけだとつまらないので複雑めにFizzBuzz書きました

```php
<?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は黙ってセミコロン書いたほうがいいですね

なんでこんな物を書こうと思ったのか不明です