Question

I want to convert English digits (0,1,2,3,...) to Arabic digits (۰,۱,۲,۳,...) in content of some HTML document using a PHP function.
I wrote this function:

function en2ar($str) {
    $ends = array('0','1','2','3','4','5','6','7','8','9');
    $ards = array('۰','۱','۲','۳','۴','۵','۶','۷','۸','۹');
    return str_replace($ends,$ards,$str);
}

but it converts all digits in document, while I want to convert only digits in content of document.
for example, I want to convert:

<h1 style="color: #333;">1</h1>
<div style="width: 180px;">2</div>

to:

<h1 style="color: #333;">۱</h1>
<div style="width: 180px;">۲</div>

but it converts to:

<h۱ style="color: #۳۳۳;">۱</h۱>
<div style="width: ۱۸۰px;">۲</div>

and makes the document invalid.

Was it helpful?

Solution

You can try using an HTML parser like DOMDocument.

Here's an example:

$html = 
'<!DOCTYPE HTML>
<html>
<head></head>
<body>
    <h1 style="color: #333;">1</h1>
    <div style="width: 180px;">2</div>
</body>
</html>';

$doc = new DOMDocument();
$doc->loadHTML($html);
$doc->encoding = 'UTF-8'; //Appropriate encoding HERE
$root = $doc->documentElement;

var_dump($doc->saveHTML());
iterate($root);
var_dump($doc->saveHTML());

function iterate($node)
{
    if($node->nodeType === XML_TEXT_NODE) {
        $node->nodeValue = en2ar($node->nodeValue);
    }
    if ($node->hasChildNodes()) {
        $children = $node->childNodes;
        foreach($children as $child) {
            iterate($child); 
        }
    }
}

To save the output to a variable use:

$var = $doc->saveHTML();

Output:

string '<!DOCTYPE HTML>
<html><head></head><body>
    <h1 style="color: #333;">1</h1>
    <div style="width: 180px;">2</div>
</body></html>
' (length=135)
string '<!DOCTYPE HTML>
<html><head></head><body>
    <h1 style="color: #333;">۱</h1>
    <div style="width: 180px;">۲</div>
</body></html>
' (length=147)

OTHER TIPS

A rough outline of what my comment said:

$doc = new DOMDocument();
$doc->loadHTML('<h1 style="color: #333;">1</h1><div style="width: 180px;">2</div>');

$xpath = new DOMXPath($doc);
$textnodes = $xpath->query('//text()');

foreach ($textnodes as $textnode) {
    $textnode->nodeValue = en2ar($textnode->nodeValue);
}

echo $doc->saveHTML();

Caveat emptor: untested. The algorithm is simple: load up the dom, get the text nodes, for each change the value, save the modified dom.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top