【问题标题】:DOM XML string replace bugDOM XML 字符串替换错误
【发布时间】:2016-05-08 10:57:44
【问题描述】:

谁能解释 PHP 中这种奇怪的情况?这是一个例子。

我有字符串:“Olbrachtova 10”。我想在数字前添加逗号并在逗号前删除空格。所以结果会是。

“奥尔布拉赫托娃,10 岁”

这个字符串需要用 XML 编写,我使用的是 DOMDocument 库。

我正在使用此代码:

查找第一个数字位置的功能(效果很好):

private function findOffset($text){
        preg_match('/^\D*(?=\d)/', $text, $m);
        return isset($m[0]) ? strlen($m[0]) : false;
}

将字符插入字符串的功能(也很好用)

private function stringInsert($str,$insertstr,$pos)
{
    $str = substr($str, 0, $pos) . $insertstr . substr($str, $pos);
    return $str;
}

这是最终脚本

//string to change
$address = "Olbrachtova 10";

//position of first number
$numberPosition = $this->findOffset($address);

if ($numberPosition){

    //remove space before number if exists
    if($address[$numberPosition - 1] == ' '){

        //remove space - HERE IS PROBLEM
        $address[$numberPosition - 1] = '';

        //find new position of number
        $numberPosition = $this->findOffset($address);
    }

    //add comma before number
    $address = $this->stringInsert($address,", ",$numberPosition);

}else{
   //if string has no number return false - is invalid
   return false;
}

在此处理之后,我尝试将最终字符串“Olbrachtova, 10”附加到 XML。

var_dump($address);

//return

string(15) "Olbrachtova, 10" 

这是要附加的最后一行

$parcel->appendChild($xml->createElement("Indirizzo", $address));

这个输出是:

<Indirizzo>Olbrachtova</Indirizzo>

它总是在逗号之前中断,在我删除空格的地方

$address[$numberPosition - 1] = '';

为什么?

但是当我使用它来删除空间时

$address = substr_replace($address,'',$numberPosition - 1,1);

一切都很好。谁能解释一下为什么第一种方法不起作用?

编辑

这是完整的代码

    <?php


function findOffset($text){
        preg_match('/^\D*(?=\d)/', $text, $m);
        return isset($m[0]) ? strlen($m[0]) : false;
}

function stringInsert($str,$insertstr,$pos)
{
    $str = substr($str, 0, $pos) . $insertstr . substr($str, $pos);
    return $str;
}


$xml = $dom = new DOMDocument('1.0', 'UTF-8');
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;

//main element for soap request
$mainSection = $xml->createElement("Info");

$parcel = $xml->createElement("Parcel");



//string to change
$address = "Olbrachtova 10";

//position of first number
$numberPosition = findOffset($address);

if ($numberPosition){

    //remove space before number if exists
    if($address[$numberPosition - 1] == ' '){

        //remove space - HERE IS PROBLEM
        $address[$numberPosition - 1] = '';

        //find new position of number
        $numberPosition = findOffset($address);
    }

    //add comma before number
    $address = stringInsert($address,", ",$numberPosition);

}else{
   //if string has no number return false - is invalid
   return false;
}

$parcel->appendChild($xml->createElement("Indirizzo", $address));

var_dump($address);


//append Package
$mainSection->appendChild($parcel);

//append whole xml to main
$xml->appendChild($mainSection);

$output = $xml->saveXML();

print_r($output);

?>

你可以在这里测试它:http://phptester.net/

【问题讨论】:

  • 请添加您的 PHP 脚本的完整源代码。此外,您可能希望在 PHP 脚本执行期间使用 var_dump() 输出变量值,以查看这些值是如何更改的。
  • post 已编辑,您可以尝试一下。我认为这是 DOMDocument 库中的错误

标签: php xml string domdocument


【解决方案1】:

问题是您将空字符串"" 分配给字符串索引。这会导致在该位置写入 NULL 字节。来自关于strings的PHP手册:

警告 写入超出范围的偏移量会用空格填充字符串。非整数类型转换为整数。非法偏移类型发出 E_NOTICE。负偏移量在写入时发出 E_NOTICE,但读取的是空字符串。仅使用分配字符串的第一个字符。分配空字符串会分配 NULL 字节。

NULL 字节在 C/C++ 内部标记字符串的结尾。这就是为什么createElement 方法只在 XML 元素中写入值“Olbrachtova”,而不管字符串在 php 中的样子。

解决方法:任何情况下都不要写$string[$index] = "";

【讨论】:

    【解决方案2】:

    将示例分解为带有静态字符串的 DOM 函数。尝试重现。也许你在那之前有一个错误。此外,不要使用 DOMDocument::createElement() 的第二个参数 - 它不是 DOM 标准的一部分。这是一个可以破坏 XML 的bug。它不应由您提供的示例触发,但创建文本节点并附加它更安全。

    $document = new DOMDocument();
    $document
      ->appendChild($document->createElement("Indirizzo"))
      ->appendChild($document->createTextNode("Olbrachtova, 10"));
    
    echo $document->saveXml();
    

    输出:

    <?xml version="1.0"?>
    <Indirizzo>Olbrachtova, 10</Indirizzo>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 2021-09-08
      • 2014-09-07
      • 2019-03-02
      • 2014-04-13
      相关资源
      最近更新 更多