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

So I'm trying to create and implement a live search function. Here's my PHP code.
<?php
ini_set('display_errors', 1);
error_reporting(~0);
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="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></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) {
alert("Here");
$('ul#content').empty()
$.each(data, function() {
alert("Here as well");
$('ul#content').append('<li>' + this.title + '</li>');
});
}, "json");
}
});
});
</script>
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.

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.
<?php
// these should really be set in your environment's php.ini
ini_set('display_errors', 'On');
error_reporting(E_ALL);
// set mysqli to throw exceptions
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
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->execute();
$stmt->bind_result($id, $titles);
$response = [];
while($stmt->fetch()) {
$response[] = ['id' => $id, 'title' => $titles];
}
$stmt->close();
header('Content-type: application/json');
echo json_encode($response);
exit;
} catch (Exception $e) {
http_response_code(500);
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.

Related

XML Parsing Error: no root element found Location

So I'm making a simple login/registration web application but I keep getting the following error:
XML Parsing Error: no root element found Location: file:///C:/xampp/htdocs/EdgarSerna95_Lab/login.html Line Number 37, Column 3:
and
XML Parsing Error: no root element found Location: file:///C:/xampp/htdocs/EdgarSerna95_Lab/php/login.phpLine Number 37, Column 3:
here is my login.php
<?php
header('Content-type: application/json');
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "jammer";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
header('HTTP/1.1 500 Bad connection to Database');
die("The server is down, we couldn't establish the DB connection");
}
else {
$conn ->set_charset('utf8_general_ci');
$userName = $_POST['username'];
$userPassword = $_POST['userPassword'];
$sql = "SELECT username, firstName, lastName FROM users WHERE username = '$userName' AND password = '$userPassword'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$response = array('firstName' => $row['firstNameName'], 'lastName' => $row['lastName']);
}
echo json_encode($response);
}
else {
header('HTTP/1.1 406 User not found');
die("Wrong credentials provided!");
}
}
$conn->close();
?>
I've done some research about xml parsing errors but I still cant manage to make my project work, ive tried with Google Chrome and Firefox
AHA! Got this today for a reason which will make me look pretty silly but which might one day help someone.
Having set up an Apache server on my machine, with PHP and so on... I got this error... and then realised why: I had clicked on the HTML file in question (i.e. the one containing the Javascript/JQuery), so the address bar in the browser showed "file:///D:/apps/Apache24/htdocs/experiments/forms/index.html".
What you have to do to actually use the Apache server (assuming it's running, etc.) is go "http://localhost/experiments/forms/index.html" in the browser's address bar.
In mitigation I have up to now been using an "index.php" file and just changed to an "index.html" file. Bit of a gotcha, since with the former you are obliged to access it "properly" using localhost.
I had same situation in Spring MVC Application as it was declared as void, changing it to return String solved the issue
#PostMapping()
public void aPostMethod(#RequestBody( required = false) String body) throws IOException {
System.out.println("DoSome thing" + body);
}
To
#PostMapping()
public String aPostMethod(#RequestBody( required = false) String body) throws IOException {
System.out.println("DoSome thing" + body);
return "justReturn something";
}
Assuming you are working with javascript, you need to put a header in front of echoing your data:
header('Content-Type: application/json');
echo json_encode($response);
Make sure you're php server is running and that the php code is in the appropriate folder. I ran into this same issue if the php was not there. I also recommend putting your html in that same folder to prevent cross-origin errors when testing.
If that is not the issue, ensure that every SQL call is correct in the php, and that you are using current php standards... Php changes quickly, unlike html, css and Javascript, so some functions may be deprecated.
Also, I noticed that you may not be collecting your variable correctly, which can also cause this error. If you are sending variables via form, they need to be in proper format and sent either by POST or GET, based on your preference. For example, if I had a login page for a maze game:
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<form class="modal-content animate" method="post">
<div class="container">
<label><b>Username</b></label>
<input type="text" id="usernameinput" placeholder="Enter username" name="uname" required>
<label><b>Password</b></label>
<input type="password" id="passwordinput" placeholder="Enter Password" name="psw" required>
<button onclick="document.getElementById('id01').style.display='block'">Sign Up</button>
<button type="button" id="loginsubmit" onclick="myLogin(document.getElementById('usernameinput').value, document.getElementById('passwordinput').value)">Login</button>
</div>
</form>
JavaScript
function myLogin(username, password){
var datasend=("user="+username+"&pwd="+password);
$.ajax({
url: 'makeUserEntry.php',
type: 'POST',
data: datasend,
success: function(response, status) {
if(response=="Username or Password did not match"){
alert("Username or Password did not match");
}
if(response=="Connection Failure"){
alert("Connection Failure");
}
else{
localStorage.userid = response;
window.location.href = "./maze.html"
}
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
var response = xhr.responseText;
console.log(response);
var statusMessage = xhr.status + ' ' + xhr.statusText;
var message = 'Query failed, php script returned this status: ';
var message = message + statusMessage + ' response: ' + response;
alert(message);
}
}); // end ajax call
}
PHP
<?php
$MazeUser=$_POST['user'];
$MazePass=$_POST['pwd'];
//Connect to DB
$servername="127.0.0.1";
$username="root";
$password="password";
$dbname="infinitymaze";
//Create Connection
$conn = new MySQLi($servername, $username, $password, $dbname);
//Check connetion
if ($conn->connect_error){
die("Connection Failed: " . $conn->connect_error);
echo json_encode("Connection Failure");
}
$verifyUPmatchSQL=("SELECT * FROM mazeusers WHERE username LIKE '$MazeUser' and password LIKE '$MazePass'");
$result = $conn->query($verifyUPmatchSQL);
$num_rows = $result->num_rows;
if($num_rows>0){
$userIDSQL =("SELECT mazeuserid FROM mazeusers WHERE username LIKE '$MazeUser' and password LIKE '$MazePass'");
$userID = $conn->query($userIDSQL);
echo json_encode($userID);
}
else{
echo json_encode("Username or Password did not match");
}
$conn->close();
?>
It would help if you included the other parts of the code such as the html and JavaScript as I wouldn't have to give my own example like this. However, I hope these pointers help!

JSON not encoding as json or UTF-8?

I am having some headaches with JSON not returning as JSON. I get no errors, just no data. The browser shows the data in the response.
I know it's not returning as JSON because setting the dataType in the AJAX section causes it to display nothing. If I remove the dataType statement, it displays the data.
I've played around with encoding in the connection string, in the queries, as a header, and in the AJAX section all to no avail. My database is in UTF-8, general_ci.
AJAX:
$.ajax({
contentType: 'application/json; charset=UTF-8',
data: {'career' : $career},
dataType: 'json',
url: 'functions.php',
success: function(data) {
$("careerdata").html(data);
},
PHP:
if (isset($_GET['career'])) {
require_once 'config.php';
$query = $dbconnect->prepare("select * from jobs where Category = :category");
$query->bindParam(':category', $category);
$category = $_GET['career'];
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result);
$dbconnect = null;
return;
} else {
echo 'No career data found.';
};
Connection file:
try {
$dbconnect = new PDO("mysql:host=$host;dbname=$database", $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$dbconnect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
};
If any more info is needed, please let me know.
Working page is https://www.shardsmith.com/career.php and the actual query is https://www.shardsmith.com/functions.php (but it won't work independently because of the GET variable).
It seems that the MySQL (php) client does assume another client encoding than UTF-8. You can request the correct encoding using
$dbhconnect->exec("SET NAMES utf8");
directly after you connect to the database.
Alternatively, you can use PDO::MYSQL_ATTR_INIT_COMMAND (see http://php.net/manual/de/ref.pdo-mysql.php) in your connection config:
$dbconnect = new PDO("mysql:host=$host;dbname=$database", $user,
$pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
And be careful with unchecked frontend parameters: this is an open door for SQL injections. Either use a prepared statement like this:
$query = $dbconnect->prepare("select * from jobs where Category = :cat");
$query->execute(array(':cat' => $_GET['career']));
or escape the input paramerers first:
$cat = $dbhconn->quote($_GET['career']);
$res = dbhconnect->query("select * form jobs where Category = {$cat}")->fetchAll();
I ended up figuring it out myself. The json itself was fine. At some point I completely forgot about each-looping through the key-value pairs in order to actually display them. For example:
$.each(data, function(key,value) {
var $itemid = value.ItemID;
var $db = value.DB;
var $job = value.Job;
var $recipe = value.Recipe;
var $level_range = value.Level_Range;
var $level = value.Level;
var $grade = value.Grade;
var $rarity = value.Rarity;
var $complete = value.Complete;
$("careerdata table").append("<tr class=\"recipe\" id=\""+$recipe+"\">"
+"<td>"+$level+$grade+"</td>"
+"<td class=\"icon\"><img style=\"background: url(\'/images/items/"+$job+"/"+$itemid+".png\') 0 1px/42px 42px;\" src=\"/images/items/reflection.png\" /></td>"
+"<td class=\""+$rarity+"\">"+$recipe+"</td>"
+"<td><input class=\"complete\" type=\"checkbox\" value=\""+$complete+"\"></td>"
+"</tr>");
});

PDO, $_GET, and SELECTing from MySQL Database

So I'm working on a PHP Pastebin-esque project on my freetime to learn PHP and server management, and I've run into a LOT of issues, and I haven't been able to solve them. I decided to restart from sratch on my own with the information I've gathered so far, and threw this code together.
<?php
require 'connection.php';
$getid = $_GET["id"];
$sql = 'SELECT paste FROM pasteinfo WHERE id=:id';
$stmt = $con->prepare($sql);
$stmt->bind_param(':id', trim($_GET["id"], PDO::PARAM_INT));
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['paste'];
}
?>
What I'm trying to achieve with this code is a system where a user can type the id of whatever paste they're interested in viewing in the url and have it display the pasteinfo row, which is the row that holds the paste itself. The format they should have is viewpaste.php?id=(user input).
How can I fix this code? I would also greatly appreciate if you explain whatever code you might end up putting in the comments so I can learn from it. Thanks!
Try this;
connection.php
try{
$db = new PDO('mysql:host=localhost;dbname=database_name;charset=utf8mb4', 'database_username', 'database_password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch (PDOException $ex){
echo $ex->getMessage();return false;
}
function retrieve($query,$input) {
global $db;
$stmt = $db->prepare($query);
$stmt->execute($input);
$stmt->setFetchMode(PDO::FETCH_OBJ);
return $stmt;
}
To retrieve data, call the retrieve() function
Retrieval page, say display.php
require 'connection.php';
$getid = $_GET["id"];
$result=retrieve("SELECT paste FROM pasteinfo WHERE id=?",array($getid));
$row=$result->fetch();
//To get paste column of that id
$paste=$row->paste;
echo $paste;

Converting PHP query to PDO query

I have some php that is receiving a variable from jquery and querying the DB. I recently learned that I need to use PDO to prevent SQL Injections and such so I have been trying to convert my query to it. I am new at php anyway so this is turning out to be more difficult than I thought (even though all the articles I read looked quite straightforward)...The DB connection is working and 'name' is receiving the right value but it is not updating the page like it used to. I am guessing it has to do with my loop that contains the json_encode. Below is my old php and then my attempt at turning it into PDO format.
Old PHP:
$dbstylename = $_POST['name'];
$result = mysql_query("SELECT * FROM style where stylename like '$dbstylename'");
$array = mysql_fetch_row($result);
echo json_encode($array);
mysql_close($con);
?>
New PDO attempt:
<?php
include 'db.php';
try {
$dbConnection = new PDO('mysql:host=$dbhost;dbname=$dbhost;', $user, $pass);
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
#Prepare the query
$dbstylename = $_POST['name'];
$result = $dbConnection->prepare('SELECT * FROM style where stylename like :dbstylename');
#bind
$result->bindParam(':dbstylename', $dbstylename, PDO::PARAM_STR);
#execute
if ($result->execute(array($dbstylename))) {
while ($row = $result->fetch()) {
json_encode($row);
}
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
================UPDATE==============================
In addition to #MadaraUchiha great answer and follow up help I had to change my jQuery from this (which worked before PDO):
$.ajax({
url: '../test.php',
type: 'POST',
data: {'name' : target},
dataType: 'json',
success: function(data) {
var styleid = data[0];
var stylename = data[1];
var stylecss = data[2];
$('#codeTest').html("<b>id: </b><br />"+styleid+"<br /><b> stylename: </b><br />"+stylename+"<br /><b> stylecss: </b><br />"+stylecss);
}
});
To this:
$.ajax({
url: '../test.php',
type: 'POST',
data: {'name' : target},
dataType: 'json',
success: function(data) {
var styleid = data.styleid;
var stylename = data.stylename;
var stylecss = data.stylecss;
$('#codeTest').html("<b>id: </b><br />"+styleid+"<br /><b> stylename: </b><br />"+stylename+"<br /><b> stylecss: </b><br />"+stylecss);
}
});
Let me start with this, it's great that you're working on improving from the old ext/mysql to PDO. Well done!
Well, first, you don't need to check for errors! Since you've set PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION, an Exception would be thrown if there's an error! so your if statement on
if ($result->execute(array($dbstylename))) {
Is redundant.
Second, since you've already bound the parameter with bindParam, passing it again with the array is also redundant.
Lastly, if you only expect one result, you can drop the while loop, or even use $result->fetchAll(PDO::FETCH_ASSOC) to fetch all of the result into a single array.
Now for the real problem, you aren't echoing the result of json_encode(), like you used to in the first script (You're just calling it without doing anything with the result).
Corrected code, with all of the above taken into account:
<?php
include 'db.php';
try {
$dbConnection = new PDO('mysql:host=$dbhost;dbname=$dbhost;', $user, $pass);
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
#Prepare the query
$dbstylename = $_POST['name'];
$result = $dbConnection->prepare('SELECT * FROM style where stylename like :dbstylename');
#bind
$result->bindParam(':dbstylename', $dbstylename, PDO::PARAM_STR);
#execute
$result->execute();
$row = $result->fetch(PDO::FETCH_ASSOC);
echo json_encode($row);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
Other than that, you're PDO code is flawless, keep it up!
Also sequence of json encoded strings with array elements are not equal to hole json encoded array. Replace while loop with
echo json_encode($result->fetchAll());
In my original post I mentioned my jQuery change. However, I read up a bit more about PDO in the manual (specifically: http://www.php.net/manual/en/pdostatement.fetch.php) and found that if I changed $row = $result->fetch(PDO::FETCH_ASSOC); from #MadaraUchiha answer to $row = $result->fetch(PDO::FETCH_BOTH); I could keep my original jQuery that used the array/bracket notation.

Web server exited unexpectedly, restarting new instance

I do not have any other option, but to ask here again... and problem is killing me for the past 5 hours. I got button that call javascript function, and then javascript opens another php page and does insert in MySQL database.
HTML code:
<ul>
<li id="ConfirmButton" name="Insert" onclick="GetAllIDs()"><a>Potvrdi</a></li>
</ul>
Javascript code:
var request_type;
var browser = navigator.appName;
if (browser == "Microsoft Internet Explorer") {
request_type = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
request_type = new XMLHttpRequest();
}
var http = request_type;
http.open('get', 'insert.php?MatchID='+MatchID+'&TipID='+TipID+'&UserID=' + 1,true);
http.send(null);
PHP code:
include('config.php');
$matchID = $_GET['MatchID'];
$tipID = $_GET['TipID'];
$userID = $_GET['UserID'];
// Escape User Input to help prevent SQL Injection
$MatchID = mysql_real_escape_string($matchID);
$TipID = mysql_real_escape_string($tipID);
$UserID = mysql_real_escape_string($userID);
$insertTicket_sql = "INSERT INTO
betslips(DateTime,MatchID,TipID,UserID)
VALUES(".$MatchID.",".$TipID.",'".date("Y-m-d H:i:s")."',".$UserID.")";
$insertTick= mysql_query($insertTicket_sql) or die(mysql_error());
So after I run this code and I use break point I see in my php code all parameters I sent over forms normally and it's all there, but when I reach code $insertTick I get error
web server exited unexpectedly, restarting new instance.
Has anyone seen this problem before, and how can I deal with it?
Thanks
did anyone seen this problem before?
Not me, I dont use the mysql_* functions.
Your INSERT query parameter and values dont match.
So ive ported your example code to PDO perhaps its some interest:
<?php
//PDO Connect
try{
$con = new PDO('mysql:host=127.0.0.1;dbname=yourDB','root','password');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
}catch (Exception $e){
die('Cannot connect to database. Details:'.$e->getMessage());
}
//Check that the variables are set
if(isset($_GET['MatchID']) && isset($_GET['TipID']) && isset($_GET['UserID'])){
//Prepare your query
$query = $con->prepare("INSERT INTO betslips (DateTime,MatchID,TipID,UserID)
VALUES ('".date("Y-m-d H:i:s")."', :matchID, :tipID, :userID)");
//Bind your values with the placeholders
$query->bindParam(":matchID", $_GET['MatchID']);
$query->bindParam(":tipID", $_GET['TipID']);
$query->bindParam(":userID", $_GET['UserID']);
//Execute
$query->execute();
die('Success!');
}else{
die('Error: Parameter not set.');
}
?>

Categories