wordpress 如何在PHP中队列多个脚本调用?

t8e9dugd  于 2023-06-21  发布在  WordPress
关注(0)|答案(1)|浏览(121)

我有一个PHP脚本,它打开一个XML文档,获取DOM并修改它,然后它就可以正常工作了。我在自定义WordPress插件中使用它。据我所知,当多个用户或一个用户同时使用这个函数时,同时XML文件将没有元素,只有<?xml version="1.0" encoding="utf-8"?>
它与PHP函数的异步行为有关吗?我怎么解决这个问题?我应该排队的功能?怎么做?
代码为:

function ym_update_product_xml($p_id, $p_name, $p_status, $p_exerpt, $p_price, $p_inventory){

 if($p_id){
  $xml = new DOMDocument('1.0', 'utf-8');
  $xml->formatOutput = true; 
  $xml->preserveWhiteSpace = false;
  $xml->load(YDE_INC . 'all_products.xml');
  $ym_all_products = $xml->documentElement;
  $xpath = new DOMXPath($xml);

  $_product_name = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_name');
  $_product_status = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_status');
  $_product_exerpt = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_exerpt');
  $_product_price = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_price');
  $_product_invt = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_invt');

  if( $p_name != null ){$_product_name->item(0)->nodeValue = $p_name;}
  if( $p_status != null ){$_product_status->item(0)->nodeValue = $p_status;}
  if( $p_exerpt != null ){$_product_exerpt->item(0)->nodeValue = $p_exerpt;}
  if( $p_price != null ){$_product_price->item(0)->nodeValue = $p_price;}
  if( $p_inventory != null ){$_product_invt->item(0)->nodeValue = $p_inventory;}

  $xml->save(YDE_INC . 'all_products.xml');

    return true;
    }else{
   return false;
  }
}

功能正常工作。

eqqqjvef

eqqqjvef1#

您遇到的问题与PHP函数的异步行为无关,而是与多个用户或同时请求对XML文件的并发访问有关。当多个用户同时执行该函数时,可能会出现争用情况,其中一个用户的更改会覆盖另一个用户的更改,从而导致只有XML声明的空XML文件。
要解决这个问题,可以实现一种锁定机制,以确保一次只有一个用户可以修改XML文件。一种方法是在PHP中使用文件锁定。以下是包含锁定机制的代码的更新版本:

function ym_update_product_xml($p_id, $p_name, $p_status, $p_exerpt, $p_price, $p_inventory) {
    if ($p_id) {
        $xmlFile = YDE_INC . 'all_products.xml';
        $xml = new DOMDocument('1.0', 'utf-8');
        $xml->formatOutput = true;
        $xml->preserveWhiteSpace = false;

        // Acquire an exclusive lock on the XML file
        $fileHandle = fopen($xmlFile, 'r+');
        if (flock($fileHandle, LOCK_EX)) {
            $xml->load($xmlFile);
            $ym_all_products = $xml->documentElement;
            $xpath = new DOMXPath($xml);

            $_product_name = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_name');
            $_product_status = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_status');
            $_product_exerpt = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_exerpt');
            $_product_price = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_price');
            $_product_invt = $xpath->query('/ym_all_products/product[@id="' . $p_id . '"]/product_invt');

            if ($p_name != null) {
                $_product_name->item(0)->nodeValue = $p_name;
            }
            if ($p_status != null) {
                $_product_status->item(0)->nodeValue = $p_status;
            }
            if ($p_exerpt != null) {
                $_product_exerpt->item(0)->nodeValue = $p_exerpt;
            }
            if ($p_price != null) {
                $_product_price->item(0)->nodeValue = $p_price;
            }
            if ($p_inventory != null) {
                $_product_invt->item(0)->nodeValue = $p_inventory;
            }

            $xml->save($xmlFile);

            // Release the lock and close the file handle
            flock($fileHandle, LOCK_UN);
            fclose($fileHandle);

            return true;
        } else {
            // Failed to acquire the lock, handle the error
            fclose($fileHandle);
            return false;
        }
    } else {
        return false;
    }
}

在此更新的代码中,flock函数用于在加载和修改XML文件之前获取XML文件上的排他锁(LOCK_EX)。如果成功获取锁,则进行更改,然后释放锁(LOCK_UN)。如果无法获取锁,则函数返回false以指示发生了错误。
通过使用文件锁定,可以确保一次只有一个用户可以修改XML文件,从而防止并发修改和潜在的数据丢失。

相关问题