Json Returning [object object] instead of array - php

I have json data being fed into a Sencha touch app. Here's the json:
http://pastie.org/2622260 - (modified for an example, of course)
When I return the "images" and console.log it, it returns the following:
images: "[object Object],[object Object],[object Object],[object Object],[object Object]"
Rather than the URLs.
My json encoder looks like this (I'm pulling the data out of a Wordpress site):
case 'posts':
foreach(get_posts('numberposts=50&category=') as $post) {
$count = 0;
$imgurl = array();
foreach( get_group('Photo', $post->ID) as $images){
$count++;
$imgurl[] = array(
'count'=>$count,
'imageurl'=>get('photo_image_file', $count, 1, false, $post->ID),
);
}
$json['posts'][] = array(
'id'=>$post->ID,
'title'=>$post->post_title,
'body'=>apply_filters('the_excerpt', $post->post_content),
'date'=>$post->post_date,
'user'=>get_userdata($post->post_author)->user_firstname,
'images'=>$imgurl
);
}
}
header('Content-type: application/json');
echo json_encode($json);
exit();
What I am looking for it to do is to return the array of image urls, rather than the [object object] that I am currently getting.
EDIT: Here is the sencha code I'm using to try to pull the imageurl out:
console.log(this.record.data);
console.log(this.record.data.images);
console.log(this.record.data.images.length);
var numberOfPages = this.record.data.images.length;
// Create pages for the carousel
var pages = [];
for (var i=0; i<numberOfPages; i++) {
pages.push(new Ext.Component({
id: 'page'+i,
cls: 'page',
tpl: '<tpl for=".">{imageurl}</tpl>',
//html:'test',
}));
}
// Create the carousel
this.carousel = new Ext.Carousel({
id: 'carousel',
title:'Gallery',
iconCls:'photos2',
defaults: {
cls: 'card'
},
items: pages,
});

Associative arrays in PHP encoded as JSON become objects in JavaScript when decoded. What you're seeing is correct and normal. Access them as you would any other object in JavaScript.

Update: Sorry, for the irrelevant example I had given
Where is your pages[i].update(this.record.data.images); ?
You can try the following -
var numberOfPages = this.record.data.length;
// Create pages for the carousel
var pages = [];
for (var i=0; i<numberOfPages; i++) {
var tmp = new Ext.Component({
id: 'page'+i,
cls: 'page',
tpl: '<tpl for=".">{imageurl}</tpl>'
});
tmp.update(this.record.data[i].images);
pages.push(tmp);
}

Found the answer, gave it to Rifat because his answer was the springboard.
I had the [object object]'s coming through as a literal string of characters. I wrote a quick test.php outside Sencha touch and was able to get the actual array to work. My first issue was the json itself - It needed to be validated. You guys were all correct and thank you for that clue.
Second, once I got the test.php document working, I realized it had to be within Sencha itself. The nagging feeling that the string of characters had something to do with it sat in my head. Finally, I went to my model and found how I was pulling the images:
{name: "images", type: "string"},
I saw string, and the aha moment hit! This fixed it and gave me my URL's:
{name: "images"},
Can't thank Ignacio and Rifat enough. You guys hung in there with me and got the answer to (eventually) appear. Thanks again, and hope this helps anyone else that may run into a similar issue.

I had a similar issue once, in the javascript backend. Here is an answer for people using JS:
Make sure to stringify your object arrays before sending them:
JSON.stringify(array[i]);
Unless ofcourse you are ONLY sending JSON, which in that case sending regular JSON should work fine :)

Related

problems with parsing arguments jquery: $getJSON --> php:$_GET

I want to invoke a php program from javascript and send relevant info by $.getJSON from the js side to be processed to the php module through $_GET.
Thankful for any helpful suggestions
Cheers, Nisse
I start out with functioning legacy code looking like:
onestr='?q=valuezero';
$.getJSON(onestr ,function() {
console.log("Be here now:");
}
)
On the server side, I get _GET:
{"view":"app","q":"valuezero"}
which is what I want.
I then want to augment onestr with the content of two objects:
clientside (js):
my_obj1={property1:"value1",property2:"value2",propery3:"value3"};
my_obj2={property4: "value4", property5: "value5", propery6: "value6"};
scr_str1=JSON.stringify(my_obj1).substr(1).slice(0,-1);
scr_str2=JSON.stringify(my_obj2).substr(1).slice(0,-1);
//the substr and slice breaks everything down to one level
//
onestr='?q=valuezero'+'&'+scr_str1+'&'+scr_str2;
$.getJSON(onestr ,function() {
console.log("Be here now");
}
)
On the server side, I now get :
_GET: {"view":"app","q":"valuezero","\"property1\":\"value1\",\"property2\":\"value2\",\"propery3\":\"value3\"":"","\"property4\":\"value4\",\"property5\":\"value5\",\"propery6\":\"value6\"":""}
whereas the desired result would have been:
{"view":"app","q":"valuezero","property1":"value1","property2":"value2","propery3":"value3","property4":"value4","property5":"value5","propery6":"value6"}
It initially looked trivial to append something like .replace(/\\/g,'').replace(/'""'/g,'"'); to the def of scr_str1 and scr_str2 but then I realized that the backstrokes appear on the server side; also tried replacer function in stringify and other stuff but I just cant transfer _GET to an associative array of the desired structure.
If you need to compose an url having as GET parameters the property values coming from an object, this could be the strategy to get there:
Warning! I'm not escaping the property names/values that may need to pass through encodeURIComponent
my_obj1 = {property1:"value1",property2:"value2",propery3:"value3"};
my_obj2 = {property4: "value4", property5: "value5", propery6: "value6"};
const params = {...my_obj1, ...my_obj2};
let url = buildUrl("https://host.com/path/to/action", params);
console.log(url);
function buildUrl(baseurl, params){
const queryParams = Object.entries(params)
.map(([key, value]) => `${key}=${value}`)
.join('&');
return `${baseurl}?${queryParams}`;
}

PHP json_encode - Same Code once delivers an Array and once an object

I am using the same code within two PHP- classes. I copied and pasted it.
In one class an Array is delivered to the JavaScript in which I use a copied/pasted piece of code, too and once an Object.
Here is the PHP- Code:
private $status_good = array('Status' => 'good');
private $status_fail = array('Status' => 'fail');
echo json_encode($this->status_fail);
And here is the JS/jquery- Code:
$.post("./someclass.php",
{
code : this.code,
input : this.input
},
function( data ){
console.log("Data: ")
console.log(data );
}
Once the console says: Data: {"Status":"fail"}
In the other script: Data: Object { Status: "fail" }
I am doing no UTF- manipulation nor any header- manipulation.
Please be so kind and tell me how this may happen with exactly the same code in different classes.
Thanks in advance.
Add the dataType argument to $.post and/or set Content-type header in the php.
$.ajax does a "best guess" at the data type being returned if it is not explicitly told what to expect and there is no header to help it decide.
It would appear that it is getting it right in the one case and parsing JSON and in the other it is treating it as text and returning a string to the callback.
$.post("./someclass.php",
{
code : this.code,
input : this.input
},
function( data ){
console.log("Data: ")
console.log(data );
},'json')

Read POST data in AJAX call

I have some Session values that I am constantly changing via Ajax calls. I can't seem to get a handle on the POST data to process it and set the values.
What I am passing to it here is an array of strings like is shown in my code below.
Here is where AJAX calls:
var sessionValues = [];
str = {"PID": "1", "Level": "Main", "MenuName": "Kitchen", "State": "CHECKED"}
sessionValues.push(str);
var postObj = {"sessionData": sessionValues};
$.ajax({
type: 'POST',
data: {'data': postObj},
url: 'setSession.asp'
}).done(function(response){
console.log(response);
})
I have this working fine in a PHP version of the program but my ASP version is not grabbing the data. Here is my PHP ver and the ASP ver as best as I could convert it.
<-- php setSession.php works fine -->
$data = $_POST['data'];
foreach ($data['sessionData'] as $key => $value) {
$projectProduct = "1";
$level = $value["Level"];
$menuName = $value["MenuName"];
$state = $value["State"];
$_SESSION['PID:'.$projectProduct][$level][$menuName]['menu_state'] = $state;
echo "[PID:".$projectProduct."][".$level."][".$menuName."][".$state."]<br>";
}
0 =>>>>> Array<br>[PID:1][Main][Kitchen][CHECKED]
Here I want to do the same thing in ASP
' setSession.asp
data = Request.Form("data")
For Each part In data("sessionData")
projectProduct = part("PID")
level = part("Level")
menuName = part("MenuName")
state = part("State")
Session("PID:" & projectProduct).Item(level).Item(menuName).Remove("menu_state")
Session("PID:" & projectProduct).Item(level).Item(menuName).Add "menu_state", state
response.write("[PID:" & projectProduct&"]["&level&"]["&menuName&"]["&state&"]<br>")
Next
outputs blank
It looks like it never has any data but doesn't throw any errors. Am I reading the POST object correctly?
[edit]
Here is the RAW POST data captured from Fiddler:
data%5BsessionData%5D%5B0%5D%5BPID%5D=1&data%5BsessionData%5D%5B0%5D%5BLevel%5D=Main&data%5BsessionData%5D%5B0%5D%5BMenuName%5D=Kitchen&data%5BsessionData%5D%5B0%5D%5BState%5D=CHECKED
here I used a URL Decode on that string-
data[sessionData][0][PID]=1&data[sessionData][0][Level]=Main Level Plan&data[sessionData][0][MenuName]=Kitchen&data[sessionData][0][State]=CHECKED
This looks like I should be able to loop through the strings now by using
For Each part In Request.Form("data[sessionData]")
but nothing happens. I added a simple loop to look at the request.form and here is what it is seeing:
for each x in Request.Form
Response.Write(x)
Next
' outputs -> data[sessionData][0][PID]data[sessionData][0][Level]data[sessionData][0][MenuName]data[sessionData][0][State]
I guess what this comes down to is just reading through and processing that string correctly, or multiple if more than one is sent. Correct?
The RAW output definitely helps work out what is going on.
What is happening is jQuery is translating the JSON structure into HTTP POST parameters but during the process, it creates some overly complex key names.
If you break down the key value pairs you have something like
data[sessionData][0][PID]=1
data[sessionData][0][Level]=Main Level Plan
data[sessionData][0][MenuName]=Kitchen
data[sessionData][0][State]=CHECKED
As far as Classic ASP is concerned the this is just a collection of string key and value pairs and nothing more.
The correct approach to work out what these keys are is to do what you have done in the question, but with some minor alternations.
For Each x In Request.Form
Response.Write(x) & "=" & Request.Form(x) & "<br />"
Next
Which when outputted as HTML will look similar to the break down shown above.
Armed with the knowledge of what the keys are you should be able to reference them directly from the Request.Form() collection.
Dim pid: pid = Request.Form("data[sessionData][0][PID]")
Response.Write pid
Output:
1

Get memcache data from php in nodejs

I have problem with get data from memcache in nodejs.
First of all i set data in memcache with php
Php code:
$memcache = new Memcache;<br>
$memcache->connect("localhost",11211);<br>
$array = array("id"=>"1","name"=>"aaa");<br>
$memcache->set("key",$array);
After this i check if this data is set in memcache and it show:
a:2:{s:2:"id";s:1:"1";s:4:"name";s:3:"aa a";}
Everything seems to be okay. Now i want to get this data in nodejs:
Nodejs code:
var memcache = require('mem');
var client = new memcache.Client(11211,'localhost');
client.connect();
client.get('key', function(err,result){
console.log(result);
});
And here i have problem...In console i get
a:2:{s:2:"id";s:1:"1";s:4:"name";s:3:"aa a";}
And my Question is
How to get in console name : aaa ?
I only add that:
console.log(result['name']); => show : undefined
Please help
Try using a more portable format to share data between the systems. E.g. JSON.
$memcache = new Memcache;
$memcache->connect("localhost",11211);
$data = json_encode(array("id"=>"1","name"=>"aaa"));
$memcache->set("key",$data);
I expect this to then show in memcache as
{ "id" : 1, "name": "aaa" }
Then you should be able to extract it as JSON:
var memcache = require('mem');
var client = new memcache.Client(11211,'localhost');
client.connect();
client.get('key', function(err,result){
console.log(result);
var entry = JSON.parse(result);
console.log(entry.name);
});
The PHP data looks likes it's being automatically serialized for you.
Instead of letting that happen, I would suggest you encode your array into JSON data prior to inserting into memcache, which you can easily decode with node.
So instead of
$memcache->set("key",$array);
do:
$memcache->set("key", json_encode($array));
And then in node, instead of:
client.get('key', function(err,result){
console.log(result);
});
do:
client.get('key', function(err,result){
var object = JSON.parse(result);
console.log(object);
console.log(object['name']);
});
Which will load that data into a JS object.

JavaScript two-dimensional Array to PHP

I have to send a two-dimensional JavaScript Array to a PHP page.
Indeed, I'm working on a form-builder, in which the user can add or remove fields.
These fields are added (or removed) using JavaScript (jQuery). When the user is done and hit a 'publish' button, I have to get all the fields concerned and send them to a PHP page which would build a real form with it.
I found a way to do it but I'm pretty sure it's not very clean :
addedFields = new Array();
$("#add-info .field").each(function() {
addedFields.push(new Array($(this).find('.name').val(), $(this).find('.type').val(), $(this).find('.size').val()));
});
Basically, the ".field" class objects are <tr> and the ".name", ".type" and ".size" objects are inputs.
So I get an array of [name, type, size], then I convert it into a string using
addedFields = addedFields.join(";");
Finally, I go to the PHP form that way ;
document.location.href = "create.php?addedfields=" + addedFields;
Concerning the PHP code, I create a PHP array using the explode() function:
$addedFields = explode(";", $_GET['addedfields']);
and then I use it again for each element in the array:
foreach ($addedFields as $field) {
$field = explode(",", $field);
echo "<li>Field with name : '$field[0]', of '$field[1]' type and with a size of $field[2]</li>";
}
So it works, but it seems very dirty...
Use the auto-array feature in PHP:
var data = {};
$("#add-info .field").each(function(i) {
data['field['+i+'][name]'] = $(this).find('.name').val();
data['field['+i+'][type]'] = $(this).find('.type').val();
data['field['+i+'][size]'] = $(this).find('.size').val()]);
});
$.post("target.php", data);
then on the server side
var_dump($_POST['field']);
// array(
// 0 => array(
// 'name' => ...
// 'type' => ...
// 'size' => ...
// ),
// 1 => ...
Edit: slightly more elegant version of the loop:
$("#add-info .field").each(function(i) {
for (attr in {name: 1, type: 1, size: 1}) {
data['field['+i+']['+attr+']'] = $(this).find('.'+attr).val();
}
});
Put those input fields in a form-element. Use JSON like
var formData = $('form').serializeArray();
formData = window.JSON.stringifiy(formData);
$.post('address', {addedfields: formData}, function(){});
something similar to that should do it in jQuery.
on the backend convert the JSON into an object and loop through.
Try consider using JSON to interact data between PHP and JavaScript.
JSON is built into Javascript and there is an awesome library for PHP. Check them out.

Categories