2

This is my first website and project and I'd like to be able to complete it.

I have a small, simple site running on a Raspberry Pi 2 in my room. On the site, users vote yes or no. My problem is, something isn't working.

The browser is not showing the correct values for the variables taken from the text file. When the yes or no button is pressed, PHP should add 1 to either the $yes variable or the $no variable depending on which button was clicked, obviously. This will be clearer when you see the code below.

Sometimes however, the variable is not echoed correctly in the table at the bottom of the page. The variable in the text file is updated each time the button is pressed. This leads me to believe that it's to do with the echoing or the writing and reading speed. On refreshing the page, the table usually updates.

The code below is my HTML page. I think this is correct. Apologies if this shows my lack of experience; I'm open to all suggestions!

    <!DOCTYPE HTML>
<!--start of html. sets background image-->
<html style="background-image: url(confectionary.png); color:black; padding:20px;">
<head>
    <title>Is the Sky Blue | Vote</title>
        <!--sets up js funtion for buttons to call and start running it-->
        <script type="text/javascript" src="vote.js"></script>
            <!--calls css to position yes and no buttons-->
            <link rel="stylesheet" href="navbar.css">
</head>
<body>
<!--first header-->
<h1 align="center"><font size="7">Is the sky blue?</h1>
    <!--div with class="menu" allow css above to center the yes and no buttons-->
    <div class="menu">
        <ul>
        <li name="vote" value="0" onclick="getVote(0)"><font size="6"><a href="yes.php">Yes</a></li>
        <li name="vote" value="1" onclick="getVote(1)"><font size="6"><a href="no.php">No</a></li>
        </ul>
    </div>

<!--image of the sky-->
<div style="text-align: center;"><img style="width: 800px; height: 600px;" alt="" src="sky.jpg"></div>

</body>
</html>

yes.php below

    <!DOCTYPE HTML>
<!--start of html. sets background image-->
<html style="background-image: url(confectionary.png); color:black; padding:20px;">
<head>
    <title>Thank You For Voting</title>
        <!--calls css to position yes and no buttons-->
        <link rel="stylesheet" href="navbar.css">
</head>
<body>
<!--first header-->
<h1 align="center"><font size="6">Thank You For Voting</h1>
    <div class="menu">
        <ul>
        <li><font size="6"><a href="index.html">Home</a></li>
        </ul>
    </div>
<hr>
<p align="center"><font size="5">You have voted that the sky is blue.</p>

<!--first part of php which declares variables for the table to use-->
<?php
$filename = "poll_result.txt";
$content = file($filename);
$array = explode("||", $content[0]);
$yes = $array[0];
$no = $array[1];
$total = $yes + $no;
?>

<!--table of results and graph-->
<h4>Result:</h4>
<table>
<tr>
<td>Yes:</td>
<td>
<img src="poll.gif"
width='<?php echo(100*round($yes/($no+$yes),2)); ?>'
height='20'>
<?php echo(100*round($yes/($no+$yes),2)); ?>%
</td>
</tr>
<tr>
<td>No:</td>
<td>
<img src="poll.gif"
width='<?php echo(100*round($no/($no+$yes),2)); ?>'
height='20'>
<?php echo(100*round($no/($no+$yes),2)); ?>%
</td>
</tr>
<tr>
<td>Total number of votes:</td>
<td><?php echo $total; ?></td>
</tr>
</table>

</body>
</html>

vote.js below

function getVote(int) {
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  } else {  // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
      document.getElementById("poll").innerHTML=xmlhttp.responseText;
    }
  }
  xmlhttp.open("GET","poll_vote.php?vote="+int,true);
  xmlhttp.send();
}

poll_vote.php below

<?php
$vote = $_REQUEST['vote'];

//get content of textfile
$filename = "poll_result.txt";
$content = file($filename);

//put content in array
$array = explode("||", $content[0]);
$yes = $array[0];
$no = $array[1];

if ($vote == 0) {
  $yes = $yes + 1;
}
if ($vote == 1) {
  $no = $no + 1;
}

//insert votes to txt file
$insertvote = $yes."||".$no;
$fp = fopen($filename,"w");
fputs($fp,$insertvote);
fclose($fp);
?>

This is most of the code behind the site.

Why does the $total variable not get shown properly in the table?

  • After you've defined `$array`, temporarily add `print_r($array);` on its own line. This will dump the array contents for you to examine. What does it contain? – halfer Apr 26 '15 at 19:54
  • The same thing happens so `$array[0]` is still not getting 1 added to it. `$array[0] + $array[1]` still equals `$total`. –  Apr 26 '15 at 21:38
  • OK, so there are two issues at play here, and I think you are looking at the wrong one. They are: (1) does the vote display page show the votes correctly? and (2) do the vote scripts increase the vote counts in the text file? Since you've shown the code for the first one, it seems that you have assumed the problem is there, but I suspect it's in the second place (you say you expect one of the tallies to increase, but the shown code does not do that). Can we see one of the vote scripts? I expect they are similar, except for the yes/no response. – halfer Apr 26 '15 at 21:47
  • I have updated the question to also include, "vote.js" and "poll_vote.php". –  Apr 26 '15 at 22:29
  • OK, next step is to see if the AJAX operation is working. Have you checked your [browser network monitor](https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor) when the AJAX op fires? You need to ensure it is found and working correctly (at a minimum, returns a 200 response code). – halfer Apr 27 '15 at 08:22
  • Should I use Wireshark for this? –  Apr 27 '15 at 16:36
  • No. I hyperlinked my comment so you can see how to do it! `:-)` – halfer Apr 27 '15 at 17:40
  • https://www.dropbox.com/s/gjr2smgm6900be4/Screen%20Shot%2004-27-15%20at%2009.51%20PM.JPG?dl=0 this is an image of what the network monitor shows –  Apr 27 '15 at 20:55

1 Answers1

0

I suspect you might be facing one or both of the problems below:

Doing two things simultaneously - behavior might be unexpected?

When you click on the "Yes" link, you are doing two things at the same time:

  1. Making the AJAX request to poll_vote.php
  2. Navigating to yes.php

If the navigation occurs faster than the AJAX request can complete, then the AJAX request might be terminated. Or, it may succeed, but poll_vote.php was retrieved before the AJAX request completed, which means poll_vote.php might be showing the outdated results (a refresh should work in this case).

What I might do is (quick hack) use location.href="yes.php" after the document.getElementById("poll").innerHTML=xmlhttp.responseText; line, and remove the A tag so that only when the AJAX request is completed does the navigation to yes.php take place. A cleaner way is simply to move the polling code to the yes.php (meaning you update the text file values in yes.php itself, before outputting the totals and such) thus avoiding XMLHttpRequest completely. You can write the code in another file and then include it in yes.php, so that the code can also be included in no.php and you can avoid having to repeat twice.

Browser caching

The browser might be caching the poll_vote.php page, or the yes.php page, or both! For example, when you run

 xmlhttp.open("GET","poll_vote.php?vote="+int, true);

The browser might decide: hey, I've already retrieved poll_vote.php?vote=0 previously, I don't need to retrieve it again, and thus the server-side (PHP) never receives the request. To get around this problem you can append a random value to the GET request e.g.

xmlhttp.open("GET","poll_vote.php?vote="+int+"&rand="+Math.random(),true);

or some other ways as mentioned in Prevent browser caching of jQuery AJAX call result. A more "elegant" solution would be to have poll_vote.php send headers to tell the browser: don't cache me! See How to prevent Browser cache for php site

The other problem might be that yes.php is also cached! As with above, the browser thinks, I just retrieved yes.php, I don't have to retrieve it again, so it shows the page as it was previously retrieved (with the outdated data).

PHP supposedly sends the no-cache headers by default, but when I tested your code, it works okay in Chrome, but not in IE. It seems that (when I tried) IE caches the poll_vote.php file, hence I had to add that random number thing to get it to work consistently in IE.

Community
  • 1
  • 1
Kai Yao
  • 351
  • 1
  • 6
  • Thank you very much for the time and effort you have put into this answer. It's something I really appreciate and I hope you know that. I give both the random number generator, and the no-caching techniques a go and I believe the former has solved my problem. However the page was still cached when I checked chrome://cache so I think I'm doing something wrong here. Is there a better way than others to prevent caching of an html file/page? Thank you very much again for your help! –  May 16 '15 at 00:08