Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> XmlWriter вывод в php://output, предотвратить сброс буфера 
:(
    Опции темы
Logree
Дата 14.2.2016, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Здравствуйте, помогите разобраться с проблемой: есть простая задача - сгенерировать sitemap.xml.
Хочу генирировать код сразу в php://output, делаю так:
Код

class SitemapXmlGenerator extends \XMLWriter
{
    /**
     * SitemapXmlGenerator constructor.
     */
    public function __construct()
    {
        $response = Yii::$app->response;
        $response->format = Response::FORMAT_RAW;
        $response->getHeaders()->set('Content-Type', 'text/xml; charset=utf-8');
    }

    /**
     * @inheritdoc
     */
    public function execute($dstResource) {

        //ob_start();

        if ($this->openUri($dstResource) === false) {

            throw new Exception("Can't open resource {$dstResource}");
        };

        $this->startDocument('1.0', 'UTF-8');
        $this->setIndent(true);
        $this->setIndentString("\t");

        $this->startElement('urlset');
            $this->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');

        // urls

        $this->writeUrls();

        $this->endElement(); // urlset
        $this->endDocument();

        //ob_end_flush();
    }

    public function writeUrls()
    {
        $urls = $this->getUrls();

        foreach ($rls->batch(100) as $part) {
            foreach ($part as $url) {
                $this->writeUrl($url);
            }
        }
    }

public function writeUrl($loc, $priority = 0.5, $changeFreq = 'weekly', $lastMod = null)
    {
        $flags = \ENT_QUOTES | \ENT_XML1;

        if (empty($loc) || strlen($loc) > self::LOC_MAX_LEN || strpos($loc, 'http') !== 0) {
            return;
        }

        $this->startElement('url');
            $this->writeElement('loc', \htmlspecialchars($loc, $flags));
        if ($priority !== null) {
            $this->writeElement('priority', $priority);
        }
        if ($changeFreq !== null) {
            $this->writeElement('changefreq', $changeFreq);
        }
        if ($lastMod !== null) {
            $this->writeElement('lastmod', $lastMod);
        }
        $this->endElement(); // url
    }

}

просто генерируем документ наследуясь от XMLWriter
Код

$g = new SitemapXmlGenerator();
$g->execute('php://output');

Все работает, все красиво, но для больших объемов данных ответ приходил с Content-type: text/html вместо text/xml хотя все генерировалось полностью. 
Оказалось что заголовки отправляются как только размер переваливает за 8016 байт. т.е скидывается буфер из-за этого меняется Content-type, если я все правильно понимаю.

Пробывал спользовать ob_start(), как в примере выше (закоментированно) - без результата.

Подскажите как правильно сделать? Можно ли реализовать без использования временного файла?



--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
Logree
Дата 14.2.2016, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Странно что ни кто не дал ответ.

Судя по всему Yii2 по какой-то причине в данном случае не проставляет (не успевает) изменить заголовки  в конструкторе:
Код

/**
     * SitemapXmlGenerator constructor.
     */
    public function __construct()
    {
        $response = Yii::$app->response;
        $response->format = Response::FORMAT_RAW;
        $response->getHeaders()->set('Content-Type', 'text/xml; charset=utf-8');
    }

заменяем на:
Код

/**
     * SitemapXmlGenerator constructor.
     */
    public function __construct()
    {
        header('Content-Type: text/xml; charset=utf-8');
    }

И все работает. 
Если кто-то, на пример SamDark, сможет дать комментарий, буду благодарен)


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
Logree
Дата 15.2.2016, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Поторопился - проблема НЕ решена.  Поделитесь мыслями.


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.1219 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.