Weird JSON encoding using json_encode - php

I'm using WordPress together with the JSON API Plugin (http://wordpress.org/extend/plugins/json-api/) to generate responses to our other site.
I've hit a really weird problem (we're using PHP 5.3.6), when I pass the following array http://pastebin.com/xdfYjrvK to json_encode() it gives me this (with json content-type): http://pastebin.com/T61XGPP5
So the crap in the beginning, in the above example it's 2609 and 0 in the end, it changes depending on the size of the response, more content -> higher hex number. It also appears only when the amount of response is "high enough", so it works on small responses.
First I thought it was the plugin, but it works locally (on two different machines Mac OS X) and we've updated all packages on the VPS (Debian, Apache, Nginx, PHP) to the latest versions.
It's only displayed when sending the content-type, not when outputting the $result with plain text instead of application/json:
$charset = get_option('blog_charset');
if (!headers_sent()) {
header('HTTP/1.1 200 OK', true);
header("Content-Type: application/json; charset=$charset", true);
}
echo $result;
$charset is set to utf-8.
The Google chrome console says: "Resource interpreted as Document but transferred with MIME type application/json."
So, does anyone have a clue whats happening here?

This looks like chunked encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Make sure to check that your headers are setting the Content-Length properly in the response to make sure you aren't forcing the web server to use CTE.

One requirement json have is that all data you give to it must be UTF-8 encoded. json_encode() does not do this automaticly. So you can try to run this array_map("utf8_encode", $array); before you json_encode it.
Else... It looks weird, so Im just guessing...

Related

Postman returns 404, while website returns 200

I have a Laravel sever serving an api at http://localhost:8000/api/v1_0/login.
This API when hit from the web page (a login form) works fine with 200 OK status, however when I try to hit the same API with Postman, it returns me 404. I'm sure that my headers and URL spellings are correct. Is this a bug? what else could be the reason?
Just in case someone still need an answer for this. I checked the answer posted by #ZI3n but the solution didn't worked for me.
Postman was receiving a String text\html which is a default Content-Type so I suspected the code I used to processed the JSON was, somehow, forming a string not recognized by Postman as a JSON. But when was received I could see it as JSON, if changed the body type to JSON.
Because of this the request was being received as JSON formatted text but was not recognized as a JSON content, and since I was expecting a JSON the status code was ignored and replaced with 404 Not Found. Not sure if this was by the server or Postman.
So I visited the URL directly on the browser, and it was obvious that the JSON was displayed but still read as text/html and not as application/json
The next step was to refactor the code again, this time I reprocessed the JSON string by assigning the string to a variable $json as follow:
//assigning previous json string to $json
$json = $originalEchoedJsonString;
//reprocessing the string a converting it back to object
$newJson = json_decode($json);
//preparing to be send
//if PHP version 5.4+
http_response_code(200);
// Any PHP version specially 5.3 and under
header('HTTP/1.1 200 Ok', true, 200);
header('Content-type: application/json; charset=UTF-8;');
//echoing JSON back with json_encode();
echo json_encode($newJson);
After doing this I sent the request with Postman again and voila, I got a 200 Ok status and the string was properly displayed as a JSON file. Also was recognized by the browser JSON formatter as a JSON.
I know this is a very old question, but for future people with this problem I'll add this.
On the Headers tab, there is a Host header option. If it is not checked then the server may not accept the request and return an error. In my case a 404 rather than the 400 shown in the postman tooltip below.
Curl and browsers do add it automatically, which is why they can behave differently when this option is not checked.

json_decode with file_get_contents

I am trying to use PHP to echo the contents as plain text so that I can use it my application.
I am trying to obtain the contents of http://www.revctrl.com/api/projects/231 which is in jSON format then convert it to an associated array then manually echo the contents in a nice and neat format. But for some reason, file_get_contents is returning NULL everytime.
I have no clue what is wrong with the code.
$jsonData = json_decode(file_get_contents("https://www.revctrl.com/api/projects/231"), true);
The link works in the browser. The jSON output is valid (checked using http://jsonlint.com/).
Any idea why I get a null from file_get_contents?
Is there any server setting that needs to be set to allow outside links to be accessible?
file_get_contents just discards the server response body in case the HTTP status code indicates the some kind of error; and standard PHP error reporting won’t give you a much of a clue either in case you’re using the function to make an HTTP request.
You can pass in an HTTP context via stream_context_create, setting the option ignore_errors to true – then you will get the error message description the server has likely send in the response body returned.
Use var_dump to output it – then you should be able to figure out what goes wrong on the remote end.

Slash command response not parse correctly

My question is related to Slack's Slash commands.
I am trying to echo response back to invoking channel.
e.g I have integerated a test command like
/test hello
and I want response as:
Hello
Wold
but I am currently getting it as (in my slack channel):
{"text":"hello\nworld"}
This is my PHP code:
$payload = '{"text":"hello\nworld"}';
echo $payload;
Note I don't want to just echo like this:
echo "hello\nworld";
Thanks in advance :)
Maybe useful in giving answer:-
Sample wrong response actual:
Slack slash command API url:
https://api.slack.com/slash-commands
If you had carefully read the docs (which you linked), you would have noticed that it says:
NOTE: If you are responding with JSON instead of plain text, the content-type header of the response must match the disposition of your content, application/json.
It looks like you're just outputting JSON without sending the correct Content-Type header, so Slack thinks it's plain text and displays your JSON as plain text.
Also, consider using json_encode instead of manually writing JSON.

JSON is invalid (JSONview), but I don't see how

OK, I've been going nuts with this. I'm outputting a JSON from PHP, and the JSON View extension, for both Chrome and Firefox, is claiming it's invalid. Both extensions work correctly on JSON View's example, so it seems likely that there actually is something wrong with my JSON – but I have no idea what.
The Firefox version has an error message:
There was an error parsing the JSON document. The document may not be well-formed.
The Chrome version lacks such error messages, but still prints the JSON as plaintext.
I am setting the header, like so: header('Content-Type: application/json'); I've checked the response header in Firebug and Chrome's development tools; it is correctly set in both cases. Removing that hides the error message in the Firefox version and the plaintext is not in a monospace font, but that's it.
Complete request headers:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:msgPublishID=1347362550,1345649049; logout_rem=1; sh_rand=625703e7f9f9e03efabaef56f52ff97d7f68bc67; username=kryan; password=f85720746a490ece4dd7a945f5c9ed8e25b15f1f; fullname=Kevin+Ryan; user_type=1
Host:localhost
Pragma:no-cache
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1
Complete response headers:
Connection:Keep-Alive
Content-Length:371
Content-Type:application/json
Date:Thu, 27 Sep 2012 19:12:52 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.2 (Win32) OpenSSL/1.0.1c PHP/5.4.4
X-Powered-By:PHP/5.4.4
I've gone through many variations on the JSON itself, but I can't imagine that it's the JSON's problem when something as simple as this:
{"session":"expired"}
is still failing. I've checked repeatedly; that is literally the entirety of the server's response, but JSON View still complains. For more complicated JSONs, I've been using
echo json_encode($output, JSON_PRETTY_PRINT);
where $output is an associative array; the output looks completely right but JSON View is still complaining. This is the only echo in the file that isn't commented out.
So what on earth could be going wrong here? I really need JSON View; I work with very large JSONs constantly and the ability to collapse and expand objects and arrays is critical to debugging my application. This online JSON viewer seems to work, but my productivity is going to take a hit if I have to copy and paste the output of these PHP files every time I'm testing them.
EDIT: One thing I have found that works is if I do this:
<?php
header('Content-Type: application/json');
die('{"debug":true}');
// remainder of the program as-is, starting with...
require('dbinfo.php');
If I then go with this:
<?php
header('Content-Type: application/json');
require('dbinfo.php'); // note this comes before the die statement
die('{"debug":true}');
// remainder of the program as-is
I get the error again.
So this implies that dbinfo.php is causing the problem.
EDIT: Sorry, I've removed dbinfo.php from this question because it might possibly contain sensitive data that should not be public (even though I stripped out the obvious things). Since the content of dbinfo.php wasn't relevant, it just seems safer to remove it. See my answer below.
Argh.
I figured it out: the BOM was screwing things up, but of course it was also being completely invisible. Checking and changing the encoding to UTF-8 without BOM fixed the problem entirely.
I don't know if this BOM thing is a problem with PHP's design or Unicode's design, but it is certainly obnoxious.

Slow HTTP POST request in php

I'm trying to POSTing some data (a JSON string) from a php script to a java server (all written by myself) and getting the response back.
I tried the following code:
$url="http://localhost:8000/hashmap";
$opts = array('http' => array('method' => 'POST', 'content' => $JSONDATA,'header'=>"Content-Type: application/x-www-form-urlencoded"));
$st = stream_context_create($opts);
echo file_get_contents($url, false,$st);
Now, this code actually works (I get back as result the right answer), but file_get_contents hangs everytime 20 seconds while being executed (I printed the time before and after the instruction). The operations performed by the server are executed in a small amount of time, and I'm sure it's not normal to wait all this time to get the response.
Am I missing something?
Badly mis-configured server maybe that doesn't send the right content-size and using HTTP/1.1.
Either fix the server or request the data as HTTP/1.0
Try adding Connection: close and Content-Length: strlen($JSONDATA) headers to the $opts.
Also, if you want to avoid using extensions, have a look at this class I wrote some time ago to perform HTTP requests using PHP core only. It works on PHP4 (which is why I wrote it) and PHP5, and the only extension it ever requires is OpenSSL, and you only need that if you want to do an HTTPS request. Documented(ish) in comments at the top.
Supports all sorts of stuff - GET, POST, PUT and more, including file uploads, cookies, automatic redirect handling. I have used it quite a lot on a platform I work with regularly that is stuck with PHP/4.3.10 and it works beautifully... Even if I do say so myself...

Categories