I'm making a simple login test and the code returns the json response when the fields are empty,but not when the login fails or succeds, like:
Empty Fields - OK
Login Succeded - nope
Login failed - nope
Request:
var loader = $('#trabalhando');
$(function() {
$('form').submit(function(e) {
loader.fadeIn("slow");
e.preventDefault();
$.ajax({
url: 'login.php',
data: $(this).serialize(),
method: 'post',
dataType: 'JSON',
success: function(data){
loader.fadeOut("slow");
console.log(data);
alert(data.resp);
},
error: function(data) {
alert(':(');
loader.fadeOut("slow");
console.log(data);
}
});
});
});
Response:
<?php
header('Content-Type: application/json');
if (isset($_POST['cpf']) && isset($_POST['pass']) && $_POST['cpf'] != "" && $_POST['pass'] != "") {
$cpf = $_POST['cpf'];
$passw = sha1(strrev(md5($_POST['pass'])));
include 'config.php';
$sql = "SELECT * FROM users WHERE cpf = :cp AND passwd = :pw";
$chec = $db->prepare($sql);
$chec->bindParam('cp', $cpf, PDO::PARAM_STR);
$chec->bindParam('pw', $passw, PDO::PARAM_STR);
$chec->execute();
if ($chec->rowCount() > 0) {
echo json_encode(array('resp' => 'nice'));
} else {
echo json_encode(array('resp' => 'nope'));
}
} else {
echo json_encode(array('resp' => 'fields'));
}
?>
Edit: updated the code
You are not binding your parameters properly, so you probably have a PDO error that you're not handling. Change:
$chec->bindParam('cp', $cpf, PDO::PARAM_STR);
$chec->bindParam('pw', $passw, PDO::PARAM_STR);
To:
// notice the colon : in front of var names, so it matches the placeholders!
$chec->bindParam(':cp', $cpf, PDO::PARAM_STR);
$chec->bindParam(':pw', $passw, PDO::PARAM_STR);
In general, database, file and remote server operations (FTP, HTTP, SSH...) are very finicky so when you rely on these, always error check! You should factor out your queries into a specialized function that does proper error checking.
/**
* #param PDO $db The PDO object with which to perform queries
* #param string $sql raw SQL (eg: "select * from t where a = :param" )
* #param array $params Array of parameter names and values eg: [':param' => 'value']
* #param string $error Will be filled with the error details if the DB operations fail
* #return false|PDOStatement FALSE on error, or the statement on success
*/
function query(PDO $db, $sql, array $params, &$error){
try{
// error check every step!
if(!$stmt = $db->prepare($sql)) throw new Exception($db->errorInfo()[2]);
if(!$stmt->execute($params)) throw new Exception($stmt->errorInfo()[2]);
return $stmt; // return the $stmt for further processing
}catch (Exception $e){
$error = $e->getMessage();
return false;
}
}
Now you can perform your queries much more simply:
$stmt = query($db, $sql, $params, $error);
// decide what to do on failure
if(!$stmt) die($error);
// now it's safe to use $stmt to fetch results, count rows...
Update
You said:
the fail is exactaly the same as the success, loader out and alert, but this time with a sad face on the alert
That's expected. success in the Ajax call just means that the server responded normally. It doesn't say anything about what is inside the json string. If you want to trigger the error Ajax callback, your server will need to set an error HTTP response code like this:
http_response_code(401);
echo json_encode(array('resp' => 'nope'));
Update 2
To find out the details of the error triggered by the Ajax call, modify the callback and examine the results:
error: function(jqXHR, textStatus, errorThrown){
console.log('textStatus: ' + textStatus);
console.log('errorThrown: ' + errorThrown);
}
Maybe your server is sending other content along with the JSON that is corrupting the output. Try closing the buffer at the top of your script, and exiting immediately with your echo:
<?php
ob_end_clean(); // at top of script
//try echoing this way
die(json_encode(array('resp' => 'nice')));
die(json_encode(array('resp' => 'nope')));
It would seem like there is either a problem in your config.php file, or with your sql statement
try putting your code into a try catch, and then returning the error as json:
<?php
header('Content-Type: application/json');
if (isset($_POST['cpf']) && isset($_POST['pass']) && $_POST['cpf'] != "" && $_POST['pass'] != "")
{
$cpf = $_POST['cpf'];
$passw = sha1(strrev(md5($_POST['pass'])));
try
{
include 'config.php';
$sql = "SELECT * FROM users WHERE cpf = :cp AND passwd = :pw";
$chec = $db->prepare($sql);
$chec->bindParam(':cp', $cpf, PDO::PARAM_STR);
$chec->bindParam(':pw', $passw, PDO::PARAM_STR);
$chec->execute();
if ($chec->rowCount() > 0)
{
echo json_encode(array('resp' => 'nice'));
}
else
{
echo json_encode(array('resp' => 'nope'));
}
}
catch(Exception $e)
{
echo json_encode($e->getMessage());
}
}
else
{
echo json_encode(array('resp' => 'fields'));
}
?>
Edit: incorporates #BeetleJuice's fix
Related
I've tried to verify if an email already exists in the database.
The same system worked perfectly if I tried to verify a username.
I'm using AJAX and PHP.
This is the file that gets the $_POST variables.
<?php
require_once 'Config.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = $_POST['email'];
$password = $_POST['password'];
if (!empty($password) and !empty($email)) {
$notEmpty = true;
include 'validate.php';
if($notEmpty == true and validateEmail($email) == true){
$password = md5($password);
$stmt = $link->prepare("INSERT INTO `Users`(`user_password`, `user_email`) VALUES (?,?)");
$stmt->bind_param("ss",$email,$password);
$stmt->execute();
}
}else{
$notEmpty == false;
}
}
?>
and this is the file that verifies the email doesn't exist on the database.
function validateEmail($user_email){
include '../Backend/Config.php';
$sql = "SELECT `user_password`, `user_email` FROM `Users` WHERE `user_email` = ?";
$stmt = $link->prepare($sql);
$stmt->bind_param("s",$user_email);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$row = $result->fetch_assoc();
if ($result->num_rows > 0) {
echo 1;
return false;
}
else{
// echo json_encode(array('status' => 'OK'));
echo 0;
return true;
}
}
Js code(ajax):
$('#form').submit(function(e) {
//Don't refresh the page
e.preventDefault();
//Collecting data for the server call
post_data = {
'email' : $('input[name=email]').val(),
'password': $('input[name=password]').val()
};
//AJAX server call to signup.php,which calls validate.php
$.ajax({
method: "POST",
url: "../Backend/signup.php",
data: post_data
})
//Server response and setting the input values to ""
.then(function( msg ) {
if(msg == 0){
console.log("Success, user data inserted. Code: " + msg);
}
//Failed
if(msg == 1){
console.log("Inserting failed. Error code:" + msg);
document.getElementById("error").innerHTML = "This email already exists.";
}
$('input[name=email]').val("");
$('input[name=password]').val("");
});
});
It inserts it anyway, what is the problem here?
If you immediately call num_rows() after executing a prepared statement, it will usually return 0 as it has no way to know how many rows are in the result set, since the result set is not saved in memory yet. You must first call store_result() to buffer the results so that the subsequent call to num_rows() will contain the correct results.
This is explained in the "User Notes" section at the bottom of the PHP documentation for num_rows().
I've been pounding on this for a few days, so time to ask for help. I'm trying to use Ajax/PHP/MySQL to show only a subset of a table based on the user's selections in dropdown. The PHP code calls a MySQL stored procedure. The call I'm constructing is right, and if I echo it out and then copy it and run it as is from the phpMyAdmin MySQL console, I get exactly the results I expect. But from the PHP code that's called by Ajax, I instead see this result (echoed in Firebug, after I JSON_encode it):
{"current_field":null,"field_count":null,"lengths":null,"num_rows":null,"type":null}
The relevant part of the page itself is:
<script>
function updateActions() {
var results = '';
var success = false;
var selectedIssues = getIssues();
var fnargs = "GetActions|'" + selectedIssues + "'";
$.ajax({
url: 'retrievedata.php',
type: "POST",
async:false,
data: {"functionname":"getactions", "arguments":fnargs},
dataType: "JSON",
complete: function (obj, textStatus) {
if( (obj.error != '') ) {
alert(JSON.parse(obj));
$("#testresult").text(textStatus);
}
else {
$("#testresult").text("Error");
// console.log(obj.error);
}
success = true;
},
error: function(textStatus, errorThrown) {
success = false;
$("#testresult").text('Error occurred: '.textStatus);
}
})
};
</script>
Two notes. First, the getIssues script it calls returns the expected value. Second, I haven't actually written the right code to process the result once I get it. Still trying to get the right result back to the page.
Page retrievedata.php looks like this:
<?php
include "dbfns.php";
$aResult = array();
$returnval = 'before tests';
if( !isset($_POST['functionname']) ) {
$aResult['error'] = 'No function name!';
}
if( !isset($_POST['arguments']) ) {
$aResult['error'] = 'No function arguments!';
}
if( !isset($aResult['error']) ) {
$functionName = $_POST['functionname'];
$argsarray = explode('|', $_POST['arguments']);
$argcount = count($argsarray);
$returnval = 'before switch';
switch($_POST['functionname']) {
case 'getactions':
if( $argcount < 2 ) {
$returnval = 'too few arguments';
}
else {
$returnval = 'in else';
$returnval = getactions($argsarray[0], $argsarray[1]);
}
break;
default:
$returnval = 'function not found';
break;
}
}
return $returnval;
?>
The relevant portions of dbfns.php (with identifying data and credentials removed, of course) are:
<?php
function connect2db() {
$hostname = "XXX";
$username = "XXX";
$password = "XXX";
$database = "XXX";
$conn = mysqli_connect($hostname, $username, $password, $database);
if( $conn == false ) {
echo "Connection could not be established.<br />";
die( print_r( myslqi_connect_error(), true));
}
return $conn;
}
function getactions($spname, $params, $errorstring = 'Unable to retrieve requested data') {
$conn = connect2db();
$query = "CALL ".$spname."(".$params.")";
echo $query."\r\n";
$result = mysqli_query($conn, $query);
if ($result == false) {
$errmessage = mysqli_error($conn);
$allresult = $errmessage;
echo $errmessage;
die( print_r( mysql_error(), true));
}
else {
echo "In else case\r\n";
$allresult = json_encode($result);
}
echo $allresult;
return $allresult;
}
?>
I have another PHP function in retrievedata that calls the same MySQL SP, but not from Ajax and it returns the expected result, so I'm pretty confident that the SP does what I expect.
I think there must be something I don't get about how to do all this from Ajax.
Edit: Just want to add that I've tried success rather than complete in the ajax call, and _GET rather than _POST. No change in results.
That looks like it's serializing the result object from mysqli_query(). I'm not sure what it does internally, but it may not return the actual resulting data until you enumerate/fetch the results.
See this example on one way to convert it to a JSON result.
in the below code I am passing ipdno as a param, and then I am getting the response from server for that this is my code.
php
$('#print').click(function(){
var ipdNo = $('#hid_ipd_id').val();
var param = "ipdNo="+ipdNo;
alert("Param: "+param);
$.ajax({
url: "ipd_bill_print.php", //The url where the server req would we made.
async: true,
type: "POST", //The type which you want to use: GET/POST
data: param, //The variables which are going.
dataType: "html",
success: function(data){
//alert("Result: "+data+"\nRefreshing page... ");
if(data=='success'){
alert("Record updated succcessfully!");
location.reload(true);
}else{
alert("Record could not be updated!");
}
}
});
});
In this code I want to indicate the success when there are some rows, otherwise it should indicate the failure.
ipd_bill_print.php
<?php
require_once("db/include.php");
$ipd_no = $_POST['ipd_no'];
$token = "Empty";
try{
$dbh = getConnection();
$flag = true;
$sql = "SELECT ipd_reg_no
FROM ipd_bill
WHERE ipd_reg_no = ?";
$sth = $dbh->prepare($sql);
$sth->bindParam(1,$ipd_no);
$row = $sth->fetch(PDO::FETCH_ASSOC);
echo $row;
if($row >==0)
$flag = false;
if($flag)
echo "success";
else{
$dbh->rollback();
echo "fail";
}
//echo "\n FLAG: $flag \n";
$dbh->commit();
}catch(PDOException $e){
print($e);
try{
$dbh->rollback();
}catch(PDOException $e){
die($e->getMessage());
}
}
else{ //if ends here..
echo "Outside if...";
}
In JavaScript code you have provided the ipdNo as the AJAX parameter, but in the PHP file you try to access an undefined key named ipd_no through $_POST. I also recommend to change the AJAX dataType from "html" to the "text", because you are just echoing some plain text in the PHP file.
In the PHP file, in order to use the PDO::commit or PDO::rollBack, you need to first invoke PDO::beginTransaction.
Before calling PDOStatement::fetch, you need to execute your statement through PDOStatement::execute.
In the if statement you need to change the syntactically wrong statement of $row >==0 to something like $row!==false && count($row)>0. Finally, consider that you don't have any matching if statement for you last else statement, where you commented //if ends here.., However; It just maybe not visible in you code snippet.
In addition, you are better to always check the returning result from any method call or function invoke.
I have a page powered with PHP and AJAX, when a user submits one of my forms I check for errors in the getData.php script.
This example is if the user submits the form with the default value I'm wondering if there is a way to pass back those errors or trigger the AJAX to fire an error if the user commits on or if I need to do error handling before the AJAX call
$('form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'post',
url: '_ajax/addData.php',
data: $('form').serialize(),
success: function () {
$("input").val('Info Here');
$("form").hide();
reloadInfo();
}
});
});
PHP
$info = $_POST['info'];
if($info != 'Info Here') {
$conn = mysqli_connect();
$query = "INSERT INTO leads VALUES(0, '$companyName', 1, NOW(), 3)";
$result = mysqli_query($conn, $query) or die ('Error Could Not Query');
$id = mysqli_insert_id($result);
header("Location: http://localhost/manage/info.php?id=$id");
mysqli_close($conn);
} else {
echo '<script>alert("Error");/script>'
}
PART 2
Javascript:
success: function (data) {
if(!data.success) alert(data.errors); // Just for demonstration purposes
$("input").val(data.errors);
$("form").hide();
reloadInfo();
}
PHP:
header("Content-Type: text/json; charset=utf8");
if($info != 'Info Here') {
$conn = mysqli_connect();
$query = "INSERT INTO leads VALUES(0, '$companyName', 1, NOW(), 3)";
$result = mysqli_query($conn, $query) or die ('Error Could Not Query');
$id = mysqli_insert_id($result);
header("Location: http://localhost/manage/info.php?id=$id");
mysqli_close($conn);
} else {
echo json_encode(array("success" => false,"error" => "Some random error happened"));
}
There are several issues with your code:
$companyName is not defined anywhere
You should use prepared statements instead of throwing data into your SQL query
You should put your entire AJAX PHP code inside one try..catch block
At the end of your AJAX PHP code, write something some JSON
I don't get why you are trying to redirect an AJAX call, usually you'd tell the client to do the redirect.
For example, I would write your PHP code like so:
try {
if(!isset($_POST['info']))
throw new Exception('Post info was not set');
$info = $_POST['info'];
if($info == 'Info Here')
throw new Exception('Invalid value for info');
$conn = mysqli_connect();
if(!$conn)
throw new Exception('Database connection failure');
$companyName = '?????';
$query = 'INSERT INTO leads VALUES(0, ?, 1, NOW(), 3)';
$stmt = mysqli_prepare($query);
if(!$stmt)
throw new Exception('Could not query database');
mysqli_stmt_bind_param($stmt, 's', $companyName);
mysqli_stmt_close($stmt);
$id = mysqli_stmt_insert_id($stmt);
mysqli_close($conn);
echo json_encode(array(
'success' => true,
'new_id' => $id,
));
}catch(Exception $ex){
echo json_encode(array(
'success' => false,
'reason' => $ex->getMessage(),
));
}
Alternate Approach
HTML: place this paragraph tag where you want to display an error.
<p id="display_error"></p>
Ajax success call: change your Ajax code bit like...
success: function(response)
{
if((response !== "") && ($.isNumeric(response))) {
{
//redirect in ajax success
location.href = "http://localhost/manage/info.php?id="+ response;
}
else {
//this will display the custom error.
$("#display_error").html("<p>" + response + "</p>"); //output: something went wrong!
}
}
PHP
$info = $_POST['info'];
if($info != 'Info Here') {
$conn = mysqli_connect();
$query = "INSERT INTO leads VALUES(0, '$companyName', 1, NOW(), 3)";
$result = mysqli_query($conn, $query) or die ('Error Could Not Query');
$id = mysqli_insert_id($result);
echo $id;
//header("Location: http://localhost/manage/info.php?id=$id");
mysqli_close($conn);
} else {
echo 'something went wrong!';
}
How to POST values from submit and check if they exist in mysql?
And what do I have to type in my .php file?
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$('#login').submit(function(){
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
});
}
function getData(sendData) {
$.ajax({
type: 'POST',
url: 'http://www.url.php',
data: { 'username': username, 'password': password },
success: afhandeling,
});
}
Call ajax like this:
jQuery.ajax({
type: "POST",
url: "http://www.url.php",
data: { username:username,password:password },
success: function( data )
{
}
});
and in ajax file:
if (isset($_POST['username']) && isset($_Post['password']))
{
$query = "SELECT * FROM users WHERE username='".$_POST['username']."' AND password=".$_POST['password'];
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if($row)
{
echo 'login';
}
else
{
echo "error";
}
}
I think the URL has to be a local one, i.e. "/projects/blindchat/login.php".
On that page you can write something like this:
if (isset($_POST['username']) && isset($_POST['password'])) {
// MYSQL query:
SELECT 1 FROM users WHERE username = ? AND password = ?
}
Remember you have to escape the variables first to prevent SQL injection.
In login.php page you need to do something like this:
if(isset($_POST['username']) && isset($_Post['password'])) {
$q = "SELECT * FROM users WHERE username=$_POST['username'] AND password=$_POST['password']"
$r = mysql_query($q);
if(mysql_num_rows($r)==1) //Do Login
else echo "ERROR";
}
You submit the form which launches your ajax script that sends the data over to your PHP file that handles the input and gives you an answer.
Use PDO or MySqLi. Mysql is depreceated and no longer supported. My example below uses the PDO method.
Your PHP should look something like this(this is untested code, so there might be typos):
<?php
$username = $_POST['username'];
$password = $_POST['password'];
if (!empty($username) && !empty($password)) {
// We create a PDO connection to our database
$con = new PDO("mysql:host=yourhost;dbname=yourdatabase", "username", "password");
// We prepare our query, this effectively prevents sql injection
$query = $con->prepare("SELECT * FROM table WHERE username=:username AND password=:password LIMIT 1");
// We bind our $_POST values to the placeholders in our query
$query->bindValue(":username", $username, PDO::PARAM_STR);
$query->bindValue(":password", $password, PDO::PARAM_STR);
// We execute our query
$query->execute();
$result = $query->fetch(); // Grab the matches our query produced
// Here we check if we found a match in our DB
if (!empty($result)) {
echo "Matches were found";
} else {
echo "No matches found";
}
} else {
echo "Please fill out all fields";
}
?>
As for getting a reply from your AJAX script you can simply alert the response or show it as you please.
success: function(data) {
alert(data);
}