Two Ajax calls from different sources causing one to silently fail [closed] - php

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Edit: Just ran into a wrinkle, I just got this working on an iPhone over the weekend and just out of curiosity ran it on two phones at once and it worked. So it ran happily along (as I expected it to the first time) when one phone was an iPhone (iOS 6) and the other was HTC One (Android 4.3). This was however on another person's WIFI. Could my home WIFI be a factor in blocking two devices going to the same location? (The second phone I was using when it didn't work was a Samsung Galaxy Ace 2 (Android 2.3))
So I've got this problem. I am using PhoneGap and coming up with a basic quiz system to muck around with. I've got it working and I'm having a great time. It works essentially through a web console where I can set up a quiz and cycle through questions and with a not so complex series of status updates to an underlying database I use Ajax calls from my mobile to read the status and display a question or wait for the next one.
Basic call is:
$(function checkForQuestion() {
var postData = "stuff needed in called PHP";
$.ajax({
type: "POST",
data: postData,
url: "my called php",
success: function(data){
var result = JSON.parse(data);
if (result == "question") {
--Display Question
} else {
setTimeout(checkForQuestion, 1000);
return false;
}
});
return false;
});
In my limited experience this seems to be a general use of Ajax with a recursive call back if it needs to wait for a new status.
Now this isn't everything by far, but a taster of what I'm doing. It works extremely well with one mobile device and a web console happily working through quizzes.
When I attempt to add a second mobile (haven't even attempted three yet) what happens is the second mobile just silently fails where it is supposed to be calling this ajax. Now the second mobile can quite happily chug along with this on it's own so it shouldn't be a hardware issue. There are no errors thrown out in the PHP, and with a little logging I can't find anything obviously failing.
At this point I thought, perhaps there is a limit on connections on my web host (I'm just using a shared server web host I'm using to test this out) and there are but that is limited to 20 entry processes with Cloud Linux LVE. However This should not preclude two mobiles calling the same PHP (via wifi) at roughly the same time. It should just run the calls concurrently and one will return slight faster than the other (or that is my understanding).
I thought perhaps this is a lock put on the MySQL database I'm using not allowing multiple users/PHP to query it at roughly the same time, but the consecutive nature of PHP should rule that out and some Googling assures me that calls will be queued.
I'm guessing that what is happening is the two calls come in and without returning any error one silently conflicts with the other causing a fail, but I have no idea hwo to find the fail and fix it.
Any suggestions?
Request for the actual code:
$(function () {
$(document).on("pagebeforeshow", "#page6", function () {
document.getElementById("mob_user_name2").innerHTML = window.localStorage.getItem("mob_local_login_name");
$(function checkForQuestion() {
//sort out the data to be posted
var postData = "mob_quizwait_quizcode=" . concat(window.localStorage.getItem("mob_local_quiz_code"), "&mob_quizwait_email=", window.localStorage.getItem("mob_local_login_email"), "&mob_quizwait_password=", window.localStorage.getItem("mob_local_login_password"), "&mob_quizwait_questionid=", window.localStorage.getItem("mob_question_id"));
$.ajax({
type: "POST",
data: postData,
url: "url of php",
success: function(data){
var mob_quizwait_data = JSON.parse(data);
if (mob_quizwait_data.mob_quizwait_success == "mob quizwait go") {
window.localStorage.setItem("mob_question_id", mob_quizwait_data.mob_quizwait_questionid);
window.localStorage.setItem("mob_question_score", mob_quizwait_data.mob_quizwait_score);
window.localStorage.setItem("mob_question_category", mob_quizwait_data.mob_quizwait_category);
window.localStorage.setItem("mob_question_question", mob_quizwait_data.mob_quizwait_question);
window.localStorage.setItem("mob_answer1", mob_quizwait_data.mob_quizwait_correct);
window.localStorage.setItem("mob_answer2", mob_quizwait_data.mob_quizwait_wrong1);
window.localStorage.setItem("mob_answer3", mob_quizwait_data.mob_quizwait_wrong2);
window.localStorage.setItem("mob_answer4", mob_quizwait_data.mob_quizwait_wrong3);
$.mobile.changePage("#page7", {transition:"slide", changeHash:false});
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait stay") {
setTimeout(checkForQuestion, 1000);
return false;
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait intermission") {
document.getElementById("mob_intermission").innerHTML = "Intermission";
$.mobile.changePage("#page6", {transition:"none", changeHash:false});
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait finish") {
$.mobile.changePage("#page8", {transition:"slide", changeHash:false});
} else {
navigator.notification.alert("Status Check Failed. Please Try Again.", function(){}, "Alert", "OK");
}
}
});
return false;
});
});
});
And the PHP:
<?PHP
include '../open.php';
//take in POST variables
$quizcode = $link->real_escape_string($_POST["mob_quizwait_quizcode"]);
$email = $link->real_escape_string($_POST["mob_quizwait_email"]);
$password = $link->real_escape_string($_POST["mob_quizwait_password"]);
$questionid1 = $link->real_escape_string($_POST["mob_quizwait_questionid"]);
$quizid = 0;
$status = "X";
$questionid = 0;
$sql = "SELECT QUIZ_ID FROM B_QUIZ WHERE QUIZ_CODE = '$quizcode'";
$res = $link->query($sql);
while ($row = $res->fetch_array()) {
$quizid = $row['QUIZ_ID'];
}
$sql = "SELECT USER_ID FROM A_USER WHERE USER_EMAIL = '$email' AND USER_PASSWORD = '$password'";
$res = $link->query($sql);
while ($row = $res->fetch_array()) {
$userid = $row['USER_ID'];
}
$sql = "SELECT QUIZ_STATUS, IFNULL(QUESTION_ID, 0) AS QUESTION_ID FROM B_GAME WHERE QUIZ_ID = $quizid";
$res = $link->query($sql);
while ($row = $res->fetch_array()) {
$status = $row['QUIZ_STATUS'];
$questionid = $row['QUESTION_ID'];
}
if ($questionid == $questionid1) {
$questionid = 0;
}
if ($status != "F") {
if ($quizid != 0 && $status != "X") {
//get details to be written to the profile page
if ($questionid != 0) {
$sql = "SELECT SCORE FROM B_PARTICIPANT WHERE USER_ID = $userid AND QUIZ_ID = $quizid";
$res = $link->query($sql);
while ($row = $res->fetch_array()) {
$score = $row['SCORE'];
}
$sql = "SELECT b.QUESTION_ID, c.CATEGORY, b.QUESTION, b.CORRECT_ANSWER, b.WRONG_ANSWER_1, b.WRONG_ANSWER_2, b.WRONG_ANSWER_3
FROM B_GAME a, B_QUESTION b, D_CATEGORY c
WHERE a.QUESTION_ID = b.QUESTION_ID
AND b.CATEGORY_ID = c.CATEGORY_ID
AND a.QUIZ_ID = $quizid";
$res = $link->query($sql);
while ($row = $res->fetch_array()) {
$questionid = $row['QUESTION_ID'];
$category = $row['CATEGORY'];
$question = $row['QUESTION'];
$correct = $row['CORRECT_ANSWER'];
$wrong1 = $row['WRONG_ANSWER_1'];
$wrong2 = $row['WRONG_ANSWER_2'];
$wrong3 = $row['WRONG_ANSWER_3'];
}
if ($status == "R") {
$arr = array("mob_quizwait_success" => "mob quizwait go",
"mob_quizwait_questionid" => $questionid,
"mob_quizwait_score" => $score,
"mob_quizwait_category" => $category,
"mob_quizwait_question" => $question,
"mob_quizwait_correct" => $correct,
"mob_quizwait_wrong1" => $wrong1,
"mob_quizwait_wrong2" => $wrong2,
"mob_quizwait_wrong3" => $wrong3);
echo json_encode($arr);
} else if ($status == "N") {
$arr = array("mob_quizwait_success" => "mob quizwait stay");
echo json_encode($arr);
} else if ($status == "I") {
$arr = array("mob_quizwait_success" => "mob quizwait intermission");
echo json_encode($arr);
}
} else {
$arr = array("mob_quizwait_success" => "mob quizwait stay");
echo json_encode($arr);
}
} else {
$arr = array("mob_quizwait_success" => "mob quizwait failed");
echo json_encode($arr);
}
} else {
$arr = array("mob_quizwait_success" => "mob quizwait finished");
echo json_encode($arr);
}
include '../close.php';
?>
open.php:
<?PHP
//DATABASE DETAILS//
$DB_ADDRESS = "yeah";
$DB_USER = "not";
$DB_PASS = "gonna";
$DB_NAME = "do it";
//Connect to the MySQL database
$link = new mysqli($DB_ADDRESS, $DB_USER, $DB_PASS, $DB_NAME);
if (mysqli_connect_errno()) {
printf("Connect Failed: %s\n", mysqli_connect_error());
exit();
}
?>
close.php:
<?PHP
mysqli_close($link);
?>

The silent fail may be because there is a server error when processing the ajax call.
Add an error handler to the ajax call.
$.ajax({
type: "POST",
data: postData,
url: 'url of php',
success: successFunction(),
error: function(xhr, status, err) { alert("Ajax request failed"); }
});
You may need to step through PHP code or add additional logging to see the flow of the application.

Try:
<script>
var st_flag = true;
$(function () {
$(document).on("pagebeforeshow", "#page6", function () {
document.getElementById("mob_user_name2").innerHTML = window.localStorage.getItem("mob_local_login_name");
$(function checkForQuestion() {
if(!st_flag)
{
setTimeout(checkForQuestion, 1000);
}
//sort out the data to be posted
var postData = "mob_quizwait_quizcode=" . concat(window.localStorage.getItem("mob_local_quiz_code"), "&mob_quizwait_email=", window.localStorage.getItem("mob_local_login_email"), "&mob_quizwait_password=", window.localStorage.getItem("mob_local_login_password"), "&mob_quizwait_questionid=", window.localStorage.getItem("mob_question_id"));
$.ajax({
type: "POST",
data: postData,
url: "url of php",
st_flag = false;
success: function(data){
var mob_quizwait_data = JSON.parse(data);
if (mob_quizwait_data.mob_quizwait_success == "mob quizwait go") {
window.localStorage.setItem("mob_question_id", mob_quizwait_data.mob_quizwait_questionid);
window.localStorage.setItem("mob_question_score", mob_quizwait_data.mob_quizwait_score);
window.localStorage.setItem("mob_question_category", mob_quizwait_data.mob_quizwait_category);
window.localStorage.setItem("mob_question_question", mob_quizwait_data.mob_quizwait_question);
window.localStorage.setItem("mob_answer1", mob_quizwait_data.mob_quizwait_correct);
window.localStorage.setItem("mob_answer2", mob_quizwait_data.mob_quizwait_wrong1);
window.localStorage.setItem("mob_answer3", mob_quizwait_data.mob_quizwait_wrong2);
window.localStorage.setItem("mob_answer4", mob_quizwait_data.mob_quizwait_wrong3);
$.mobile.changePage("#page7", {transition:"slide", changeHash:false});
st_flag = true;
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait stay") {
setTimeout(checkForQuestion, 1000);
return false;
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait intermission") {
document.getElementById("mob_intermission").innerHTML = "Intermission";
$.mobile.changePage("#page6", {transition:"none", changeHash:false});
} else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait finish") {
$.mobile.changePage("#page8", {transition:"slide", changeHash:false});
} else {
navigator.notification.alert("Status Check Failed. Please Try Again.", function(){}, "Alert", "OK");
}
}
});
return false;
});
});
});
</script>
Wait for first call to be complete.

Even though your problem is complicated by nature and I've got no reason to come to the conclusion I'm going to say but my bets are on session.auto_start.
As I see you've got no use for session in your code and in your case it might be a problem starting it. Set session.auto_start to false so your code won't use sessions at all and then test your code. It's a long shot but it's the best I've got.
To explain myself, php makes use of files for sessions by default. And it does so by opening the file in exclusive mode. It means if one request is running on the server, the second one with the same session_id will be blocked until the first one realizes it. So each browser can have only one request executed on the server at a time. I know your javascript won't be making the second request before the first one is returned but as I said your problem is complicated and it's the only guess I could come up with and I believe it's worth a test.
So my solution is: make sure you are not using sessions at all.

As Kami said, i think there should be some issues in the server side(PHP) only. And lot of time, PHP don't used to show the errors due to the server settings. I would suggest you to check the apache error logs, so that you can get to know if any unshown error is present. To check this, just load the URL which is having the problem and then check the error log usually present in var/log/ folder.

I have a strange suggestion after your edit. Wifi hotspot hides real adresses by NAT so from server's point of view both your devices has the same IP address. Server sends the answer to your Wifi spot and it route the packets to real addresses. Sometimes I had package missing but I can't remember the situation when all packets had been lost.
You should request the page from both devices and log the scrpit's work result on the server side. If there was 2 requests and all DB requests worked properly that means that one of your clients didn't get the response. It is probably because of your router, probably NAT

This turned out to be an unknown issue with the Web Host provider. Despite more than a dozen detailed requests for what on their side was blocking things I was always referred to how my own equipment or own code was at fault.
Set myself up a VPS and presto change-o I have a working system with no modifications to the code or the equipment.
TIL I don't like people who cover up their incompetency by blaming others.

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.

PHP MYSQL JQuery Long Polling - Not working as expected

My long polling implementation isn't working. Been having a very difficult time understanding where to look toward debugging said code.
Key Points
No Errors
Long polling working randomly (only responds to some changes in MySQL with no distinct pattern)
MySQL is updating correctly
I'm testing this via Localhost WAMP and two browsers with two different sessions
PHP Portion -
$path= $_SERVER[ 'DOCUMENT_ROOT'];
$path .= "/config.php" ;
require_once($path);
require_once(PHP_PATH . "/classes/user.php");
session_start();
require_once(PHP_PATH . "/functions/database.php");
// Return to Login if no Session
if(!isset($_SESSION['user'])){
header("Location: /login");
die();
}
$db = connectdatabase();
$timeout = 40;
// if no post ids kill the script // Should never get here
if(!isset($_POST['post_ids'])){
die();
}
if(!isset($_POST['timestamp'])){
die();
}
$last_ajax_call = $_POST['timestamp'];
$post_ids = trim(strip_tags($_POST['post_ids']));
$id = $_SESSION['user']->getID();
// Check if there are posts from the last search that need to be updated with a comments or the like number has to be updated
$query = "SELECT posts.*, users.first_name, users.last_name, users.picture
FROM posts
LEFT JOIN users
ON users.id = posts.user_id
WHERE ((UNIX_TIMESTAMP(posts.date) > :last_ajax_call OR UNIX_TIMESTAMP(posts.last_modified) > :last_ajax_call)
AND posts.parent IN (:post_ids)) OR (posts.id IN (:post_ids) AND UNIX_TIMESTAMP(posts.last_modified) > :last_ajax_call)";
while ($timeout > 0) {
$check_for_updates = $db->prepare($query);
$check_for_updates->bindParam(':post_ids', $post_ids);
$check_for_updates->bindParam(':last_ajax_call', $last_ajax_call);
$check_for_updates->execute();
$r = $check_for_updates->fetchAll();
if(!empty($r)){
// Get current date time in mysql format
$unix_timestamp = time();
// Cofigure result array to pass back
$result = array(
'timestamp' => $unix_timestamp,
'updates' => $r
);
$json = json_encode($result);
echo $json;
return;
} else {
$timeout --;
usleep( 250000 );
clearstatcache();
}
}
// you only get here if no data found
$unix_timestamp = time();
// Cofigure result array to pass back
$result = array(
'timestamp' => $unix_timestamp
);
$json = json_encode($result);
echo $json;
JQuery Ajax -
function getUpdates(timestamp) {
var post_ids = $("#newsfeed").find("#post_ids").attr('data-post-ids');
var data = {'timestamp' : timestamp,
'post_ids' : post_ids};
poll = $.ajax({
type: 'POST',
url: '/php/check_for_updates.php',
data: data,
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
success: function(data) {
try {
// put result data into "obj"
var obj = jQuery.parseJSON(data);
// put the data_from_file into #response
//$('#response').html(obj.data_from_file);
// repeat
console.log("SQL: " + obj['timestamp']);
setTimeout( function() {
// call the function again, this time with the timestamp we just got from server.php
getUpdates(obj['timestamp']);
}, 1000 );
} catch( e ) {
// repeat
// Get mysql formated date
var unix_timestamp = Math.floor(Date.now() / 1000);
console.log("JS: " + unix_timestamp);
setTimeout( function() {
getUpdates(unix_timestamp);
}, 1000 );
}
}
}
);
}
Thanks for all the help guys! I asked around a lot of people and got a bunch of great places to look to debug the code.
I finally found the answer here -
http://blog.preinheimer.com/index.php?/archives/416-PHP-and-Async-requests-with-file-based-sessions.html
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
It looks like I the PHP checking for updates was blocking any updates from happening till the PHP stop checking for updates.
Couple things you can do is:
1.) Open the Chrome Developer tools and then click on the Network tab and clear everything out. Then click on submit. Look at the network tab and see what is being posted and what isn't. Then adjust accordingly from there.
2.) Echo out different steps in your php script and do the same thing with the Network tab and then click on the "results" area and see what's being echoed out and if it's as expected.
From there, you should be able to debug what's happening and figure out where it's going wrong.

extjs4 and php issue - 500 Internal server error when creating entries

I've been stuck with this problem for a day now. I think I'm overlooking something simple but I can't see it.
I am developing a web application where the user fills up forms and the forms get saved in the database. However, I'm having a problem inserting values to a form. The database does not update and I get a 500 Internal Server Error at the console.
Here is the controller that I call when the user saves the form that was filled up
var personStore = Ext.getStore('personBaseDetails');
var caStore = Ext.getStore('creditApplication');
var form = button.up('form').getForm();
var id = personStore.first().get('ID');
//use this to update
if(caStore.count() < 1){
var creditApplication = Ext.ModelManager.create({
}, 'app.model.creditApplicationModel');
caStore.add(creditApplication);
}
var record = caStore.first();
form.updateRecord(record);
caStore.getProxy().extraParams = {
selectedUserID: id
};
caStore.sync({
success: function(batch) {
console.log(batch.operations[0].request.scope.reader.jsonData['message']);
},
failure: function(batch) {
console.log("Failed syncing ca");
}
});
I have checked with various console.log statements that all of the variables here have the proper values.
Here is the php file that gives the 500 Internal Server Error problem:
<?php
require_once('../../db_connection.php');
require_once '../../lib/response.php';
require_once '../../lib/request.php';
class creditApplication{
var $ID_PERSON;
var $APPLICATION_TYPE;
var $APPLICATION_SUB_TYPE;
var $APPLICATION_NUMBER;
var $CUSTOMER_NUMBER;
var $DATE;
var $STATUS;
var $ID_UNIT;
}
$request = new Request(array());
if(isset($request->params)){
var $selectedCustomer = '';
if(isset($_GET['selectedUserID'])){
$selectedCustomer = $_GET['selectedUserID'];
$array_r=$request->params;
$inputData = new creditApplication();
$inputData->ID_PERSON=$selectedCustomer;
$inputData->APPLICATION_TYPE=($array_r->APPLICATION_TYPE);
$inputData->APPLICATION_SUB_TYPE=($array_r->APPLICATION_SUB_TYPE);
$inputData->APPLICATION_NUMBER='sample application number';
$inputData->CUSTOMER_NUMBER='sample customer number';
$inputData->DATE='2014-4-4';
$inputData->STATUS=42;
$inputData->ID_UNIT='sampleUnit';
$query="INSERT INTO CREDIT_APPLICATION (ID_PERSON, APPLICATION_TYPE, APPLICATION_SUB_TYPE, APPLICATION_NUMBER,
CUSTOMER_NUMBER, DATE, STATUS, ID_UNIT)
VALUES ($inputData->ID_PERSON,
'$inputData->APPLICATION_TYPE',
'$inputData->APPLICATION_SUB_TYPE',
'$inputData->APPLICATION_NUMBER',
'$inputData->CUSTOMER_NUMBER',
'$inputData->DATE',
$inputData->STATUS,
'$inputData->ID_UNIT')";
$result = mysql_query($query);
//object response
$res = new Response();
$res->success = true;
$res->message = "Created user";
print_r($res->to_json());
}
else{
$res = new Response();
$res->success = false;
$res->message = "Error - no userID";
$res->data = array();
print_r($res->to_json());
}
}
else{
$res = new Response();
$res->success = false;
$res->message = "Error - no request";
$res->data = array();
print_r($res->to_json());
}
?>
All the database rows are varchars except for ID_PERSON and STATUS which are ints (hence the single quotes in the insert) and the DATE which is of date format.
Now, I've tried hard coding the values, commenting out the if else conditions, and calling the php file through localhost:8888/..../createCreditApplication.php and it actually works. The problem happens when I bring back the if-else blocks and get the values passed to the php file.
I appreciate any help.

get the result from mysql+php and shows in titanium

I have developing the one application using titanium.
Here the values are inserted successfully.But i didn't get the success message from webservices code.
I have using following code for insert a databaase :
In titanium side code :
function StaffRegistration(){
if($.staff_firstname.value != "" && $.staff_firstname.value != null){
var request = Ti.Network.createHTTPClient({
onload:alert(this.responseText),
onerror: function(e){
Ti.API.debug(e.error);
alert(this.responseText);
},
timeout:1000,
});
request.open("POST","xxx/xxx.php");
var params = ({"staff_firstname": $.staff_firstname.value,"staff_email": $.staff_email.value,"staff_password": $.staff_password.value,});
request.send(params);
}
else{
alert("Please enter the firstname");
}
Ti.API.info("Result for registration = " + this.responseText);
};
I have using a following php(webservice code) :
<?php
$request = base64_decode($_POST['jsondata']);
$data = json_decode($request,true);
$staff_firstname = $data['staff_firstname'];
$staff_email = $data['staff_email'];
$staff_password = md5($data['staff_password']);
include "db_connect.php";
$db = new DB_CONNECT();
$result = mysql_query("SELECT staff_email,staff_firstname from at_staff WHERE staff_email = '$staff_email'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
while($queryresult=mysql_fetch_array($result)) {
$uname[]=$queryresult['staff_firstname'];
$uemail[]=$queryresult['staff_email'];
}
if(in_array($staff_firstname,$uname) and in_array($staff_email,$uemail)) {
$response='{"Error":"1","Message":"Username and Email already exist"}';
echo $response;
} else if (in_array($staff_firstname,$uname)) {
$response='{"Error":"1","Message":"Username already exist"}';
echo $response;
} else {
$response='{"Error":"1","Message":"Email already exist"}';
echo $response;
}
} else {
$response='{"Error":"1","Message":"Successfully Registered"}';
echo $response;
$data=array("staff_firstname"=>"'".$staff_firstname."'",
"staff_email"=>"'".$staff_email."'",
"staff_password"=>"'".$staff_password."'"
);
echo $response;
}
?>
How can i get the $response in titanium from this webservice url.
#user2218667
Ti.API.info("Result for registration = " + this.responseText);
will NEVER work as you show in the first piece of code .
why ? because you send a request which will take like 1 seconde (for exemple), obviously, your programm won't wait 1 sec after
request.send(params);
i will continue the programm and when the request return a result, it will get into
onload(e) :
and here only you will be able to have your $result.
is this ok? well now, if this.responseData isn't effective, I don't have the solution .Can you check your line : "} else {" ,i supose there is a if above in the code? are you sure $result is defined upper?
Can you try the same request without titanium with a basic html form to be sure $result is write correctly in this case, like this, we will know if the problem come from php or from the link betwin php & titanium.
well , i supose it's asynchronous request, so the folowing may not work
Ti.API.info("Result for registration = " + this.responseText);
coud you try :
onload : function(e) {
Ti.API.info(this.responseText); // maybe Ti.API.info(this.reponsedata) according to your php.
},
onerror : function(e) {...
in my mind, if you receive JSON information (it trully look's like), you need
this.responseData //instead of this.responseText

mb_strlen() & strlen() don't return correct values from an Ajax call to PHP

How can I add a check in the PHP for the length of the $username passed. The site is UTF-8 but I believe Javascript is using a different encoding. You can see in the comments where I tried different things in the PHP and they don't work.
What I tried and didn't work:
Changing Ajax (javascript) to pass variables by UTF-8 and not javascript encoding
strlen, mb_strlen in the PHP - both return incorrect values
MORE INFO
My Ajax sends a username to my PHP, which checks the SQL DB and returns available or not. I decided to try and do some extra checking in the PHP before checking the DB (like mb_strlen($username). mb_internal_encoding("UTF-8"); is also set.
I was going to try and send the Ajax request in UTF-8 but didnt see a way to do that.
is UPPER being used correctly in the MySQL? - for UTF-8 stuff?
PHP BELOW ***********
// Only checks for the username being valid or not and returns 'taken' or 'available'
require_once('../defines/mainDefines.php'); // Connection variables
require_once('commonMethods.php');
require_once('sessionInit.php'); // start session, check for HTTP redid to HHHTPs
sleep(2); // Looks cool watching the spinner
$username = $_POST['username'];
//if (mb_strlen($username) < MIN_USERNAME_SIZE) echo 'invalid_too_short';
//if (mb_strlen($username, 'UTF-8') < 10) { echo ('invalid_too_short'); exit; }
//die ('!1!' . $username . '!2!' . mb_strlen($username) . '!3!' . strlen($username) . '!4!');
$dbc = mysqli_connect(DB_HOST, DB_READER, DB_READER_PASSWORD, DB_NAME) or die(DB_CONNECT_ERROR . DB_HOST . '--QueryDB--checkName.php');
$stmt = mysqli_stmt_init($dbc);
$query = "SELECT username FROM pcsuser WHERE UPPER(username) = UPPER(?)";
if (!mysqli_stmt_prepare($stmt, $query)) {
die('SEL:mysqli_prepare failed somehow:' . $query . '--QueryDB--checkName.php');
}
if (!mysqli_stmt_bind_param($stmt, 's', $username)) {
die('mysqli_stmt_bind_param failed somehow --checkName.php');
}
if (!mysqli_stmt_execute($stmt)) {
die('mysqli_stmt_execute failed somehow' . '--checkName.php');
}
mysqli_stmt_store_result($stmt);
$num_rows = mysqli_stmt_num_rows($stmt);
mysqli_stmt_bind_result($stmt, $row);
echo ($num_rows >= 1) ? 'taken' : 'available';
mysqli_stmt_close($stmt);
mysqli_close($dbc);
AJAX CODE BELOW
function CheckUsername(sNameToCheck) {
document.getElementById("field_username").className = "validated";
registerRequest = CreateRequest();
if (registerRequest === null)
alert("Unable to create AJAX request");
else {
var url= "https://www.perrycs.com/php/checkName.php";
var requestData = "username=" + escape(sNameToCheck); // data to send
registerRequest.onreadystatechange = ShowUsernameStatus;
registerRequest.open("POST", url, true);
registerRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
registerRequest.send(requestData);
}
}
function ShowUsernameStatus() {
var img_sad = "graphics/signup/smiley-sad006.gif";
var img_smile = "graphics/signup/smiley-happy088.gif";
var img_checking = "graphics/signup/bluespinner.gif";
if (request.readyState === 4) {
if (request.status === 200) {
var txtUsername = document.getElementById('txt_username');
var fieldUsername = document.getElementById('field_username');
var imgUsername = document.getElementById('img_username');
var error = true;
var response = request.responseText;
switch (response) {
case "available":
txtUsername.innerHTML = "NAME AVAILABLE!";
error = false;
break;
case "taken":
txtUsername.innerHTML = "NAME TAKEN!";
break;
case "invalid_too_short":
txtUsername.innerHTML = "TOO SHORT!";
break;
default:
txtUsername.innerHTML = "AJAX ERROR!";
break;
} // matches switch
if (error) {
imgUsername.src = img_sad;
fieldUsername.className = 'error';
} else {
imgUsername.src = img_smile;
fieldUsername.className = 'validated';
}
} // matches ===200
} // matches ===4
}
TESTING RESULTS
This is what I get back when I DIE in the PHP and echo out as in the following (before and after making the Ajax change below [adding in UTF-8 to the request]...
PHP SNIPPIT
die ('!1!' . $username . '!2!' . mb_strlen($username) . '!3!' . strlen($username) . '!4!');
TEST DATA
Username: David Perry
!1!David Perry!2!11!3!11!4!
Username: ܦ"~÷Û♦
!1!ܦ\"~��%u2666!2!9!3!13!4!
The first one works. The second one should work but it looks like the encoding is weird (understandable).
7 visible characters for the 2nd one. mb_strlen shows 9, strlen shows 13.
After reading Joeri Sebrechts solution and link they gave me I looked up Ajax request parameters and someone had the following...
AJAX SNIPPIT (changed from original code)
registerRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
(I added in the charset=UTF-8 from an example I saw on a article).
UPDATE: Nov 27, 9:11pm EST
Ok, after much reading I believe I am encoding my JS wrong. I was using escape... as follows...
var requestData = "username=" + escape(sNameToCheck);
After looking at this website...
http://www.the-art-of-web.com/javascript/escape/
it helped me understand more of what's going on with each function and how they encode and decode. I should be able to do this...
var requestData = "username=" + encodeURIComponent(sNameToCheck);
in JS and in PHP I should be able to do this...
$username = rawurldecode($_POST['username']);
Doing that still gives me 8 characters for my weird example above instead of 7. It's close, but am I doing something wrong? If I cursor through the text on the screen it's 7 characters. Any ideas to help me understand this better?
FIXED/SOLVED!!!
Ok, thank you for your tips that lead me in the right direction to make this work. My changes were as follows.
In the AJAX -- i used to have escape(sNameToCheck); --
var requestData = "username=" + encodeURIComponent(sNameToCheck);
In the PHP *-- I used to have $username = $_POST['username']; --*
$username = rawurldecode($_POST['username']);
if (get_magic_quotes_gpc()) $username = stripslashes($username);
I really hate magic_quotes... it's caused me about 50+ hours of frustration over form data in total because I forgot about it. As long as it works. I'm happy!
So, now the mb_strlen works and I can easily add this back in...
if (mb_strlen($username) < MIN_USERNAME_SIZE) { echo 'invalid_too_short'; exit; }
Works great!
PHP is a byte processor, it is not charset-aware. That has a number of tricky consequences.
Strlen() returns the length in bytes, not the length in characters. This is because php's "string" type is actually an array of bytes. Utf8 uses more than one byte per character for the 'special characters'. Therefore strlen() will only give you the right answer for a narrow subset of text (= plain english text).
Mb_strlen() treats the string as actual characters, but assumes it's in the encoding specified via mbstring.internal_encoding, because the string itself is just an array of bytes and does not have metadata specifying its character set. If you are working with utf8 data and set internal_encoding to utf8 it will give you the right answer. If your data is not utf8 it will give you the wrong answer.
Mysql will receive a stream of bytes from php, and will parse it based on the database session's character set, which you set via the SET NAMES directive. Everytime you connect to the database you must inform it what encoding your php strings are in.
The browser receives a stream of bytes from php, and will parse it based on the content-type charset http header, which you control via php.ini default_charset. The ajax call will submit in the same encoding as the page it runs from.
Summarized, you can find advice on the following page on how to ensure all your data is treated as utf8. Follow it and your problem should resolve itself.
http://malevolent.com/weblog/archive/2007/03/12/unicode-utf8-php-mysql/
From a quick glance, you can clean this up:
if (request.status == 200) {
if (request.responseText == "available") {
document.getElementById("txt_username").innerHTML = "NAME AVAILABLE!";
document.images['img_username'].src=img_smile;
document.getElementById("continue").disabled = false;
document.getElementById("field_username").className = 'validated';
} else if (request.responseText == "taken") {
document.getElementById("txt_username").innerHTML = "NAME TAKEN!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
} else if (request.responseText == "invalid_too_short") {
document.getElementById("txt_username").innerHTML = "TOO SHORT!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
} else {
document.getElementById("txt_username").innerHTML = "AJAX ERROR!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
}
}
to:
// I prefer triple equals
// Read more at http://javascript.crockford.com/style2.html
if (request.status === 200) {
// use variables!
var txtUsername = document.getElementById('txt_username');
var fieldUsername = document.getElementById('field_username');
var imgUsername = document.getElementById('img_username');
var response = request.responseText;
var error = true;
// you can do a switch statement here too, if you prefer
if (response === "available") {
txtUsername.innerHTML = "NAME AVAILABLE!";
document.getElementById("continue").disabled = false;
error = false;
} else if (response === "taken") {
txtUsername.innerHTML = "NAME TAKEN!";
} else if (response === "invalid_too_short") {
txtUsername.innerHTML = "TOO SHORT!";
} else {
txtUsername.innerHTML = "AJAX ERROR!";
}
// refactor error actions
if (error) {
imgUsername.src = img_sad;
fieldUsername.className = 'error';
} else {
imgUsername.src = img_smile;
fieldUsername.className = 'validated';
}
}

Categories