How to get JS to read the code thrown by PHP die - php

My JS function expects a certain return from the PHP code in case of a failure.
function showResult(data)
{
if (data == 'save_failed') {
document.getElementById('result').innerHTML = 'Unfortunately, we were not able to save your information. Please contact an admin.';
return false;
} else {
$("#notify").clearForm().clearFields().resetForm();
document.getElementById('result').innerHTML = 'Thank you for signing up with us.';
return false;
}
}
This works fin when I echo 'save_failed'; in case of an explicit error, but it does not work in the case of die statements, such as this one:
mysql_connect("host", "user", "pass") or die('save_failed');
I entered a wrong hostname but the JS function did not receive the 'save_failed' return.
PHP script:
if (!(empty($_POST['name']) && empty($_POST['email'])))
{
//sanitizing inputs for MySQL insertion
$name = mysql_real_escape_string($_POST['name']);
$email = mysql_real_escape_string($_POST['email']);
//connecting to db
mysql_connect("host", "user", "pass") or die('save_failed');
mysql_select_db("table") or die('save_failed');
//inserting into table
mysql_query("INSERT INTO notify (name, email) VALUES('" . $name . "', '" . $email . "' ) ")
or die('save_failed');
}
else
{
echo 'save_failed';
}

Even though die("save_failed") will output "save_failed", it will not stop any previous output in your script from being sent.
Ensure that if you go to the script yourself then you are receiving just "save_failed" in the page source and no erroneous characters

I would propose another strategy in dealing with errors.
Use output buffering to ensure no data will be send to client (eg. the beginning of a HTML-Document)
Start using Exceptions. They represent fatal errors, but with the ability to determine the exact line and parameters the error occurred.
The Browser tries to evaluate the type of response based on the content type header. If you want it to display simple text use
header('Content-Type: text/plain');
Use a global Exception handler, to transform the messages the way you like.
Works for me! Most servers have enough power today to use these, little more advanced methods.

It is not a good idea to use die to pass some information to the page. Normally, there will be other data in the response string.
An easier way is to embed PHP code in your JS code. An example will be like this:
<script type="text/javascript">
data = "<?php echo('Save Failed'); ?>";
</script>

Related

Ajax rejecting JSON created by PHP with "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data"

I have a page that makes an Ajax call, which retrieves, JSON encodes and returns data from a database. The page was working, but in the midst of making some changes, it's now failing. (Should note that I'm working with a test site and test database as I make the changes.)
The errorThrown parameter of the error case shows me "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data."
Here's the function with the Ajax call. (I've enhanced what's in the alerts for debugging purposes. I'll rip that back out once things are working.)
function acceptConfCode(){
var emailAddr = $('#email').val();
var confCode = $('#confcode').val();
var fnargs = "ConfirmCode|'" + emailAddr + "'," + confCode ;
$.ajax({
url: 'retrievedata.php',
type: "POST",
async: true,
data: {"functionname":"confirmcode","arguments":fnargs},
dataType: "JSON",
success: function (obj) {
if (!obj.error) {
$('#logininfo').hide();
$('#emailrow').hide();
$('#coderow').hide();
$('#reviewactions').show();
updateListOfActions(obj);
}
else {
success = false;
alert("The confirmation code you entered didn't match or has expired. Please try again. Type 1");
}
},
error: function(xhr, textStatus, errorThrown) {
success = false;
alert("The confirmation code you entered didn't match or has expired. Please try again. Type 2. textStatus = " + textStatus + "; errorThrown = " + errorThrown);
}
});
};
The retrievedata PHP page is mostly a CASE statement. The relevant case is this (again with added debugging code):
case 'confirmcode':
if ($argcount <2) {
$returnval = 'too few arguments';
}
else {
$returnval = confirmcode($argsarray[0], $argsarray[1]);
echo "Back from confirmcode\r\n";
var_dump($returnval);
}
break;
At the end of the page, it returns $returnval.
The key action is in the confirmcode function, which runs a MySQL SP to confirm that the user has a valid email and code, and then calls another function to retrieve the actual data. Here's confirmcode. As the commented out pieces show, I've checked results along the way and I am getting what I expect and it's getting JSON encoded; I've ran the encoded JSON back through JSON_decode() in testing to confirm it was decodable.
function confirmcode($spname, $params, $errorstring = 'Unable to send requested data') {
$conn = connect2db();
$query = "SELECT ".$spname."(".$params.") as result";
//echo $query."\r\n";
$result = mysqli_query($conn, $query);
$allresult = "unknown";
if (!$result) {
$errmessage = mysqli_error($conn);
$allresult = $errmessage;
$allresult = json_encode($allresult);
//echo $errmessage;
die( print_r( mysql_error(), true));
}
else {
//echo "In else case\r\n";
//retrieve list of action submissions
$resultobj = mysqli_fetch_object($result);
if ($resultobj->result == 1) {
//echo "In success subcase\r\n";
$allresult = getsubmissions($conn);
//echo "After getsubmissions\r\n";
//print_r($allresult);
}
else {
//echo "In failure subcase\r\n";
$result = array('error'=>true);
$allresult = $result;
}
//echo "Before JSON encode\r\n";
$finalresult = json_encode($allresult);
//echo "After JSON encode\r\n";
//echo json_last_error_msg()."\r\n";
//var_dump($finalresult);
$allresult = $finalresult;
return $allresult;
}
}
Finally, here's getsubmissions, again with some debugging code:
function getsubmissions($conn) {
echo "In getsubmissions\r\n";
$query = "CALL GetSubmissions()";
$submissions = mysqli_query($conn, $query);
if (!$submissions) {
echo "In failure case\r\n";
$errmessage = mysqli_error($conn);
$allresult = $errmessage;
$allresult = json_encode($allresult);
echo $errmessage;
die( print_r( mysql_error(), true));
}
else {
echo "In success case\r\n";
$rows = array();
while ($row = mysqli_fetch_assoc($submissions)) {
$rows[] = $row;
}
$allresult = $rows; //json_encode($rows);
}
//print_r( $allresult);
return $allresult;
}
What's really weird is I have another page in the site that retrieves almost exactly the same data through an Ajax call with no problem. The one that works contains a few additional fields, and doesn't contain two date fields that are in this result.
In addition, the live version of the site retrieves exactly the same data as here, except from the live database rather than the test database, and it works. While this version of the code has some additional things in it, the only differences in the relevant portions are the debugging items. (That is, I've made changes, but not in the part I'm showing here.) That leads me to think this may be an issue with the test data rather than with the code, but then why does the other page work in the test site?
UPDATE: To try to see whether this is a data problem, I cut the test data way down so that it's only returning a couple of records. I grabbed the generated JSON and ran it through JSONLint.COM and it says it's valid.
UPDATE 2: With the reduced data set, here's the string that's returned from retrievedata.php to the Ajax call:
[{"ActionSource":"https:\/\/www.voterheads.com\/","ActionSourceName":"Wall-of-us","Title":"Sign up to get notified about local meetings","Description":"Sign up at www.voterheads.com to get notified about local meetings. When we did, using the free option, this is what happened: a page popped up with a list of municipality meetings in the zip code we entered. We clicked on one of the meetings, and presto! -- instant access to the date, time, location, and agenda of the meeting. Pretty awesome.","StartDate":null,"EndDate":null,"UrgencyDesc":"Anytime","UrgencyColor":"#00FF00","UrgOrder":"5","DurationDesc":"Ongoing","DurOrder":"6","CostDesc":"Free","CostOrder":"1","Issues":"Advocacy","Types":"Learn","States":"ALL","iID":"20"},{"ActionSource":"https:\/\/actionnetwork.org\/forms\/ctrl-alt-right-delete-newsletter-2","ActionSourceName":"Ctrl Alt Right Delete","Title":"Sign up to learn what the \"alt-right\" is up to","Description":"Understand how the right operates online. Sign up for a weekly newsletter.","StartDate":null,"EndDate":null,"UrgencyDesc":"Anytime","UrgencyColor":"#00FF00","UrgOrder":"5","DurationDesc":"An hour or less","DurOrder":"2","CostDesc":"Free","CostOrder":"1","Issues":"Advocacy","Types":"Learn","States":"ALL","iID":"25"}]
As noted above, JSONLint.COM says it's valid JSON.
I've found a solution, though I'm just starting to understand why it works. On retrievedata.php, I uncommented:
echo $returnval;
just before the Return statement and it's working again. So I think the issue is that since retrievedata is a page, but not a function, the return statement didn't actually return anything. I needed code to actually return the JSON-encoded string.

Code to validate an email address always fails

I have edited some code I found on 'ye old internet (http://net.tutsplus.com/tutorials/other/using-htaccess-files-for-pretty-urls/). I have not gotten my variation of the code to work properly. My edited versions requests another input called "pages" from index.php. Pages is put into the database along with $url and $short. Pages goes into a pages field in the database which has a varchar value. Pages is later called in serve.php for a javascript purpose. In the code below I have noted where I think the problem occurs. If your interested in my faulty code, stay tuned; I have yet to edit the other files.
I am starting to think the error could be happening in MYSQL because I almost always receive the first $html error of "Error: invalid url"
<?php
require("./db_config.php");
$url = $_REQUEST['url'];
$pages = $_REQUEST['pages'];
//this seems to be where the errors are occuring
if(!preg_match("/^[a-zA-Z]+[:\/\/]+[A-Za-z0-9\-_]+\\.+[A-Za-z0-9\.\/%&=\?\-_]+$/i", $url)) {
$html = "Error: invalid URL";
} else {
$db = mysql_connect($host, $username, $password);
$short = substr(md5(time().$url), 0, 5);
if(mysql_query("INSERT INTO `".$database."`.`url_redirects` (`short`, `url`, `pages`) VALUES ('".$short."', '".$url."', '".$pages."');", $db)) {
$html = "Your short URL is<br />www.srprsr.com/".$short;
} else {
$html = "Error: cannot find database";
}
mysql_close($db);
}
?>
Consider filter_var($url, FILTER_VALIDATE_URL) instead of a regular expression.
http://php.net/filter.examples.validation
http://php.net/filter.filters.validate

Jquery Validation Remote Check Unique Not Working

I wanted to post this online because I have been searching for days on this JQuery Remote validation issue. I cannot get it to work. I think my PHP code is correct as I have test the URL with a query in the URL and it returns false and true depending on with the recordset count is one or more
This is my Jquery Validate Code:
// validate form and submit
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j("#myform").validate({
rules: {
ord_ref: {
required: true,
minlength: 12,
remote: "check_ord_ref.php"
},
messages: {
ord_ref: {
remote: "Order Number Does Not Exist"
}
}
}
});
});
This is my PHP code for the remote page "check_ord_ref.php"
$colname_rscheck_ord_ref = "-1";
if (isset($_GET['ord_ref'])) {
$colname_rscheck_ord_ref = (get_magic_quotes_gpc()) ? $_GET['ord_ref'] : addslashes($_GET['ord_ref']);
}
mysql_select_db($database_conn, $conn);
$query_rscheck_ord_ref = sprintf("SELECT ref_ord FROM orders WHERE ref_ord = '%s'", $colname_rscheck_ord_ref);
$rscheck_ord_ref = mysql_query($query_rscheck_ord_ref, $conn) or die(mysql_error());
$row_rscheck_ord_ref = mysql_fetch_assoc($rscheck_ord_ref);
$totalRows_rscheck_ord_ref = mysql_num_rows($rscheck_ord_ref);
if($totalRows_rscheck_ord_ref < 0){
$valid = 'false';
} else {
$valid = 'true';
}
echo $valid;
Please someone can you help solve the puzzle for myself and anyone else having issues
Using JQuery 1.5.2min
Validates OK without remote function
Ok, so I'm no PHP expert, but I do know that jQuery Validate expects the following result from a remote validation method:
The response is evaluated as JSON and must be true for valid elements,
and can be any false, undefined or null for invalid elements
Sending down "true" or "false" (note the quotation marks) is going to result in the value being parsed as the error message instead of being evaluated as a boolean primitive.
Back to the PHP part, I think you should probably use json_encode with a boolean primitive. I'm not quite sure the way to do this in PHP, but I believe it would be something like this:
$colname_rscheck_ord_ref = "-1";
if (isset($_GET['ord_ref'])) {
$colname_rscheck_ord_ref = (get_magic_quotes_gpc()) ? $_GET['ord_ref'] : addslashes($_GET['ord_ref']);
}
mysql_select_db($database_conn, $conn);
$query_rscheck_ord_ref = sprintf("SELECT ref_ord FROM orders WHERE ref_ord = '%s'", $colname_rscheck_ord_ref);
$rscheck_ord_ref = mysql_query($query_rscheck_ord_ref, $conn) or die(mysql_error());
$row_rscheck_ord_ref = mysql_fetch_assoc($rscheck_ord_ref);
$totalRows_rscheck_ord_ref = mysql_num_rows($rscheck_ord_ref);
if($totalRows_rscheck_ord_ref < 0){
$valid = false; // <-- Note the use of a boolean primitive.
} else {
$valid = true;
}
echo json_encode($valid);
This problem seems to be plaguing remote validation scripters and the jQuery documentation on the matter is clearly lacking.
I notice you are using jQuery 1.5.2: from what I understand (and found from experience) you must use the jQuery callback that is sent to the remote script with $_REQUEST with versions after 1.4, AND jQuery is expecting "true" or "false" as a STRING. Here is an example, confirmed working on multiple forms (I'm using jQuery 1.7.1):
if($totalRows_rscheck_ord_ref < 0){
header('Content-type: application/json');
$valid = 'false'; // <---yes, Validate is expecting a string
$result = $_REQUEST['callback'].'('.$check.')';
echo $result;
} else {
header('Content-type: application/json');
$valid = 'true'; // <---yes, Validate is expecting a string
$result = $_REQUEST['callback'].'('.$check.')';
echo $result;
}
I found this answer here (in the answers section), randomly, and have since stopped pulling out my hair. Hope this helps someone.
To add to Andrew Whitaker's response above, I must stress that you are sure that the response is strictly JSON and that there are no other content types being returned. I was having the same issue with my script, and everything appeared to be set properly - including using json_encode(). After some troubleshooting with Firebug's NET tab, I was able to determine that PHP notices were being sent back to the browser converting the data from JSON to text/html. After I turned the errors off, all was well.
//check_validate.php
<?php
// some logic here
echo json_encode(true);
?>

500 Server Error in PHP

If you visit my script "page.php" in the URL. A 500 Error appears. If you submit through a form it works.
<?php
## send forgot pass
$a=$_REQUEST['email_address'];
include("template.funcs.php");
$yz = mysql_connect("","","");
mysql_select_db("", $yz);
$b=mysql_real_escape_string($a);
$d=mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".$b."'");
if (mysql_affected_rows()==0){
header("Location: cart.php?pass=notsent");
}else{
send_registration_email($b,'','','');
header("Location: cart.php?pass=sent");
}
mysql_close($yz);
?>
A 500 error is a server side error, and I've found the best way to fix this is to check the logs on your server.
On the other hand, looking at your code, you may not have defined $_REQUEST['email_address']. Try this:
<?php
if (isset($_REQUEST['email_address'])) {
## send forgot pass
$a=$_REQUEST['email_address'];
include("template.funcs.php");
$yz = mysql_connect("","","");
mysql_select_db("", $yz);
$b=mysql_real_escape_string($a);
$d=mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".$b."'");
if (mysql_affected_rows()==0){
header("Location: cart.php?pass=notsent");
}else{
send_registration_email($b,'','','');
header("Location: cart.php?pass=sent");
}
mysql_close($yz);
}
?>
I would assume this has something to do with $_REQUEST['email_address'] not being defined on normal page load...
Use useful variable names. Use indenting appropriately. Only escape input before inserting it into your database. Group often used functionality in functions. Don't use $_REQUEST. Fail fast. A few hints which massively increase your code quality.
Now have a look at this:
include("template.funcs.php");
function Redirect($to)
{
header("Location: " . $to);
exit();
}
if ($_SERVER['REQUEST_METHOD' != "POST" || !isset($_POST['email_address']))
{
Redirect("cart.php?pass=notsent");
// or redirect to your "forgot password" form
}
$mailAddress = $_POST['email_address'];
$dbconn = mysql_connect("","","");
mysql_select_db("", $dbconn);
mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".mysql_real_escape_string($mailAddress)."'");
if (mysql_affected_rows() == 0)
{
Redirect("cart.php?pass=notsent");
}
send_registration_email($mailAddress,'','','');
Redirect("cart.php?pass=sent");

dojo.xhrGet Returns PHP Source Code, not Text Response

The code below calls a PHP file for a true or false text result using the dojo.xhrGet method. When I load the PHP file by itself (replacing the $variable = $_GET("passedVariable"); with a hard-wired value), it correctly generates a "true" or "false" in my browser window. However, when I run the call in my larger web app, it returns the PHP source code instead of the results of my database query. Using JQuery's .get() method, I receive a XML object.
Here's the Javascript...
dojo.xhrGet({
url: "php/check.php",
handleAs: "text",
content: {guid: featureGuid},
load: function(response){
alert(response);
dojo.style(dojo.byId("photoLink"), "display", "");
}
});
Here's the PHP...
<?php
$guid = $_GET["guid"];
// Connect to Database
$server = "server";
$connectionSettings = array("Database"=>"db", "UID"=>"uid", "PWD"=>"pwd");
$connection = sqlsrv_connect($server, $connectionSettings);
if (!$connection){
die("Failed Connection");
}
// Prepare and Execute query
$sql = "sql";
$results = sqlsrv_query($connection, $sql);
if ($results){
$rows = sqlsrv_has_rows( $results );
if ($rows === true) {
header('Content-Type: text/plain');
echo "true";
}
else {
header('Content-Type: text/plain');
echo "false";
}
}
else{
header('Content-Type: text/plain');
echo "false";
}?>
Anything anybody see wrong with this?
Thanks.
I'd check the requests and responses using Firebug - check that the URLs and headers are the same when you call the URL directly from the browser as opposed to via the XHR.
I am not sure but:
Try making sure that your Main App is executing PHP properly, it seems odd that JavaScript can pull the source code.
Try adding: die() after echo true or echo false which will prevent it from going any further.
The reason I say to check the larger app for PHP execution is because it almost seems like the webserver is rendering the source code as html and not running it through the interpreter.

Categories