2017-03-19 4 views
-1

J'ai écrit un script pour un plugin wordpress. Ce plugin Wordpress gère l'importation de fichiers XML vers des produits. Parce que le plugin écrase normalement le produit existant avec les nouvelles valeurs, j'ai ajouté du code personnalisé pour ajouter les nouvelles informations sur le produit et les écraser.PHP Script: Comment optimiser

Le premier problème était que j'ai "épuisé Ram" parce que j'ai utilisé d'autres méthodes de plugin qui appelle une requête wordpress et ainsi de suite. J'ai donc corrigé cela et maintenant j'utilise directement l'instance de requête SQL d'appeler la fonction et la fonction appelle la requête et ainsi de suite ...

Mais maintenant j'ai un autre problème. Le code fonctionne. Tout apparaît et est placé là où il est censé être! Mais maintenant le script ralentit la progression entière .. Soit mon Ram est épuisé ou ma base de données SQL ... Donc je suis supposé optimiser mon code.

J'ai déjà pris deux looks mais à mes yeux tout ce que j'appelle et économise est nécessaire ... Est-ce que quelqu'un sait comment je peux optimiser mon plugin?

function wp_all_import_before_xml_import($import_id){ 

    if($import_id !== 72 || $import_id !== 88){ 

     unlink("wp_all_import.txt"); 

     //Datenbankverbindung aufbbauen 
     $database = new mysqli("localhost", "wordpress_dc", "censored", "wordpress_5"); 
     $database_gk = new mysqli("localhost", "wordpress_8", "censored", "wordpress_6"); 

     //Datenbankverbindung checken 
     if($database->connect_errno){ 
      $myfile = fopen("wp_all_import.txt", "a"); 
      fwrite($myfile, "+++Couldn't connect to database!+++\n\n"); 
      fclose($myfile); 
     } 

     if($database_gk->connect_errno){ 
      $myfile = fopen("wp_all_import.txt", "a"); 
      fwrite($myfile, "+++Couldn't connect to database!+++\n\n"); 
      fclose($myfile); 
     } 

     //WP_ALL_IMPORT Tabelleninhalt löschen 
     $sql = 'DELETE FROM `wp_all_import`'; 
     $database->query($sql); 

     //Holen alle Posts 
     $values_gkw = $database_gk->query("SELECT `ID` FROM `fWR6qIN_posts` where post_type = 'product' AND post_status = 'publish'"); 

     while($row = $values_gkw->fetch_assoc()){ 
      $id = $row["ID"]; 
      $pid = $id; 
      $title = get_the_title($pid); 

      $repeater = $database_gk->query("SELECT Count(meta_key) AS cnt FROM `fWR6qIN_postmeta` Where meta_key like 'product_shops_%_price' AND (post_id = $pid)"); 

      while($row = $repeater->fetch_assoc()){ 
       $count = $row["cnt"]; 
      } 

      for($i = 0; $i < $count; $i++){ 
       $price_meta = "product_shops_".$i."_price"; 
       $price_old_meta = "product_shops_".$i."_price_old"; 
       $link_meta = "product_shops_".$i."_link"; 
       $shop_meta = "product_shops_".$i."_shop"; 

       $price; 
       $price_old; 
       $link; 
       $shop; 

       $details = $database_gk->query("SELECT `meta_key`, `meta_value` FROM `fWR6qIN_postmeta` WHERE post_id = '$pid' AND (meta_key like '$price_meta' OR meta_key like '$price_old_meta' OR meta_key like '$link_meta' OR meta_key like '$shop_meta')"); 

       while($row_meta = $details->fetch_assoc()){ 
        if($row_meta["meta_key"] == $price_meta){ 
         $price = $row_meta["meta_value"]; 
        }elseif($row_meta["meta_key"] == $price_old_meta){ 
         $price_old = $row_meta["meta_value"]; 
        }elseif($row_meta["meta_key"] == $link_meta){ 
         $link = $row_meta["meta_value"]; 
        }elseif($row_meta["meta_key"] == $shop_meta){ 
         $shop = $row_meta["meta_value"]; 
        }else{ 
         $myfile = fopen("wp_all_import.txt", "a"); 
         fwrite($myfile, "Is not matching!\n"); 
         fclose($myfile); 
        } 
       } 

       //Checken ob Product Shop Row noch in Datenbank vorhanden 
       $values = $database->query("SELECT * FROM `wp_all_import_xml` WHERE name = '$title' AND price = '$price' AND shop = '$shop' AND url = '$link'"); 

       $count_values = mysqli_num_rows($values); 

       //Falls nein, lösche diese Product Shop Row aus Datenbank 
       //Falls ja, füge Product Shop Row der "echten" Datenbank hinzu 
       if($count_values == 0){ 
        $sql = "DELETE FROM `wp_all_import` WHERE pid = '$pid' AND shop = '$shop' AND price = '$price' AND link = '$link'"; 
        $database->query($sql); 

        /* 
        $myfile = fopen("wp_all_import.txt", "a"); 
        fwrite($myfile, "Would delete! " . $pid . " Preis: " . $price . " Link: " . $link . "\n"); 
        fclose($myfile); 
        */ 

       }elseif($count_values == 1){ 
        $sql = "INSERT INTO `wp_all_import` (pid, price, price_old, link, shop) VALUES ('$pid', '$price', '$price_old', '$link', '$shop')"; 

        if($database->query($sql) === TRUE){ 

        }else{ 
         $myfile = fopen("wp_all_import.txt", "a"); 
         fwrite($myfile, "Product ERROR!\n"); 
         fclose($myfile); 
        } 

        /* 
        $myfile = fopen("wp_all_import.txt", "a"); 
        fwrite($myfile, "Would insert! " . $pid . " Preis: " . $price . " Link: " . $link . "\n"); 
        fclose($myfile); 
        */ 

       }else{ 
        $myfile = fopen("wp_all_import.txt", "a"); 
        fwrite($myfile, "ERROR by detecting Product (More than 1 Row return by SQL!): " .$title. " Preis: " .$price. " Shop: " .$shop. " Link: " .$link. "\t num_rows: " .$count_values. "\n\n"); 
        fclose($myfile); 
       } 

       $price = null; 
       $price_old = null; 
       $link = null; 
       $shop = null; 
       $price_meta = null; 
       $price_old_meta = null; 
       $link_meta = null; 
       $shop_meta = null; 

      } 

      $title = null; 
      $count = null; 
     } 
    } 
} 

function my_saved_post($pid, $xml_node){ 
    $title = get_the_title($pid); 

    if($title != "End of Import" || $title !== "Start of Import" || $title !== "Start of Import1" || $title !== "Start of Import2" || $title !== "Start of Import3" || $title !== "Start of Import4" || $title !== "Start of Import5"){ 

     //Datenbankverbindung aufbbauen 
     $database = new mysqli("localhost", "wordpress_dc", "Q037u_PnMf", "wordpress_5"); 
     $title = get_the_title($pid); 

     //Datenbankverbindung checken 
     if($database->connect_errno){ 
      $myfile = fopen("wp_all_import.txt", "a"); 
      fwrite($myfile, "+++Couldn't connect to database!+++\n\n"); 
      fclose($myfile); 
     } 

     //Anzahl an an Product Shop Rows holen 
     $aktueller_counter = -1; 
     while(have_rows('product_shops', $pid)): the_row(); 
      $aktueller_counter = $aktueller_counter + 1; 
     endwhile; 

     if($aktueller_counter == -1){ 
      $aktueller_counter = 0; 
     } 

     $pic = get_field("product_gallery_external_0_url", $pid); 
     $alt = get_field("product_gallery_external_0_alt", $pid); 

     delete_row('product_gallery_external', 1, $pid); 

     if($pic != null && $alt != null){ 
      update_post_meta($pid, 'fifu_image_url', $pic); 
      update_post_meta($pid, 'fifu_image_alt', $alt); 
     } 

     //Preis, Alter Preis, Link und Shop holen 
     $price = get_field("product_shops_0_price", $pid); 
     $price_old = get_field("product_shops_0_price_old", $pid); 
     $link = get_field("product_shops_0_link", $pid); 
     $shop = get_field("product_shops_0_shop", $pid)->ID; 


     //Holen Preis, Alten Preis, Link und Shop aus "echter" Datenbenk, wo PID = PID Und Shop = Shop 
     $value = $database->query("SELECT `price`, `price_old`, `link`, `shop` FROM `wp_all_import` WHERE pid = '$pid' AND shop = '$shop' AND link = '$link'"); 
     $count_values = mysqli_num_rows($values); 

     //Itterieren über Rückgabewert(e) der Datenbank 
     while($row = $value->fetch_assoc()){ 
      //Wenn Shop = Shop und Preis oder Alter Preis haben sich geändert, dann lösche Eintrag aus der "echten" Datenbank, wo PID = PID, SHOP = SHOP und PREIS = PREIS (Könnten mehere Sein!) 
      //Anschließend füge neuen Wert in Dantenbank ein 
      if($row["shop"] == $shop && $row["link"] == $link && ($row["price"] != $price || $row["price_old"] != $price_old)){ 

       $rprice = $row["price"]; 
       $rprice_old = $row["price_old"]; 
       $rshop = $row["shop"]; 

       $sql = "DELETE FROM `wp_all_import` WHERE pid = '$pid' AND shop = '$rshop' AND price = '$rprice'"; 
       $database->query($sql); 

       $sql = "INSERT INTO `wp_all_import` (pid, price, price_old, link, shop) VALUES ('$pid', '$rprice', '$rprice_old', '$link', '$rshop')"; 
       $database->query($sql); 
      } 
     } 

     //Holen Preis, Alten Preis, Link und Shop aus "echter" Datenbenk, wo PID = PID 
     $values = $database->query("SELECT `price`, `price_old`, `link`, `shop` FROM `wp_all_import` WHERE pid = '$pid'"); 
     $count_values = mysqli_num_rows($values); 

     //Itterieren über Rückgabewert(e) der Datenbank 
     while($row = $values->fetch_assoc()) { 
      $row = array(
       'price' => $row["price"], 
       'price_old' => $row["price_old"], 
       'currency' => 'euro', 
       'portal' => '', 
       'link' => $row["link"], 
       'shop' => $row["shop"] 
      ); 

      //Wenn ungleich Preis = Preis, Alter Preis = Alter Preis, Link = Link und Shop = Shop, dann füge Row hinzu, da nicht gerade hinzugefügte Row aus Import und Import hat alle Product Shop Rows gelöscht 

      //Ansonsten füge Eintrag in Datenbank ein, da eben neu hinzugefügt durch Import 
      if(!($row["price"] == $price && $row["price_old"] == $price_old && $row["link"] == $link && $row["shop"] == $shop)){ 
       $j = add_row('product_shops', $row, $pid); 
      }else{ 
       $sql = "INSERT INTO `wp_all_import` (pid, price, price_old, link, shop) VALUES ('$pid', '$price', '$price_old', '$link', '$shop')"; 
       $database->query($sql); 
      } 
     } 
    } 
} 

Salutations et merci!

+0

L'exécution de requêtes MySQL à l'intérieur de boucles est généralement une mauvaise idée et pourrait être un coupable pour la lenteur. Jetez un coup d'œil aux transactions qui vous aideront aussi à l'intégrité des données, car si vous rencontrez une erreur à mi-chemin dans votre script, vous pouvez annuler les modifications apportées à la base de données et ne pas vous inquiéter de la rupture. Voir la documentation de MySQL ici: https://dev.mysql.com/doc/refman/5.7/en/commit.html edit: on dirait que vous faites quelque chose de similaire avec fopen et fwrite. Pour ajouter plusieurs lignes à un fichier, vous devez construire la piqûre dans votre boucle, puis écrire une fois dans le fichier. – Christopher

+0

Je viens d'écrire quelque chose dans un fichier si quelque chose ne va pas. Mais rien ne va mal réel. Donc ça ne devrait pas être l'erreur en ce moment ... –

Répondre

0

Terriblement inefficace:

$array = SELECT ...; 
foreach ($array as $item) 
{ 
    do some SQL with $item 
} 

, Au lieu de chercher un moyen de faire tout si à la fois. Exemples:

INSERT INTO ... SELECT ..., 

DELETE FROM a JOIN b ON ... WHERE ... 

Peut-on améliorer:

DELETE a row 
INSERT replacement for that row 

Au lieu de cela:

INSERT ... ON DUPLICATE KEY UPDATE ... 

et assurez-vous d'avoir un approprié

UNIQUE(pid, shop, price) 

pour qu'il sache quelle ligne vous sont "upserting".

Vous avez mentionné XML et à court de RAM? Je ne vois aucune fonction XML? XML peut être un cochon de la mémoire.

Vous devez vérifier les erreurs après chaque query().

J'espère que vous ne vous reconnectez pas plusieurs fois par série.