0

I have a PHP script that creates an object in PHP which is then used by jQuery after being ran through json_encode(). I've been trying to include a jQuery incline function in the PHP object that will work for my jQuery script after ran through json_encode, but I can't get it right.

For example, the PHP:

function get_columns_object() {

    foreach( ... ) {
        $columns[ $table ][] = array(
            'data'           => $name === 'cb' ? null : $name,
            'title'          => $header[ 'title' ],
            'callback'       =>       <<== HOW TO SPECIFY INLINE FN HERE?
        );
    }
}

Then, in the PHP script that outputs page HTML I include:

<script async>
    var columns = <?php echo json_encode( get_columns_object() ); ?>;
</script>

This works fine for the variables, but how can I include a jQuery callback function and an inline jQuery function using this approach? Or can I? :S

rwkiii
  • 5,716
  • 18
  • 65
  • 114
  • See: http://stackoverflow.com/questions/1745248/php-json-encode-and-javascript-functions "Not possible with JSON" and then they link to http://web.archive.org/web/20080828165256/http://solutoire.com/2008/06/12/sending-javascript-functions-over-json/ – Twisty Apr 19 '17 at 19:33
  • `json_encode()` cannot understand the `function`, so it suggests to store the function code and rewrite it when you create the javascript. – Twisty Apr 19 '17 at 19:35
  • @twisty So the whole fix is to exclude the inline function 'string' from getting encoded? Maybe I'm over-simplifying. That second article is excellent. Thanks for that. – rwkiii Apr 19 '17 at 19:40
  • I think that it does not understand what object type it is, just did some quick research. I agree, the second article is much more clear and helpful, just older. Should be able to use `JSON.parse()` now with jQuery 3.0+ – Twisty Apr 19 '17 at 19:48
  • 1
    Function is not included as a type for json, take a look at http://json.org. One workaround could be to declare the function before and reference it using the name as string, take a look at: http://stackoverflow.com/questions/912596/how-to-turn-a-string-into-a-javascript-function-call – Ricardo Enrique Ibarra Cabrera Apr 19 '17 at 19:49

1 Answers1

1

Expanding on my comment, and also looking at modern techniques, you could do something like this:

PHP

function get_columns_object() {
  foreach( ... ) {
    $columns[ $table ][] = array(
      'data'     => $name === 'cb' ? null : $name,
      'title'    => $header[ 'title' ],
      'callback' => "function() { alert('Callback Event'); }"
     );
  }
}

JavaScript

var columns = JSON.parse(<?php echo json_encode( get_columns_object() ); ?>);

Upon further research , I found: jQuery execute string as function

This could also work.

<?php
$columns = array(
    "table1" => array(
        "data" => "MyName",
        "title" => "Name",
        "callback" => "function(){ alert('Callback Event'); }"
    )
);

$json_data = json_encode($columns);
?>
<html>
    <head>
        <title>Test Passing Function</title>
        <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script>
            var columns = <?php echo $json_data; ?>;
            columns.table1.callback = eval(columns.table1.callback);
            console.log(columns);
            $(function(){
                var link = $("<a>", {
                    href: "#"
                }).html("Click Me");
                link.click(columns.callback);
                link.appendTo($("#sandbox"));
            });
        </script>
    </head>
    <body>
        <p>Test Passing:</p>
        <pre><?php echo $json_data; ?></pre>
        <div id="sandbox">
        </div>
    </body>
</html>

Was testing in phpfiddle.org, but they see eval() and kill it.

Update

Was able to test here: https://jsfiddle.net/Twisty/z0xpqorz/2/

var columns = <?php echo json_encode( get_columns_object() ); ?>;
$(function() {
  var link = $("<a>", {
    href: "#"
  }).html("Click Me");
  link.click(eval('(' + columns.table1.callback + ')'));
  link.appendTo($("#sandbox"));
});

See more: Passing a JavaScript function from JSON encoded PHP

Also read through the post that Ricardo Enrique Ibarra Cabrera mentioned. Good suggestions. Those posts suggest avoiding eval() at all cost for good reason.

Community
  • 1
  • 1
Twisty
  • 30,304
  • 2
  • 26
  • 45
  • I won't be able to use eval() in this app due to the obvious security risks. You jsfiddle works great, I can't see how my use of `new function() isn't working. Does that approach work with a simple callback? So instead of specifying an inline function only the function name were specified? Obviously, the jQuery issue is technically that the inline function is getting wrapped in quotes, otherwise the json string would be correct. – rwkiii Apr 24 '17 at 21:45
  • @rwkiii more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function – Twisty Apr 24 '17 at 22:19
  • Much like `new Date()` constructs a new Date object, `new Function()` would construct a new function object. The `functionBody` is *A string containing the JavaScript statements comprising the function definition* So since you have the content of your function from JSON, you can pass it into the constructor. – Twisty Apr 24 '17 at 22:23
  • @rwkiii If you're planning to have varied functions passed back, this could help: https://jsfiddle.net/Twisty/z0xpqorz/6/ – Twisty Apr 24 '17 at 22:49