Phil Bryant Phil Bryant - 1 year ago 94
PHP Question

json_encode() isn't sending data back to AJAX call

So I'm trying to create and implement a live search function. Here's my PHP code.


ini_set('display_errors', 1);

define('DB_USER', '*****');
define('DB_PASSWORD', '*****');
define('DB_SERVER', 'localhost');
define('DB_NAME', 'MUSIC');
if (!$db = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME)) {
die($db->connect_errno.' - '.$db->connect_error);

$arr = array();
$sql = "SELECT * FROM main WHERE titles LIKE '%%'";
$result = $db->query($sql) or die($mysqli->error);
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$arr[] = array('title' => $obj->titles);

echo json_encode($arr);

The script I'm calling:

<script src=""></script>
<script type="text/javascript">
$(document).ready(function() {
$('#keyword').on('input', function() {
var searchKeyword = $(this).val();
if (searchKeyword.length >= 3) {
$.post('search.php', { keywords: searchKeyword }, function(data) {
$.each(data, function() {
alert("Here as well");
$('ul#content').append('<li><a href="example.php?id=' + + '">' + this.title + '</a></li>');
}, "json");

And the little portion of HTML that applies to the code:

<form role="form" method="post">
<input type="text" class="form-control" id="keyword" placeholder="Enter keyword"></form><ul id="content"></ul>

Now in this, my script isn't receiving any data, at least not to get it to signal the "alert("Here as well")". However, the first "alert("Here")" does come up. Additionally, I know the script is entering search.php, as I tested it with inserting into my database, and it did insert on every keyup. Any ideas why it isn't returning any data? The database entries have a title, an artist, and an ID right now.

You'll notice in the script that there was a "keyword" setting that gets sent in. I removed this since I thought it was unnecessary when I'm just trying to get it to send (usually the keyword would be in the LIKE portion of the SQL statement). However could this be causing the problem? Couldn't see how.

Thanks for the help.

Answer Source

First thing, never use or die(), especially with the mysqli constructor (hint: it will never be falsy).

Second, if you encounter an error, you should respond in such a way that external consumers (such as your JS application) can understand that an error has occurred.

Third, use a prepared statement with parameter binding. This should go without saying.


// these should really be set in your environment's php.ini
ini_set('display_errors', 'On');

// set mysqli to throw exceptions

try {
    $db = new mysqli('localhost', '*****', '*****', 'MUSIC');
    $stmt = $db->prepare("SELECT `id`, `titles` from `main` WHERE `titles` LIKE CONCAT('%', ?, '%')");
    $stmt->bind_param('s', $_POST['keywords']);
    $stmt->bind_result($id, $titles);

    $response = [];
    while($stmt->fetch()) {
        $response[] = ['id' => $id, 'title' => $titles];

    header('Content-type: application/json');
    echo json_encode($response);
} catch (Exception $e) {
    echo $e;

Of course, if your query doesn't contain any results, your JS $.each will not iterate anything. You'd need to handle such a case client-side by checking data.length.

Looks to me like you should also try FULLTEXT indexing and a MATCH query instead of LIKE.