我有一个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;
  }
}

功能运行正常.

推荐答案

您遇到的问题与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文件之前获取该文件的独占锁(Lock_Ex).如果成功获取锁,则进行更改,然后释放锁(LOCK_UN).如果无法获取锁,则该函数返回FALSE以指示发生了错误.

通过使用文件锁定,您可以确保一次只有一个用户可以修改XML文件,从而防止并发修改和潜在的数据丢失.

Php相关问答推荐

Laravel通过(扩展FormRequest类)方法验证表单请求

try 修改这个PHP代码如果语句在WordPress""

尽管包含目标日期,但日期范围比较仍有意外输出

LaravelEloquent 的地方条件父/子与第三模型多对多

为什么正则表达式与得到的文本块之前得到的也行?

根据产品类型显示或隐藏WooCommerce管理产品自定义字段

按与WooCommerce管理顺序列表中的特定字符串不匹配的特定元值筛选订单

如何将隐式乘法添加到PHPPEG基本计算器语法中?

只收取WooCommerce中最高的运费

如何使用MS Graph PHP SDK V2下载文件

除WooCommerce中的特定国家/地区外,有条件地要求填写邮政编码 checkout 字段

Wordpress,配置一周第一天选项

有没有办法像引用枚举一样引用注册表中的对象?

使用动态地址和动态文件创建zip文件并获取zip文件链接

尽管有use指令,PHP 类在其他文件中仍处于可见状态

将Shopware 6后端中定义的值导入MultiFilter

Laravel 8:会话不适用

使用来自 PHP 表单的数据更新 xml 命名空间

同时执行odbc_execute、odbc_fetch_row和odbc_result

如何通过路由传递变量