Diskuze: End of script output before headers
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.


Ahoj, tobě webhosting opravdu umožňuje modifikovat parametry pro max_execution_time a memory_limit?
Popravdě mě nenapadá, čeho se z těch mála informací chytit. Kód nám sem asi nedodáš, tak třeba výpis phpinfo pro localhost a remote.
Takhle čistě na první dobrou to opravdu vypadá na nějaký limit. Plus tedy to, že 40s na localhostu není pro čas vykonání na remote žádný směrodatný údaj, jelikož záleží i na přidělených systémových prostředcích. Pokud ty XML soubory v čase rostou, klidně jsi na limit mohl narazit.
Omlouvám se za nedodání informací. Dodávám kod, který načítám a který mi hodí tu chybu 500.
Jinak v administraci hostingu můžu nastavit níže uvedené hodnoty.
memory_limit: 128M
max_file_uploads: 20
upload_max_filesize: 128M
post_max_size: 128M
max_execution_time: 90s
include "../../config/konfigurace.php";
$prefix_dodavatele = 'RA';
$aktual_time = time();
$aktual_time_prevod = date("Y-m-d H:i:s", $aktual_time);
$cil_server = "xml_data.xml";
// smazání všech dříve importovaných produktů
MySQL_Query("TRUNCATE TABLE `import_dodavatel_product`") or die("Chyba smazání importu import_dodavatel_product");
MySQL_Query("TRUNCATE TABLE `import_dodavatel_category`") or die("Chyba smazání importu import_dodavatel_category");
MySQL_Query("TRUNCATE TABLE `import_dodavatel_images`") or die("Chyba smazání importu import_dodavatel_images");
// read XML data string - číst XML datový řetězec
$xml = simplexml_load_file($cil_server) or die("ERROR: Cannot create SimpleXML object");
// ** čtení XML souboru ** //
foreach ($xml->SHOPITEM as $SHOPITEM) {
$PRODUCT = $SHOPITEM->PRODUCT;
// odstranění entit
$PRODUCT_PREVOD = htmlspecialchars($PRODUCT, ENT_QUOTES);
$pred = array("&");
$po = array("");
$PRODUCT_PREVOD_OREZ = str_replace($pred, $po, $PRODUCT_PREVOD);
$DESCRIPTION = $SHOPITEM->DESCRIPTION;
// odstranění entit
$DESCRIPTION_PREVOD = htmlspecialchars($DESCRIPTION, ENT_QUOTES);
$URL = $SHOPITEM->URL;
$DELIVERY_DATE = $SHOPITEM->DELIVERY_DATE;
$KOD = $SHOPITEM->KOD;
$PRICE = $SHOPITEM->PRICE;
$PRICE_VAT = $SHOPITEM->PRICE_VAT;
$PRICEVO = $SHOPITEM->PRICEVO;
$PRICEVO_VAT = $SHOPITEM->PRICEVO_VAT;
$IMGURL = $SHOPITEM->IMGURL;
$CATEGORYTEXT = $SHOPITEM->CATEGORYTEXT;
$IMAGES = $SHOPITEM->IMAGES;
$IMAGE = $IMAGES->IMAGE;
$EAN = $SHOPITEM->EAN;
$PACKAGE_MINIMUM = $SHOPITEM->PACKAGE_MINIMUM;
$PACKAGE_SIZE = $SHOPITEM->PACKAGE_SIZE;
$PACKAGING = $SHOPITEM->PACKAGING;
$STOCK = $SHOPITEM->STOCK;
$AGE = $SHOPITEM->AGE;
$DISCOUNTGROUPID = $SHOPITEM->DISCOUNTGROUPID;
$DISCOUNTGROUP = $SHOPITEM->DISCOUNTGROUP;
$COLORS = $SHOPITEM->COLORS;
// ** informace s tabulky o produktu
// import do tabulky rappa
$query = "INSERT INTO import_dodavatel_product VALUES ('$prefix_dodavatele$KOD', '$PRODUCT_PREVOD_OREZ', '$DESCRIPTION_PREVOD', '$URL', '$DELIVERY_DATE', '$PRICE', '$PRICE_VAT', '$PRICEVO', '$PRICEVO_VAT', '$IMGURL', '$EAN', '$PACKAGE_MINIMUM', '$PACKAGE_SIZE', '$PACKAGING', '$STOCK', '$AGE', '$DISCOUNTGROUPID', '$DISCOUNTGROUP', '$COLORS')";
mysql_query($query) or die("Chybný importu $KOD");
echo "$prefix_dodavatele$KOD <br>";
// ** načtení kategorii ** //
foreach ($CATEGORYTEXT as $CATEGORY) {
// ** rozsekání oddělovačem | ** //
$CATEGORY_one_Kategorie = substr($CATEGORY, 12);
$CATY_bez_carky = str_replace("'","", $CATEGORY_one_Kategorie);
$query = "INSERT INTO import_dodavatel_category VALUES ('','$KOD','$CATY_bez_carky')";
mysql_query($query) or die("Není možné přidat záznam do databáze!");
}
// ** načtení fotek ** //
foreach ($IMAGE as $IMAGE_DETAIL) {
$IMAGE_DETAIL_OREZ = substr($IMAGE_DETAIL, 46);
$query_into = "INSERT INTO import_dodavatel_images VALUES ('', '$prefix_dodavatele$KOD', '$prefix_dodavatele$IMAGE_DETAIL_OREZ', '$IMAGE_DETAIL')";
mysql_query($query_into) or die("Chyba vložení obrázku $IMAGE_DETAIL");
}
}
// ** END čtení XML souboru ** //
echo "import hotový";
Neaktivní uživatel:18.4.2020 11:07
Jak velký je ten XML soubor? Na kód jsem koukal a stále si myslím, že jde o timeout při provádění nebo o nedostatek paměti pro načtení. Jaké máš hodnoty na localu ve srovnání s webhostingem?
Jelikož všechna data z SQL mažeš, tak předpokládám, že xml opravdu s časem výrazně roste. Nešlo by namísto toho získávat časově ohraničené záznamy a tabulky spíše aktualizovat než pravidelně plnit od nuly? Současný přístup totiž opravdu trpí na to, že se stává s časem náročnější na prostředky pro zpracování.
- Pouzivas stary sql ovladac, mysql, pouzivej pdo.
- Zkus pridat vypis chyb, error_reporting, mysql_error, mozna hosting upgradoval a pise ti to chyby prave s tim ovladacem, nebo selhal nektery sql dotaz. Mas tam jakysi vypis chyb, nepise to nejakou?
- Zkus pouzivat escapovani hodnot nez je dostanes do sql dotazu. Mas tam htmlspecialchar pro html, ale nikde nevidim, ze by sis pohlidal sql (v pdo se to jmenuje prepare statemant). V sql hodnote musis odstranit nebo escapovat vsechny znaky, ktere by nejak mohly narusit sql dotaz. Napriklad apostrofy '.
$KOD = "aaa','bbb'";
$CATY_bez_carky = "123";
$query = "INSERT INTO import_dodavatel_category VALUES ('','$KOD','$CATY_bez_carky')";
$query = "INSERT INTO import_dodavatel_category VALUES ('','aaa','bbb','123')";
To je ale preci uplne jiny sql dotaz, 4 sloupce a tabulka ma jen 3!
4. Zkus si vypisovat seznam provedenych akci nebo aspon jmeno produktu,
kategorie. Pouziva se k tomu prikaz echo. Teoreticky, ikdyz skonci timelimitem,
uvidis, co se ti tam pridalo a co uz nee.
5. Zkus pouzivat uvolnovani resultu, ale to asi neni treba pri insertu a zvlast,
kdyz to neukladas do promenne.
6.Muzes taky zkusit to xml rozsekat na vic souboru. Pripadne pouzit postupnou
parsovaci funkci, ktera nenacita cely soubor do pameti.
https://stackoverflow.com/…files-in-php
$xmlFile = 'the_LARGE_xml_file_to_load.xml'
$primEL = 'the_name_of_your_element';
$xml = new XMLReader();
$xml->open($xmlFile);
// finding first primary element to work with
while($xml->read() && $xml->name != $primEL){;}
// looping through elements
while($xml->name == $primEL) {
// loading element data into simpleXML object
$element = new SimpleXMLElement($xml->readOuterXML());
// DO STUFF
// moving pointer
$xml->next($primEL);
// clearing current element
unset($element);
} // end while
$xml->close();
<?php
set_time_limit(0);
$reader = new XMLReader();
if (!$reader->open("data.xml"))
{
die("Failed to open 'data.xml'");
}
while($reader->read())
{
$node = $reader->expand();
// process $node...
}
$reader->close();
?>
Mimochodem, 40s import je pomerne drama. Ja upravoal jeden script a stahl jsem to asi na 7s. Uploadoval jsem zip soubor kvuli limitu na upload.
Děkuji všem za pomoc. Přiznám se, že jsem se do toho nějak zasekl, sedím nad tím už tři dny a večery a zatím se mi nepodařilo rozlousknout.
To xml má 5 mb. Celkem je tam asi 2200 položek z různými parametry.
Zkusil jsem jít uplně od začátku.
Když zkouším importovat jen do jedné tabulky, tak mi to zhavaruje a hodí asi po 40 sek tu chybu 500. Kod vypadá takto:
<?php
include "../../config/konfigurace.php";
$prefix_dodavatele = 'RA';
$aktual_time = time();
$aktual_time_prevod = date("Y-m-d H:i:s", $aktual_time);
//$server_xml_data_rappa = "http://www.rappa.cz/export/vo.xml";
$cil_server = "xml_data.xml";
// smazání všech dříve importovaných produktů
MySQL_Query("TRUNCATE TABLE `import_dodavatel_product`") or die("Chyba smazání importu import_dodavatel_product");
MySQL_Query("TRUNCATE TABLE `import_dodavatel_category`") or die("Chyba smazání importu import_dodavatel_category");
MySQL_Query("TRUNCATE TABLE `import_dodavatel_images`") or die("Chyba smazání importu import_dodavatel_images");
// read XML data string - číst XML datový řetězec
$xml = simplexml_load_file($cil_server) or die("ERROR: Cannot create SimpleXML object");
// $xml = simplexml_load_file("http://www.rappa.cz/export/vo.xml") or die("ERROR: Cannot create SimpleXML object");
// ** čtení XML souboru ** //
foreach ($xml->SHOPITEM as $SHOPITEM) {
$PRODUCT = $SHOPITEM->PRODUCT;
$PRODUCT_OREZ = mysqli_real_escape_string($PRODUCT);
$PRODUCT_OREZ = htmlspecialchars($PRODUCT_OREZ);
$DESCRIPTION = $SHOPITEM->DESCRIPTION;
$DESCRIPTION_OREZ = mysqli_real_escape_string($DESCRIPTION);
$DESCRIPTION_OREZ = htmlspecialchars($DESCRIPTION_OREZ);
$URL = $SHOPITEM->URL;
$DELIVERY_DATE = $SHOPITEM->DELIVERY_DATE;
$KOD = $SHOPITEM->KOD;
$PRICE = $SHOPITEM->PRICE;
$PRICE_VAT = $SHOPITEM->PRICE_VAT;
$PRICEVO = $SHOPITEM->PRICEVO;
$PRICEVO_VAT = $SHOPITEM->PRICEVO_VAT;
$IMGURL = $SHOPITEM->IMGURL;
$CATEGORYTEXT = $SHOPITEM->CATEGORYTEXT;
$IMAGES = $SHOPITEM->IMAGES;
$IMAGE = $IMAGES->IMAGE;
$EAN = $SHOPITEM->EAN;
$PACKAGE_MINIMUM = $SHOPITEM->PACKAGE_MINIMUM;
$PACKAGE_SIZE = $SHOPITEM->PACKAGE_SIZE;
$PACKAGING = $SHOPITEM->PACKAGING;
$STOCK = $SHOPITEM->STOCK;
$AGE = $SHOPITEM->AGE;
$DISCOUNTGROUPID = $SHOPITEM->DISCOUNTGROUPID;
$DISCOUNTGROUP = $SHOPITEM->DISCOUNTGROUP;
$COLORS = $SHOPITEM->COLORS;
// ** informace s tabulky o produktu
echo "$prefix_dodavatele$KOD / $PACKAGE_MINIMUM / $STOCK<br>";
// import do tabulky produktu
$query_product = "INSERT INTO import_dodavatel_product VALUES ('$prefix_dodavatele$KOD', '$PRODUCT_PREVOD_OREZ', '$DESCRIPTION_PREVOD', '$URL', '$DELIVERY_DATE', '$PRICE', '$PRICE_VAT', '$PRICEVO', '$PRICEVO_VAT', '$IMGURL', '$EAN', '$PACKAGE_MINIMUM', '$PACKAGE_SIZE', '$PACKAGING', '$STOCK', '$AGE', '$DISCOUNTGROUPID', '$DISCOUNTGROUP', '$COLORS')";
mysql_query($query_product) or die("Chybný importu $KOD");
// ** načtení kategorii ** //
foreach ($CATEGORYTEXT as $CATEGORY) {
// ** rozsekání oddělovačem | ** //
$CATEGORY_one_Kategorie = substr($CATEGORY, 12);
$CATY_bez_carky = str_replace("'","", $CATEGORY_one_Kategorie);
$query_category = "INSERT INTO import_dodavatel_category VALUES ('','$KOD','$CATY_bez_carky')";
mysql_query($query_category) or die("Není možné přidat záznam do databáze!");
}
// ** načtení fotek ** //
foreach ($IMAGE as $IMAGE_DETAIL) {
$IMAGE_DETAIL_OREZ = substr($IMAGE_DETAIL, 46);
$query_image = "INSERT INTO import_dodavatel_images VALUES ('', '$prefix_dodavatele$KOD', '$prefix_dodavatele$IMAGE_DETAIL_OREZ', '$IMAGE_DETAIL')";
mysql_query($query_image) or die("Chyba vložení obrázku $IMAGE_DETAIL");
}
}
// ** END čtení XML souboru ** //
echo "import hotový";
?>
Když z výše uvedeného vyhodím to načítání do jedné tabulky níže uvedené, tak funguje
// import do tabulky produktu
$query_product = "INSERT INTO import_dodavatel_product VALUES ('$prefix_dodavatele$KOD', '$PRODUCT_PREVOD_OREZ', '$DESCRIPTION_PREVOD', '$URL', '$DELIVERY_DATE', '$PRICE', '$PRICE_VAT', '$PRICEVO', '$PRICEVO_VAT', '$IMGURL', '$EAN', '$PACKAGE_MINIMUM', '$PACKAGE_SIZE', '$PACKAGING', '$STOCK', '$AGE', '$DISCOUNTGROUPID', '$DISCOUNTGROUP', '$COLORS')";
mysql_query($query_product) or die("Chybný importu $KOD");
Zkoušel jsem tu variantu s tou parsovaci funkci, ktera nenacita cely soubor do pameti, ale to se přiznám, se mi nepodařilo naprogramovat
SQL té dané tabulky vypadá takto:
CREATE TABLE `import_dodavatel_product` (
`kod` varchar(8) COLLATE utf8_czech_ci NOT NULL,
`product` text COLLATE utf8_czech_ci NOT NULL,
`description` text COLLATE utf8_czech_ci NOT NULL,
`url` varchar(100) COLLATE utf8_czech_ci NOT NULL,
`delivery_date` varchar(10) COLLATE utf8_czech_ci NOT NULL,
`price` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`price_vat` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`pricevo` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`pricevo_vat` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`imgurl` varchar(250) COLLATE utf8_czech_ci NOT NULL,
`ean` varchar(40) COLLATE utf8_czech_ci NOT NULL,
`package_minimum` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`package_size` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`packaging` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`stock` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`age` varchar(20) COLLATE utf8_czech_ci NOT NULL,
`discountgroupid` varchar(50) COLLATE utf8_czech_ci NOT NULL,
`discountgorup` varchar(50) COLLATE utf8_czech_ci NOT NULL,
`colors` varchar(100) COLLATE utf8_czech_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
ALTER TABLE `import_dodavatel_product`
ADD UNIQUE KEY `KOD` (`kod`);
Ještě přikládám konfiguraci toho serveru https://hracky-rozarka.cz/test.php. Přiznám se, že uplně všem častem nerozumím, tak kdyby jste si všimli, např. nějaké funkce, co by to mohla způsobovat a je vypnutá, tak mi prosím napište. Díky
Zkus vypisovat jednotlive inserty a mysql_error. Pripadne xml error, protoze
mozna selhalo nacitani xml.
Zkus pridat pocitani radku a zastav cyklus treba po pridani 200 produktu.
Uvidis, kde ti to selhalo, jaky insert se neprovedl a zda tech 200 prvnich
proslo.
$start = 0;
$end = 200;
$i = 0; // pred cyklem
if ($i<$start) continue; // v cyklu
if ($i>end) break;
echo $i.'. '.$query; // vypis dotazu, pokud nebudes tunta a ulozis si ho do stringu $query, abys ho krome do mysql mohl poslat tez na obrazovku
mysql_query($query);
if ($error = mysql_error()) die('Error, insert query failed with:' . $error);
Zobrazeno 8 zpráv z 8.