Hledáme nového kolegu do redakce - 100% home office, 100% flexibilní pracovní doba. Více informací.
Využij akce až 80 % zdarma při nákupu e-learningu - více informací. Zároveň pouze tento týden sleva až 80 % na e-learning týkající se Swift
discount week 80
Avatar
Jiří Janeček:17.4.2020 12:09

Mám několik skriptu, kterými načítání XML soubory do myslql databáze.
Mám verzi 5...

Když se spusti skript, běží cca 40 sekund. Zobrazí se chyba 500. Na localhostu mi to funguje v poradku, ale na na webhostingu ne.

Fungovalo mi to několik měsíců a bez úprav to přesto fungovat. V logu error se mi pak zobrazí End of script output before headers.

Nevíte prosím co s tím? Díky

Zkusil jsem: Zkoušel jsem, jestli nemám mezeru na začátku a na konci a nejsou.

Zvýšil sem moznost timeout na 90sek, paměť 128 mb

Chci docílit: Snažím se odstranit to, aby mi skript doběhl do konce.

 
Odpovědět
17.4.2020 12:09
Avatar
Martin Kašpar:17.4.2020 12:30

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.

 
Nahoru Odpovědět
17.4.2020 12:30
Avatar
Jiří Janeček:17.4.2020 13:45

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_fi­lesize: 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ý";
 
Nahoru Odpovědět
17.4.2020 13:45
Avatar
Odpovídá na Jiří Janeček
Martin Kašpar: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í.

 
Nahoru Odpovědět
18.4.2020 11:07
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.4.2020 9:20
  1. Pouzivas stary sql ovladac, mysql, pouzivej pdo.
  2. 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?
  3. 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.

Editováno 20.4.2020 9:21
 
Nahoru Odpovědět
20.4.2020 9:20
Avatar
Jiří Janeček:23.4.2020 22:55

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

 
Nahoru Odpovědět
23.4.2020 22:55
Avatar
Jiří Janeček:23.4.2020 23:06

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

 
Nahoru Odpovědět
23.4.2020 23:06
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.4.2020 8:39

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);
 
Nahoru Odpovědět
24.4.2020 8:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.