2

I am working with Blockly to make some Blocks. All the errors came up when I am making Blockly Blocks. IS there anyone who knows why my code is not working in Blockly?

I have a URL including a set of JSON code. I got the content in a myPhp.php file using:

$data = file_get_contents("URL");

and then, I decode the data using:

$objects = json_decode($data, true);

$objects contains:

[0] => Array
        (
            [name] => Light
            [x] => 5
            [h] => 5
            [y] => 5
            [status] => on
        )

Now I want to push this array of data into a JavaScript array using:

<script type="text/javascript">
    var obj = new Array();
    <?php 
     foreach($objects as $key => $value){ 
    ?>
    obj.push('<?php echo $value; ?>');
    <?php } ?>
</script>

And $value needs to have all those data.

But I am getting Invalid or unexpected token JavaScript error. and when I look at to the source code, it shows the error is related to this line: obj.push and it says obj.push('<br /> <b>Notice</b>: Array to string conversion in <b>myPhp.php</b> on line <b>20</b><br /> Array');.

maziarser
  • 125
  • 1
  • 7
  • When you say “No I want”, do you mean “Now I want”?  Click on [edit] to fix it. (Do not reply in a comment.) – G-Man Says 'Reinstate Monica' Sep 16 '17 at 17:54
  • This is off topic here. Elsewhere, it would be good to tell if it's a PHP error or JavaScript error, and if the latter: show the generated JavaScript. (My guess: your `$value` contains single quotes.) – Arjan Sep 16 '17 at 17:55
  • @Arjan this is the error: obj.push('
    Notice: Array to string conversion in myPhp.php on line 20
    Array');
    – maziarser Sep 16 '17 at 18:01
  • Hint: that's probably not what you expect to be in `$value`...? (If you do, it probably contains a newline.) – Arjan Sep 16 '17 at 18:07
  • Don't you think this is a security risk? – inf3rno Sep 16 '17 at 18:08
  • @inf3rno can you please explain?! – maziarser Sep 16 '17 at 18:20
  • If you don't use json_encode, everybody will be able to inject javascript code. – inf3rno Sep 16 '17 at 19:11
  • 1
    Like I already commented on Super User: the most important part of your question (the **full, exact** line with the error message, including the JavaScript and newlines) is still in a comment... :-( Also, how do you expect people to help you without knowing what is in `$objects` and what you expected to be in `$value`? See stackoverflow.com/help/mcve – Arjan Sep 17 '17 at 10:52
  • 1
    @Arjan it is edited accordingly. – maziarser Sep 17 '17 at 11:37
  • Are you sure you're not missing some newlines there...? – Arjan Sep 17 '17 at 12:09
  • [var_dump](https://php.net/manual/en/function.var-dump.php) is your friend. – faintsignal Sep 17 '17 at 12:13
  • @Arjan i am sure that there is no new lines left, but i do not know why my question rated -1??????? – maziarser Sep 17 '17 at 12:20
  • The downvote is not mine, though I also feel you're just not giving us the information we need. The information you've given now should not yield a JavaScript `Invalid or unexpected token` error. – Arjan Sep 17 '17 at 12:21
  • @MehravishTemkar encode the $objects and put in in obj is not working in my case as I have tried it before! – maziarser Sep 17 '17 at 12:23
  • @Arjan I am working with Blockly to make some Blocks for Students. All the errors came up whenI am making Blockly Blocks - while I am sure that my code is correct. – maziarser Sep 17 '17 at 12:26
  • @Arjan BUT I have thought that I might miss or make a mistake. That's why I asked here. – maziarser Sep 17 '17 at 12:27
  • Really, you're not giving enough details. Also, this runs just fine: https://jsfiddle.net/395h9bxf/ Success! – Arjan Sep 17 '17 at 12:30

3 Answers3

2

Your $value itself is an array and here your $key is 0.

$key

 [0] => 

$value

 Array
    (
        [name] => Light
        [x] => 5
        [h] => 5
        [y] => 5
        [status] => on
    )

So you need another loop for $value to obtain each value like thus

<script type="text/javascript">
 var obj = new Array();
<?php 
 foreach($objects as $key => $value){ 
   foreach($value as $key1 => $value1){
 ?>
 obj.push('<?php echo $value1; ?>');
 <?php } }?>
</script>
Arjan
  • 22,808
  • 11
  • 61
  • 71
Osama
  • 2,912
  • 1
  • 12
  • 15
  • 1
    This does not explain why one would get `Invalid or unexpected token` in JavaScript (the PHP notice message should be no problem for `obj.push`, unless it somehow creates invalid JavaScript, like due to single quotes or newlines in the PHP message), but the question is simply not specific enough to tell. Also, when going to push all properties it's probably easier to pass the full JSON string to the JavaScript directly, but then again, we don't even know what the OP wants to push into `obj`. – Arjan Sep 17 '17 at 12:06
  • Cannot echo an array so obj.push(echo array ) give invalid token – Osama Sep 17 '17 at 12:15
  • Nope. PHP already converts the array into a string, in this case: the error message. Next, JavaScript should have no problem with `obj.push('
    Notice: Array to string conversion in myPhp.php on line 20
    Array');` (unless there's a newline in that PHP message, which is not shown in the question). (But again, I'm quite sure that's a problem with the question; I am not criticizing the answer and that upvote is mine.)
    – Arjan Sep 17 '17 at 12:18
  • @Osama its is a great solution, but it is not working in this case – maziarser Sep 17 '17 at 12:29
  • Thank you Arjan I understand you now but does the browser expected this string as an array value ? Or it design to know that is an error message and consider it as invalid token?? – Osama Sep 17 '17 at 13:13
  • @Osama it is a good solution when it is not based on the Blockly blocks. The block that I have made and it needs to push the php array to the JavaScript array is still not pushing the data into the `obj` – maziarser Sep 17 '17 at 13:48
  • 1
    @Osama, see the example in my answer, assuming there's a newline somewhere in that generated message. – Arjan Sep 17 '17 at 17:48
2

Instead of going through the hassle of looping through the array or even decoding it (unless there is a specific reason to do so), just use json_encode. JSON is JavaScript's native language, so it will understand it.

<?php 
$data = json_decode(file_get_contents("URL"));
?><script type="text/javascript"><?php
    // echo out JSON encoded $data or a string of '[]' (empty JS array) if it is a false value (error occured with json_decode)
    ?>var obj = <?= json_encode($data) | '[]' ?>;<?php
    // In JavaScript "Light" is available as obj[0].name or it does not exist (empty array if an error occured with json_encode or json_decode)
?></script>
Jim
  • 3,210
  • 2
  • 17
  • 23
  • For the most part, `json_encode` automatically encodes special characters to output valid JSON (though in some cases you may need to decode them if they are already in some form of encoded type). In some cases you may need to change the encoding type - check out the parameter 'options' section in the link as the flags typically handle the majority of cases: http://php.net/manual/en/function.json-encode.php – Jim Sep 17 '17 at 14:03
  • Also, unless the input is a string, the output will not be a string. It will be an array if a non-associative array is passed or an object if an object or associative array is passed, int for int, float for float (keep in mind JS does not handle floats all that well), etc. – Jim Sep 17 '17 at 14:05
  • @Arjan - no, no quotes or it would output as a string (unless that is what you want it to do, then you would need to decode it on the JS/client side). – Jim Sep 17 '17 at 14:06
  • Now that I assume it works, why even first `json_decode`? :-) – Arjan Sep 17 '17 at 14:40
  • 1
    @Arjan - While technically not required to even use `json_decode` if the data is already in a valid JSON format when it is pulled from the file, I added it just as an added security layer. If the file contains invalid JSON, it will cause errors in the client. The added `json_decode` then `json_encode` ensures that if something is not right at least an empty array should be output instead of causing a syntax error in JS (which can halt processing in the browser and cause additional problems). – Jim Sep 17 '17 at 14:45
1

A few things to get you started:

  • JSON is "JavaScript Object Notation". Though it is used in many other languages, JavaScript understands it natively.

    This means that once you've got a JSON string, you can get a JavaScript object out of that directly. If the JSON string represents a single object, you'll get a single JavaScript object. If it represents an array, you'll get a JavaScript array of JavaScript objects. If it is some nested structure, then you'll get just that. In a modern browser all you need on the JavaScript side is JSON.parse(...) to do the magic.

  • To get the JSON into JavaScript, either:

    • Get it in JavaScript directly, using XMLHttpRequest or helpers such as jQuery's $.get. That will need you to understand some asynchronous programming, so maybe indeed one of the following is easier to start with:

    • Get it in PHP, parse it like you tried in your question, and then generate proper JavaScript to create a JavaScript object or array again. Note that PHP's json_decode gets you some associative array, which you then need to map to a JavaScript object.

    • Get it in PHP, do not parse it at all, and simply forward the JSON string to JavaScript and parse it there, using JSON.parse.

    • Get it in PHP, use Jim's simple solution to get it into JavaScript.

When generating JavaScript in PHP, you need to be careful with quotes, newlines and other special characters in string values. Like if the JSON is:

{"quote": "She said: 'Beware', and walked off"}

...then you cannot just concatenate text into obj.push('...') as that would create invalid JavaScript:

obj.push('She said: 'Beware', and walked off');

Above, JavaScript does not know what to do with the text after the second single quote, and throws Uncaught SyntaxError: missing ) after argument list. Likewise, newlines may be troublesome, like when unexpectedly getting a PHP error while generating the JavaScript (for reasons explained in Osama's answer), which will yield invalid JavaScript and throw Invalid or unexpected token:

obj.push('<br />
<b>Notice</b>: Array to string conversion
in <b>myPhp.php</b> on line <b>20</b><br /> Array');

In the JSON example above, you could use double quotes in obj.push("..."), to generate:

obj.push("She said: 'Beware', and walked off");

But in general you might not know what values you get, so you need to "escape" troublesome characters.

I don't know enough about PHP to know what's the best way to escape the strings. As (valid) JSON uses double quotes, it should already have escaped double quotes when needed. So, a JSON string might look like:

{"quote": "She said: \"Beware\", and walked off.\n\nWe'll remember her."}

Above, you need to take care of the backslashes that JSON already added for escaping. So PHP's addslashes might do, bus I did not test this:

<script type="text/javascript">
  var obj = JSON.parse("<?= addslashes($data) ?>");
</script>

Otherwise, when first parsing $data into a PHP object using json_decode (or when not even doing that!), Jim's simple solution is certainly preferred.

Arjan
  • 22,808
  • 11
  • 61
  • 71