PHP尝试按关键字设置类别没有错误和空标签

问题描述

我尝试通过名称中的特定关键字制作带有产品类别的 XML 提要,并从 .csv 中获取这些数据一切正常.. 唯一的问题是将类别分配到 xml 提要中..

.csv 目录的链接https://ociostock.gesio.be/dyndata/exportaciones/csvzip/catalog_1_51_54_2_38849185cc8487a046bd2bf4a46de0ed_csv_plain.csv

赋值条件:

$catalog_name = 'catalog.csv';
$file_url = 'https://ociostock.gesio.be/dyndata/exportaciones/csvzip/catalog_1_51_54_2_38849185cc8487a046bd2bf4a46de0ed_csv_plain.csv';
file_put_contents($catalog_name,fopen($file_url,'r'));

$categories = [
    'facemask' => 'mascarillas','mascarilla' => 'mascarillas','mask' => 'mascarillas','juego' => 'juguetes','playdoh' => 'juguetes','puzzle' => 'juguetes','monopoly' => 'juguetes','notebook' => 'papeleria','pencil' => 'papeleria','pencil case' => 'papeleria','bag' => 'otros','schoolbag' => 'otros','rucksack' => 'otros','quokka' => 'otros','mug' => 'otros','bottle' => 'otros','towel' => 'otros','funko' => 'colleccionables',];

$dom = new DOMDocument();

$dom->encoding = 'utf-8';



$dom->xmlVersion = '1.0';



$dom->formatOutput = true;



$xml_file_name = 'products.xml';

$root = $dom->createElement('SHOP');


$flag = true;     

$h = fopen($catalog_name,'r');
while (($data = fgetcsv($h,30000,';')) !== FALSE)
{  
    if($flag) {
        $flag = false;
        continue;
    }
        
    $item_node = $dom->createElement('SHOPITEM');
    
    $name = $data[3];
    $description = $data[5];
    $price = $data[8] * 1.30 * 1.21;
    $rounded_price = round($price,2);
    $active = $data[13];
    $stock = $data[15];
    $ean = $data[19];
    $img_url = $data[22];
    $units_per_order = $data[24]; 
    
    $trimmed_ean = utf8_decode($ean);
   
    if ($units_per_order != "1") {
        $active = "0"; 
        $stock = "0";
    }
   
    if ($active != "1" || $units_per_order != "1") {
        continue; 
    }
    
    $category = $categories[$name] ?? '';
    var_dump($category);
   
    
    $item_node->appendChild($dom->createElement('PRODUCTNAME',htmlspecialchars($name)));
    $item_node->appendChild($dom->createElement('DESCRIPTION',htmlspecialchars($description)));
    $item_node->appendChild($dom->createElement('PRICE_VAT',strval($rounded_price)));
    $item_node->appendChild($dom->createElement('IMG_URL',strval($img_url)));
    $item_node->appendChild($dom->createElement('EAN',strval($trimmed_ean)));
    $item_node->appendChild($dom->createElement('STOCK',strval($stock)));
    $item_node->appendChild($dom->createElement('ACTIVE',strval($active)));
    $item_node->appendChild($dom->createElement('CATEGORYTEXT',htmlspecialchars($category)));        
    
    
    $root->appendChild($item_node);
    
} 
    
fclose($h); 
  

$dom->appendChild($root);



$dom->save($xml_file_name); 

在这里我附加了一个函数,该函数使 CATEGORYTEXT 带有来自上面条件块的类别名称..所以,如果某个关键字在 $name 变量中,那么它应该按条件设置 $category 变量..

但是正如您所见,我的 XML 提要 http://tiendadejuguetes.eu/wp-content/cron/products.xml 中的每个产品都有空的 CATEGORYTEXT 标签,例如第一个产品的名称中有关键字“bottle”,那么为什么 CATEGORYTEXT 标签是空的?

解决方法

你的条件不适用。见:

$name = 'facemask';
var_dump(
    strpos($name,'facemask' || 'mascarilla' || 'mask')
);

输出:

bool(false)

这是因为您的论证评估为真:

var_dump('facemask' || 'mascarilla' || 'mask'); 

输出:

bool(true)

我建议使用地图。但是每个类别都允许在 $name 中包含多个子字符串,这就有点复杂了,所以让我们定义一个封装逻辑的小类:

class CategoryMatcher {
    
    private $_map;
    
    public function __construct(array $map) {
        $this->_map = $map;
    }
    
    public function match(string $text): ?string {
        $text = strtolower($text);
        foreach ($this->_map as $category => $subStrings) {
            if ($this->containsOneOf($text,$subStrings)) {
                return $category;
            }
        }
        return NULL;
    }
    
    private function containsOneOf(string $text,array $subStrings): bool {
        foreach ($subStrings as $subString) {
            if (FALSE !== strpos($text,$subString)) {
                return TRUE;
            }
        }
        return FALSE;
    }
}

$matcher = new CategoryMatcher(
    [
        'doll' => ['figure'],'clothes' => ['t-shirt'],'stationary' => ['notebook','pencil case']
    ]
);
    

$examples = [
   'assorted A5 notebook','premium adult t-shirt','adult premium t-shirt','Daisy figure','Cars Pencil case','Cars Pole Gym bag 35cm'
];
foreach ($examples as $example) {
   echo $example,': ',$matcher->match($example),"\n";  
}

输出:

assorted A5 notebook: stationary
premium adult t-shirt: clothes
adult premium t-shirt: clothes
Daisy figure: doll
Cars Pencil case: stationary
Cars Pole Gym bag 35cm: 

此外,请注意 DOMdocument::createElement() 的第二个参数 - 如果您的变量包含不是有效实体的一部分的 &,它会中断。最好使用 DOMNode::$textContent

$document = new DOMDocument();
$document
  ->appendChild($document->createElement('CATEGORYTEXT'))
  ->textContent = 'mascarillas';
echo $document->saveXML();  

输出:

<?xml version="1.0"?>
<CATEGORYTEXT>mascarillas</CATEGORYTEXT>