3

Following is my code

$obj = new stdClass();
$obj->xAxis = new stdClass();
$obj->xAxis->allowDecimals = false;
$obj->xAxis->labels = new stdClass();
$obj->xAxis->labels->formatter = function() { return this.value; };

return $obj;

I want to response as json in ajax as following

xAxis: {
    allowDecimals: false,
    labels: {
        formatter: function () {
            return this.value;
        }
    }
}
A J
  • 3,970
  • 14
  • 38
  • 53
Rahul Tank
  • 130
  • 1
  • 8

5 Answers5

1

Of course, you can't transform a PHP function into a Javascript function using json_encode, since PHP will have no clue to transform PHP function's body into its Javascript counterpart, so JSON (when used to transfer data between 2 programming languages) is meant to transfer data, like object attributes with some scalar values or arrays with scalar values and so, but not code logic (functions).

Ermac
  • 1,181
  • 1
  • 8
  • 12
1

No. There is no way to pass that function in Javascript because not only PHP runs on server side and Javascript will run on client side, but also that function will be parsed into function object by the time you get that object $obj.

The output of var_dump($obj) is

object(stdClass)#1 (1) { ["xAxis"]=> object(stdClass)#2 (2) { ["allowDecimals"]=> bool(false) ["labels"]=> object(stdClass)#3 (1) { ["formatter"]=> object(Closure)#4 (0) { } } } }

You can see that the function is parsed into an object and the end output that you might will get won't have that function at all. You will get rest of the params and values, though.

{"xAxis":{"allowDecimals":false,"labels":{"formatter":{}}}}

Using JSON, you can pass key and values between 2 programming languages, but not functions. So, there is only one option is to create a related function in Javascript and use it for what you want to accomplish.

If you want to use a function at client side, see if this answer can help.

A J
  • 3,970
  • 14
  • 38
  • 53
  • No, that function is not being executed. `object(Closure)` is the function object itself, not its return value. – deceze Apr 11 '18 at 10:04
  • Oh. Didn't properly see the `var_dump` output. But in the end, the function won't work at all. – A J Apr 11 '18 at 10:06
  • Thank you very much, I got idea from your reference. I have written json parser script. JSON.parse(val, function(k, v) { if(typeof v === "string" && v.indexOf("function(") != -1) return eval('(' + v + ')'); else return v; }) – Rahul Tank Apr 11 '18 at 11:09
1

It is possible, but if you will do it, it will mean that you are really weird person. According to this answer - reconstruct/get code of php function

you may get php function code as string something like this:

$a = function () {
    echo "hello";
};
$func = new ReflectionFunction($a);
$filename = $func->getFileName();
$start_line = $func->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block
$end_line = $func->getEndLine();
$length = $end_line - $start_line;

$source = file($filename);
$body = implode("", array_slice($source, $start_line, $length));
print_r($body);

After you will got function code as string, you will be able to send it to javascript as string, write your own php parser (with blackjack and whores), parse your function and according to your results transform function into js function, and then using eval construction do your weird stub.

But if you will look on your problem on other angle, you will see, that no need to this it. Most easiest way is use decorator or facade on javascript side:

    function MyCoolObjectDecorator(data) {
        this.data = data;
    }
    MyCoolObjectDecorator.prototype.formatter = function () {
        return this.data;
    }

[send ajax request].then(function(response) {
    return new MyCoolObjectDecorator(response).
}).then(function(response){
    console.log(response.formatter());
})

Using this approach you will use your backend as data layer, and your frontend as UI layer, instead of making data-representation mess.

degr
  • 1,559
  • 1
  • 19
  • 37
  • And also, if you will look into your example, you are using js syntaxis inside of php. So, it's difficult to understand - did you forgot to write quotes, or you write invalid syntax. In case if you write js inside of php code you may reuse this code on js side with `eval` construction. – degr Apr 11 '18 at 10:28
  • 1
    Bite my shiny metal arse, that's a well placed quote. – deceze Apr 11 '18 at 10:35
0

JSON can only express data, not code. There's no way PHP's json_encode will ever return "formatter": function () { ... }, since it's not valid JSON.

More fundamentally, function() { return this.value; } is not valid PHP code.* If anything it would have to be function () { return $this->value; }.** And then json_encode would have to know to transform that into the Javascript equivalent. But wait, JSON isn't specific to Javascript, you could also be sending your JSON to a service written in any other programming language…

I hope it's obvious that there's no way for JSON to express code in a language-independent fashion.

* Well, it is syntactically valid, but it does not mean what you want it to mean.
** Which is invalid because $this is used outside a class context, but let's ignore that for the moment…

So, no, you cannot return a function definition in JSON. You can of course use echo 'function () { this.value; }'; to output Javascript code from PHP, but again, you want to keep things language and implementation independent and only return data from your PHP and leave the code up to the specific Javascript implementation.

deceze
  • 510,633
  • 85
  • 743
  • 889
-1

You must prepare $my_array with this data structure and then echo

json_encode($my_array);

In JS you can get this data with AJAX in this way:

$.get('script.php', /* optional get variables*/ function(output) {
  var data = $.parseJSON(output);
});
4b0
  • 21,981
  • 30
  • 95
  • 142