Symfony Component Advent Calendar 2023の9日目の記事です。
式を評価、"ExpressionLanguage"
ExpressionLanguageは、文字列の式を評価してくれるコンポーネントです。Symfony以外でも使えます。
インストール
composer require symfony/expression-language
使い方
"文字列の式を評価"というのはなかなか伝わりにくいかなと思うんですが、実際のコードを見れば一目瞭然かなと思います。
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$expressionLanguage = new ExpressionLanguage();
$resulst = $expressionLanguage->compile('3 + 2'); // (3 + 2)
$result = $expressionLanguage->evalute('3 + 2'); // 5
compile()
は与えた文字列の式をPHPにコンパイルします。evaluate()
はコンパイルせずに与えた文字列の式を評価して、結果を返してくれます。基本使うのはevaluate()
かな。。
上記はただの算数ですが、変数を渡して評価することもできます。メソッドの呼び出しは->
から.
に変わります。
$apple = new Item();
$apple
->setName('りんご')
->setPrice(100)
;
$expressionLanguage = new ExpressionLanguage();
$expressionLanguage->evaluate('item.getName()', ['item' => $apple]); // りんご
$expressionLanguage->evaluate('item.getPrice() > 50', ['item' => $apple]); // true
独自構文
コンポーネントでいくつかの構文は用意していますが、独自構文も作成可能です。
$expressionLanguage = new ExpressionLanguage();
$expressionLanguage->register('isPublished', function (): string {
return 'コンパイルした時の文字列';
}, function (array $arguments): bool {
return $arguments['item']->getPublishedAt()->diff(new DateTimeImmutable(), true);
});
$item = new Item();
$item->setPublishedAt(new DateTimeImmutable('2023-12-01 00:00:00'));
$expressionLanguage->evaluate('isPublished()', ['item' => $item]); // true
なお、Symfonyで使う場合は、さらに以下の構文も用意されています。
なにがうれしいか
これの便利なところは、設定ファイルなどに式を記述できることで、プログラムを修正することなく安全にロジック変更することができるところです。
# キャンペーンの開始条件を設定
parameters:
campaign_condition: "campaign.isActive() && campaign.getStartedAt().format('YmdHis') > 20231209000000"
class SomeController
{
public function __construct(
#[Autowire(param: 'campaign_condition') private readonly $condition)
{
}
public function index(Campaign $campaign)
{
$expressionLanguage = new ExpressionLanguage();
$started = $expressionLanguage->evaluate(
$this->condition,
['campaign' => $campaign]
);
if (!$started) {
throw NotFoundHttpException();
}
return ['campaign' => $campaign];
}
}
まとめ
今回はExpressionLanguage
でした。Symfony以外でも使えますが、Symfonyの設定(config
配下)で使うことができ、非常に柔軟に設定を行うことができるようになるコンポーネントとなっています。