Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Новое в Symfony 2.4: компонент ExpressionLanguage

Anna | 31.05.2014 | нет комментариев

В Symfony 2.4 появится новейший компонент — ExpressionLanguage. Компонент является движком для компиляции и исполнения «выражений».
Данный язык является урезанной версией твига. Выражения укладываются в одну строку и традиционно возвращают булево значения, но не ограничиваются этим.
В различии от твига, ExpressionLanguage работает в 2-х режимах:

  • Компиляция: выражение компилируется в PHP код для дальнейшего исполнения (код не зависит от среды выполнения)
  • Исполнение: выражение исполняется без заблаговременной компиляции

Дабы было допустимо компилировать выражения в PHP код, не нуждающийся в модификации во время выполнения, оператор . должен быть очевидным и обозначать лишь одно допустимое поведение: 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'));

Последнее, но не по значению — вы можете легко расширить функциональность языка. Они работают верно также как их аналоги в твиге (для подробного ознакомления посмотрите способ register())
Как на счет примеров применения? Мы встроили компонент во уйма других компонентов, используемых в Symfony.

Контейнер сервисов (Service Container)

Вы можете применять выражения в любом месте, где дозволено передать довод в контейнер:

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

В контейнере выражения дополняются двумя функциями: service(), Дабы получить сервис, и parameter, Дабы получить значение параметра:

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

В XML:

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

Тут нет никакого оверхеда во время исполнения, так как PHP-дампер компилирует выражения. Предшествующий пример скомпилируется в дальнейший PHP код:

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

Правила доступа (Access Control Rules)

Настройка правил доступа может ввести в заблуждения, что может привести к незащищенным приложения
Новая директива allow_if упрощает настройку правил доступа в вашем приложении:

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

Это правило ограничивает пути, начинающиеся с /_internal/secure для пользователей зашедших не сlocalhost либо не имеющих права менеджера.
requesttoken и user — переменные, к которым у вас есть доступ, is_anonymous()is_authenticated(),is_fully_authenticated()is_rememberme()and has_role() — функции доступные в выражениях при настройке правил доступа.

Twig

Вы также можете применять выражения в ваших образцах, с поддержкой функции 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 будет частью 3 версии бандла, тот, что выйдет перед Symfony 2.4

Кеширование

В третьей версии SensioFrameworkExtraBundle также будет доступна аннотация @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)
{
    // ...
}

 

Маршрутизация (Routing)

Из коробки Symfony может предпочесть роут по предопределенным переменным (таким как infomethod,sheme), но некоторым необходима больше трудная логика, основывающаяся на информации из запроса (объектRequest)
Дабы покрыть эти особые случаи, вы можете применять дериктиву condition, которая разрешает добавить всякое выражение использующее переменные request и routing context:

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

И вновь таки, применяя PHP дампер правил маршрутизации (URL matcher), нет никакого оверхеда, так как все выражения компилируются в 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

Validation

Новое условие Expression разрешает применять выражения для валидации:

use Symfony\Component\Validator\Constraints as Assert;

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

В выражениях валидатора this ссылается на нынешний объект валидации.

Движок бизнес-правил (Business Rule Engine)

Помимо того применяя компонент в самом фреймворке язык выражений чудесный кандидат для создания движка бизнесс-правил. Идея в том, что вебмастер (менеджер) сайта может эластично настроить сайт, без применения 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. В течении нескольких дней будет доступна первая пред-релизная версия (release candidate).

Ощущаю что не каждому приглянется сходственное применение PHP, но умоляю учесть что я переводчик, статьи, а не создатель этого компонента и пока сам не разобрался нравится он мне либо нет (исключительно поразило для чего выражения встроили в твиг).
Все примечания и пожелания пожалуйста в личку

Как вы относитесь к компоненту

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовал 1 человек. Воздержавшихся нет.

Источник: programmingmaster.ru

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB