Symfony2 — исключение преобразования массива в строку с флэш-сообщением

Я установил флэш-сообщение в контроллере со следующим кодом:

$this->get('session')->getFlashBag()->add('success', 'Message sent successfully');

И в моем шаблоне я использую следующее, чтобы (попытаться) отобразить его:

{% if app.session.flashbag.has('success') %}
    <div id="flash">
        {{ app.session.flashbag.get('success') }}
    </div>
{% endif %}

Проблема в том, что, несмотря на то, что в документации API указано, что get возвращает строку, я получаю исключение преобразования массива в строку. Если я изменю код в шаблоне на:

{% for flashMessage in app.session.flashbag.get('success') %}
    <div id="flash">
        {{ flashMessage }}
    </div>
{% endfor %}

Это работает отлично. Я бы предпочел не использовать здесь цикл, так как у меня либо будет одно сообщение, либо нет.

Есть ли решение, в котором я могу просто проверить наличие одного флэш-сообщения и отобразить его, если оно есть? Или я застрял с бесполезным циклом?


person Major Productions    schedule 23.03.2013    source источник


Ответы (4)


Решил это путем индексации в 0:

{{ app.session.flashbag.get('success')[0] }}

Мои подозрения оправдались - get возвращает массив, а не строку. Вот метод add flashbag:

public function add($type, $message)
{
    $this->flashes[$type][] = $message;
}

И get:

public function get($type, array $default = array())
{
    if (!$this->has($type)) {
        return $default;
    }

    $return = $this->flashes[$type];

    unset($this->flashes[$type]);

    return $return;
}

Им нужно исправить документацию API, чтобы она отражала реальность. Они также должны обеспечивать элегантный способ обработки одного мгновенного сообщения.

РЕДАКТИРОВАТЬ: версия с обратной совместимостью (PHP 5.3 и ниже) -

{% if app.session.flashbag.has('success') %}
    {% set flashbag = app.session.flashbag.get('success') %}
    {% set message = flashbag[0] %}
    <div id="flash">
        {{ message }}
    </div>
{% endif %}
person Major Productions    schedule 23.03.2013
comment
9 месяцев, а документ все еще отстает - person jsgoupil; 04.11.2013

Для одного флеш-сообщения:

{{ app.session.flashbag.get('success')[0] }}

Для всех:

{% for type, messages in app.session.flashbag.all() %}
    {% for message in messages %}
        <div class="alert alert-{{ type }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}
person mkjasinski    schedule 23.03.2013

Я сам только что наткнулся на это. Это было потому, что я использовал метод add() вместо set().

Различия между «Добавить» и «Установить»:

public function add($type, $message)
{
    $this->flashes[$type][] = $message;
}

Вышеприведенное добавит дополнительный массив, который в данном случае не требуется.

В то время как:

public function set($type, $messages)
{
    $this->flashes[$type] = (array) $messages;
}

Таким образом, set() приводит к $array[$key] = $value, а не к тому, что делает add, что является $array[$key][] = $value, что вызывает преобразование вашего массива в строку, потому что вы передаете массив, а не строку.

person Matt Cavanagh    schedule 08.10.2015

Хорошо, я вижу, что вы решили эту проблему самостоятельно, но это может быть более простой способ:

{% if app.session.hasFlash('success') %}
    {{ app.session.flash('success') }}
{% endif %}

... так как вы не можете гарантировать, что всегда будет хотя бы флеш-сообщение ;)

person Jovan Perovic    schedule 23.03.2013
comment
Это проще, и это то, что у меня изначально было. Проблема в том, что способ сделать это будет объявлен устаревшим в версии 2.3, поэтому на будущее я решил использовать flashbag. - person Major Productions; 23.03.2013
comment
Ах, у меня еще нет времени читать 2.3 список изменений. Спасибо за информацию :) - person Jovan Perovic; 23.03.2013