Я написал скрипт для плагина WordPress. Этот плагин WordPress обрабатывает импорт из XML-файлов в продукты. Поскольку плагин обычно перезаписывает существующий продукт новыми значениями, я добавил некоторый пользовательский код, чтобы добавить информацию о новом продукте, вместо того, чтобы перезаписывать его.
Первая проблема заключалась в том, что я получил «Ram исчерпан», потому что я использовал некоторые другие методы плагина, которые вызывают запрос WordPress и так далее. Так что я исправил это, и теперь я использую SQL-запрос напрямую, вызывая функцию, а функция вызывает запрос и так далее …
Но теперь у меня есть другая проблема. Код работает. Все появляется и устанавливается там, где должно быть!
Но теперь сценарий замедляет весь процесс. Или мой Ram исчерпан, или моя база данных SQL … Так что я должен оптимизировать свой код.
Я уже сделал два взгляда, но в моих глазах все, что я звоню и сохраняю, необходимо … Кто-нибудь знает, как я могу оптимизировать свой плагин?
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);
}
}
}
}
Приветствую и спасибо!
Ужасно неэффективно:
$array = SELECT ...;
foreach ($array as $item)
{
do some SQL with $item
}
Вместо этого ищите способ сделать все, если это сразу. Примеры:
INSERT INTO ... SELECT ...,
DELETE FROM a JOIN b ON ... WHERE ...
Может быть улучшена:
DELETE a row
INSERT replacement for that row
Вместо:
INSERT ... ON DUPLICATE KEY UPDATE ...
и обязательно иметь подходящий
UNIQUE(pid, shop, price)
так что он знает, какой ряд вы «upserting».
Вы упомянули XML и не хватает оперативной памяти? Я не вижу никаких функций XML? XML может быть проблемой памяти.
Вы должны проверять ошибки после каждого query()
,
Я надеюсь, что вы не переподключаете несколько раз за прогон.
Других решений пока нет …