Here is my situation:
I have a JS function that creates an XMLHttpRequest object. The request is opened, and I'm calling the "GET" method on a specified url. The request works, as in it gets to the url destination and executes the code in the destination, but I'm not sure how to access a variable in the destination code.
Here's what I've got:
JS:
function fillTestsTable()
{
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
xhr.open("GET", "./db-queries/get-tests.php");
xhr.send(null);
}
PHP destination file:
<?php
$conn = mysqli_connect("localhost:3306" , "exampre2_tplugin" , ",Vyml.F!#(}{" , "exampre2_totaltoefltimeplugin");
if (!$conn) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
$sql = "SELECT * FROM TOEFLTESTS";
$result = mysqli_query($conn, $sql);
//return $result;
?>
What I am trying to do is return the data in the $result variable in the php. Is there a way of doing this?
In PHP, return is used to return a value from the current function to where that function was called.
To output data in the HTTP response use echo or print.
Note that mysqli_query returns a mysqli_result object so you will need to extact the data you want from that (e.g. with fetch_array) and then convert it to a suitable text format (e.g. with json_encode).
For example: if you wanted to return JSON formatted data for your Ajax callback function to play with you might do something like this:
<?php
$conn = mysqli_connect("localhost:3306" , "exampre2_tplugin" , ",Vyml.F!#(}{" , "exampre2_totaltoefltimeplugin");
$data=[]; //store recordset here
$sql = "SELECT * FROM TOEFLTESTS";
$result = mysqli_query($conn, $sql);
if( $result ){ /* iterate through the recordset, add each row to output data */
while( $rs=$result->fetch_object() ){
$data[]=$rs;
}
}
/* send data back to the ajax callback function */
exit( json_encode( $data ) );
?>
There are many ways you could proceed with this but it helps to clearly define the purpose and identify how your app is to work. The callback will then manipulate the response data to add new rows to your HTML table. Knowing what the callback is to do will generally ( or can ) affect the format of data you return - in your case if it is simply to be new rows in an HTML table it would be better to format the data server-side as HTML and send back raw html text.
Using Ajax allows your app to request data of whatever sort without the need to reload the page ( usually a traditional form submission )
As a basic example of populating an HTML table following a basic ajax request ( POST rather than GET but would work the same )
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = 'xxx';
$dbname = 'maps';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
ob_clean();
$sql='select `name`,`address`,`lat`,`lng` from `maps` limit 10';
$res=$db->query( $sql );
while( $rs=$res->fetch_object() ){
printf('
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>',
$rs->name,
$rs->address,
$rs->lat,
$rs->lng
);
}
exit();
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Ajax: fetch data from db - add to table</title>
<script>
const ajax=function(url,params,callback){
let xhr=new XMLHttpRequest();
xhr.onload=function(){
if( this.status==200 && this.readyState==4 )callback.call( this, this.response )
};
xhr.open( 'POST', url, true );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send( params );
};
</script>
</head>
<body>
<input type='button' value='Fetch Data' />
<table></table>
</body>
<script>
document.querySelector('input[type="button"]').onclick=function(e){
ajax( location.href, false, function(r){
this.innerHTML=r
}.bind( e.target.nextElementSibling ))
}
</script>
</html>
Related
So, I'm working on a project which involves getting data from my website into the ESP32. I came across making the Json array and updating the info from time to time, but now I need to get the specific info from my Json array so I can use it with my ESP. For some reason when I try to access the data from my page, I'm getting 0 instead of the number that is in that place, in the case of text, I don't receive anything as a response. I fixed not receiving any response from the file, I had to create a separate PHP file in which get the database info and turns that info in a datajson.json file, so the code that I have works, but I will need to update the PHP file every 1 second, I saw that Ajax was the way to go since I wouldn't need to refresh the page every time, only the content
ESP32 code:
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("https://nps-tech.com.br/receive.php"); //Specify the URL and certificate
int httpCode = http.GET();
if (httpCode > 0)//Check for the returning code
{
String payload = http.getString();
Serial.println("\nStatuscode: "+ String(httpCode));
Serial.println(payload);
char json[500];
payload.replace(" ", "");
payload.replace("\n", "");
payload.trim();
payload.remove(0,1);
payload.toCharArray(json, 500);
StaticJsonDocument<200> doc;
deserializeJson(doc, json);
int id = doc["AutoIncrement"];
const char* nome = doc["Nome Aparelho"];
int stat = doc["Status"];
Serial.println(id);
Serial.println(nome);
Serial.println(stat);
}
else
{
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
delay(10000);
}
New response from ESP32:
Statuscode: 200
[{"AutoIncrement":"1","Aparelho":"LED","Status":"0"}]
1
LED
0
PHP Code, How can I set a SetInterval to update get_data function from php every 1 second, without reloading the page:
<!DOCTYPE html>
<html lang="pt-br">
<head>
</head>
<body>
<?php
function get_data()
{
$servername = "stuuf";
$dBUsername = "stuuf";
$dBPassword = "stuuf";
$dBname = "stuuf";
$conn = mysqli_connect($servername, $dBUsername, $dBPassword, $dBname);
if ($conn->connect_error){
die ("Connection failed". $conn->connect_error);
}
$sql = "SELECT * FROM dados;";
$result = mysqli_query($conn, $sql);
$json_array = array();
while($row = mysqli_fetch_assoc($result))
{
$json_array[] = array(
'AutoIncrement' => $row["AutoIncrement"],
'Aparelho' => $row["aparelho"],
'Status' => $row["Status"],
);
}
return json_encode($json_array);
}
$file_name = 'dadosjson' . '.json';
if (file_put_contents($file_name, get_data()))
{
echo $file_name. ' file created';
}
else
{
echo 'There is some error';
}
?>
<script>
setInterval(1000);
//ajax to update every 1s
</script>
I need my page bargraph.html to get parameters like .../bargraph.html?di=xxxx&mn=yyyy and save the values of di and mn using a php script in a text file named cred.txt. The code I'm using for bargraph.html is
<body>
<?php
$mobile_num = $_GET["mn"];
$device_id = $_GET["di"];
$file_name = "cred.txt";
$location = "cred/".$file_name;
$text = $mobile_num."\n".$mobile_num;
$my_file = fopen($location, "w") or die("Unable to open file!");
fwrite($my_file, $text);
echo "response submitted successfully!";
fclose($my_file);
?>
</body>
The file named cred.txt is not created inside the cred/ directory and neither I get any errors. What am I doing wrong?
If the same thing can be done using JavaScript I'll use that instead of php for this purpose.
The question references bargraph.html - presumably the php code that you have is NOT on that page but a separate script? If that is the case then if you were to use exception handling to try to track down the issue it might help. Also, I have always found better success when using full paths as opposed to relative ones
<?php
if( isset( $_GET['mn'], $_GET['di'] ) ){
try{
$filename='cred.txt';
$mobile_num=filter_input( INPUT_GET, 'mn', FILTER_SANITIZE_STRING );
$device_id=filter_input( INPUT_GET, 'di', FILTER_SANITIZE_STRING );
/*
I have always found it is best to use a full path rather than relative
Change `path/to/` to the appropriate path
*/
$path=$_SERVER['DOCUMENT_ROOT'] . '/path/to/cred';
/* If the path does not exist, warn user */
if( !realpath( $path ) ){
throw new Exception( sprintf( 'Unable to find path: %s', $path ) );
}
/* Can the chosen directory be read? */
if( is_readable( $path ) && is_writable( $path ) ){
$file=$path . '/' . $filename;
#$text=$mobile_num . PHP_EOL . $mobile_num . PHP_EOL;
/* I think this is probably what you intended? */
$text=$device_id . PHP_EOL . $mobile_num . PHP_EOL;
$status=file_put_contents( $file, $text, FILE_APPEND | FILE_TEXT );
throw new Exception( $status ? sprintf('All good! Saved %s',$file) : sprintf('Error - unable to save %s',$file) );
} else {
/*
should set permissions if reading/writing of target folder failed
chmod($path,0777); etc
*/
throw new Exception( sprintf( 'The path %s is either not readable or writable',$path ));
}
}catch( Exception $e ){
exit( $e->getMessage() );
}
}
?>
Using a plain HTML page you could send an ajax request to the above PHP script ( in code below called bargraph.php )
<html>
<head>
<title>ajax-store credentials</title>
</head>
<body>
<form id='bg'>
<input type='text' name='mn' id='mn' placeholder='Mobile number: eg 0141 353 3874' />
<input type='text' name='di' id='di' placeholder='Device ID: eg yellow banana' />
<input type='button' id='bttn' value='Go' />
</form>
<script>
document.getElementById('bttn').onclick=function(e){
var mn=document.getElementById('mn').value;
var di=document.getElementById('di').value;
if( mn != '' && di != '' ){
var xhr=new XMLHttpRequest();
xhr.onload=function(r){
document.getElementById('status').innerHTML=this.response;
};
xhr.onerror=function(r){
document.getElementById('status').innerHTML=err.message;
};
xhr.open('GET','?mn='+mn+'&di='+di,true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send();
}
}
</script>
<div id='status'></div>
</body>
</html>
You can do like this.
$mobile_num = $_GET["mn"];
$device_id = $_GET["di"];
$file_name = "cred.txt";
$path = getcwd();
$location = $path.'/cred/'.$file_name;
$text = $device_id."\n".$mobile_num;
$my_file = fopen($location, "w") or die("Unable to open file!");
fwrite($my_file, $text);
echo "response submitted successfully!";
fclose($my_file);
You need to give write permission on cred folder.
I want to update my table with javascript every couple seconds.
So far I made an ajax post request to my update.php and trigger if is set. Then do a mysql query and put the resultset in a json variable.
After this i get it with a XMLHttpRequest.
The problem is that every XMLHttpRequest example uses echo json. But
when I put my echo json in my isset post check it wont return anything
anymore.
I think the problem is that it can't echo?
This is my code:
PHP:
if (isset($_POST["updateTable"])) {
$result = mysqli_query($con,"SELECT * FROM users");
$row = mysqli_fetch_row($result);
$rsArray[] = array();
while ($row) {
$rsArray[] = $row;
$row = mysqli_fetch_row($result);
}
echo json_encode($rsArray);
}
AJAX:
var updateTable = "true";
setTimeout(function(){
$.ajax({
type: 'POST',
url: '../EXT_PHP/update.php',
data: { updateTable: updateTable }
});
console.log(updateTable);
}, 3000);
xmlhttpRequest:
setTimeout(function(){
var oReq = new XMLHttpRequest();
oReq.onload = function() {
alert(this.responseText);
};
oReq.open("get", "../EXT_PHP/update.php", true);
oReq.send();
}, 3000);
Have you Tried to set the header of you PHP Script to JSON?
header('Content-Type: application/json');
Note that the header must be set before the first output of your Programm (i.E. the first echo)
<?php
header('Content-Type: application/json');
if (isset($_POST["updateTable"])) {
$result = mysqli_query($con,"SELECT * FROM users");
$row = mysqli_fetch_row($result);
$rsArray[] = array();
while ($row) {
$rsArray[] = $row;
$row = mysqli_fetch_row($result);
}
echo json_encode($rsArray);
}
if that doenst work still you should check if there has been any errors within the json_encode function, there are some problems with encoding by time. Use
echo json_last_error_msg();
for this.
ok I have edited this to another couple of questions I've asked on a similar issue, but I really am in a rush so thought I'd start a new one, sorry if it bothers anyone.
first I have a php script on test.php on the apache server
<?php
//create connection
$con = mysqli_connect("localhost", "user", "password", "dbname");
//check connection
if (mysqli_connect_errno()){
echo "failed to connect to MySQL: " . mysqli_connect_error();
}
$grab = mysqli_query($con, "SELECT * FROM table");
$row = mysqli_fetch_array($grab);
$name = $row["name"];
$color = $row["color"];
$price = $row["price"];
$n1 = $name[0];
$c1 = $color[0];
$p1 = $price[0];
?>
Then I've got this ajax script set to fire onload of page a webpage written in html. so the load() function is onload of the page in the body tag. This script is in the head.
function load(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "test.php", true);
xmlhttp.send();
xmlhttp.onreadystatecahnge = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("itemNameLink1").innerHTML = "<?php echo $n1;?>;
}
}
}
ok so what I want is the $n1 variable in the php script to be used in the javascript ajax code. Where the script is, but I'm not sure where or how to make use of the variable, I've tried a few things. All that happens right now is the innerHTML of itemNameLink1 just disappears.
I'm quite new so any advise would be appreciated, thanks.
The response (this is what you echo in php) returned from request you can get by responseText attribute of XMLHttpRequest object.
So first your JS code should be:
function load(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "test.php", true);
xmlhttp.send();
xmlhttp.onreadystatecahnge = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("itemNameLink1").innerHTML = xmlhttp.responseText;
}
}
}
now in php echo $n1 variable:
....
$grab = mysqli_query($con, "SELECT * FROM table");
$row = mysqli_fetch_array($grab);
$name = $row["name"];
$color = $row["color"];
$price = $row["price"];
$n1 = $name[0];
$c1 = $color[0];
$p1 = $price[0];
// echo it to be returned to the request
echo $n1;
Update to use JSON for multiple variables
so if we do this:
$name = $row["name"];
$color = $row["color"];
$price = $row["price"];
$response = array
(
'name' => $name,
'color' => $color,
'price' => $price
);
echo json_encode($response);
Then in javascript we can parse it again to have data object containing 3 variables.
var data = JSON.parse(xmlhttp.responseText);
//for debugging you can log it to console to see the result
console.log(data);
document.getElementById("itemNameLink1").innerHTML = data.name; // or xmlhttp.responseText to see the response as text
Fetching all the rows:
$row = mysqli_fetch_array($grab); // this will fetch the data only once
you need to cycle through the result-set got from database: also better for performance to use assoc instead of array
$names = $color = $price = array();
while($row = mysqli_fetch_assoc($grab))
{
$names[] = $row['name'];
$color[] = $row['color'];
$price[] = $row['price'];
}
$response = array
(
'names' => $names,
'color' => $color,
'price' => $price
);
You can dynamically generate a javascript document with php that contains server side variables declared as javascript variables, and then link this in the head of your document, and then include this into your document head whenever server side variables are needed. This will also allow you to dynamically update the variable values upon page generation, so for example if you had a nonce or something that needs to change on each page load, the correct value can be passed upon each page load. to do this, you need to do a few things. First, create a php script and declare the correct headers for it to be interpreted as a script:
jsVars.php:
<?php
//declare javascript doc type
header("Content-type: text/javascript; charset=utf-8");
//tell the request not to cache this file so updated variables will not be incorrect if they change
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
header('Expires: 0'); // Proxies.
//create the javascript object
?>
var account = {
email: <?= $n1; ?>,
//if you need other account information, you can also add those into the object here
username: <?= /*some username variable here for example */ ?>
}
You can repeat this for any other information you need to pass to javascript on page load, and then reference your data using the namespaced javascript object (using object namespacing will prevent collisions with other script variables that may not have been anticipated.) wherever it is needed as follows:
<script type="text/javascript>
//put this wherever you need to reference the email in your javascript, or reference it directly with account.email
var email = account.email;
</script>
You can also put a conditional statement into the head of your document so it will only load on pages where it is needed (or if any permission checks or other criteria pass as well). If you load this before your other scripting files, it will be available in all of them, provided you are using it in a higher scope than your request.
<head>
<?php
//set the $require_user_info to true before page render when you require this info in your javascript so it only loads on pages where it is needed.
if($require_user_info == TRUE): ?>
<script type="text/javascript" href="http://example.com/path-to-your-script/jsVars.php" />
<?php endif; ?>
<script type="text/javascript" href="your-other-script-files-that-normally-load" />
</head>
You can also do this for any other scripts that have to load under specific criteria from the server.
You should define the PHP variable. And use that variable in your javascript:
<?php
$n1 = "asd";
?>
<html>
<head></head>
<body>
<div id="itemNameLink1"></div>
<script>
function load()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', '/test.php', true);
xmlhttp.send(null);
//Note you used `onreadystatecahnge` instead of `onreadystatechange`
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("itemNameLink1").innerHTML = '<?=$n1?>';
}
}
}
load();
</script>
</body>
</html>
I'm trying to transcribe what my programmer told me. He and I may be doing this all wrong, so I need to make sure he and I am doing it in the right manner. Here is what we are trying to do:
I have a page on a website and within that page, I have a button. When you click on it, I want it to (via AJAX so the page doesn't refresh)
Send data (time capture) to the DB
See that the DB recorded the change and in turn return a different value back to the site
This would in turn change the button, noting that it is in a recording mode.
Think of it in this way, the button is a timer. On click, it records the time in the DB, and in the DB it also changes the state to recording. Since it is in the recording phase, somehow it gets sent back to the website page and changes the button showing that it is recording. Naturally clicking again would stop it and record the time in the DB.
Here is how the snippets are set up (not working I think) ATM:
*sidenote: This is in Joomla
Page:
<script src="js/ajax_link.js" type="text/javascript"></script>
<div id="ajaxlink" onclick="loadurl('php/ticket_timer.php',<?php echo $row->id?>)">Start Time</div>
ajax_link.js
function loadurl(dest,ticket_id) {
jQuery.ajax({
url: dest,
type: "POST",
data: "ticket_id="+ticket_id,
success: function(msg){
alert(msg);
jQuery('#ajaxlink').text("Timer Stop");
}
});
}
ticket_timer.php
<?php
define( '_JEXEC', 1 );
define( 'DS', DIRECTORY_SEPARATOR );
define( 'JPATH_BASE', $_SERVER[ 'DOCUMENT_ROOT' ] );
require_once( JPATH_BASE . DS . 'includes' . DS . 'defines.php' );
require_once( JPATH_BASE . DS . 'includes' . DS . 'framework.php' );
require_once( JPATH_BASE . DS . 'libraries' . DS . 'joomla' . DS . 'factory.php' );
$mainframe =& JFactory::getApplication('site');
$ticket_id = $_POST['ticket_id'];
$user =& JFactory::getUser();
$user_id=$user->get('id');
//DB Query
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('id', 'ticket_id', 'user_id', 'times','current_time')));
$query->from($db->quoteName('#__support_ticket_times'));
$query->where($db->quoteName('ticket_id') . ' LIKE '. $db->quote($ticket_id));
$query->where('ticket_id = '. $ticket_id, 'AND')
->where('user_id=' . $user_id );
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();
$current_time=$results[0]->current_time;
$times=$results[0]->times;
$id_results = $db->loadColumn();
$db->setQuery($idquery);
$timesString = $times . ',' . date('Y-m-d g:i');
echo($timesString);
if(empty($results[0])){
$values = array(max($id_results)+1, $ticket_id, $user_id, $db->quote(date('Y-m-d g:i')),$db->quote(date('Y-m-d g:i')));
//echo "YOU GET NOTHING, MAKING NEW ROW";
$columns = array('id', 'ticket_id', 'user_id', 'times','current_time');
// Prepare the insert query.
$insert_query = $db->getQuery(true);
$insert_query
->insert($db->quoteName('#__support_ticket_times'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($insert_query);
$db->query();
}else{
//echo("CURRENT TIME" . $current_time);
if($current_time=='0000-00-00 00:00:00'){
echo "NO TIME";
$fields = array(
$db->quoteName('current_time'). '=' . $db->quote(date('Y-m-d g:i'))
);
}
// . $db->quote(date('Y-m-d g:i'))
else{
echo "ADD TIME";
$fields = array($db->quoteName('times') . '=' . $db->quote($timesString) ,
$db->quoteName('current_time'). "='0000-00-00 00:00:00'"
);
}
$update_query = $db->getQuery(true);
$conditions = array(
$db->quoteName('user_id') . '=' . $db->quote($user_id),
$db->quoteName('ticket_id') . '=' . $db->quote($ticket_id)
);
$update_query->update($db->quoteName('#__support_ticket_times'))->set($fields)->where($conditions);
$db->setQuery($update_query);
$db->query();
//echo $update_query;
}
?>
Can anyone suggest how to get the timer to fire back that the timer has started? Are we butchering this and is there a better way to code this?
You need to exchange some data between the PHP and the HTML page. The HTML page can be modified with Javascript, of course. The notation typically used for this kind of an exchange is JSON. In this example, we're using JSON to:
Send a boolean timerRunning to the PHP,
change the value in PHP,
send a reply,
modify the HTML page, and
store the timerRunning value in the HTML element.
So, for starters, we pass some data from the HTML element to Javascript using the HTML5 data- attributes, like this:
<div id="ajaxlink" data-url="php/ticket_timer.php" data-ticketId="<?php echo $row->id; ?> " data-timerRunning="false">Start Time</div>
In your Javascript, we access the parameters set above and send them to your PHP script via AJAX:
jQuery(document).ready(function($){
// Add an 'onClick' handler to the element
jQuery('#ajaxlink').on('click', function(event) {
// Get the url and ticket_id from the element's 'data-' attributes
var url = jQuery(this).data( 'url' );
var data = {
'ticketId' : jQuery(this).data( 'ticketId' ),
'timerRunning' : jQuery(this).data( 'timerRunning' )
}
// Send an AJAX request
jQuery.ajax({
type: 'POST',
url: url,
data: data
}).done( function(response) {
// This runs when the AJAX request succeeds
if ( 'undefined' == typeof( response.timerRunning ) ) {
alert( 'The server didn\'t tell the timer state' );
return;
}
// Store the value in the element
jQuery('#ajaxlink').data( 'timerRunning', response.timerRunning );
// Change the element HTML
if ( response.timerRunning )
jQuery('#ajaxlink').html( 'Stop Timer' );
else
jQuery('#ajaxlink').html( 'Start Timer' );
}).fail( function(jqXHR, textStatus, errorThrown ) {
// This runs when the AJAX request fails
alert( 'The AJAX request failed with the error ' + errorThrown );
});
});
});
In your PHP script, check the timerRunning value and react accordingly:
if ( isset( $_POST['timerRunning'] ) ) { // Check that we got some value for 'timerRunning'
if ( $_POST['timerRunning'] ) {
// The 'timerRunning' value is TRUE, the timer is running, now stop it
your_code_here_to_stop_the_timer();
$reply = array( 'timerRunning' => false );
} else {
// The 'timerRunning' value is FALSE, the timer isn't running, now start it
your_code_here_to_start_the_timer_and_whatever();
$reply = array( 'timerRunning' => true );
}
// Send the correct header for a JSON response
header('Content-type: application/json');
// Send the $reply array encoded as JSON
echo json_encode( $reply );
}