27

I need to encode a javascript function into a JSON object in PHP.

This:

$function = "function(){}";
$message = "Hello";

$json = array(   
      'message' => $message,
      'func' => $function
);
echo json_encode($json);

outputs:

{"message":"Hello","func":"function(){}"}

What I want is:

{"message":"Hello","func":function(){}}

Can I do this with json_encode?

9 Answers 9

24

As Jani said, this is not possible directly with JSON, but this might help you: http://web.archive.org/web/20080828165256/http://solutoire.com/2008/06/12/sending-javascript-functions-over-json/

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

2 Comments

Yes, as long as you parse it with eval instead of using a strict JSON parser.
Eval=Evil just that you know
11

json_decode parse the given array to json string, so you can play with it as a string. Just use some unique string to indicate the start and the end of the function. Then use str_replace to remove the quotes.

$function = "#!!function(){}!!#"; 
$message = "Hello";

$json = array(   
  'message' => $message,
  'func' => $function
);
$string = json_encode($json);
$string = str_replace('"#!!','',$string);
$string = str_replace('!!#"','',$string);
echo $string;

The output will be:

{"message":"Hello","func":function(){}}

2 Comments

A small variant to be able to use characters: preg_match_all('/\#([^\#]*)\#/', json_encode($json), $unescape); foreach ($unescape['0'] as $key => $fn) { $string = str_replace($fn, json_decode($unescape['0'][$key]), $string); }
or use simpler preg_replace("/(\"#!!)|(!!#\")/", '', json_encode($json))
9

No. JSON spec does not support functions. You can write your own code to output it in a JSON-like format and it should work fine though.

Comments

8

If don't want to write your own JSON encoder you can resort to Zend_Json, the JSON encoder for the Zend Framework. It includes the capability to cope with JSON expressions.

2 Comments

Isn't there a way to make pin this answer at the top of the answers section?
The latest is now laminas-json: docs.laminas.dev/laminas-json
3

I wrote a small library that allows to do this. It's similar to Zend framworks's solution, but this library is much more lightweight as it uses the built-in json_encode function. It is also easier to use with external libraries, where json_encode is buried deeply in vendor code.

<?php
    use Balping\JsonRaw\Raw;
    use Balping\JsonRaw\Encoder;

    $array = [
        'type' => 'cat',
        'count' => 42,
        'callback' => new Raw('function(a){alert(a);}')
    ];
?>

<script>
    let bar = <?php echo Encoder::encode($array); ?>
    bar.callback('hello'); //prints hello
</script>

4 Comments

Looks like a good implementation but a major limitation is "require": {"php": ">=7.0"}, "require-dev": {"phpunit/phpunit": "^7.1"} unlike zend-json which has a dependency of "require": {"php": "^5.6 || ^7.0"}, "require-dev": {"phpunit/phpunit": "^5.7.23 || ^6.4.3", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-stdlib": "^2.7.7 || ^3.1"}. In short, your library doesn't work with php 5.6
@Fr0zenFyr PHP 5.6 was supported until Jan 2017, and received security updates until the end of 2018. The point is that you shoudn't use PHP 5.6 anyway, as it has reached its end of life.
Agreed 100%. But sometimes businesses decide to support legacy apps for many different reasons.
This is perfect - exactly what I was looking for! Thank you.
0

I write this simple function for all json function based help my myabe help someone:

function json_encode_ex($array) {
    $var = json_encode($array);
    preg_match_all('/\"function.*?\"/', $var, $matches);
    foreach ($matches[0] as $key => $value) {
        $newval = str_replace(array('\n', '\t','\/'), array(PHP_EOL,"\t",'/'), trim($value, '"'));
        $var = str_replace($value, $newval, $var);
    }
    return $var;
}

2 Comments

@luky I used this function in some project and work, why bro?
hi bro, because i wanted try it haha. but i ended with the answer of mirmidon. thank you
-1

You can try this:

var json_string = '{"message":"Hello","myfunc":"function(){ alert(this.message) }"}';
var json_string = JSON.parse(json_string, function(k,v){
    if(typeof v == 'string' && /function\(\)\{/.test(v)){
        return eval(k+' = '+v); 
    }else{
        return v
    }
});

Comments

-1

The enconding part in PHP is seems to be solved by now. You can use

json_encode($p, JSON_UNESCAPED_UNICODE)

this way your function will not be escaped. However

1 Comment

I don't think this does what you think it does. This is to not escape unicode characters which has nothing to do with functions.
-2

This function can also help:

function jsonify($var){
return str_ireplace(array("'function",'"function',"}'",'}"'),array("function",'function',"}",'}'),json_encode($var));
}

Taken from here: http://network.convergenceservices.in/forum/105-uknowva-development/4710-introducing-convhelperjsonify-in-uknowva-251.html#4710

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.