Goal:
json_encodea PHP object that has private properties- Send the encoded object as a datastring through Low Level AJAX using jQuery
json_decodethe PHP object in the AJAX URL to which the request is sent- win
Problem:
On step 3, json_last_error is returning 3 (JSON_ERROR_CTRL_CHAR Control character error, possibly incorrectly encoded)
The Class:
class Stream {
private $limit;
private $type;
private $sort;
private $offset=0;
private $userID;
private $catID;
private $content = array();
private $num_posts;
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct5($limit, $type, $sort, $userID, $catID){
$this->limit = $limit;
$this->type = $type;
$this->sort = $sort;
$this->userID = $userID;
$this->catID = $catID;
//$this->num_posts = $this->retrieveTotal();
//$this->setContent();
}
function __get($name) {
if(isset($this->$name)){
return $this->$name;
}
}
public function encodeJSON(){
foreach ($this as $key => $value){
if($key != 'content'){
$json->$key = $value;
}
}
return json_encode($json);
}
public function decodeJSON($json_str){
$json = json_decode($json_str, true);
echo '<br>error: '.json_last_error();
foreach ($json as $key => $value){
$this->$key = $value;
}
}
}
//create the object to be encoded
$strm = new Stream(5, 'toc', ' ', 1, ' ');
/*this test works
$d=$strm->encodeJSON();
$st = new Stream();
$st->decodeJSON($d);
*/
The AJAX function:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
//load more posts
$("#active").live("click", function() {
var stream= '<?= $strm->encodeJSON();?>';
var dataString = 'stream='+stream;
var request = $.ajax({
type: "POST",
url: "ajax/loadmore.php",
data: dataString,
beforeSend:function(data){
$('.load-more').html('<img src="ajax/loader.gif" alt="Loading..." />');
},
success: function(html) {
$('#active').remove();
$('#stream').append(html);
}
});
//ajax error reporting
request.fail(function(jqXHR, textStatus) {
$('#active').html(textStatus);
});
});
</script>
<a class='load-more' id='active'>load more posts</a>
The AJAX request (loadmore.php):
require_once'../../classes/stream.class.php';
$strm = new Stream();
$strm->decodeJSON($_POST['stream']);
What I have tried:
This snippet of code
$d=$strm->encodeJSON();
$st = new Stream();
$st->decodeJSON($d);
works fine. That would lead me to believe that AJAX is interfering with the decoding.
I have also tried changing $json = json_decode($json_str, true); to $json = json_decode(utf8_encode($json_str), true); and nothing changes.
NOTE: suggesting that I make the class properties public is NOT a solution
EDIT: when I echo the string, { being sent to decodeJSON it tests as valid
"limit": "5",
"type": "toc",
"sort": " ",
"offset": "0",
"userID": "3",
"catID": " ",
"num_posts": "2"
}
This screenshot shows the arg $json_str that is being sent to decodeJSON($json_str) and the error code.

After much trial and error I figured out the issue. When I was instantiating the
Stream objectthat was to be encoded, instead of using1i was using$userIDwhich was being cast as a string and messing with the URI encodingstream=%7B%22limit%22%3A%225%22%2C%22type%22%3A%22toc%22%2C%22sort%22%3A%22%20%22%2C%22offset%22%3A%220%22%2C%22userID%22%3A%223%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%22%2C%22catID%22%3A%22%20%22%2C%22num_posts%22%3A%222%22%7DI’m not really sure WHY it behaves that way, but the solution is casting the $userID as an integer. so:
The URI encoding changes to:
stream=%7B%22limit%22%3A%225%22%2C%22type%22%3A%22toc%22%2C%22sort%22%3A%22%20%22%2C%22offset %22%3A%220%22%2C%22userID%22%3A%223%22%2C%22catID%22%3A%22%20%22%2C%22num_posts%22%3A%222%22%7Dand json_decode return an array.