Symfony 2.4の新機能:ExpressionLanguageコンポーネント

Symfony 2.4は、新しいコンポーネントExpressionLanguageを導入します。 コンポーネントは、「式」をコンパイルおよび実行するためのエンジンです。

この言語は、Twigの簡易バージョンです。 式は1行に収まり、通常ブール値を返しますが、これに限定されません。

Twigとは異なり、ExpressionLanguageは2つのモードで動作します。



実行時に変更する必要のないPHPコードに式をコンパイルできるようにするには、演算子を使用し.



明示的であり、1つの可能な動作のみを意味する必要がありますfoo.bar



オブジェクトのプロパティの場合、 foo['bar']



は配列にアクセスし、 foo.getBar()



はメソッドを呼び出します。

コンポーネントの使用は可能な限り簡単です。

 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $language = new ExpressionLanguage(); echo $language->evaluate('1 + 1'); // echo 2 echo $language->compile('1 + 2'); // echo "(1 + 2)"
      
      





式言語は、小枝と同じことをサポートします:数学演算子、文字列、数値、配列、ハッシュ、ブール変数...式は非常に限られたPHPサンドボックスと見なすことができ、外部の影響は不可能であり、コンパイルまたは実行前にすべての変数を宣言する必要があります式。

 $language->evaluate('a.b', array('a' => new stdClass())); $language->compile('a.b', array('a'));
      
      





最後になりましたが、関数を使用して言語を簡単に拡張できます。 Twigの対応物と同じように機能します(詳細についてはregister()



メソッドを参照してください)

ユースケースはどうですか? Symfonyで使用される他の多くのコンポーネントにコンポーネントを埋め込みました。





サービスコンテナ



引数をコンテナに渡すことができる場所であればどこでも式を使用できます。

 $c->register('foo', 'Foo')->addArgument(new Expression('bar.getvalue()'));
      
      





コンテナでは、式は、サービスを取得するservice service()



parameter



の値を取得するparameter



2つの関数によって補完されます。

 service("bar").getValue(parameter("value"))
      
      





XMLの場合:

 <service id="foo" class="Foo"> <argument type="expression">service('bar').getvalue(parameter('value'))</argument> </service>
      
      





PHPダンパーが式をコンパイルするため、実行時にオーバーヘッドはありません。 前の例は、次のPHPコードにコンパイルされます。

 $this->get("bar")->getvalue($this->getParameter("value"))
      
      







アクセス制御規則



アクセスルールの設定は誤解を招く可能性があり、 安全でないアプリケーションにつながる可能性があります

新しいallow_if



ディレクティブを使用すると、アプリケーションでアクセスルールを簡単に設定できます。

 access_control: - { path: ^/_internal/secure, allow_if: "'127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')" }
      
      





このルールは、 localhost



または管理者権限なしでログインするユーザーに対して、 /_internal/secure



で始まるパスを制限します。

request



token



およびuser



は、アクセスできる変数ですis_anonymous()



is_authenticated()



is_fully_authenticated()



is_rememberme()



and has_role()



は、アクセスルールを設定するときに式で使用できる関数です。



小枝



expression



関数を使用して、テンプレートで式を使用することもできます

 {% if is_granted(expression('has_role("FOO")')) %} ... {% endif %}
      
      







SensioFrameworkExtraBundleを使用する場合は、 @ Security



アノテーションを使用して、コントローラーを保護するオプションもあります

 /** * @Route("/post/{id}") * @Security("has_role('ROLE_ADMIN')") */ public function showAction(Post $post) { }
      
      





@ Security



アノテーションは、Symfony 2.4より前にリリースされるバンドルのバージョン3の一部になります




キャッシング



SensioFrameworkExtraBundleの3番目のバージョンでは、@ Cacheアノテーションも使用可能になり、HTTPキャッシングにアクセスできるようになります。 単純な状況で定型コードを何度も書く代わりに:

 /** * @Route("/post/{id}") * @Cache(smaxage="15") */ public function showAction(Request $request, Post $post) { $response = new Response(); $response->setLastModified($post->getUpdated()); if ($response->isNotModified($request)) { return $response; } // ... }
      
      





アノテーションのすべてを構成できます(これはETagでも機能します)。

 /** * @Route("/post/{id}") * @Cache(smaxage="15", lastModified="post.getUpdatedAt()") */ public function showAction(Post $post) { // ... }
      
      





ルーティング



sheme



では、Symfonyは事前定義された変数( info



method



sheme



)によってルートを選択できますが、一部はリクエスト( Request



オブジェクト)からの情報に基づいてより複雑なロジックを必要とします

これらの特殊なケースをカバーするには、 condition



ディレクティブを使用します。これにより、 request



およびルーティングcontext



変数を使用して任意の式を追加できます。

 hello: path: /hello/{name} condition: "context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') =~ '/firefox/i'"
      
      





また、PHPルーティングルールダンパー(URLマッチャー)を使用すると、すべての式がPHPコードにコンパイルされるため、オーバーヘッドはありません。

 // hello if (0 === strpos($pathinfo, '/hello') && preg_match('#^/hello/(?P<name>[^/]++)$#s', $pathinfo, $matches) && (in_array($context->getMethod(), array(0 => "GET", 1 => "HEAD")) && preg_match("/firefox/i", $request->headers->get("User-Agent"))) ) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'hello')), array ()); }
      
      





これらの条件は、URLを生成するときに使用されないことに注意してください。

検証



新しいExpression



条件を使用すると、検証に式を使用できます。

 use Symfony\Component\Validator\Constraints as Assert; /** * @Assert\Expression("this.getFoo() == 'fo'", message="Not good!") */ class Obj { public function getFoo() { return 'foo'; } }
      
      





バリデータ式では、 this



は現在の検証オブジェクトを指します。

ビジネスルールエンジン



さらに、フレームワーク自体のコンポーネントを使用する式言語は、ビジネスルールエンジンを作成するための優れた候補です。 その考えは、サイトのウェブマスター(管理者)が、PHPを使用せずに、セキュリティ問題に専念することなく、サイトを柔軟に構成できるということです。

 # Get the special price if user.getGroup() in ['good_customers', 'collaborator'] # Promote article to the homepage when article.commentCount > 100 and article.category not in ["misc"] # Send an alert when product.stock < 15
      
      







これは、Symfony 2.4の新機能を見る最後の投稿です。 数日以内に、最初のプレリリースバージョン(リリース候補)が利用可能になります。



誰もがこのPHPの使用を好むとは思いませんが、私はこのコンポーネントの作成者ではなく、翻訳者であり、記事であり、それが好きかどうかを判断するまでは覚えておいてください(式が小枝に組み込まれた理由は特に印象的でした)。

すべてのコメントと提案はPMでお願いします



All Articles