0

Using a javascript application I am making a server side request for a search functionality. It works for some queries, but not for others.

For some queries the GET request returns no response, despite the fact that testing the query in workbench returns thousands of records. I tried turning on errors - no errors are generated. I tried increasing memory limit - that's not the culprit. I tried to output PDO errors/warnings - nothing generated, the PDO actually returns the records, I verified this using var_dump, as shown below.

So to conclude, everything in the below code, seems to work flawlessly, until the final line that is responsible for encoding the array into a json object - it echos nothing.

I appreciate any assistance in resolving this.

PHP

error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('memory_limit', '2048M');
$db = new PDO('mysql:host=localhost;dbname=mydb', 'root', '');

$search = $_GET['search'];
$searchBy = ( isset($_GET['searchBy']) && !empty($_GET['searchBy']) ) ? $_GET['searchBy'] : 'name';


$sql = "SELECT * FROM business WHERE name LIKE '%university%' GROUP BY id"; 
$query = $db->prepare($sql);
$query->execute();
$results = $query->fetchAll(); //query returns 5000+ records in under a second in workbench

$headers = array('Business', 'City', 'State', 'Zip', 'Phone');


$json = array("results" => $results, 'headers' => $headers, 'query' => $sql);
var_dump($json); //prints successfully 

echo json_encode($json); // echos nothing!
AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231
  • 1
    What is the **exact** output of: `var_dump(json_encode($json));` ? – Rizier123 Apr 26 '15 at 01:26
  • @Rizier123, it contains confidential information, sorry, I am not allowed to show this. I do suspect it is somehow related, I read somewhere that it may be due to utf8 encoding of the db data conflicting with json encoding? – AnchovyLegend Apr 26 '15 at 01:28
  • possible help - http://stackoverflow.com/a/29858303/689579? `array_map('utf8_encode',$results)`? – Sean Apr 26 '15 at 01:29
  • 1
    Then change it so e.g. if you get: `string(7) "[1,2,3]"` -> write something like: `string(7) "[X,X,X]"` – Rizier123 Apr 26 '15 at 01:29
  • To debug this i would first store the _`json_encode($json);`_ in a variable and _`print_r`_ it. I would also consider writing it to a file so i could see what it really was later. – Ryan Vincent Apr 26 '15 at 01:32
  • @AnchovyLegend *// echos nothing!* <- Now to get this clear, do you get any output with `json_encode($json);` or is this your output: `string(2) "[]"` or completely blank `string(0) ""`? – Rizier123 Apr 26 '15 at 01:34
  • 1
    Store it in files for a while so that when it goes wrong you have what actually was generated. – Ryan Vincent Apr 26 '15 at 01:34
  • @Rizier123, neither, completely blank, white screen. If i change 'university' in the query to say 'school' it works perfectly however. – AnchovyLegend Apr 26 '15 at 01:35
  • 1
    @AnchovyLegend *completely blank* So you don't even get this: `string(0) ""` (Also make sure you show into the source code!)? – Rizier123 Apr 26 '15 at 01:36
  • @Rizier123, I get nothing at all. – AnchovyLegend Apr 26 '15 at 01:44
  • @AnchovyLegend 1. Please add `echo "here";` before your connection to check that you look at the correct file! 2. Make sure you show us your **full** and **real** code here! (3. Also restart your webserver and your db server) – Rizier123 Apr 26 '15 at 01:48
  • I found the issue! One of the fields in the returned data set, looked something as follows (replaced sensitive info): `...That’s unusual. I do thank you for checking.` ... the apostrophe was the cause of the issue. As soon as I remove the apostrophe from the field on the db side, it works as it should! Any idea how to resolve this for ALL cases moving forward, without manipulating the database data? – AnchovyLegend Apr 26 '15 at 02:04
  • This is 'interesting'. Somewhere you have a character set mismatch. Embedded 'single quotes', apostrophes etc. are not an issue. Double quote characters are as that is the delimiter. There are utilities available for checking the validity of JSON data. 1) a website: [JSONLint - The JSON Validator](http://jsonlint.com/). 2) A 'command line' utility (needs node.js) : https://github.com/zaach/jsonlint – Ryan Vincent Apr 26 '15 at 02:27
  • Yes, you're correct @RyanVincent, I realized that shortly after posting. The character is indeed a single quote, but thats not technically the issue, the issue is the character set OF the single quote, as you said. Not sure what the 'best practice' way to overcome this issue for ALL cases is, but the solution below seemed to work pretty well. – AnchovyLegend Apr 26 '15 at 02:29
  • 1
    Always run with something that works! :) Glad it is sorted out. – Ryan Vincent Apr 26 '15 at 02:30
  • 1
    Also you could make sure that yout database, tables, fields have utf8 character set and utf8_general_ci (fast) or utf8_unicode_ci (slower) character collation. I wouldn't suggest uf8_bin though, it doesn't offer unicode normalization so some strings may not be matched when you expect them to. – GeorgeKaf Apr 26 '15 at 02:34

3 Answers3

3

EDIT:

use utf8_encode() then json_encode() as mentioned here (Special apostrophe breaks JSON)

OR

$dbHandle = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8", $dbUser, $dbPass,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));

will parse all the data in utf8.

Old

What's the result if you do this ?

echo json_encode($results);
//scratch those
//$json = array("results" => $results, 'headers' => $headers, 'query' => $sql);
//var_dump($json); //prints successfully 

May be you run out of memory? Try with a 100 results. I know from experience with other projects that json_encode can consume a shared server's ram.

Sorry if I am not as helpful as you would like me to be but we can't really test you code, you have to do it for us.

Community
  • 1
  • 1
GeorgeKaf
  • 599
  • 8
  • 23
2

I had this exact error when I tried to use json_encode the other day. It returned no errors... just a blank screen, and finally it hit me. The issues was with character encoding. The column I was trying to use had been used by copywriters who cut and pasted from Microsoft Word directly into the wysiwyg.

echo json_last_error() after your json_encode and see what you get

.
.
.
echo json_encode($json); // echos nothing!
echo json_last_error(); // integer if error hopefully 0

It should return an integer specifying one of the errors below.

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

In my case it returned a 5. I then had to clean every "description" column before it would work. In the event it is the same error, I've included the function you will need to run all your columns through to clean them out.

function utf8Clean($string)
{
    //reject overly long 2 byte sequences, as well as characters above U+10000 and replace with *
    $string = preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]'.
     '|[\x00-\x7F][\x80-\xBF]+'.
     '|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*'.
     '|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})'.
     '|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/S',
     '*', $string );

    //reject overly long 3 byte sequences and UTF-16 surrogates and replace with ?
    $string = preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]'.
     '|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $string );

    return $string;
}

for more info on json_last_error() go to the source! http://php.net/manual/en/function.json-last-error.php

Eko3alpha
  • 540
  • 6
  • 16
0

It is really easy with the JSON Builder : Simple JSON for PHP

include('includes/json.php');

$Json = new json();

$Json->add('status', '200');
$Json->add('message', 'Success');
$Json->add('query', 'sql');
$Json->add("headers",$headers);
$Json->add("data",$results);

$Json->send();
Alexis Paques
  • 1,885
  • 15
  • 29