この言語は、Twigの簡易バージョンです。 式は1行に収まり、通常ブール値を返しますが、これに限定されません。
Twigとは異なり、ExpressionLanguageは2つのモードで動作します。
- コンパイル:式は後続の実行のためにPHPコードにコンパイルされます(コードはランタイムに依存しません)
- 実行:式は予備コンパイルなしで実行されます
実行時に変更する必要のない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でお願いします