0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Symfony4.1アップグレードから、長く使えるコードについて考えてみた

Posted at

タイトル詐欺かも。
「サービスを自作クラスでラップして使ってたので助かった」話ですね。

要点は:

  • Symfony 4.1を5.4に更新。
    • いわゆるUpgradeは全て失敗したので、5.4をクリーンインストールして、そこにコードをコピペして動かした。
    • 作業は思ったより簡単にできた。
    • クラス名やネームスペースが変わったぐらいで、文字列変換で対応できた。
  • ただし、フレームワーク側での大きな変更点は2つあった。
    • Swiftmailerが廃止され、Symfony/Mailerが採用されてた。
    • Twigにnamespaceが導入されてた。
  • たまたまMailerTwigも別クラスでラップしてたので、修正が一か所ですんだ。
    • ラッキーだったね。

という話です。

Twig

twigは、簡単なクラスでラップしてましたので、\Twig_Environment\Twig\Environmentに書き換えるだけで対応が完了!
コードは、こんな感じ。

 class Template
{
    private \Twig\Environment $twig;
    public function __construct(\Twig\Environment $twig)
    {
        $this->twig = $twig;
    }
    public function render($view, $parameters = []): string
    {
        return $this->twig->render($view, $parameters);
    }
}

そもそも、なぜラップする気になったのか不思議なぐらい単純なクラス。これならクラスを挟まなくても文字列置換で十分対応できたでしょう。
おそらく名前空間のないクラス、Twig_Environmentを直接使いたくなかったとかでしょう…

SwiftMailerがSymfony/Mailer

メーラーをラップするのは難しいので、逆にメールの情報を共通化して
利用してました。ので、結果的に修正が一か所で済みました。

Abstract Class

最初からアブストラクトクラスを作ってたので、こんな風に改良。

abstract class AbstractMailer
{
    protected MailerInterface $mailer;
    protected Template $template;
    public function __construct(MailerInterface $mailer, Template $template)
    {
        $this->mailer = $mailer;
        $this->template = $template;
    }
    abstract public function render(): string;
    abstract public function subject(): string;
    abstract public function from(): string;
    abstract public function mailTo(): string;
    public function mail(): void
    {
        $mail = new Email();
        $mail->from($this->from())
            ->to($this->mailTo())
            ->subject($this->subject())
            ->html($this->render());
        $this->mailer->send($mail);
    }
}

使い方

使う場合は、次のようなクラスとして実装します。

class WelcomeUserMailer extends AbstractMailer
{
    private User $user;
    public function subject(): string {
        return 'Welcome!';
    }
    public function mailTo(): string {
        return $this->user->getEmail();
    }
    public function from(): string {
        return 'from@example.com';
    }
    public function setUser(User $user)
    {
        $this->user = $user;
    }
    public function render(): string
    {
        return $this->twig->render('welcome.twig', ['user' => $this->user]);
    }
}

WelcomeUserMailerはDIしてもらっておいて、

$this->mailer->setUser($user);
$this->mailer->mail();

となって、Controller側の修正箇所はなしでした。

まとめ

話としては以上なのだけど、無理やりまとめると、

  • 外部ライブラリは不安定。
  • 守りたいのはコントローラーも含んだ自分の書いたコード。
  • ラップするレイヤーも、自分のコードとして管理するほうが良さそう。
  • でも、メールやORMのように複雑なAPIがある場合に、レイヤーを挟むのは難しい…
    • メールだと、メールという情報を統一化したらうまくできた。

やはり一度書いたコードは、出来るだけ長く使いたいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?