Всем привет!
Народ, столкнулся вот с такой проблемой. Есть PHP-файл. Он генерирует XML.
Этот сгенерированный XML отображается на странице.
Проблема в том, что когда данных много, XML генерируется долго. Хочется сделать так, чтобы сгенерированный XML сохранялся бы по окончании работы скрипта в ту же папку, где и сам скрипт лежит.
Помогите пожалуйста, куда копать? Как это парвильно делается. Сейчас в голову приходит только
[CODE]ob_start();
...Контент
$content = ob_get_contents(); ob_end_clean();[/CODE]
Но этот способ не работает - страница в браузере при генерировании XML выдаёт ошибку:
[CODE]This page contains the following errors:error on line 10 at column 1: Extra content at the end of the document
Below is a rendering of the page up to the first error.[/CODE]
Помогите пожалуйста, может кто с этим сталкивался. В конечном итоге нужно, чтоб скрипт по крону отрабатывал, и рядом бы сохранял готовый XML.
Вот код того, что есть:
[CODE]<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/classes/general/xml.php');
CModule::IncludeModule("iblock");
CModule::IncludeModule("catalog");
CModule::IncludeModule("sale");
ini_set('memory_limit','2G');
ini_set('max_execution_time', 3600*2);
header("Content-Type: text/xml; charset=windows-1251");
header("Content-Type: text/xml;");
//Начало буферизации
//ob_start();
echo "<"."?xml version=\"1.0\" encoding=\"windows-1251\"?".">";
?>
<?if (!isset($_GET["referer1"]) || strlen($_GET["referer1"])<=0)
$_GET["referer1"] = "yandext"?>
<?
function getFinalPriceInCurrency($item_id, $sale_currency = 'RUB') {
global $USER;
$currency_code = 'RUB';
// Простой товар, без торговых предложений (для количества равному 1)
$price = CCatalogProduct::GetOptimalPrice($item_id, 1, $USER->GetUserGroupArray(), 'N');
// Получили цену?
if(!$price || !isset($price['PRICE'])) {
return false;
}
// Меняем код валюты, если нашли
if(isset($price['CURRENCY'])) {
$currency_code = $price['CURRENCY'];
}
if(isset($price['PRICE']['CURRENCY'])) {
$currency_code = $price['PRICE']['CURRENCY'];
}
// Получаем итоговую цену
$final_price = $price['PRICE']['PRICE'];
// Ищем скидки и пересчитываем цену товара с их учетом
$arDiscounts = CCatalogDiscount::GetDiscountByProduct($item_id, $USER->GetUserGroupArray(), "N", 2);
if(is_array($arDiscounts) && sizeof($arDiscounts) > 0) {
$final_price = CCatalogProduct::CountPriceWithDiscount($final_price, $currency_code, $arDiscounts);
}
// Если необходимо, конвертируем в нужную валюту
if($currency_code != $sale_currency) {
$final_price = CCurrencyRates::ConvertCurrency($final_price, $currency_code, $sale_currency);
}
return $final_price;
}
function getChilds_4($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?}
}
function getChilds_3($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?=getChilds_4($arSect['ID'], $arSect['DEPTH_LEVEL'])?>
<?}
}
function getChilds($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?=getChilds_3($arSect['ID'], $arSect['DEPTH_LEVEL'])?>
<?}
}
?>
<?
ob_start();
?>
<!DO CTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2022-04-15 18:40">
<shop>
<name>Название магазина</name>
<company>Shop Name</company>
<url>https://www.shop.ru</url>
<currencies>
<currency id="RUB" rate="1"/>
</currencies>
<categories>
<?
//Вытаскиваем категории из инфоблока Каталог товаров -> Каталог товаров
$cur_depth = 1;
$arFilter = Array('IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'DEPTH_LEVEL' => $cur_depth
);
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?
getChilds($arSect['ID'], $arSect['DEPTH_LEVEL']);
}
?>
</categories>
<offers>
<?
//Вытаскиваем товары
$arSelect = Array("ID", "IBLOCK_ID","XML_ID","DETAIL_PICTURE","CODE" ,"NAME", "DATE_ACTIVE_FROM","PROPERTY_*");
$arFilter = Array("IBLOCK_ID"=>3, "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y");
$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>600), $arSelect);
$count = 0;
while($ob = $res->GetNextElement()){
$arFields = $ob->GetFields();
$arProps = $ob->GetProperties();
$product_res = CCatalogProduct::GetByID($arFields['ID']);
$ar_price_res = CPrice::GetBasePrice($arFields['ID'], false, false);
$arPrice = CCatalogProduct::GetOptimalPrice($arFields['ID'], 1, Array(), "N");//для получения скидочной цены
?>
<offer id="<?=$arFields['ID']?>" productId="<?=$arFields['ID']?>" quantity="<?=$product_res['QUANTITY']?>">
<url><?='https://'.SITE_SERVER_NAME.'/product/'.$arFields['ID'].'/'.$arFields['CODE'].'/'?></url>
<price>
<?
//Получаем базовую цену товара и SALE(скидочную цену товара).
//Если SALE < базовой, то базовая цена это oldprice, а SALE это просто price
//Если SALE=базовой, то price это базовая цена
//echo '<pre>';
//print_r($ar_price_res['PRICE']);
//echo '</pre>';
//echo $ar_price_res['PRICE'];
$PRICE_TYPE_ID = 14;
$sale_price = '';
$db_price_res = CPrice::GetList(
array(),
array(
"PRODUCT_ID" => $arFields['ID'], // Получаем ID Товара
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID // Получаем ID типа цен из переменной
)
);
if ($ar_res = $db_price_res->Fetch())
{
//$sale_price = CurrencyFormat($ar_res["PRICE"], $ar_res["CURRENCY"]);
$sale_price = $ar_res["PRICE"];
//echo $sale_price;
}
if($sale_price < $ar_price_res['PRICE'])
echo $sale_price;
else
echo $ar_price_res['PRICE'];
//var_dump(getFinalPriceInCurrency($arFields['ID']));
?>
</price>
<currencyId><?=$ar_price_res['CURRENCY']?></currencyId>
<?/*<categoryId>123</categoryId>*/?>
<?/*<picture>https://www.shop.ru/product_img/<?=$arFields['ID']?>/b1.jpg</picture>*/?>
<picture>https://cdn.shop.ru/product_img/826041/b1.jpg</picture>
<?/*<name><?=$arFields['NAME']?></name>*/?>
<xmlId><?=$arFields['XML_ID']?></xmlId>
<param name="Вес" unit="г"><?=$product_res['WEIGHT']?></param>
<param name="article" code="article"><?=$arProps['CML2_ARTICLE']['VALUE']?></param>
<param name="Артикул = баркоду" code=""><?=$arProps['CML2_ARTICLE']['VALUE']?></param>
<prod_count><?=$product_res['QUANTITY']?></prod_count>
<warehouse_name>склад шоп</warehouse_name>
</offer>
<?
$count++;
}?>
</offers>
</shop>
</yml_catalog>
<?
$content = ob_get_contents();
ob_end_clean();
?>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
?>[/CODE]
Народ, столкнулся вот с такой проблемой. Есть PHP-файл. Он генерирует XML.
Этот сгенерированный XML отображается на странице.
Проблема в том, что когда данных много, XML генерируется долго. Хочется сделать так, чтобы сгенерированный XML сохранялся бы по окончании работы скрипта в ту же папку, где и сам скрипт лежит.
Помогите пожалуйста, куда копать? Как это парвильно делается. Сейчас в голову приходит только
[CODE]ob_start();
...Контент
$content = ob_get_contents(); ob_end_clean();[/CODE]
Но этот способ не работает - страница в браузере при генерировании XML выдаёт ошибку:
[CODE]This page contains the following errors:error on line 10 at column 1: Extra content at the end of the document
Below is a rendering of the page up to the first error.[/CODE]
Помогите пожалуйста, может кто с этим сталкивался. В конечном итоге нужно, чтоб скрипт по крону отрабатывал, и рядом бы сохранял готовый XML.
Вот код того, что есть:
[CODE]<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/classes/general/xml.php');
CModule::IncludeModule("iblock");
CModule::IncludeModule("catalog");
CModule::IncludeModule("sale");
ini_set('memory_limit','2G');
ini_set('max_execution_time', 3600*2);
header("Content-Type: text/xml; charset=windows-1251");
header("Content-Type: text/xml;");
//Начало буферизации
//ob_start();
echo "<"."?xml version=\"1.0\" encoding=\"windows-1251\"?".">";
?>
<?if (!isset($_GET["referer1"]) || strlen($_GET["referer1"])<=0)
$_GET["referer1"] = "yandext"?>
<?
function getFinalPriceInCurrency($item_id, $sale_currency = 'RUB') {
global $USER;
$currency_code = 'RUB';
// Простой товар, без торговых предложений (для количества равному 1)
$price = CCatalogProduct::GetOptimalPrice($item_id, 1, $USER->GetUserGroupArray(), 'N');
// Получили цену?
if(!$price || !isset($price['PRICE'])) {
return false;
}
// Меняем код валюты, если нашли
if(isset($price['CURRENCY'])) {
$currency_code = $price['CURRENCY'];
}
if(isset($price['PRICE']['CURRENCY'])) {
$currency_code = $price['PRICE']['CURRENCY'];
}
// Получаем итоговую цену
$final_price = $price['PRICE']['PRICE'];
// Ищем скидки и пересчитываем цену товара с их учетом
$arDiscounts = CCatalogDiscount::GetDiscountByProduct($item_id, $USER->GetUserGroupArray(), "N", 2);
if(is_array($arDiscounts) && sizeof($arDiscounts) > 0) {
$final_price = CCatalogProduct::CountPriceWithDiscount($final_price, $currency_code, $arDiscounts);
}
// Если необходимо, конвертируем в нужную валюту
if($currency_code != $sale_currency) {
$final_price = CCurrencyRates::ConvertCurrency($final_price, $currency_code, $sale_currency);
}
return $final_price;
}
function getChilds_4($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?}
}
function getChilds_3($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?=getChilds_4($arSect['ID'], $arSect['DEPTH_LEVEL'])?>
<?}
}
function getChilds($parent_id, $parent_depth){
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$arFilter = Array(
'IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'SECTION_ID' => $parent_id
//'DEPTH_LEVEL' => $parent_depth + 1
);
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" parent-id="<?=$parent_id?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?=getChilds_3($arSect['ID'], $arSect['DEPTH_LEVEL'])?>
<?}
}
?>
<?
ob_start();
?>
<!DO CTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2022-04-15 18:40">
<shop>
<name>Название магазина</name>
<company>Shop Name</company>
<url>https://www.shop.ru</url>
<currencies>
<currency id="RUB" rate="1"/>
</currencies>
<categories>
<?
//Вытаскиваем категории из инфоблока Каталог товаров -> Каталог товаров
$cur_depth = 1;
$arFilter = Array('IBLOCK_ID'=>3,
'GLOBAL_ACTIVE'=>'Y',
'ACTIVE' => 'Y',
'UF_NOT_IN_SITE'=> 'N',
'DEPTH_LEVEL' => $cur_depth
);
$arSelect = Array('ID','NAME','UF_NOT_IN_SITE','DEPTH_LEVEL','LEFT_MARGIN','RIGHT_MARGIN');
$db_list = CIBlockSection::GetList(Array('ID'=>'ASC'), $arFilter, true, $arSelect);
while($arSect = $db_list->GetNext()){?>
<category id="<?=$arSect['ID']?>" data-depth="<?=$arSect['DEPTH_LEVEL']?>">
<?=$arSect['NAME']?>
</category>
<?
getChilds($arSect['ID'], $arSect['DEPTH_LEVEL']);
}
?>
</categories>
<offers>
<?
//Вытаскиваем товары
$arSelect = Array("ID", "IBLOCK_ID","XML_ID","DETAIL_PICTURE","CODE" ,"NAME", "DATE_ACTIVE_FROM","PROPERTY_*");
$arFilter = Array("IBLOCK_ID"=>3, "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y");
$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>600), $arSelect);
$count = 0;
while($ob = $res->GetNextElement()){
$arFields = $ob->GetFields();
$arProps = $ob->GetProperties();
$product_res = CCatalogProduct::GetByID($arFields['ID']);
$ar_price_res = CPrice::GetBasePrice($arFields['ID'], false, false);
$arPrice = CCatalogProduct::GetOptimalPrice($arFields['ID'], 1, Array(), "N");//для получения скидочной цены
?>
<offer id="<?=$arFields['ID']?>" productId="<?=$arFields['ID']?>" quantity="<?=$product_res['QUANTITY']?>">
<url><?='https://'.SITE_SERVER_NAME.'/product/'.$arFields['ID'].'/'.$arFields['CODE'].'/'?></url>
<price>
<?
//Получаем базовую цену товара и SALE(скидочную цену товара).
//Если SALE < базовой, то базовая цена это oldprice, а SALE это просто price
//Если SALE=базовой, то price это базовая цена
//echo '<pre>';
//print_r($ar_price_res['PRICE']);
//echo '</pre>';
//echo $ar_price_res['PRICE'];
$PRICE_TYPE_ID = 14;
$sale_price = '';
$db_price_res = CPrice::GetList(
array(),
array(
"PRODUCT_ID" => $arFields['ID'], // Получаем ID Товара
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID // Получаем ID типа цен из переменной
)
);
if ($ar_res = $db_price_res->Fetch())
{
//$sale_price = CurrencyFormat($ar_res["PRICE"], $ar_res["CURRENCY"]);
$sale_price = $ar_res["PRICE"];
//echo $sale_price;
}
if($sale_price < $ar_price_res['PRICE'])
echo $sale_price;
else
echo $ar_price_res['PRICE'];
//var_dump(getFinalPriceInCurrency($arFields['ID']));
?>
</price>
<currencyId><?=$ar_price_res['CURRENCY']?></currencyId>
<?/*<categoryId>123</categoryId>*/?>
<?/*<picture>https://www.shop.ru/product_img/<?=$arFields['ID']?>/b1.jpg</picture>*/?>
<picture>https://cdn.shop.ru/product_img/826041/b1.jpg</picture>
<?/*<name><?=$arFields['NAME']?></name>*/?>
<xmlId><?=$arFields['XML_ID']?></xmlId>
<param name="Вес" unit="г"><?=$product_res['WEIGHT']?></param>
<param name="article" code="article"><?=$arProps['CML2_ARTICLE']['VALUE']?></param>
<param name="Артикул = баркоду" code=""><?=$arProps['CML2_ARTICLE']['VALUE']?></param>
<prod_count><?=$product_res['QUANTITY']?></prod_count>
<warehouse_name>склад шоп</warehouse_name>
</offer>
<?
$count++;
}?>
</offers>
</shop>
</yml_catalog>
<?
$content = ob_get_contents();
ob_end_clean();
?>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
?>[/CODE]