Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> TIME OUT lub CPU LIMIT skryptu, aktualizacja stanów magazynowych prestashop
tom3k21
post
Post #1





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 6.05.2014

Ostrzeżenie: (0%)
-----


Witam wszystkich (IMG:style_emoticons/default/smile.gif)
Mam nadzieje że jest ktoś w stanie mi pomóc rozwiązać problem ze skryptem do aktualizacji stanów magazynowych.
Otóż sklep stoi na home.pl i tutaj jest problem... (od administatorów jedyne czego się dowiedziałem to żeby przenieść na inny pakiet hostingowy (IMG:style_emoticons/default/tongue.gif) ot tak pomocni są)... a mianowicie mają ustawione limity CPU (ok rozumie) ale także max_execution_time na ok 5min którego zmienić nie można :/ ale do sedna...

Moje wypociny ponizej i jako że jestem laikiem w programowaniu to nie bardzo wiem jak go zoptymalizować lub podzielić na części aby wykonywały się jedna po drugiej (np podzielic plik xml i jeden po drugim parsowac, plik zawiera około 10 000 produktów ~10mb).

  1. <?php
  2. //error_reporting(E_ALL);
  3. header('Content-type: text/html; charset=utf8');
  4. include 'import_config.php';
  5. include 'import_functions.php';
  6. ?>
  7. <body>
  8.  
  9. <div id="information"></div>
  10.  
  11. <?php
  12.  
  13. $xmlfile = 'import/plik.xml';
  14.  
  15. if($xml = simplexml_load_file($xmlfile)){
  16. echo "<br>Załadowano poprawnie plik XML<br>";
  17. } else {
  18. echo "<br><span style='color:red'>Nie załadowano pliku XML, operacja została przerwana</span><br>";
  19. }
  20.  
  21. $total = mysql_result(mysql_query('SELECT COUNT(id_product) FROM ps_product'), 0);
  22.  
  23. $row2 = $productid = $instock = array();
  24.  
  25. foreach($xml->offers->offer as $entry)
  26. {
  27. $productid[] = $entry->id;
  28. if(!empty($entry->instock)){
  29. $instock[] = $entry->instock;
  30. } else {
  31. $instock[] = '0';
  32. }
  33.  
  34. }
  35.  
  36. $query= mysql_query("SELECT `id_product`, `reference` FROM `ps_product`");
  37. $row = mysql_fetch_assoc($query);
  38. while($row = mysql_fetch_assoc($query)){
  39. $row2[] = $row;
  40. }
  41.  
  42. $niezmienione = $nieaktywne = $zaktualizowane = 0;
  43. for($i = 0; $i <= $total; $i++){
  44. $reference = $row2[$i]['reference'];
  45. $productid2 = array_search($reference, $productid);
  46. if(isset($reference) == $productid2){
  47. $id_produktu = mysql_result(mysql_query("SELECT id_product FROM ps_product WHERE reference = '".$reference."'"), 0);
  48. if(!empty($instock[$productid2])){$stock2 = $instock[$productid2];} else { $stock2 = 0; }
  49. @mysql_query("UPDATE ps_stock_available SET `quantity` = '".$stock2."' WHERE `id_product` = '".$id_produktu."'");
  50. if( $stock2 > 0){ $active = 1; } else { $active = 0; }
  51. @mysql_query("UPDATE ps_product_shop SET `active` = '".$active."' WHERE `id_product` = '".$id_produktu."'");
  52. $zaktualizowane++;
  53. //echo $row2[$i]['reference']. ' znaleziony ze stanem magazynowym '. $stock2 .'<br>';
  54. } else {
  55. $instock2 = '0';
  56. if((int)$reference){
  57. @mysql_query("UPDATE ps_stock_available SET `quantity` = '".$instock2."' WHERE `id_product` = '".$id_produktu."'");
  58. @mysql_query("UPDATE ps_product_shop SET `active` = '".$instock2."' WHERE `id_product` = '".$id_produktu."'");
  59. $nieaktywne++;
  60. //echo $row2[$i]['reference']. ' <span style="color:red">nie znaleziony! Zmieniono stan magazynowy na '. $instock2 .'</span><br>';
  61. } else {
  62. $niezmienione++;
  63. //echo $row2[$i]['reference']. ' <span style="color:green">Stan nie zmieniony</span><br>';
  64. }
  65. }
  66. echo '<script language="javascript">
  67. document.getElementById("information").innerHTML="'.$i.' / '.$total.'<br>Produkty zaktualizowane: '.$zaktualizowane.'<br>Produkty niezmienione: '.$niezmienione.'<br>Nieaktywne produkty: '.$nieaktywne.'";
  68. </script>';
  69. echo str_repeat(' ',1024*64);
  70. flush();
  71. }
  72. echo '<script language="javascript">document.getElementById("information").innerHTML="Aktualizacja zakonczona<br>Produkty zaktualizowane: '.$zaktualizowane.'<br>Produkty niezmienione: '.$niezmienione.'<br>Nieaktywne produkty: '.$nieaktywne.'"</script>';
  73.  
  74. mysql_close($con2);
  75. unlink($xmlfile);
  76. ?>
  77. </body>


Fragment XML:
  1. <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE nokaut SYSTEM "http://www.nokaut.pl/integracja/nokaut.dtd">
  2. -<nokaut ver="7.2" generator="Comarch ERP e-Sklep">-<offers>-<offer><id>23270</id><name>PEDAŁY DO ROWERKA JD BUG TC04G czarne </name><description> PEDAŁY DO ROWERKA JD BUG TC04G czarne Zestaw do rowerków - mechanizm do rowerków biegowych. kompatybilny z modelami Nanny i Billy. </description><price>89.41</price><weight>1.000</weight><category>Dla dzieci / Sport dla dzieci / Rowery biegowe</category><producer>Smj</producer><property name="Dostępne kolory">Czarny</property><instock>3</instock></offer></offers></nokaut>


pokrótce:
skrypt pobiera xml przy pomocy simpleXML oraz laczy sie z baza danych gdzie wcześniej zostały zaimportowane produkty z numerem ID wpisanym do tabelki `reference` i jeśli produkt istnieje zarówno w DB jak i XML jego stan magazynowy zostaje uzupelniony odpowiednią liczbą, natomiast jeśli produkt znajduje się w bazie danych ale nie w XMLu to jego stan określa się jako 0. całość opiera się na metodzie array_search() czyli przeszukuje określonego wyrażenia w całej tablicy trzymającej numery ID produktów z XML'a. I pewnie dlatego nieraz otrzymuje komunikat CPU LIMIT jednak nie wymyśliłem jakiegoś innego sposobu aby to sprawdzać.

Za każdą sugestie podpowiedź, przykład, rzut okiem na kod będę bardzo wdzięczny (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
tom3k21
post
Post #2





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 6.05.2014

Ostrzeżenie: (0%)
-----


+plusik dla każdego za dobre chęci i rady (IMG:style_emoticons/default/smile.gif)

Udało mi się to dopracowac (tak przynajmniej mysle) nie jest idealnie poniewaz wykorzystałem petelke for aby robiła się ograniczona ilosc produktów a nastepnie GETem pobierało na czym się zakończył poprzedni proces ale działa. Ale przez to za każdym nowym wywołaniem skryptu musi on tworzyć od nowa całą tablice z pliku xml i kontynuować od wyznaczonego miejsca (wykorzystałem XMLreader ale czy poprawnie?).

Jeszcze mam takie pytanie:
Czy jakbym chciał ten skrypt wrzucic do CRONa aby robił się automatycznie to nie bedzie problemu z takim przekazywaniem zmiennych GETem?
  1. print '<meta http-equiv="Refresh" content="0; url='.$_SERVER['PHP_SELF'].'?x='.($x+1).'&file='.$plik.'&updated='.$zaktualizowane.'&inactive='.$nieaktywne.'&dontexist='.$niezmienione.'">';


jako że nigdy nie korzystałem z CRONa to niestety nie wiem i prosiłbym tylko o jeszcze taką drobną podpowiedz (IMG:style_emoticons/default/smile.gif)

Kodzik dla zainteresowanych:
  1. $plik = 'tmp_xml';
  2. if(isset($_GET['file'])){
  3. $xmlfile = 'import/'.$_GET['file'].'.xml';
  4. } else {
  5. $xmlfile = 'import/'.$plik.'.xml';
  6. $xmlurl = 'URL_DO_PLIKU';
  7.  
  8. $downxml = file_get_contents($xmlurl);
  9. file_put_contents($xmlfile, $downxml);
  10. }
  11.  
  12. $total = mysql_result(mysql_query('SELECT COUNT(id_product) FROM ps_product'), 0);
  13.  
  14. $xml = new XMLReader();
  15. if($xml->open($xmlfile)){
  16. echo "<br>Załadowano poprawnie plik XML<br>";
  17. } else {
  18. echo "<br><span style='color:red'>Nie załadowano pliku XML, operacja została przerwana</span><br>";
  19. }
  20. $productid = $instock = array();
  21. while ($xml->read() && $xml->name !== "offer");
  22. do {
  23. $node = new SimpleXMLElement($xml->readOuterXML());
  24. $productid[] = $node->id;
  25. if($node->instock){
  26. $instock[] = $node->instock;
  27. } else {
  28. $instock[] = '0';
  29. }
  30. } while ($xml->next('offer'));
  31.  
  32. $query= mysql_query("SELECT `id_product`, `reference` FROM `ps_product`");
  33. while($row = mysql_fetch_assoc($query)){
  34. $row2[] = $row;
  35. }
  36.  
  37.  
  38. if(isset($_GET['x']) && isset($_GET['updated']) && isset($_GET['inactive']) && isset($_GET['dontexist'])){
  39. $x = $_GET['x'];
  40. $zaktualizowane = $_GET['updated'];
  41. $nieaktywne = $_GET['inactive'];
  42. $niezmienione = $_GET['dontexist'];
  43. } else {
  44. $x = $niezmienione = $nieaktywne = $zaktualizowane = 0;
  45. }
  46. $limit = $x+1000;
  47. for($i = $x; $i <= $limit; $i++){
  48. $reference = $row2[$i]['reference'];
  49. $productid2 = array_search($reference, $productid);
  50. $id_produktu = mysql_result(mysql_query("SELECT id_product FROM ps_product WHERE reference = '".$reference."'"), 0);
  51. if(false !== $productid2){
  52. if(!empty($instock[$productid2])){$stock2 = $instock[$productid2];} else { $stock2 = 0; }
  53. @mysql_query("UPDATE ps_stock_available SET `quantity` = '".$stock2."' WHERE `id_product` = '".$id_produktu."'");
  54. if( $stock2 > 0){ $active = 1; } else { $active = 0; }
  55. @mysql_query("UPDATE ps_product_shop SET `active` = '".$active."' WHERE `id_product` = '".$id_produktu."'");
  56. $zaktualizowane++;
  57. //echo $reference. ' znaleziony ze stanem magazynowym '. $stock2 .'<br>';
  58. } else {
  59. $instock2 = '0';
  60. if((int)$reference){
  61. @mysql_query("UPDATE ps_stock_available SET `quantity` = '".$instock2."' WHERE `id_product` = '".$id_produktu."'");
  62. @mysql_query("UPDATE ps_product_shop SET `active` = '".$instock2."' WHERE `id_product` = '".$id_produktu."'");
  63. $nieaktywne++;
  64. //echo $reference. ' <span style="color:red">nie znaleziony! Zmieniono stan magazynowy na '. $instock2 .'</span><br>';
  65. } else {
  66. $niezmienione++;
  67. //echo $reference. ' <span style="color:green">Stan nie zmieniony</span><br>';
  68. }
  69. }
  70.  
  71. echo '<script language="javascript">
  72. document.getElementById("information").innerHTML="'.$x.' / '.$total.'<br>Produkty zaktualizowane: '.$zaktualizowane.'<br>Produkty niezmienione: '.$niezmienione.'<br>Nieaktywne produkty: '.$nieaktywne.'";
  73. </script>';
  74. echo str_repeat(' ',1024*64);
  75. flush();
  76.  
  77. if($i==$total){
  78. echo '<script language="javascript">document.getElementById("information").innerHTML="Aktualizacja zakończona<br>Produkty zaktualizowane: '.$zaktualizowane.'<br>Produkty niezmienione: '.$niezmienione.'<br>Nieaktywne produkty: '.$nieaktywne.'"</script>';
  79. if(unlink($xmlfile)){
  80. echo "Usunięto plik XML";
  81. } else {
  82. echo "<span style='color:red'>Nie udało się usunąć pliku XML, usuń go samodzielnie: </span>". $xmlfile;
  83. }
  84. } elseif($i==$limit){
  85. print '<meta http-equiv="Refresh" content="0; url='.$_SERVER['PHP_SELF'].'?x='.($x+1).'&file='.$plik.'&updated='.$zaktualizowane.'&inactive='.$nieaktywne.'&dontexist='.$niezmienione.'">';
  86. //print '<a href="'.$_SERVER['PHP_SELF'].'?x='.($x+1).'&file='.$plik.'&updated='.$zaktualizowane.'&inactive='.$nieaktywne.'&dontexist='.$niezmienione.'">Kontynuuj import od: .'$x'.</a>';
  87. }
  88. $x++;
  89. }


----- EDIT

Ok trochę poszperałem i już wiem że głupie pytanie zadałem bo przecież oczywiste ze meta i headers jest dla przegladarki i CRON to pominie :/
Jednak jakby ktoś mógł mi pokazać jak zamienić ten meta tag i GET na CURL byłbym ogromnie wdzięczny, ponieważ gdzieś wynalazłem iż tym da rade wykonać to co stworzyłem jako zadanie crona

Pozdrawiam

Ten post edytował tom3k21 7.05.2014, 11:07:14
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 10.10.2025 - 17:57