Home > Net >  turn HTML (heredoc) to valid json using PHP
turn HTML (heredoc) to valid json using PHP

Time:10-07

let's say I have the following heredoc

$content = <<< AF
<div >
    <form id="auth"  enctype="multipart/form-data" onsubmit="auth(this)">
        <div >
            <input type="email" name="email" id="email" dir="ltr">
            <label for="email" >
                <div ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="#040505" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2" /><polyline points="3 7 12 13 21 7" /></svg></div>
                <div >email</div>
            </label>
        </div>
        <div >
            <input type="password" name="pass" id="pass" dir="ltr">
            <label for="pass" >
                <div ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="#040505" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="11" width="14" height="10" rx="2" /><circle cx="12" cy="16" r="1" /><path d="M8 11v-4a4 4 0 0 1 8 0v4" /></svg></div>
                <div >pass</div>
            </label>
        </div>
        <button type="submit">login</button>
    </form>
</div>
AF;

how can I turn it into a valid json string? like {"content":"<div...."}

I have tried many things but it does not end up in a valid json! tried every flag out there but not working

even tried php's "loadHTML" to recreate the html but not working.

this is one of my many attempts

    $Obj = new stdClass();

$content = <<< AF
<div >
    <form id="auth"  enctype="multipart/form-data" onsubmit="auth(this)">
        <div >
            <input type="email" name="email" id="email" dir="ltr">
            <label for="email" >
                <div ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="#040505" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2" /><polyline points="3 7 12 13 21 7" /></svg></div>
                <div >email</div>
            </label>
        </div>
        <div >
            <input type="password" name="pass" id="pass" dir="ltr">
            <label for="pass" >
                <div ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="#040505" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="11" width="14" height="10" rx="2" /><circle cx="12" cy="16" r="1" /><path d="M8 11v-4a4 4 0 0 1 8 0v4" /></svg></div>
                <div >pass</div>
            </label>
        </div>
        <button type="submit">login</button>
    </form>
</div>
AF;
$content = stripslashes(html_entity_decode($content));
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding(htmlspecialchars($content), 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
$atag = $dom->getElementsByTagName('svg');
foreach ($atag as $i) {
    $old = $i->getAttribute('xmlns');
    $i->setAttribute('xmlns', urlencode($old));
}
$ptag = $dom->getElementsByTagName('p')->item(0);
$content = html_entity_decode(implode(
    "",
    array_map([$dom, 'saveHTML'], iterator_to_array($ptag->childNodes))
));
$Obj->content = $content;
echo json_encode($Obj, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_ERROR_UTF8 );

and this is the output:

{"content":"\u003Cdiv class=\u0022authform\u0022\u003E\r\n \u003Cform id=\u0022auth\u0022 class=\u0022flex rad\u0022 enctype=\u0022multipart\/form-data\u0022 onsubmit=\u0022auth(this)\u0022\u003E\r\n \u003Cdiv class=\u0022input\u0022\u003E\r\n \u003Cinput type=\u0022email\u0022 name=\u0022email\u0022 id=\u0022email\u0022 dir=\u0022ltr\u0022\u003E\r\n \u003Clabel for=\u0022email\u0022 class=\u0022flex\u0022\u003E\r\n \u003Cdiv class=\u0022icon\u0022\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 viewBox=\u00220 0 24 24\u0022 stroke-width=\u00221.5\u0022 stroke=\u0022#040505\u0022 fill=\u0022none\u0022 stroke-linecap=\u0022round\u0022 stroke-linejoin=\u0022round\u0022\u003E\u003Crect x=\u00223\u0022 y=\u00225\u0022 width=\u002218\u0022 height=\u002214\u0022 rx=\u00222\u0022 \/\u003E\u003Cpolyline points=\u00223 7 12 13 21 7\u0022 \/\u003E\u003C\/svg\u003E\u003C\/div\u003E\r\n \u003Cdiv class=\u0022title\u0022\u003Eemail\u003C\/div\u003E\r\n \u003C\/label\u003E\r\n \u003C\/div\u003E\r\n \u003Cdiv class=\u0022input\u0022\u003E\r\n \u003Cinput type=\u0022password\u0022 name=\u0022pass\u0022 id=\u0022pass\u0022 dir=\u0022ltr\u0022\u003E\r\n \u003Clabel for=\u0022pass\u0022 class=\u0022flex\u0022\u003E\r\n \u003Cdiv class=\u0022icon\u0022\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 viewBox=\u00220 0 24 24\u0022 stroke-width=\u00221.5\u0022 stroke=\u0022#040505\u0022 fill=\u0022none\u0022 stroke-linecap=\u0022round\u0022 stroke-linejoin=\u0022round\u0022\u003E\u003Crect x=\u00225\u0022 y=\u002211\u0022 width=\u002214\u0022 height=\u002210\u0022 rx=\u00222\u0022 \/\u003E\u003Ccircle cx=\u002212\u0022 cy=\u002216\u0022 r=\u00221\u0022 \/\u003E\u003Cpath d=\u0022M8 11v-4a4 4 0 0 1 8 0v4\u0022 \/\u003E\u003C\/svg\u003E\u003C\/div\u003E\r\n \u003Cdiv class=\u0022title\u0022\u003Epass\u003C\/div\u003E\r\n \u003C\/label\u003E\r\n \u003C\/div\u003E\r\n \u003Cbutton type=\u0022submit\u0022\u003Elogin\u003C\/button\u003E\r\n \u003C\/form\u003E\r\n \u003C\/div\u003E"}

but I get the following trying to parse it using js:

"Uncaught SyntaxError: Expected ',' or '}' after property value in JSON at position 24"

thanks in advance

CodePudding user response:

Just put the variable in an associative array and convert it to JSON.

$content = <<<AF 
...
AF;
echo json_encode(['content' => $content], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_ERROR_UTF8);

CodePudding user response:

You shouldn't need to do anything fancy. just add it as a property, then json_encode()

$Obj = new stdClass();
$Obj->content = $content;
$json_obj = json_encode( $Obj );
  • Related