0

I need to generate the following script using PHP and json_encode().

var obj= {
    o1:123,
    o2: {
        o3: 456,
        o4: function() {return $( "#myID" ).val();}
    }
}

My attempt to do so is as follows.

<?php
$a=array(
    'o1'=>123,
    'o2'=>array(
        'o3'=>456,
        'o4'=>'function() {return $( "#myID" ).val();}'
    )
);
$json=json_encode($a);
?>
<script type="text/javascript"> 
    <?php echo("var obj={$json};");?>
    console.log(obj);
</script>

The resultant output is as follows. The quotes around the properties poses no issues, however, the quotes around the JavaScript renders it as a string and not JavaScript. I obviously can't not quote the JavaScript in the array as it will result in malformed JSON.

How can I include JavaScript in PHP's json_encode()?

var obj={
    "o1":123,
    "o2":{
        "o3":456,
        "o4":"function() {return $( \"#username\" ).val();}"
    }
};
2
  • 2
    You won't be able to generate a JavaScript object with json_encode because a JSON is not the same a JavaScript object. Commented Jun 13, 2014 at 20:17
  • @DaveChen. Is it possible to create the appropriate text for a JavaScript object using any built in PHP function which takes its input from an array or object? Commented Jun 13, 2014 at 20:19

3 Answers 3

2

How about removing the quotations that surround the function?

<?php

$obj = array(
    'o1' => 123,
    'o2' => array(
        'o3' => 456,
        'o4' => 'function() {return $( "#myID" ).val();}',
        'o5' => 'function(param) {return $( "#myID" ).val();}'
    )
);
$json = json_encode($obj);

while ($func = strpos($json, '":"function(')) {
    $json = substr($json, 0, $func + 2) . substr($json, $func + 3);
    while ($quote = strpos($json, '"', $func + 2)) {
        $func = $quote + 1;
        if (substr($json, $quote - 1, 1) == "\\") {
            $json = substr($json, 0, $quote - 1) . substr($json, $quote);
            continue;
        }
        $json = substr($json, 0, $quote) . substr($json, $quote + 1);
        break;
    }
}

echo $json;

This checks if the string starts with function(, and if it is, removes the double quotes.

The result is a JSON (but can still be used as a JavaScript object):

{"o1":123,"o2":{"o3":456,"o4":function() {return $( "#myID" ).val();},"o5":function(param) {return $( "#myID" ).val();}}}

Upon setting this object to a variable, you can see that the function registered fine.

With that, you can still use the same technique you used before:

<script type="text/javascript"> 
    <?php echo("var obj={$json};");?>
    console.log(obj);
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Dave. Both your and my solution work perfectly, but I like yours as it doesn't require multiple methods like mine does.
2

JSON does not support functions. It's a data interchange format. Perhaps you should send some configuration data down and have a function change its behavior on that. Or since you aren't doing it as an AJAX call at this point, just echo it out:

<script type="text/javascript"> 
<?php echo("var obj={$json};");?>
<?php echo("obj.myFunc  = function..."); ?>
console.log(obj);
</script>

1 Comment

Thanks Daniel. My actual array which gets converted to JSON is much more complicated, and takes a bit of manipulation to create it. I am not trying to create JSON, but trying to create an object (will actually be used with the following: jqueryvalidation.org/remote-method). I've created the array, just can't echo it. Maybe some elaborate parsing to remove only the quotes for JavaScript in the PHP rendered JSON, but that sounds complicated.
1

This is what I ended up doing. Kind of hackish, and I expect Dave's is a better solution, but haven't yet tested it. I will do so.

<?php

class fubar {
    public function json_encode_JS($array)
    {
        $array=$this->_json_encode_JS($array);
        $json=json_encode($array);
        $json=str_replace(array('"%','%"'), '', $json);
        $json=str_replace('\"', '"', $json);
        return $json;
    }
    private function _json_encode_JS($array)
    {
        foreach($array as $key => $value){
            if(is_array($value)){$array[$key]=$this->_json_encode_JS($value);}
            else {
                if(strpos($value, 'function(')===0){
                    $array[$key]='%'.$value.'%';
                }
            }
        }
        return $array;
    }
}

$array=array(
    'o1'=>123,
    'o2'=>'function() {return $("#myID").val();}',
    'o3'=>array(
        'o4'=>456,
        'o5'=>'function() {alert("Hello why don\'t you answer "+$("#myID").val());}'
    )
);

?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js" type="text/javascript"></script>
<script type="text/javascript"> 
    <?php
    $obj=new fubar();
    echo('var obj='.$obj->json_encode_JS($array).';');
    ?>
    console.log(obj);
    obj.o3.o5();
</script>
<input id="myID" name="myID" type="text" value="hello">

2 Comments

I like this method! I have adapted my code to allow for parameters within the function. (Searching for function( instead of function()) I can see my method isn't far from yours actually. Mine removes the first double quotation at ":"function(, and removes all the escape characters, then removes the last double quotation that isn't escaped. Whereas, you add a delimiter % to any string that starts with function(, json_encode, then remove the quotation & delimiter, and then removing all the escape characters. The only issue would be that if you had a string with a quotation...
it wouldn't work. For example, array('a' => 'hello " world'). Other than that, it's pretty much the same thing.

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.