Ajax and/or PHP error - php

I am using AJAX along with PHP to communicate the time a visitor spends on a page to the server where the PHP scripts writes the time spent along with other details to a text file. The AJAX script is unable to call the php script and hence the visitor details are not being logged
<script type="text/javascript">
var startTime = new Date(); //Start the clock!
window.onbeforeunload = function() //When the user leaves the page(closes the window/tab, clicks a link)...
{
var endTime = new Date(); //Get the current time.
var timeSpent = (endTime - startTime); //Find out how long it's been.
var xmlhttp; //Make a variable for a new ajax request.
if (window.XMLHttpRequest) //If it's a decent browser...
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest(); //Open a new ajax request.
}
else //If it's a bad browser...
{
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //Open a different type of ajax call.
}
xmlhttp.open("GET","ajaxphp.php?time="+timeSpent,false); //The false at the end tells ajax to use a synchronous call which wont be severed by the user leaving.
xmlhttp.send(); //Send the request and don't wait for a response.
}
</script>
This is the AJAX script
The PHP script is given below too :
<?php
$time=$_GET["time"];
$countfile = "counter.txt";
// location of site statistics.
$statsfile = "stats.txt";
// checks whether the file exist, if not then server will create it.
if (file_exists($countfile)) {
// open the counter hit file.
$fp = fopen($countfile, "r");
// reads the counter hit file and gets the size of the file.
$output = fread($fp, filesize($countfile));
// close the counter hit file.
fclose($fp);
// get the integer value of the variable.
$count = intval($output);
}
// if file is doesn't exist, the server will create the counter hit file and gives a value of zero.
else {
$count = 0;
}
// showcount function starts here.
function ShowCount() {
// declares the global variables.
global $ShowCount, $countfile, $statsfile, $count,$time;
// get the current month.
$month = date('m');
// get the current day.
$day = date('d');
// get the current year.
$year = date('Y');
// get the current hour.
$hour = date('G');
// get the current minute.
$minute = date('i');
// get the current second.
$second = date('s');
// this is the date used in the stats file
$date = "$month/$day/$year $hour:$minute:$second";
// this is the remote IP address of the user.
$remoteip = getenv("REMOTE_ADDR");
// some of the browser details of the user.
$otherinfo = getenv("HTTP_USER_AGENT");
// retrieve the last URL where the user visited before visiting the current file.
$ref = getenv("HTTP_REFERER");
// open the statistics file.
$fp = fopen($statsfile, "a");
// put the given data into the statistics file.
fputs($fp, "Remote Address: $remoteip | ");
fputs($fp, "Information: $otherinfo | ");
fputs($fp, "Date: $date | ");
fputs($fp, "Referer: $ref\n");
fputs($fp, "Time Spent: $time | ")
// close the statistics file.
fclose($fp);
// adds 1 count to the counter hit file.
$count++;
// open the counter hit file.
$fp = fopen($countfile, "w");
// write at the counter hit file.
// if the value is 34, it will be changed to 35.
fwrite($fp, $count);
// close the counter hit file.
fclose($fp);
// showcount variable is equal to count variable.
$ShowCount = $count;
// return the value of the count variable into showcount variable.
return $ShowCount;
}
// display the value in the counter hits file.
echo showcount(), " visits";
?>

Try the following:
Access the url ajaxphp.php?time=123456 directly with your web browser and note what happens
Use an onclick handler on a button that activates the ajax call and note what happens
Use jquery instead for the ajax and note what happens
I'm sure one of these will give you more clues to why your current setup fails.

Related

Is that possible to refresh a page from another page in php

I have 2 PHP pages called view.php and Operation.php
In view.php I have one execute button which calls the operation.php page at the backend execution - Not redirecting.
In Operation.php I am doing some DB activity.
* For that I am changing the status as In-progress initially
* And changing to Pass/Fail at the end of the page based on the execution.
My question is: Is it possible to refresh the view.php from the Operation.php page once it updates the status as In-progress?
Note: without Ajax and Header method(I don't want to redirect, because
I am not redirected to Operation.php, User is able to see only the
view.php)
EDIT : Below is my code
view.php
echo "<td><a id='execute' href='' onclick='execute_adhoc_prep_page($workflow_id,".$row['Task_Number'].",\"".$row['Script_Name']."\")'>
function execute_adhoc_prep_page(id,tnum,scriptName){
$.ajax({
url: 'view.php', // redirecting to same pages.
method: "POST",
data: {
id: id,
tnum:tnum,
scriptName:scriptName
},
success: function(data) {
console.log(data);
}
});
}
if(isset($_POST['id']) && isset($_POST['tnum']) && isset($_POST['scriptName']) ){
$workflow_id = $_POST['id'];
$taskNum = $_POST['tnum'];
$script = $_POST['scriptName'];
$logfile = fopen("C:\Admin\www\Trigger_next.txt", "w") or die("Unable to open file!");
fwrite($logfile,$workflow_id);
fwrite($logfile,$taskNum);
// using PowerShell via task scheduler I am calling the operation.php script
}
In Operation.php
$myfile = fopen("C:\Admin\www\Trigger_next.txt", "r") or die("Unable to open file!");
if(0 == filesize("C:\Admin\www\xpress\Trigger_next.txt")){
echo "file has NO data";
}else{
echo "file has data";
while (($line = fgets($myfile)) !== false) {
$array[] = $line;
}
fclose($myfile);
}
$workflow_id = $array[0];
$taskNum = $array[1];
// here I am changing the status as I in DB
// And I want to refresh the view.php page
// Once All the activity is completed it will change the status to Pass/Fail
Actually, In my project there is 2 way of calling this Operation.php -> one is Manual execute another one is Automatic (TS) That's why I am doing multiple calls. I know its hard to understand, but please help me to get the way to refresh view.php from operation.php
There is no issue in the code it's updating in the backend, all PS1,TS are working fine, the only thing is I need to refresh the view.php after it is set to in-progress in Operation.php to show it to the user.

How do you update an SSE (Server Sent Event) message with POST request

Please excuse me, I am quite new with backend development.
What I try to accomplish is pretty straight forward. I want to send a POST request to my server. As an example; www.domain.com/api.php?id=foo
And with that value update my SSE with that parameter. But I can't seem to figure it out. I guess I need to store that value somehow in a database or a text file? Preferably in a text file for simplicity.
What I have now:
HTML file:
<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
PHP file:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$test = "One";
echo "data: Page: {$test}\n\n";
flush();
?>
So my question is: How do I change the value of the variable 'test' from a POST request so that the SSE is updated?
It works perfectly now, if I change the value in the PHP file it starts spitting that out in the HTML. But how do I change that value with something external like a POST call?
Thank you! And let me know if I need to clarify.
Okay, so I managed to make it work with a SQL database. :) This is my solution:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// QUERY THE DATABASE FOR CURRENT PAGE NUMBER
$db = new mysqli($host, $username, $password, $database_name); // connect to the DB
$query = $db->prepare("SELECT number FROM page WHERE itemId=1"); // prepate a query
$query->execute(); // actually perform the query
$result = $query->get_result(); // retrieve the result so it can be used inside PHP
$r = $result->fetch_array(MYSQLI_ASSOC); // bind the data from the first result row to $r
// ECHO SERVER SENT EVENT
$pageNumber = $r['number'];
echo "data: Page: {$pageNumber}\n\n";
flush();
// UPDATE QUERY BASED ON GET PARAMATERS
$siteURL = $_GET['page'];
$updateQuery = $db->prepare("UPDATE `page` SET `number` = '$siteURL' WHERE `page`.`itemId` = 1;");
$updateQuery->execute();
?>

Data getting lost in server-sent event with PHP handler

I'm working on a one-way messaging system using server-sent events. I have a file (server.html) which sends the contents of a textarea to a PHP file (handler.php).
function sendSubtitle(val) {
var xhr = new XMLHttpRequest();
var url = "handler.php";
var postdata = "s=" + val;
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(postdata);
//alert(val);
}
This works (alert(val) displays the text in the textarea).
My handler.php code looks like this:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$stringData = $_POST['s'];
echo "data: Data is {$stringData}\n\n";
flush();
And the relevant part of my SSE receiver file (client.html) is as follows:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("handler.php");
source.onmessage = function(event) {
var textarea = document.getElementById('subtitles');
textarea.value += event.data + "<br>";
textarea.scrollTop = textarea.scrollHeight;
};
} else {
document.getElementById("subtitles").value = "Server-sent events not supported.";
}
The problem is that client.html only displays "data: Data is", so the text from server.html is getting lost somewhere along the way. I imagine it's the PHP code that's falling over, but I can't work out what's wrong. If anyone can help, I'd appreciate it.
EDIT
I chose to use SSE as opposed to websockets as I only need one-way communication: server.html should push the contents of its textarea to client.html whenever it changes. All the examples of SSE that I've looked at (and I've looked at a lot!) send "automatic" time-based data. I haven't seen any that use real-time user input. So perhaps I should clarify my original question and ask, "How can I use SSE to update a DIV (or whatever) in web page B whenever the user types in a textarea in web page A?"
UPDATE
I've narrowed the issue down to the while loop in the PHP file and have therefore asked a new question: Server-side PHP event page not loading when using while loop
Assuming you want to send a value from server.html and a value at client.html will be automatically updated...
You will need to store the new value somewhere because multiple instances of a script do not share variables just like that. This new value can be stored in a file, database or as a session variable, etc.
Steps:
Send new value to phpScript1 with clientScript1.
Store new value with phpScript1.
Connect clientScript2 to phpScript2.
Send stored value to clientScript2 if it is changed.
Getting the new value 'on the fly' means phpScript2 must loop execution and send a message to clientScript2 whenever the value has been changed by clientScript1.
Of course there are more and different approaches to achieve the same results.
Below there's some code from a scratchpad I've used in previous project.
Most parts come from a class (which is in development) so I had to adopt quite a lot of code. Also I've tried to fit it into your existing code.
Hopefully I didn't introduce any errors.
Do note I did not take any validation of your value into account! Also the code isn't debugged or optimized, so it's not ready for production.
Client side (send new value, e.g. your code):
function sendSubtitle(val) {
var xhr = new XMLHttpRequest();
var url = "handler.php";
var postdata = "s=" + val;
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(postdata);
//alert(val);
}
Server side (store new value):
<?php
session_start();
$_SESSION['s'] = $_POST['s'];
Client side (get new value):
//Check for SSE support at client side.
if (!!window.EventSource) {
var es = new EventSource("SSE_server.php");
} else {
console.log("SSE is not supported by your client");
//You could fallback on XHR requests.
}
//Define eventhandler for opening connection.
es.addEventListener('open', function(e) {
console.log("Connection opened!");
}, false);
//Define evenhandler for failing SSE request.
es.addEventListener('error', function(event) {
/*
* readyState defines the connection status:
* 0 = CONNECTING: Connecting
* 1 = OPEN: Open
* 2 = CLOSED: Closed
*/
if (es.readyState == EventSource.CLOSED) {
// Connection was closed.
} else {
es.close(); //Close to prevent a reconnection.
console.log("EventSource failed.");
}
});
//Define evenhandler for any response recieved.
es.addEventListener('message', function(event) {
console.log('Response recieved: ' + event.data);
}, false);
// Or define a listener for named event: event1
es.addEventListener('event1', function(event) {
var response = JSON.parse(event.data);
var textarea = document.getElementById("subtitles");
textarea.value += response + "<br>";
textarea.scrollTop = textarea.scrollHeight;
});
Server side (send new value):
<?php
$id = 0;
$event = 'event1';
$oldValue = null;
session_start();
//Validate the clients request headers.
if (headers_sent($file, $line)) {
header("HTTP/1.1 400 Bad Request");
exit('Headers already sent in %s at line %d, cannot send data to client correctly.');
}
if (isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] != 'text/event-stream') {
header("HTTP/1.1 400 Bad Request");
exit('The client does not accept the correct response format.');
}
//Disable time limit
#set_time_limit(0);
//Initialize the output buffer
if(function_exists('apache_setenv')){
#apache_setenv('no-gzip', 1);
}
#ini_set('zlib.output_compression', 0);
#ini_set('implicit_flush', 1);
while (ob_get_level() != 0) {
ob_end_flush();
}
ob_implicit_flush(1);
ob_start();
//Send the proper headers
header('Content-Type: text/event-stream; charset=UTF-8');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no'); // Disables FastCGI Buffering on Nginx
//Record start time
$start = time();
//Keep the script running
while(true){
if((time() - $start) % 300 == 0){
//Send a random message every 300ms to keep the connection alive.
echo ': ' . sha1( mt_rand() ) . "\n\n";
}
//If a new value hasn't been sent yet, set it to default.
session_start();
if (!array_key_exists('s', $_SESSION)) {
$_SESSION['s'] = null;
}
//Check if value has been changed.
if ($oldValue !== $_SESSION['s']) {
//Value is changed
$oldValue = $_SESSION['s'];
echo 'id: ' . $id++ . PHP_EOL; //Id of message
echo 'event: ' . $event . PHP_EOL; //Event Name to trigger the client side eventhandler
echo 'retry: 5000' . PHP_EOL; //Define custom reconnection time. (Default to 3000ms when not specified)
echo 'data: ' . json_encode($_SESSION['s']) . PHP_EOL; //Data to send to client side eventhandler
//Note: When sending html, you might need to encode with flags: JSON_HEX_QUOT | JSON_HEX_TAG
echo PHP_EOL;
//Send Data in the output buffer buffer to client.
#ob_flush();
#flush();
}
//Close session to release the lock
session_write_close();
if ( connection_aborted() ) {
//Connection is aborted at client side.
break;
}
if((time() - $start) > 600) {
//break if the time exceeds the limit of 600ms.
//Client will retry to open the connection and start this script again.
//The limit should be larger than the time needed by the script for a single loop.
break;
}
//Sleep for reducing processor load.
usleep(500000);
}
You called handler.php first time in the server.html and again in client.html. Both are different processes. The variable state won't be retained in the web server. You need to store it somewhere if you want that value in another PHP process. May be you can use sessions or database.
While using sessions you can store the values in two files like:
<?php
//server.php
session_start();
$_SESSION['s'] = $_POST['s'];
And in client.php
<?php
//client.php
session_start();
echo "data: Data is ".$_SESSION['s']."\n\n";

tracking clicks from edm to conversion

I need to track click-thru on my edm, and i need to see how many of these click-thru actually convert (within 30 days) at the end of the day.
So my idea is, on every link on the edm, i point them to my domain (siteA.com), where i set a cookie, then redirect them to the actual site where they initially clicked on (siteB.com).
The user then clicks on buy now and gets sent to the purchasing site (siteC.com).
On the purchase confirmation page, i call a script that resides on siteA.com, to grab the cookie that i set (if any) and logs the transaction.
So far, i managed to get to step 3, where it calls the script residing on siteA.com, but i am unable to get the value of the cookie that i set earlier. I know that it called the script, because the log file gets written to with the transaction details, but no cookie details. Am i using the wrong callback to the script on siteA.com? Or am i missing something totally?
So this is the code i'm using on the confirmation page:
<script type="text/javascript">
var adJsHost = (("https:" == document.location.protocol) ? "https://" : "http://");
document.write(unescape("%3Cscript src='" + adJsHost + "siteA.com/tracker/tracking.php' type='text/javascript'%3E%3C/script%3E"));
logTransaction (orderValue , orderRef, merchantID, uid , htname, pixel, payoutCodes, offlineCode,checkOutDate,currencyCode);
</script>
on the tracking.php file, i have the following javascript code:
function logTransaction (orderValue , orderRef, merchantID, uid , htname, pixel, payoutCodes, offlineCode,checkOutDate,currencyCode)
{
var xmlhttp;
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","http://siteA.com/tracker/confirmation.php?tranID="+uid+"&orderValue="+orderValue+"&currencyCode="+currencyCode,true);
xmlhttp.send();
}
and finally, this is what i have on the confirmation.php
if (isset($_COOKIE["myedm"])) {
$cookie_array = explode(",", $_COOKIE["myedm"]);
$mc_cid = $cookie_array[0];
$mc_eid = $cookie_array[1];
$numberofvisits = $cookie_array[2];
}
$tranID = $_GET['tranID'];
$orderValue = $_GET['orderValue'];
$currencyCode = $_GET['currencyCode'];
$file = 'people.txt';
// Open the file to get existing content
$current = file_get_contents($file);
// Append a new person to the file
$current .= "\n tranID:".$tranID;
$current .= "\n currencyCode:".$currencyCode;
$current .= "\n orderValue:".$orderValue;
$current .= "\n mc_cid:".$mc_cid;
$current .= "\n mc_eid:".$mc_eid;
$current .= "\n numberofvisits:".$numberofvisits;
// Write the contents back to the file
file_put_contents($file, $current);
Update:
I fixed the problem.. kind of..
changed the javascript calling the file to using a img pix, i.e.
<img src="http://siteA.com/tracker/confirmation.php?tranID=123&orderValue=150&currencyCode=USD">
it works! but only in firefox n chrome. In IE, doesn't seem to want to set the cookie even..

javascript is not sending data through php code

Hi i have a requirement where i need to execute mysql queries once user will confirm Ok from confirmation box.In my case what ever data i am passing to insert_details.php is not working. one more thing i would like to bring to your notice that i need to send data to different script and navigate it to different page.kindly suggest where is the problem?
<script type="text/javascript">
var r=confirm("This email address already exits in our database. Do you want to continue?");
if (r==true)
{
var dataObj = {
fname : document.getElementById('fname').value,
phone : document.getElementById('phone').value,
pemail : document.getElementById('email').value
}
var xhr = new XMLHttpRequest();
xhr.open("POST","insert_details.php", true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(JSON.stringify(dataObj));
xhr.onreadystatechange = function() {
if (xhr.readyState>3) {
window.location = 'http://localhost/myproject/test.php?eid=<?php echo $primary_email; ?>';
}
}
alert("test");
}
else
{
window.location = 'http://localhost/myproject/registration_request.php'
}
</script>
code in insert_details.php
$date = "Date:" . date("d/m/Y h:i:s") . "\n"; //to get today's date and time
$logfile = "testing";
$fpath ="myproject/";
$filepath = $fpath .$logfile . '-log-' . date('Y-m-d') . '.csv'; //path of error log file
$fh1 = fopen($filepath, 'a') or die("can't open file"); //opening the error log file
fwrite($fh1, "******************index*******************" . "\n");
fwrite($fh1, $date);
$test=json_decode(file_get_contents('php://input'));
fwrite($fh1, $test[0]);
You are not sending up a named pair. You are just sending up the value of the textbox.
what is looks like as a string.
xhr.send("myEmail#example.com");
Second you have a race condition between the Ajax call and the window.location.href.
You need to wait for the response to come back before doing the redirection.
Basic idea:
var dataObj = {
fname : document.getElementById('fname').value,
phone : document.getElementById('phone').value,
pemail : document.getElementById('email').value
}
xhr.onreadystatechange = function() {
if (xhr.readyState>=3) {
window.location = 'http://localhost/myproject/test.php?eid=<?php echo $primary_email; ?>';
}
}
xhr.send(JSON.stringify(dataObj));

Categories