PHP Poll with Results on Same Page - php

There was a great article posted by CSS-Tricks.com describing how to create a poll using PHP and a MySQL database. I've followed this and created a nice poll for myself. I noticed in the comments a mentioning of using AJAX to show the results on the same page instead of a completely separate page.
I am wondering what is the best way to display PHP Poll results on the same page?
UPDATE:
The answer is really simple. In fact, CSS-Tricks' poll without AJAX in my opinion is more difficult since it requires a database. This one does not!
The complete tutorial for creating a poll with PHP and AJAX is can be viewed here:
http://www.w3schools.com/php/php_ajax_poll.asp
I just wanted to clarify how to set the arrays up for more than two poll options. First you get the "database" (i.e. text file, not MySql).
//get content of textfile
$filename = "poll_result.txt";
$content = file($filename);
Then you put the data in an array:
//put content in array
$array = explode("||", $content[0]);
$yes = $array[0];
$no = $array[1];
//if multiple options
$array = explode("||", $content[0]);
$option1array = $array[0]; //note: these values can be text values also. If text value, nothing changes with this part of the code.
$option2array = $array[1];
$option3array = $array[2];
$option4array = $array[3];
Store Data in "database"
if ($vote == 'option1')
{
$option1array = $option1array + 1;
}
if ($vote == 'option2')
{
$option2array = $option2array + 1;
}
if ($vote == 'option3')
{
$option3array = $option3array + 1;
}
if ($vote == 'option4')
{
$option4array = $option4array + 1;
}
Then, output your results. For file structure and AJAX script, see the complete tutorial.

You have two options:
1) Use ajax just as you suggested in your question, when you submit the vote via ajax, get the results back as the response.
2) Get the results before the vote is submitted, it will still need to be submitted via ajax if you want to stay on the same page. But instead of using ajax to get back the results, since you have the results prior to the vote you could just add one vote to the appropriate selection choice, then use Javascript / CSS to change the results from hidden to displayed.

Related

random(non- repeating) file generator on click of button in php

i want to display 5 php files content randomly but non repeating when clicked a button [NEXT] using php/javascript (that works in php desktop as well).
the code i used did displayed random web page on page load but i did came across repeated web page
this is the code i used for index.php file:
<?php
$RandomList = array();
$RandomList[] = "/review/review-a1.php";
$RandomList[] = "/review/review-a2.php";
$RandomList[] = "/review/review-a3.php";
$RandomList[] = "/review/review-a4.php";
readfile($_SERVER['DOCUMENT_ROOT'].$RandomList[rand(0,count($RandomList)-1)]);
?>
please suggest how to get non repeated files .
Just save paths you already used in the session:
//Read visited paths from session or create a new list.
//?? works only in PHP7+. Use isset()?: instead of ?? for previous versions
$visitedPaths = $_SESSION['visitedPaths'] ?? [];
//Your list, just slightly changed syntax. Same thing
$randomList = [
"/review/review-a1.php",
"/review/review-a2.php",
"/review/review-a3.php",
"/review/review-a4.php"
];
//Remove all paths that were already visited from the randomList
$randomList = array_diff($randomList, $visitedPaths);
//You need to check now if there are paths left
if (!empty($randomList)) {
//The user did not load all files, so we can show him the next one
//Use array_rand() rather than $array[rand(0, count($array) -1)]
$randomPath = $randomList[array_rand($randomList)];
readfile($_SERVER['DOCUMENT_ROOT'] . $randomPath);
//Now we need to save, that the user loaded this file
$visitedPaths[] = $randomPath;
//And we need to save the new list in the session
$_SESSION['visitedPaths'] = $visitedPaths;
} else {
//TODO: Add some logic in case all paths have been visited
}

Basic addition for form security gives wrong answer PHP

I have a basic math question that the user has to answer before they can send an email:
$first_num = rand(1, 4);
$second_num = rand(1, 4);
$send = #$_POST['send'];
if($send){
//The user's answer from the input box
$answer = #$_POST["answer"];
if($answer == $first_num + $second_num) {
//Do stuff
}
else {
$error_message = "You answered the question wrong!";
}
}
I answer the question correctly (unless my first grade math is off!) yet it says I have the question wrong. I am not sure what the issue is but I imagine it is something to do with the fact that php executes immediately when the page is loaded and so new numbers are generated as soon as the user presses the submit button? Or am I way off? If that is the case, what can be done to solve this?
The problem is that you are setting your values every time your script is called. So when you post your form, two new values are set and they are likely not the same values as when you called the script the first time to show the form.
You should store your variables in a session and retrieve these values when you process your post request.
Something like:
session_start();
if (!isset($_SESSION['numbers']))
{
$_SESSION['numbers']['first'] = rand(1, 4);
$_SESSION['numbers']['second'] = rand(1, 4);
}
...
if ($answer == $_SESSION['numbers']['first'] + $_SESSION['numbers']['second']) {
//Do stuff
/**
unset the variables after successfully processing the form so that
you will get new ones next time you open the form
*/
unset($_SESSION['numbers']);
...
Note that you will need to use the session variables everywhere where you are using your own variables right now.
You should include the two numbers as hidden form inputs in your HTML, and then do the math with the entries in your $_POST array.
Make your code start like this instead:
$first_num = $_POST["first_num"];
$second_num = $_POST["second_num"];

Random SQL record while excluding specific records

I have a CodeIgniter PHP application that shows two movie covers. Beside them is a "random movie" button that uses AJAX to replace the two movies with a new set of movies. You can continue to click this, over and over, and see it continue to replace the images of the movie covers. The first two covers to show are set as the defaults, and they should never show after the user has clicked the random movie button. The problem is this: When clicking the random movie button, it will some times take many clicks to finally show a new cover. That is, the same cover will be returned multiple times in a row. The two different covers being fetched are being called from slightly different URLs, so they will rarely both break at the same time. This lets me know that it is refreshing, but that the function is returning the same movie multiple times. If I access the url that is being called via AJAX directly, I never see this take place since I have used the Session class to store the last movie's and exclude it from the SQL query (i.e. WHERE id NOT IN ($default_movie, $last_movie)). Any idea why accessing the url directly would work fine, but when calling via AJAX, I'm seeing this behavior?
I know this may not have been as clear as possible, so let me know if I can clarify something that doesn't make sense. I'll add code if that helps as well. Thanks friends!
Query to get random movie:
SELECT * FROM (`movies`) WHERE `id` NOT IN (2, 10) ORDER BY RAND() LIMIT 1
Model method:
public function getRandom($count = 1, $featured = FALSE, $series = FALSE, $exclude = 0, $last = 0) {
$this->db->order_by('id', 'random');
$this->db->limit(1);
$conditions = array();
if ($exclude > 0) {
$conditions['id !='] = $exclude;
}
if ($last > 0) {
if (!empty($conditions['id !='])) {
$conditionsNotIn = "id NOT IN (" . $conditions['id !=']. ", $last)";
unset($conditions['id !=']);
$this->db->where($conditionsNotIn);
} else {
$conditions['id !='] = $last;
}
}
if ($featured) {
$conditions['featured'] = 1;
}
if ($series) {
$conditions['current_series'] = 1;
}
$movie = $this->db->get_where('movies', $conditions);
$movie = $movie->row();
if (!is_null($movie)) {
return $movie;
} else {
return FALSE;
}
}
Any idea why accessing the url directly would work fine, but when
calling via AJAX, I'm seeing this behavior?
I have an idea yes.
Browser caching.. PITA!
Try turning off caching explicitly:
$.ajaxSetup({cache: false});
Put that before your ajax request, assuming you're using jQuery.
If you're not you need to append some random variable to the url, this keep the browser from caching the requests.

php countering in javascript doesn't work

okay here is my code :
var co = 0;
var comp = '';
<?php $i = 0;?>
while (co < <?php echo $db->count_rows(); ?>)
{
if ((parseInt(value) >= <?php echo $mfr[$i] ?>) && (parseInt(value) <= <?php echo $mto[$i] ?>))
{
comp = 'T';
break;
}
co++;
<?php $i++; ?>
}
i'm still learning about this whole php and javascript thing, and i know there are many things that i still had to work to to improve my understanding to this both language. that's why i really need your help in this
i'm trying to get the while iteration to work so i can compare the variable from javascript with variable from php which took the value from database. the php variable ('$mfr' and '$mto'), as you can see, is an array. now i want it to look at every element of both and if it meets the condition then it will update the variable 'comp' and stop the whole while iteration
but the problem is the '$i' variable doesn't do the iteration thing. it runs only once so my '$mfr' and '$mto' value doesn't go anywhere. how can i fix this so i can compare the javascript value with the php '$mfr' and '$mto' value?
your help would be much appreciated, thank you :)
EDIT
well, it is actually a function of custom validation for jqgrid.
and i do know that php is a server-side and javascript is a client-side language theoretically, though i don't really know it is practically
what i'm actually trying to do is when a user input a value and submit it, the system will check whether the value that was entered are between value of 'fromid' and 'toid' column of a table in database
here is my full code of the function
function checkid(value)
{
var co = 0;
var comp = '';
<?php $i = 0;?>
while (co < <?php echo $db->count_rows(); ?>)
{
if ((parseInt(value) >= <?php echo $mfr[$i] ?>) && (parseInt(value) <= <?php echo $mto[$i] ?>))
{
comp = 'T';
break;
}
co++;
<?php echo $i++; ?>
}
if (comp != 'T')
{
return [true, "", ""];
}
else
{
return [false, "Value entered is already between a range. Please try again!", ""];
}
}
while this is how i got the '$mfr' and '$mto' variable
<?php
$db=new database($dbtype, $dbhost, $database, $dbuser, $dbpassword, $port, $dsn);
$db->query("select fromid, toid from CORE_ID");
$i = 0;
while($row = $db->get_row())
{
$mfr[$i] = $row[fromid];
$mto[$i] = $row[toid];
$i++;
}
?>
if theres any better way to do this, then please do tell me
Typically, PHP is for server side logic and JS is for client side logic. If you want to send a value from JS to be processed in PHP, you'll probably need to use something like AJAX, which jQuery makes pretty easy with jQuery.ajax().
Getting the client value to be processed is the difficult part. Once you can do that, rewriting your code logic in full PHP should not be difficult.
EDIT: If I'm misunderstanding where variable value comes from, please say so!
EDIT 2: It looks like you want to have client input compared to server side data. JS will not have access to your PHP variables unless they are specifically sent there. Likewise, you can send your JS value to the server for validation in the PHP.
In your case, you could use JSON to send send the JS your validation dates. Assuming you don't have too many dates, it will probably be faster than sending a value to the server and waiting for a response.
I found a good example of using JSON at another post. You can send an array like:
<?php
$xdata = array(
'foo' => 'bar',
'baz' => array('green','blue')
);
?>
<script type="text/javascript">
var xdata = <?php echo json_encode($xdata); ?>;
alert(xdata['foo']);
alert(xdata['baz'][0]);
// Dot notation can be used if key/name is simple:
alert(xdata.foo);
alert(xdata.baz[0]);
</script>
For your code, you could put $mfr and $mto into a single 2D array. Here is how your new JS might look, assuming xdata contains $mfr and $mto:
function checkid(value) {
var co = 0, comp = '', i = 0, nrows = xdata.mfr.length;
while (co < nrows) {
if ((parseInt(value) >= xdata.mfr[i]) && (parseInt(value) <= xdata.mto[i])) {
comp = 'T';
break;
}
co++;
i++;
}
if (comp != 'T') {
return [true, "", ""];
} else {
return [false, "Value entered is already between a range. Please try again!", ""];
}
}
You have a loop in your Javascript, not your PHP. So the PHP is only going to get executed once. You need to rethink your approach. Without knowing what the script is supposed to actually achieve it's difficult to provide working code, but you at least need to put the loop into the PHP instead of the Javascript.
Before I can answer you should understand what's going on exactly:
PHP is being executed on the server, then sends back the result (HTML and Javascript) to the client (the browser).
Javascript is being executed on the client side. So this only starts after PHP is completely done. For this reason you can't mix Javascript and PHP.
Check the source of the page, then you'll see exactly what the server returns (what HTML/Javascript PHP generates) and you'll get a better insight of what happens.
Now, if you understand this, you may be able to solve your own problem. I don't exactly know what you want to do, but I can advice you that if you need Javascript to check values from the database, you should generate Javascript using PHP that defines these values in the Javascript like for example this:
var my_js_var = <?=$my_php_var?>
var another_var = <?=$another_one?>
Now they are defined in Javascript and you can use them (and check them).
When you have a large database it can become inefficient to do it like this and you might want to look into a technology called AJAX, which allows Javascript to do a request to the server and get back data from a PHP script.
You would also want to do this if there's data involved you don't want to be publicly viewable (because everyone can look into the source of your page.

Using For loop to get values of multiple elements in PHP

The title is so general mainly because I don't know what should be the appropriate title for it. Let me just explain the situation:
Say that I have two textboxes named LastName0 and FirstName0 and a button called addMore. When I click addMore, another two textboxes will be created through JavaScript. These textboxes will be named LastName1 and FirstName1. When I click the addMore button again, another two textboxes button will be created and named LastName2 and FirstName2 respectively. This will go on as long as the addMore button is clicked. Also, a button named deleteThis will be created alongside the textboxes. This simply deletes the created textboxes when clicked.
I also initialized a variable called counter. Every time the addMore button is clicked, the counter goes up by 1, and whenever the deleteThis button is clicked, the counter decreases by 1. The value of the counter is stored in a hidden input type.
When the user submits the form, I get the value of the counter and create a For loop to get all the values of the textboxes in the form. Here is the sample code:
//Suppose that the user decides to add 2 more textboxes. Now we have the following:
// LastName0 FirstName0
// LastName1 FirstName1
// LastName2 FirstName2
$ctr = $_POST['counter']; //the counter == 3
for ($x = 0; $x < $ctr; $ctr++)
{
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//This will get the values of LastName0,1,2 and FirstName0,1,2
//code to save to database…
}
On the code above, if the value of counter is equal to 3, then the values of textboxes LastName0,1,2 and FirstName0,1,2 will be saved. Now here is the problem: If the user decided to delete LastName1 and FirstName1, the For loop will not be able to iterate properly:
$ctr = $_POST['counter']; //the counter == 2
for ($x = 0; $x < $ctr; $ctr++)
{
//Only LastName0 and FirstName0 will be saved.
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//code to save to database…
}
Someone told me to use the "push and pop" concept to solve this problem, but I am not really sure on how to apply it here. So if anyone can tell me how to apply it, it'll be grand.
Add your input text boxes with name as array ie, <input type="text" name="FirstName[]" />
In php you can fetch them as a array. ie,
foreach($_POST["FirstName"] as $k=>$val){
echo $val; // give you first name
echo $_POST["LastName"][$k]; // will give you last ame
}
In this case even if one set of field is removed in HTML will not affect the php code.
One solution would be to use the isset function like this:
$ctr = $_POST['counter'];
for ($x = 0; $x < $ctr; $ctr++)
{
isset($_POST["LastName$x"])?$lastname = $_POST["LastName$x"]:;
isset($_POST["FirstName$x"])?$firstname = $_POST["FirstName$x"]:;
}
If it is possible, instead of using LastNameN and FirstNameN names try using LastName[N] and FirstName[N], this way the result is an array and you can iterate through it with a foreach, meaning you will not need the counter and the index of the value will not be important:
foreach ($_POST["LastName"] as $i=>$lastname) {
if (!isset($_POST["FirstName"][$i])) {
// This should only happen if someone messes with the client side before posting
throw new Exception("Last name input does not have a related First name input");
}
$firstname = $_POST["FirstName"][$i];
}
If not, then you may have to use your $counter in a different way
$current = 0;
while ($counter) { // Stop only when i found all
if (isset($_POST["LastName$current"]) {
$counter--; // Found one
$lastname = $_POST["LastName$current"];
$firstname = $_POST["FirstName$current"];
}
$current++;
}
A better way to solve this would be to use arrays for Firstname and Lastname. Instead of calling them Lastname0 and Firstname0, then Lastname1 and Firstname1, call them all Lastname[] and Firstname[]. Give them ID's of Lastname0 and Firstname0 and so on for the delete function, but keep the names as arrays.
When the form is submitted use the following:
foreach($_POST['Lastname'] as $i => $lastname) {
$firstname = $_POST['Firstname'][$i]
//... code to save into the database here
}
Be warned though that in IE if you have an empty field it will not be submitted, so if Lastname0 has a value, but Firstname0 does not, then $_POST['Firstname'][0] will in fact contain the value of Firstname1 (assuming it has a value in it). To get around this you can use javascript to check if a field is empty when submitting the form, and if so put the word EMPTY in it.
Do not use counter if not required
A much easier way is to add array name when admore clicked.
Give a name like first_name[] in textbox
if you create form like that you can use foreach through $_POST['first_name']
try var_dump($_POST) in you php code to see how things goes on.
Inside your for loop, maybe you could try...
if ((isset($_POST["LastName$x"])) && (isset($_POST["FirstName$x"]))){
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//code to save to database…
}
This will check if the variables exists before you try to do anything with them.

Categories