目标:
json_encode
具有私有(private)属性的 PHP 对象- 通过 Low Level AJAX 将编码后的对象作为数据字符串发送使用 jQuery
json_decode
请求发送到的 AJAX URL 中的 PHP 对象- 获胜
问题:
在第 3 步中,json_last_error返回 3(JSON_ERROR_CTRL_CHAR 控制字符错误,可能编码不正确
)
类(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);
*/
AJAX 功能:
<!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>
AJAX 请求(loadmore.php):
require_once'../../classes/stream.class.php';
$strm = new Stream();
$strm->decodeJSON($_POST['stream']);
我尝试过的:
这段代码
$d=$strm->encodeJSON();
$st = new Stream();
$st->decodeJSON($d);
工作正常。这会让我相信 AJAX 正在干扰解码。
我还尝试将 $json = json_decode($json_str, true);
更改为 $json = json_decode(utf8_encode($json_str), true);
但什么也没有变化。
注意:建议我将类属性公开并不是解决方案
编辑:当我回显字符串时,{
“限制”:“5”,
“类型”:“目录”,
“种类”: ” ”,
“偏移”:“0”,
“用户ID”:“3”,
“猫ID”:“”,
“帖子数量”:“2”
}
被发送到decodeJSON,它测试为 valid
此屏幕截图显示了发送到decodeJSON($json_str) 的参数$json_str 和错误代码。
最佳答案
JSON_ERROR_CTRL_CHAR
的原因
返回的原因 JSON_ERROR_CTRL_CHAR
不是因为字符编码(即utf8或iso)。当数据编码不正确并且生成的字符串不是有效的 JSON 时,它会遇到此错误。如果您混合使用单引号 '
和双引号 "
它也可能会干扰编码过程,保持一致很重要。
话虽如此,
它很可能会返回错误,因为您一开始就没有发送任何实际数据。您通过请求发送一个空字符串。好吧,不是真的,你实际上是在发送字符串
<?= $strm->encodeJSON();?>
然后变成
json_encode("<?= $strm->encodeJSON();?>");
在你的loadmore.php中。
但如果你使用正确的 php 标签 <?php ?>
无论如何它都是空的因为你没有回应任何东西。
改变
var stream= '<?= $strm->encodeJSON();?>';
到一个正确的 php 标签,并确保你确实输出了一些东西,否则 stream
只是一个空字符串。
var stream= '<?php echo $strm->encodeJSON(); ?>';
它应该可以正常工作。
其他
一般来说,通过 AJAX 发送数据时,您应该 encodeURIComponent()
它可以转义任何特殊字符。
data: "stream="+encodeURIComponent(stream),
$json = json_decode(urldecode($json_str), true);
<强> .live
已弃用
.live
函数从 1.7 开始已弃用,您现在应该使用函数 .on
附加事件处理程序。在您的情况下,您最好使用简写函数 .click()
.
链接必须有href
<a>
标签必须有 href 属性,否则它就不是链接,您不妨使用 <div>
如果你不打算使用它。至少你应该有 href="#"
然后添加 event.preventDefault()
.
文件名
命名文件时,尽量避免使用句点 stream.class.php
,它们是等待发生的事故。某些系统(尤其是较旧的系统)无法正确解释它们,并且您将很难重命名所有系统。标准约定建议对稳定的文件系统使用下划线或连字符。
这对我来说有效(所有文件都在同一文件夹中)
HTML 默认值 (index.php)
<?php
include_once("stream.php");
?>
<!DOCTYPE html>
<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
$(document).ready(function(){
$("#active").click(function(e) {
e.preventDefault();
var stream = '<?php echo $strm->encodeJSON();?>';
var dataString = stream;
var request = $.ajax({
type: "POST",
url: "loadmore.php",
data: "stream="+encodeURIComponent(stream),
dataType: "html",
beforeSend:function(data){
$('.load-more').html('<img src="ajax-loader(1).gif" alt="Loading..." />');
},
success: function(html) {
$('#active').remove();
$('#stream').append(html);
}
});
//ajax error reporting
request.fail(function(jqXHR, textStatus) {
$('#active').html(textStatus);
});
});
});
</script>
</head>
<body>
<a href="#" class='load-more' id='active'>load more posts</a>
<div id="stream"></div>
</body>
</html>
流.php
<?php
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(urldecode($json_str), true);
foreach ($json as $key => $value){
$this->$key = $value;
}
}
}
//create the object to be encoded
$strm = new Stream(5, 'toc', ' ', 1, ' ');
?>
loadmore.php
<?php
include_once('stream.php');
$strm = new Stream();
$strm->decodeJSON($_POST['stream']);
//Output a private property
echo $strm->__get("type");
?>
关于php - json_decode + ajax + 私有(private)属性 = 灾难 [错误 : JSON_ERROR_CTRL_CHAR],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10005796/