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

Поиск:

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


Опытный
**


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

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



Здравствуйте, помогите разобраться с проблемой: есть простая задача - сгенерировать sitemap.xml.
Хочу генирировать код сразу в php://output, делаю так:
Выделить всёРазвернуть кодкод PHP
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
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(100as $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
Выделить всёкод PHP
1:
2:
$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 по какой-то причине в данном случае не проставляет (не успевает) изменить заголовки  в конструкторе:
Выделить всёкод PHP
1:
2:
3:
4:
5:
6:
7:
8:
9:
/**
     * SitemapXmlGenerator constructor.
     */
    public function __construct()
    {
        $response Yii::$app->response;
        $response->format Response::FORMAT_RAW;
        $response->getHeaders()->set('Content-Type''text/xml; charset=utf-8');
    }

заменяем на:
Выделить всёкод PHP
1:
2:
3:
4:
5:
6:
7:
/**
     * 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   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

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

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


 




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


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

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