0

Can anybody explain this weird situation in PHP? Here is example.

I have string: "Olbrachtova 10". I want to add comma before number and remove space before comma. So result will be.

"Olbrachtova, 10"

This string needs to be written in XML and I am using DOMDocument library.

I am using this code:

Function to find position of first number (works well):

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

Funtion to insert character into string (works well too)

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

And here is final script

//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;
}

After this processing I am trying to append final string which is "Olbrachtova, 10" to XML.

var_dump($address);

//return

string(15) "Olbrachtova, 10" 

And here is final line to append

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

Output of this is:

<Indirizzo>Olbrachtova</Indirizzo>

It always break before comma, in the place where i removed space with

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

WHY?

But when i am using this to remove space

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

Everything works great. Can anybody explain why the first method didn't work?

EDIT

Here is full code

    <?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);

?>

And you can test it here: http://phptester.net/

2
  • Please add the full source code of your PHP script. Also you might want to use var_dump() to output the variable values during the execution of your PHP script to see how the values are changed. Commented May 8, 2016 at 14:31
  • post edited, you can try it.. I think that it is bug in DOMDocument library Commented May 8, 2016 at 14:44

2 Answers 2

2

The problem is that you assign the empty string "" to a string index. This results in the NULL byte being written at that location. From the PHP manual about strings:

Warning Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer. Illegal offset type emits E_NOTICE. Negative offset emits E_NOTICE in write but reads empty string. Only the first character of an assigned string is used. Assigning empty string assigns NULL byte.

And the NULL byte marks the end of a string in C/C++ internally. So thats why the createElement method only writes the value "Olbrachtova" in the XML element, regardless of what the string looks like in php.

Solution: Do not write $string[$index] = ""; under any circumstances

Sign up to request clarification or add additional context in comments.

Comments

0

Break the example down to the DOM functions with static strings. Try to reproduce. Maybe you have an error before that. Additionally do not use the second argument of DOMDocument::createElement() - it is not part of the DOM standard. Here is a bug that can break the XML. It should not be triggered by the example you provided, but it is safer to create the text node and append it.

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

echo $document->saveXml();

Output:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.