2

I simply just want to count the clicks of a button and save the amount of clicks to a text file, but I cannot seem to get this code to work. It does not save the amount of clicks.

In the HTML file I have a button that runs the JavaScript using onClick:

function do() {
    if (window.XMLHttpRequest){
              xhr = new XMLHttpRequest()
    }
    else 
    {
    if (window.ActiveXObject){
              var xhr = new ActiveXObject("Microsoft.XMLHTTP");
              }
              }
            xhr.open('GET','count.php',false);
            xhr.onreadystatechange = function() {
                if( xhr.readyState === 4 && xhr.status === 200 ) {
                    while(results.hasChildNodes()) {
                        results.removeChild(results.lastChild);
                    }
                    results.appendChild(document.createTextNode(xhr.responseText));
                }
            }
            xhr.send();
    }

In the PHP file we called, we have the following code:

<?php

    $clicks = file_get_contents("clicks.txt");
    $clicks++;

    $fp = fopen("clicks.txt", "w+");

    while ( !flock($fp, LOCK_EX) ) {    
        usleep(500000); // Delay half a second
    }

    fwrite($fp, $clicks);
    fclose($fp);
    flock($fp, LOCK_UN);

?>

Can you help me to find the problem in my code?
How would I read the text file in another HTML page?
(Just show the information of the text file.)

8
  • What is the problem in your code? Commented Jun 22, 2012 at 16:58
  • Can you access your PHP file directly in your browser, and see what happens? Commented Jun 22, 2012 at 16:59
  • Are there any error messages? Commented Jun 22, 2012 at 17:02
  • Tried now! It worked! Increases the amount in the text file. The problem might be in the JavaScript. Commented Jun 22, 2012 at 17:02
  • In case xhr = new XMLHttpRequest() should be used, the actual request to count.php is never executed because the relevant code is only present in the scope of else. Move the remaining code outside the if statement Commented Jun 22, 2012 at 17:04

2 Answers 2

1

Assuming the PHP page is functioning properly, the following should work:

<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <script type="text/javascript">

function getXMLHttp()
{
  var xmlHttp
  try
  {
    xmlHttp = new XMLHttpRequest();
  }
  catch(e)
  {
    try
    {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e)
    {
      try
      {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch(e)
      {
        alert("AJAX not supported.")
        return false;
      }
    }
  }
  return xmlHttp;
}

function MakeRequest()
{
  var xmlHttp = getXMLHttp();
  xmlHttp.onreadystatechange = function()
  {
    if(xmlHttp.readyState == 4)
    {
      HandleResponse(xmlHttp.responseText);
    }
  }
  xmlHttp.open("GET", "count.php", true); 
  xmlHttp.send(null);
}

function HandleResponse(response)
{
  document.getElementById('ResponseDiv').innerHTML = response;
}
        </script>
        <input type='button' onclick='MakeRequest();' value='Button'/>
        <br />
        <br />
        <div id='ResponseDiv'>
            Count
        </div>
    </body>
</html>
Sign up to request clarification or add additional context in comments.

4 Comments

Yes, proper error handling is important, doing AJAX requests while AJAX is not supported makes absolutely no sense and might cause errors.
If Ajax dose not work, I do not want to disturb the user. Is that OK to just remove it?
Only remove the alert("AJAX not supported.") line, then the user won't be disturbed in case AJAX is not available. Don't touch the try statements, they are required for proper error handling.
Thanks. They don't have to know if their click is not counted - agree? What should I do if I do not want to show the count on this page - just count clicks - but show it on another page?
1

A few things to note here on the php side.

1) You're opening the file with w+ which is for writing and reading what you've wrote. This also truncates your file BEFORE your lock is in place.

2) Your lock will cause parallel read and writes to fail. This can set $clicks to false and possibly wipe out your counter if the file is unlocked before fopen gets called.

3) You are not correctly releasing your lock because you close the handle while the lock is active. If this happens to be a long running script the lock will not be released until the script terminates.

This should solve all of those problems.

<?php

$fp = false;
// Open file for reading, then writing
while ( ($fp=fopen('clicks.txt','r+'))===false ) {
    usleep(250000); // Delay 1/4 second
}
// Obtain lock
while ( !flock($fp, LOCK_EX) ) {    
    usleep(250000); // Delay 1/4 second
}
// Read Clicks
$clicks = trim(fread($fp,1024));
// Add click
$clicks++;
// Empty file
ftruncate($fp,0);
// Write clicks
fwrite($fp, $clicks);
// Release Lock
flock($fp, LOCK_UN);
// Release handle
fclose($fp);

?>

3 Comments

How do I show the content of the text file in a complete diffrent web page?
Just open the file as read only (r), use a read lock instead of an exclusive lock so this script can't block you in the middle of a read. You should put the fopen and flock calls in a loop since you are locking it with a different script. This sort of thing is a LOT easier if you just used a database. :)
Okay. I am going to when I get a server. I have already written the XML request thingy... do I just use that and reprogram my PHP to save it to a server?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.