我想用JSON编码一些数据并将其发送到前端Javascript。我所在的服务器不支持本机json_encode()
功能,因此我尝试自己编写它,但是遇到数据格式问题。
我尝试了substr(),但是似乎没有用。
function json_readable_encode($in, $indent = 0, $from_array = false)
{
$_myself = __FUNCTION__;
$_escape = function ($str)
{
return preg_replace("!([\b\t\n\r\f\"\\'])!", "\\\\\\1", $str);
};
$out = '';
foreach ($in as $key=>$value)
{
$out .= str_repeat("\t", $indent + 1);
$out .= "\"".$_escape((string)$key)."\": ";
if ( is_object($value) ||is_array($value))
{
$out .= "\"\n\"";
$out .= $_myself($value, $indent + 1);
}
elseif (is_bool($value))
{
$out .= $value ? 'true' : 'false';
}
elseif (is_null($value))
{
$out .= 'null';
}
elseif (is_string($value))
{
$out .= "\"" . $_escape($value) ."\"";
}
else
{
$out .= $value;
}
$out .= ",\n";
}
if (!empty($out))
{
$out = substr($out, 0, -2);
}
$out = str_repeat("\t", $indent) . "{\n" . $out;
$out .= "\n" . str_repeat("\t", $indent) . "},";
$str = $out;
echo $out;
}
我期望格式正确的东西:
[{ "Catogory": "Sedan", "Availability": "True", "Brand": "Toyota", "Model": "Camry", "Modelyear": "2013", "mileage": "85364", "FuelType": "petrol", "Seats": "5", "PricePerDay": "240", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Camry.jpg" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Nissan", "Model": "X-trail", "Modelyear": "2015", "mileage": "36782", "FuelType": "petrol", "Seats": "7", "PricePerDay": "360", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/X-trail.jpg" }, { "Catogory": "Sedan", "Availability": "False", "Brand": "Volkswagen", "Model": "Golf", "Modelyear": "2017", "mileage": "13586", "FuelType": "CNG", "Seats": "5", "PricePerDay": "180", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Golf.png" }, { "Catogory": "Sedan", "Availability": "False", "Brand": "Honda", "Model": "Civic", "Modelyear": "2018", "mileage": "9586", "FuelType": "petrol", "Seats": "5", "PricePerDay": "220", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Civic.jpg" }, { "Catogory": "Sedan", "Availability": "True", "Brand": "BMW", "Model": "320i", "Modelyear": "2013", "mileage": "5209", "FuelType": "petrol", "Seats": "5", "PricePerDay": "150", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/320i.jpg" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Benz", "Model": "GLC", "Modelyear": "2014", "mileage": "23665", "FuelType": "petrol", "Seats": "5", "PricePerDay": "170", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/GLC.png" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Jeep", "Model": "GLC", "Modelyear": "2019", "mileage": "999", "FuelType": "petrol", "Seats": "5", "PricePerDay": "130", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Cherokee.png" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Suzuki", "Model": "Jimny", "Modelyear": "2009", "mileage": "50006", "FuelType": "petrol", "Seats": "5", "PricePerDay": "80", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Jimny.jpg" },{ "0": " ", "1": " ", "2": " ", "3": " ", "4": " ", "5": " ", "6": " ", "7": " " }]
所以我尝试了
echo "[";
echo json_readable_encode($carlist, $indent = 0, $from_array = false);
echo "]";
输出为:
[ { "Catogory": "Sedan", "Availability": "True", "Brand": "Toyota", "Model": "Camry", "Modelyear": "2013", "mileage": "85364", "FuelType": "petrol", "Seats": "5", "PricePerDay": "240", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Camry.jpg" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Nissan", "Model": "X-trail", "Modelyear": "2015", "mileage": "36782", "FuelType": "petrol", "Seats": "7", "PricePerDay": "360", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/X-trail.jpg" }, { "Catogory": "Sedan", "Availability": "False", "Brand": "Volkswagen", "Model": "Golf", "Modelyear": "2017", "mileage": "13586", "FuelType": "CNG", "Seats": "5", "PricePerDay": "180", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Golf.png" }, { "Catogory": "Sedan", "Availability": "False", "Brand": "Honda", "Model": "Civic", "Modelyear": "2018", "mileage": "9586", "FuelType": "petrol", "Seats": "5", "PricePerDay": "220", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Civic.jpg" }, { "Catogory": "Sedan", "Availability": "True", "Brand": "BMW", "Model": "320i", "Modelyear": "2013", "mileage": "5209", "FuelType": "petrol", "Seats": "5", "PricePerDay": "150", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/320i.jpg" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Benz", "Model": "GLC", "Modelyear": "2014", "mileage": "23665", "FuelType": "petrol", "Seats": "5", "PricePerDay": "170", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/GLC.png" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Jeep", "Model": "GLC", "Modelyear": "2019", "mileage": "999", "FuelType": "petrol", "Seats": "5", "PricePerDay": "130", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Cherokee.png" }, { "Catogory": "SUV", "Availability": "True", "Brand": "Suzuki", "Model": "Jimny", "Modelyear": "2009", "mileage": "50006", "FuelType": "petrol", "Seats": "5", "PricePerDay": "80", "Description": "XXXXXXXXXXXXXXXXX", "imageurl": "/carrental/images/Jimny.jpg" },{ "0": " ", "1": " ", "2": " ", "3": " ", "4": " ", "5": " ", "6": " ", "7": " " },]
输出末尾有一个额外的“,”,因此会出现错误:
Uncaught SyntaxError: Unexpected token
in JSON at position 2285
at JSON.parse (<anonymous>)
at XMLHttpRequest.xmlhttp.onreadystatechange
有人建议进行这项工作吗?
答案 0 :(得分:0)
您的最初问题是,您没有尝试从外部对象列表中删除逗号,该对象在代码末尾插入。您(正确)使用substr()
仅影响内部对象。您无法轻易删除该最后的逗号;因为这是一个递归函数,所以您没有办法知道最终元素将是什么,因此必须在函数外部完成。我将您的函数包含在_encode()
类中,然后使面向公众的函数引用该函数,并使用rtrim()
处理逗号。请注意,您还必须修剪递归调用的输出。
您的转义功能无法正常工作。因为您使用的是双引号引起来的字符串,所以\t
和\n
等被解释为文字制表符和换行符。然后,您只需在它们前面加上一个反斜杠,而不是用适当的转义序列替换它们。另外,某些非PHP转义序列(例如\b
)已由正则表达式解释,因此您可能会转义不需要转义的内容。一个简单的str_replace
消除了使用正则表达式的所有问题。
我删除了缩进输出的代码。 JSON首先是一种数据传输格式,如果您需要阅读它,那么可以使用一些工具。尝试在此处的代码中这样做只会增加出错的可能性,并使代码更加复杂。
您应始终从函数中return
个值,不要回显它们。
我现在唯一缺少的就是输出JSON数组的能力。快速浏览这些键以检查是否只有数字,然后设置一个标志,这将是我对这段代码的下一步改进。
<?php
class JSON
{
public static function encode($in)
{
$output = self::_encode($in);
$output = "[" . rtrim($output, ",") . "]";
return $output;
}
private static function _escape($str)
{
// escape values with special escape sequences
$search = ["\\", "\"", "/", "\r", "\n", "\t", "\f", chr(8)];
$replace = ["\\\\", "\\\"", "\\/", "\\r", "\\n", "\\t", "\\f", "\\b"];
// escape other control chars with numeric escape sequences
for ($i = 0; $i <= 31; $i++) {
$search[] = chr($i);
$replace[] = sprintf("\\u%04x", $i));
}
return str_replace($search, $replace, $str);
}
private static function _encode($in)
{
$out = "";
$start_delimiter = "{";
$end_delimiter = "}";
foreach ($in as $key=>$value) {
$out .= "\"" . self::_escape($key) . "\":";
if (is_object($value) || is_array($value)) {
$out .= rtrim(self::_encode($value), ",");
}
elseif (is_bool($value)) {
$out .= $value ? 'true' : 'false';
}
elseif (is_null($value)) {
$out .= 'null';
}
elseif (is_string($value)) {
$out .= "\"" . self::_escape($value) . "\"";
}
else {
$out .= $value;
}
$out .= ",";
}
$out = rtrim($out, ",");
$out = $start_delimiter . $out . $end_delimiter . ",";
return $out;
}
}
header("Content-Type: application/json");
echo JSON::encode($carlist);