J'analyse un fichier XML et je voudrais INSERT les nœuds éléments XML si id n'existe pas, ou Mise à jour dossier si elle existe ...parse XML et insérer DB si EXISTE METTRE À JOUR sinon
Voici mon code à ce jour:
<?php
header('Content-type: text/html; charset=UTF-8') ;
//connection to DB here..
//.... .. .. .. ..
// Create connection
$conn = new mysqli($servername, $dbuser, $password, $dbname,3306);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Change character set to utf8
$conn->set_charset("utf8");
date_default_timezone_set('Europe/Athens');
$date_modified = strtotime("now");
$business_id = 54;
$xml_link = "https://www.mydomain.gr/test.xml";
$xml_link = $conn->real_escape_string($xml_link);
$xml_link = trim(stripslashes($xml_link));
ici, je mets à jour l'enregistrement "DATE_MODIFIED" ..
$update_business_xml = $conn->query('UPDATE business_xml SET date_modified="' . $date_modified . '" WHERE business_id=54');
Maintenant, dans cette section de code, je reçois tous les IDs des produits, et les mettre dans un tableau
$count_errors = 0;
//query to find products ids
$query_ids = $conn->query('SELECT pid FROM products WHERE business_id=54');
$rows_ids = mysqli_num_rows($query_ids);
$count_id = 0;
if($rows_ids > 0) {
while($exe_ids = mysqli_fetch_object($query_ids)) {
$arr_ids[$count_id] = $exe_ids->pid;
$count_id++;
}
}
$reader = new XMLReader();
$reader->open($xml_link);
while($reader->read()) {
if($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'product') {
$product = new SimpleXMLElement($reader->readOuterXml());
$pid = $product->id;
$name = $product->name;
$name = mb_strtolower($name,'UTF-8');
$mpn = $product->mpn;
$ean = $product->ean;
$sku = $product->sku;
$link = $product->link;
$price = $product->price;
$category_id = $product->category->attributes();
$category_path = $product->category;
$category_path = mb_strtolower($category_path,'UTF-8');
$image = $product->image;
$availability = $product->availability;
$size = $product->size;
$size = mb_strtolower($size,'UTF-8');
$color = $product->color;
$color = mb_strtolower($color,'UTF-8');
$weight = $product->weight;
$description = $product->description;
$manufacturer = $product->manufacturer;
$manufacturer = trim($manufacturer);
$instock = "Y";
$product_image = $image;
$check_product_url = $link;
$exist_pids = 0;
if(!empty($pid) || !empty($image) || !empty($price) || !empty($name) || !empty($link) || !empty($manufacturer)) {
if($category_id == 613 || $category_id == 604 || $category_id == 635) {
J'ai quelques catégories en XML que je ne veux pas dans mon DB, alors voici je Je reçois l'attribut de la catégorie, et vérifie si ce produit est l'un d'entre eux, il suffit de mettre à jour le statut de cet enregistrement sur ma base de données.
$update_business_xml = $conn->query('UPDATE products SET status=0 WHERE business_id="' . $business_id . '" AND pid= "' . $pid . '"');
$count_errors++;
}
else {
$status = 1;
$date = date('d-m-Y H:i:s'); //when insert a pr
$date_modified = strtotime("now"); //when modify a pr
$insert_business_xml = $conn->query('INSERT INTO products (business_id,pid,name,category,product_link,price,size,color,weight,description,manufacturer,mpn,ean,image,sku,instock,availability,status,date_added) VALUES("'.$business_id.'",
"' . mysqli_real_escape_string($conn,stripslashes($pid)) . '",
"' . mysqli_real_escape_string($conn,stripslashes($name)) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($category_path))) . '",
"' . $check_product_url . '",
"' . mysqli_real_escape_string($conn,stripslashes($price)) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($size)))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($color)))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($weight))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($description))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($manufacturer)))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($mpn))) . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($ean))) . '",
"' . $product_image . '",
"' . mysqli_real_escape_string($conn,stripslashes(trim($sku))) . '",
"' . mysqli_real_escape_string($conn,stripslashes($instock)) . '",
"' . mysqli_real_escape_string($conn,stripslashes($availability)) . '",
"' . $status . '", "' . $date . '") ON DUPLICATE KEY UPDATE
"business_id='.$business_id.'",
"pid=' . mysqli_real_escape_string($conn,stripslashes($pid)) . '",
"name=' . mysqli_real_escape_string($conn,stripslashes($name)) . '",
"category=' . mysqli_real_escape_string($conn,stripslashes(trim($category_path))) . '",
"product_link=' . $check_product_url . '",
"price=' . mysqli_real_escape_string($conn,stripslashes($price)) . '",
"size=' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($size)))) . '",
"color=' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($color)))) . '",
"weight=' . mysqli_real_escape_string($conn,stripslashes(trim($weight))) . '",
"description=' . mysqli_real_escape_string($conn,stripslashes(trim($description))) . '",
"manufacturer=' . mysqli_real_escape_string($conn,stripslashes(trim(strtolower($manufacturer)))) . '",
"mpn=' . mysqli_real_escape_string($conn,stripslashes(trim($mpn))) . '",
"ean=' . mysqli_real_escape_string($conn,stripslashes(trim($ean))) . '",
"image=' . $product_image . '",
"sku=' . mysqli_real_escape_string($conn,stripslashes(trim($sku))) . '",
"instock=' . mysqli_real_escape_string($conn,stripslashes($instock)) . '",
"availability=' . mysqli_real_escape_string($conn,stripslashes($availability)) . '",
"status=' . $status . '",
"date_modified=' . $date_modified . '"');
Dans le code ci-dessus, je suis en utilisant l'instruction INSERT INTO ... Duplicate KEY UPDATE afin de vérifier si l'identifiant existe, simplement mettre à jour toutes les valeurs de ce disque .. Si l'ID n'existe pas, INSERT celui-ci .. au beggining de mon code comme je l'ai dit, je suis tous les ids dans un tableau, donc ici, je suis en train d'effacer l'ID qui ont été trouvé ..
//erase from arr_ids
if(($key = array_search($pid, $arr_ids)) !== false) {
unset($arr_ids[$key]);
}
}
}
else {
$update_business_xml = $conn->query('UPDATE products SET status=0, date_modified="' . $date_modified . '" WHERE business_id="' . $business_id . '" AND pid= "' . $pid . '"');
$count_errors++;
}
} //reader nodeType
} //end while loop
$reader->close();
Last but not least, ici, je mets aussi à jour l'enregistrement avec tout le reste des identifiants qui ont été laissés à l'intérieur du tableau ... ce qui signifie que ces identifiants, n'existe pas ou ne sont plus listés dans le XML.
foreach($arr_ids as $id) {
$update_business_xml = $conn->query('UPDATE products SET status=0 WHERE business_id="' . $business_id . '" AND pid= "' . $id . '"');
}
Enfin, j'ai un message simple afin de voir combien d'erreurs il y a .. En disant des erreurs, je veux dire le nombre d'enregistrements du XML comporte des éléments vides (nom, prix, lien, l'image .. .. etc) et juste faire un écho ..
//var_dump($arr_ids);
$insert_messages = "Your XML file has been updated successfully! We found <strong>" . $count_errors . "</strong> errors. In case errors found, please check your dashboard!";
echo $insert_messages;
$conn->close();
?>
Tout ce code est dans un fichier php, qui fonctionne comme cronjob! Maintenant le problème et ma question est, que je n'ai pas vu le UPDATE fonctionnant correctement ou pas du tout, parce que le date_modified est toujours NULL dans ma base de données, qui est la valeur d'initialisation. Que suis-je manquant? (Et en général ce que je pouvais faire pour corriger le code tout, s'il y a plus d'une erreur ici?)
merci à l'avance
échantillon XML avec un produit (XML grec)
<mystore>
<created_at>2017-07-26 16:01:20</created_at>
<products>
<product>
<id>9307</id>
<name>
<![CDATA[ Minimum ανδρικό t-shirt φλάμα Percy ivory ]]>
</name>
<link>
<![CDATA[
https://www.mydomain.gr/andrika-rouxa/tshirts-andrikes-mployzes/minimum-andriko-t-shirt-percy-ivory.html
]]>
</link>
<image>
<![CDATA[
https://www.mydomain.gr/images/detailed/51/minimum-andriko-t-shirt-percy-122690105_(1).jpg
]]>
</image>
<sku>
<![CDATA[ 122690105-wh ]]>
</sku>
<mpn>
<![CDATA[ 122690105-wh ]]>
</mpn>
<category id="30">
<![CDATA[ ΑΝΔΡΙΚΑ > T- shirts ]]>
</category>
<price>27.30</price>
<description>
<![CDATA[
<ul><li>χρώμα ελεφαντόδοντου</li><li>στρογγυλή λαιμόκοψη</li><li>στρογγυλεμένο και μακρύτερο πίσω μέρος</li><li>regular fit</li><li>100% cotton</li></ul>
]]>
</description>
<instock>Y</instock>
<availability>Σε απόθεμα</availability>
<manufacturer>
<![CDATA[ Minimum ]]>
</manufacturer>
<size>L,XL</size>
<sex>
<![CDATA[ Άνδρας ]]>
</sex>
</product>
</products>
</mystore>
date_modified est varchar (128) dans mon DB - utf8_general_ci Je ne pense pas que ce soit un problème, non?
@Parfait J'ai éditer ma question .. merci de prendre le temps de répondre .. –
Quel 'UPDATE' ne fonctionne pas? La toute première boucle avant ou celle avec 'INSERT'? S'il vous plaît expliquer ce qui fonctionne. Les enregistrements sont-ils ajoutés et mis à jour sauf pour * date_modified *? Si ce champ est un 'varchar' comme vous le prétendez, la première mise à jour ne pourrait pas échouer même si vous passez un entier,' strtotime() 'car MySQL lancera en conséquence. – Parfait
Notez que votre 'INSERT' ne touche pas * date_modified *, seulement * date_added *. Donc, ces enregistrements seraient NULL pour * date_ modified *. Vérifiez soigneusement vos données et signalez un problème spécifique. – Parfait