So a PHP file returns a string ( to an ajax call ) like this :
$output = $sessID."###".$sessEmail."###".$sessFirstName."###".$sessLanguage."###".$sessRememberMe;
and in javascript i do :
if (reply.indexOf("###") >= 0) {
arrayReply = reply.split("###");
user.ID = arrayReply[0];
user.Email = arrayReply[1];
user.FirstName = arrayReply[2];
user.Language = arrayReply[3];
user.RememberMe = arrayReply[4];
}
a problem can arise when parts of reply contain the the delimiter i use "###". What can I do in such a situation? Making the delimiter more complex/rare is not a solution in my opinion.
PS: I did try JSON but it's WAY SLOWER server side.
FINAL EDIT:
server side JSON is slower, and the same for client side, however it's not going to be a bottleneck ( 430ms for 100.000 calls ) and plus there is no need as Jules said below to re-invent the wheel. There was one more solution: bin2hex() in php [which reduced the time from 430ms to 240] and then get back the string in javascript with a hex2string function, however not worth the effort. JSON it is. Thank you all!
If as you say encoding as JSON is slower than you could try the following,
$output = '"' . some_kind_of_escape_function($sessID).'","'.some_kind_of_escape_function($sessEmail).'","'.some_kind_of_escape_function($sessFirstName).'","'.some_kind_of_escape_function($sessLanguage).'","'.$sessRememberMe.'"';
and of course replace some_kind_of_escape_function with the appropriate php function (e.g. addslashes or mysql_real_escape_string) it has been a while since I've done PHP development so choose the one that best suits your needs
Then it's a simple case of splitting by the comma and removing the quotes
One option is to use JSON object instead.
For PHP (using json_encode):
$output = json_encode(array(
"sessid" => $sessID,
"sessEmail" => $sessEmail,
"sessFirstName" => $sessFirstName,
"sessLanguage" => $sessLanguage,
"sessRememberMe" => $sessRememberMe
));
For JS (using jQuery method):
$.getJSON("/path/to/script.php", function(reply) {
user.ID = reply.sessid;
user.Email = reply.sessEmail;
user.FirstName = reply.sessFirstName;
user.Language = reply.sessLanguage;
user.RememberMe = reply.sessRememberMe;
});
Otherwise, you can use any other delimiter that possibly won't be found in the fields (or you can replace it throughout the fields). One of the examples is to use symbol of newline (\n).
Why develop your own format if there is already one?
use Json:
$output = json_encode(array('sessionID'=>$sessID,'sessionEmail'=>sessEmail,'sessionFirstName'=>$sessFirstName,'sessLanguage'=>$sessLanguage,'sessRememberMe'=>$sessRememberMe));
And for the Javsascript Side see
http://www.javascriptkit.com/dhtmltutors/ajaxgetpost4.shtml
or if your using JQuery etc. your Framework is much likely to have some kind of inbuild functionality such as http://api.jquery.com/jQuery.getJSON/
However if you want to use your ###-Delimiter i'd suggest you reduce it to just "#", for the sake of simplicity and space. After that introduce what is called an escape charater such as "\" So in a prepass you'll parse your input and replace all occurences of # with #, vice versa in the output. You can then Split your String using a special Regex, which only splits by # and not by "#"
You can use json.
http://php.net/manual/en/function.json-encode.php
How to JSON decode array elements in JavaScript?
Related
Well, I'm trying to retrieve some info, from the Google Suggest tool.
The thing is, the json returned after the request, doesn't seem decode-able (using json_decode) + JSONLint sees it as "invalid".
What's wrong?
{
e: "GooDUs7lFIeXO63LgBA",
c: 0,
u: "https://www.google.com/s?gs_rn\x3d24\x26gs_ri\x3dpsy-ab\x26tok\x3dt8ORbtI13MEFLoCQjPSv6w\x26cp\x3d2\x26gs_id\x3d3i\x26xhr\x3dt\x26q\x3dtemplate\x26es_nrs\x3dtrue\x26pf\x3dp\x26safe\x3doff\x26sclient\x3dpsy-ab\x26oq\x3d\x26gs_l\x3d\x26pbx\x3d1\x26bav\x3don.2,or.r_cp.r_qf.\x26bvm\x3dbv.50500085,d.bGE\x26fp\x3dc513cf9c63a02102\x26biw\x3d1304\x26bih\x3d437\x26tch\x3d1\x26ech\x3d20\x26psi\x3dFYkDUs-xCsrT4QTD9YGwDw.1375963413783.1",
p: true,
d: "[\x22template\x22,[[\x22template\\u003cb\\u003es\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e monster\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e c++\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003es for pages\\u003c\\/b\\u003e\x22,0]],{\x22t\x22:{\x22bpc\x22:false,\x22tlw\x22:false},\x22q\x22:\x22YjrI_EdhVrEkZrkqZwaGIJ_Ih4c\x22,\x22j\x22:\x223i\x22}]"
}
That's what JSONLint gives as an error :
Parse error on line 1:
{ e: "GooDUs7lFIeXO63L
-----^
Expecting 'STRING', '}'
P.S. Even after editing it like "e": and so on, it still gives out error regarding the value of u and claiming that it was expecting a STRING or NUMBER etc... :S
The code given in the question is not valid JSON.
In order to be valid JSON, it would be required to have the field named in quotes. There are no quotes around the e variable name, or any of the others.
This is what the JSON decoder is complaining about: It is expecting to see "e", not e.
In addition, JSON does not accept the \x escaping format (character reference in hex); it can only use the \u format (unicode character reference in decimal). The code you've provided includes escaped characters in both formats.
The question is, are you using an official Google API? Because they're usually pretty good at providing valid JSON. This isn't valid JSON, so it may be that you're not using the correct API. Another clue is that the variable names aren't very meaningful; offical APIs would normally give more meaningful variable names. If it is the correct API, you should try raising a ticket with Google to fix it; broken JSON is not good, but it should be pretty trivial for them to fix.
Assuming you can't get them to fix it and we can't find an alternative API location that does give valid data, how do we deal with what we've got?
While this code may not be valid JSON, it is valid as a Javascript object (the JSON rules are stricter that those of plain Javascript). It could therefore be run in a Javascript interpreter using eval(), if you trusted it enough for that.
The only other alternativate is to fix the string prior to parsing it so that the variable names are quoted. That's a bit of a pain, but would be do-able if the output was consistent. You'll have problems though if it ever changes (and again, if it's an unofficial API, that could happen at any time without warning).
The problem is with the backslashes in the strings (used for the escape characters)
In PHP 5.4, you can use JSON_UNESCAPED_SLASHES:
echo json_encode(JSON_STRING, JSON_UNESCAPED_SLASHES);
Otherwise, you can do the replacement-
str_replace('\\/', '/', json_encode(JSON_STRING));
Since \/ is a valid way to represent /
OK, so this is what I ended up doing (not elegant at all but it works) :
$content = preg_replace_callback(
"(\\\\x([0-9a-f]{2}))i",
function($a) {return chr(hexdec($a[1]));},
$content
);
$content = str_replace("e:","\"e\":",$content);
$content = str_replace("c:","\"c\":",$content);
$content = str_replace("u:","\"u\":",$content);
$content = str_replace("p:","\"p\":",$content);
$content = str_replace("d:","\"d\":",$content);
$content = str_replace("\"[","[",$content);
$content = str_replace("]\"","]",$content);
$content = json_decode($content);
I'm trying to write a php script that handles data from a webservice that delivers "json" as a string. The problem is the string isn't really json; it's javascript. Specifically, the keys are not quoted, although the variables are. Example (the actual data is much longer and more complicated):
{desc:'User defined payload'}
As described by the php manual, json_decode() correctly fails to interpret this string.
My question is, how can I successfully interpret a string like this in php?
The only solution I can think of is to write some regular expressions that fix the syntax, but then I'd have two problems.
EDIT
Hadvig's suggestion of using the Services_JSON pear module worked, and looks like a general solution. Once I had the module installed, my code looked like this:
require_once 'PEAR.php';
require_once 'Services/JSON.php';
$Services_JSON = new Services_JSON();
$data = $Services_JSON->decode($malformed_json);
Unfortunately, this is SLOW. To interpret the whole string (~400,000 chars) took > 36 seconds! Using a regular expression to fix the quotes and then using json_decode took ~0.04 seconds. Here's what I used:
// fix single quotes
$s = str_replace("'", '"', $malformed_json);
// fix unquoted keys
$valid_json = preg_replace('/([{\[,])\s*([a-zA-Z0-9_]+?):/', '$1"$2":', $s);
$data = json_decode($valid_json);
Of course, this will break if the data contains any quotes, brackets, or commas.
Ok. try to use this. http://pear.php.net/pepr/pepr-proposal-show.php?id=198 I just check your string
Depends on how complicated your data is :
$output = "{desc:'User defined payload',asc:'whatever'}";
function json_js_php($string){
$string = str_replace("{",'{"',$string);
$string = str_replace(":'",'":"',$string);
$string = str_replace("',",'","',$string);
$string = str_replace("'}",'"}',$string);
return $string;
}
echo json_decode(json_js_php($output))->{'desc'};
returns : User defined payload
Using regexp is a no-go. JSON grammar cannot be correctly parsed using regexp. You will open yourself to a ton of future bugs.
I recommend using some kind of a YAML parser. YAML is backwards-compatible with JSON and allows unquoted literals at the same time.
Symfony YAML component worked great for me.
And remember that there will be a performance penalty in comparison to json_decode because it's implemented natively.
If the problem is just the unquoted identifiers and the data can be assumed not to contain any curly brackets, this should do it:
$goodJson = preg_replace("/{\s*([a-zA-Z0-9_]+)/", '{ "$1"', $badJson);
(not tested!)
Try this:
$jsonString = "{result:true,username:'usr000242',password:'123456',message:'Cannot send username and password to email#test.com'}";
function manualFixInvalidJSON($jsonString=''){
$jsonString = preg_replace("/([{,])([a-zA-Z][^: ]+):/", "\$1\"$2\":", $jsonString);
$jsonString = preg_replace("/:([a-zA-Z\'][^:]+)([,}])/", ":\"$1\"$2", $jsonString);
$jsonString = json_decode($jsonString,true);
function trimer($val){
return trim(trim($val,"'"),"\"");
}
$jsonString = array_map('trimer', $jsonString);
return json_encode($jsonString);
}
echo jsonString($jsonString);
I've got a php script which generates HTML content. Is there a way to send back that HTML content through JSON to my webpage from the php script?
Yes, you can use json_encode to take your HTML string and escape it as necessary to be valid JSON (it'll also do things that are unnecessary, sadly, unless you use flags to prevent it). For instance, if your original string is:
<p class="special">content</p>
...json_encode will produce this:
"<p class=\"special\">content<\/p>"
You'll notice it has an unnecessary backslash before the / near the end. You can use the JSON_UNESCAPED_SLASHES flag to prevent the unnecessary backslashes. json_encode(theString, JSON_UNESCAPED_SLASHES); produces:
"<p class=\"special\">content</p>"
Do Like this
1st put all your HTML content to array, then do json_encode
$html_content="<p>hello this is sample text";
$json_array=array(
'content'=>50,
'html_content'=>$html_content
);
echo json_encode($json_array);
All string data must be UTF-8 encoded.
$out = array(
'render' => utf8_encode($renderOutput),
'text' => utf8_encode($textOutput)
);
$out = json_encode($out);
die($out);
In PHP:
$data = "<html>....";
exit(json_encode($data));
Then you should use AJAX to retrieve the data and do what you want with it. I suggest using JQuery: http://api.jquery.com/jQuery.getJSON/
You can send it as a String, why not. But you are probably missusing JSON here a bit since as far as I understand the point is to send just the data needed and wrap them into HTML on the client.
Just to expand on #T.J. Crowder's answer.
json_encode does well with simple html strings, in my experience however json_encode often becomes confused by, (or it becomes quite difficult to properly escape) longer complex nested html mixed with php. Two options to consider if you are in this position are: encoding/decoding the markup first with something like [base64_encode][1]/ decode (quite a bit of a performance hit), or (and perhaps preferably) be more selective in what you are passing via json, and generate the necessary markup on the client side instead.
All these answers didn't work for me.
But this one did:
json_encode($array, JSON_HEX_QUOT | JSON_HEX_TAG);
Thanks to this answer.
I'm not talking about JSON. I've got a program with the input being a javascript data structure in string format, something like this:
$string = "
var records = new Array();
records[0] = new Record('data1','data2',data3');
records[1] = new Record('data1','data2',data3');
records[2] = new Record('data1','data2',data3');";
Is there an easy way/library to turn this into a PHP data structure? The only way I can think of is to use str_replace to manipulate the string in order to turn it into JSON and then use json_decode.
Just wondering if there's a better way to do it.
Nope, you pretty much hit on the best way to do it.
You can post it to PHP as a string delimited by some character:
$phpArray = explode(",",$postValue);
This is not a better way just another way to do it. But not without potential problems. You have to ensure the delimiter you use is not used in the text and validate.
I'm playing with the flickr api and php. I want to pass some information from PHP to Javascript through Ajax. I have the following code:
json_encode($pics);
which results in the following example JSON string:
[{"id":"4363603591","title":"blue, white and red...another seattle view","date_faved":"1266379499"},{"id":"4004908219","title":"\u201cI just told you my dreams and you made me see that I could walk into the sun and I could still be me and now I can't deny nothing lasts forever.\u201d","date_faved":"1259987670"}]
Javascript has problems with this, however, due to the unescaped single-quote in the second item ("can't deny").
I want to use the function json_encode with the options parameter to make it strip the quotes, but that's only available in PHP 5.3, and I'm running 5.2 (not my server). Is there a fast way to run through the entire array and escape everything before encoding it in Json? I looked for a way to do this, but it all seems to deal with encoding it as the data is generated, something I cannot do as I'm not the one generating the data.
If it helps, I'm currently using the following javascript after the ajax request:
var photos = eval('(' + resptxt + ')');
Have you considered using JSON2 instead of eval()? Details here.
str_replace('\'', '\\'', json_encode($pics))
You'll have to do a (recursive) foreach to walk through the array and manipulate them manually. You can do a str_replace, but addslashes works just as fine (and addcslashes is even better.)