I have a a function that returns an array that is structured like this
[[{"title":"Mr","first_name":"James","last_name":"Loo","date_of_birth":36356,"email":"test#test.com","phone_number":1234567890,"company":"CompanyOne"},{"title":"Mr","first_name":"Jonah","last_name":"Lee","date_of_birth":42629,"email":"test#test2.com","phone_number":1234567890,"company":"CompanyTwo"}],
[]]
Within the array are 2 arrays. The first one is a "entry not inserted" array and the second one is a "entry inserted" array.
However when I execute the code through this function
$result = $this->curl->execute();
$result_errors = array();
for($j=0;$j<sizeof($result);$j++){
$result_errors = $result[0];
}
if(sizeof($result_errors)>0){
echo json_encode($result_errors);
}
The result I get in the console is "[" only.
Am I missing something? I have read that I had to echo and json encode arrays but it doesn't seem to be coming out.
if $result is literally as you've printed above, then it's not a PHP array, just a string in JSON format. PHP can't interpret it until you decode it. Your for loop is a waste of time because you always assign the first index of $result to your $result_errors variable. In PHP if you try to fetch an index of a string, you simply get the character which is at that place in the string. The first character of $result is "[".
If you're trying to get the first array out of that response, you need to decode the JSON into a PHP array, select the first inner array, and then re-encode that back to JSON for output, like this:
$array = json_decode($result);
echo json_encode($array[0]);
That will give you the first array, containing the two objects. If that's not the output you're after, then please clarify.
I am not sure you will get what you want but the problem is the assignment to $result_errors. That var should be an array but when you make the assignment $result_errors = $result[0]; your change it from an array to whatever value is at $result[0]; Try this
for($j=0;$j<sizeof($result);$j++){
$result_errors[] = $result[0];
}
My question to you is: Since $result is apparently an array (as indicated by the use of $result[0]) then why not simply do this?
echo json_encode($result);
A suggestion: Instead of sizeof use count.
if(count($result_errors) > 0)
{
echo json_encode($result_errors);
}
count is less likely to be misunderstood by others. It has a totally different meaning in other programming languages.
Oh, and the answer from #ADyson is right to point out the need to decode the json string into a PHP array.
Related
I have a PHP script that runs an SQL query. I'd like to put the results in an array, encode it as a JSON object, echo it back to the Javascript that called it, and use it as an array to write some HTML.
This is the JS which calls the PHP script using POST. I attempt to parse the echoed data using JSON.parse(data) (I also tried jQuery.parseJSON(data) - not sure if there's a difference), and I display the raw echoed data on the HTML page for testing.
var components = []; // create empty array for component list
if ($('#area').val) { // if area contains a value and isn't zero (i.e. an area has been selected)
$.post("/basic/get_area_components.php"
,{area: $("#area").val()}
,function(data){ components = JSON.parse(data);
$("#components_raw").html(data);
$("#components").html(components);
});
}
The PHP script (after the database connection has been set up) looks like this:
$result = $conn->query("SELECT Component FROM ConfigComponent WHERE Parent =" . $area);
while($row = $result->fetch_array()) {
$rows[] = $row;
}
$i = 1;
foreach ($rows as $value) {
$components[$i] = $value[0];
$i++;
}
echo json_encode($components);
When I run the script, I get the raw output on the HTML page as follows:
{"1":"Handlebar","2":"Stem","3":"Headset","4":"Fork"}
which appears to be a correctly formatted JSON object, but nothing from the parsed components array, and no exceptions. I have tried scanning the array using forEach and printing or alerting the elements individually, to no avail.
How can I parse the JSON object correctly and use it in the Javascript? Is it a problem with the JS parsing, or the PHP encoding?
This behavior is normal. Javascript only support indexed arrays. Because your index in php starts with 1 instead of 0 it becomes an associative array instead of indexed.
$i = 0; // start with 0
foreach ($rows as $value) {
$components[$i] = $value[0];
$i++;
}
or
foreach ($rows as $value) {
// or don't use an index when adding a value to the array
$components[] = $value[0];
}
This will result in a json array
["Handlebar","Stem","Headset","Fork"]
Interesting problem. In Js the line:
{"1":"Handlebar","2":"Stem","3":"Headset","4":"Fork"}
Is no longer an array. It's an object. It seems jQuery actually disregards objects passed into the .html() method. It will render strings or execute functions.
So, you are already doing it right it's just not displaying to the page properly. I suggest using console.log instead.
Try defining the type of data javascript should expect from the server. Try the following
$.post("/basic/get_area_components.php",
{area: $("#area").val()},
function(data){
var components = JSON.parse(data);
$("#components_raw").html(data);
$("#components").html(components);
},
"json"); //define expected type here
Try it out and let me know if it works for you. More information on how to use $.post() can be found here
I suppose you're using jquery there so this maybe of help:
How do I iterate over a JSON structure?
and yes for loop will also do:
var componentFormatted;
for (var k in obj){
componentFormatted += obj[k];
}
then just apply any of your formatted output here
$("#components").html
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');.
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>
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>
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.
My question is very specific, and I can't seem to find a close enough question anywhere else to allow me to understand this. Basically, I've found a solution to my problem, but I don't understand why it works. I've come to it via a lot of research and then a lot of trial and error.
Short explanation: getting a two column MySQL database into an array in PHP then into javascript is resulting in an array of arrays of arrays. I'm not understanding why it is 3 arrays deep and not 2.
Here is the long explanation with code examples:
I am getting all of my two column MySQL database via:
while ($row = $table->fetch_assoc()) { // get the SQL data
$columnA[] = $row['columnA']; // get columnA (array)
$columnB[] = $row['columnB']; // get columnB (array)
}
$combinedData[] = [$columnA, $columnB]; // combine them in an array to split up later
echo json_encode($combinedData); // send to javascript file via ajax
I then send this to my javascript file, which does a JSON.parse:
$.ajax({
url: 'loader.php', // the php code from above
type: "POST"
}).done(function(data) {
console.log("columnA: "+JSON.parse(data)[0][0][0].toString()); //why [0][0][0] ... why 3 arrays deep?
console.log("columnB: "+JSON.parse(data)[0][1][0].toString());
}
);
This is the ONLY way I've found I can get each individual cell output into my javascript. Two things don't make sense to me though:
MY QUESTION: $combinedData is an array of arrays, so why, when I get data from php into javascript, do I have to go 3 arrays in... JSON.parse(data)[0][0][0] ?
I understand the last array is the array of individual cells ($columnA from the php), and the 2nd one is the array of columns ($combinedData from the php). Where is the first one coming from?
I also don't why I have to split $row and then recombine them. If I just echo $row I can't (figure out how to) parse the data correctly in js.
Since $combinedData is an array, and that you are appending [$columnA, $columnB] to it, this is what you currently get:
$combinedData = array(
0 => [$columnA, $columnB]
)
My understanding is you don't want to append [$columnA, $columnB] to $combinedData, you want combinedData to be [$columnA, $columnB]. This will give you what you want:
$combinedData = [$columnA, $columnB]; // combine them in an array to split up later
You have this:
$combinedData[] = [$columnA, $columnB];
1. ^------------------^ wrap two arrays in a new array
2. ^^----------------------- append array from #1 to a NEW array
You end up with arrays nested 3 deep. All you needed was
$combinedData = [$columnA, $columnB];
^--- no []
Why can't you just...
while ($row = $table->fetch_assoc()) { // get the SQL data
$combinedData[] = $row;
}
Think your would have what you expect
I've never seen this problem before, and I can't find the issue anywhere online. I'm using Angular to post form data to a PHP page. I'm using the file_get_contents() method of retrieving the POST data, which is a simple JSON object.
The problem arises with the data attributes - when I assign php vars to the data, they always have the value "{" or "[" (I echo'd and logged them). Any idea what could be causing this problem?
The relevant form declaration:
<form name="itemForm" ng-if="true" id="newItemForm" class="add-item" ng-submit="addItem(itemForm)">
<input type="text" class="form-control data-entry" ng-model="itemForm.itemType" placeholder="Type" ng-focus="true">
Here's my Angular function:
$scope.addItem = function(itemForm) {
$http.post("../ajax/addItem.php", itemForm).success(function(data) {
//console.data(JSON.stringify(itemForm));
console.log(data);
currItem = itemForm;
itemsArr.push(angular.copy(itemForm));
$scope.itemForm = defaultForm;
getItem();
});
};
partial PHP:
<?php
$params = file_get_contents('php://input');
if($params){
$item = $params["item"];
$type = $item["itemType"];
//get other parameters, insert into MySQL database
echo json_encode(["type = " => $type]);
}
?>
You're using string-based keys for your array. In Javascript terms, that has to be represented as an Object, which uses {} as the delimiters. Proper arrays, which use [], only accept numerical keys.
And note that type = as an array key is somewhat redundant. Why not just type?
The file_get_contents function returns a string, so the $params variable is a string not an array. However, strings in php can be accessed in an array like fashion (except the key must be a number). In your code $item = $params["item"] should will give you a php warning and php will automatically assume an index of 0 since the key you gave was not a number. This is why you were getting { or [ when you echoed the data from php (because valid json is enclosed by {} or []).
To use $params as an array like you are trying to do you first need to do $params = json_decode($params). This will only work assuming you have a valid json string in the file you are reading from.
<?php
// Open the file
$filename = 'pvemail.txt';
$fp = fopen($filename, 'r');
// Add each line to an array
if ($fp) {
$array = explode("\n", fread($fp, filesize($filename)));
}
//print_r ($array);
for ($c = 0; $c < count($array); $c++){
$cell = explode(",", $array[$c]);
//print_r ($cell);
if ($cell[3] == 'ACTIVE')
{
echo $cell[2].' - '.$cell[12].' '.$cell[11];
echo '<br/>';
}
}
?>
This code takes a CSV file, reads it and the first if statement explodes each line of the file into its own array. The for loop the explodes each of these lines into arrays made up of 20 key=>value pairs. The second if statement then loops through these pairs to extract and print to the screen the three pairs that I want.
The problem I'm having is I now want the data to be sorted alphabetically, and so far no matter what sort() function I use, or where I put it, nothing happens.
I tried to use sort($cell) between the for loop and the second if loop and nothing happened, I tried using the same code inside, and after, the if loop and nothing happened, I've tried moving the $cell array to another array and sorting that, I've tried ksort($cell, asort($cell), I've even tried passing the array to JavaScript and sorting it that way and nothing is happening!
I'm starting to pull my hair out here, is there anything obvious that I'm missing or not doing that's stopping the sort working?
It's not meaningful to sort $cell because it represents one row, not the whole file.
But let's start by simplifying the code. This line will single-handedly load your data and convert it into a multidimensional array:
$data = array_map('str_getcsv', file('pvemail.txt'));
You can then use usort with a callback function to sort this array of lines based on any column you want ("alphabetically" is not very clear). This question shows how to do it (disclosure: I have an answer there too).
Assuming that you want to sort based on the first column, you might do
usort($data, function($a, $b) { return strcmp($a[0], $b[0]); });
That should be it, you can then use foreach to print out the results.