PHP - odd one out - php

I am trying to create a "find the odd word" application (given a list of words like cat, dog, bird and car, the latter is the odd one because it's not an animal).
Firstly, I retrieve and shuffle randomly five words from the DB. They are called: odd (which is the odd one), one, two, three, four (which are the other four).
Then, I produce a form (radio button) with the five words, so that users can select one of their choice:
$words = array
(
$odd,
$one,
$two,
$three,
$four,
);
shuffle($words);
foreach ($words as $word)
{
$string = $word;
echo '<html><input type="radio" name="odd" value="'.$string.'">'.$string.'<br><br></html>';
}
In the next PHP page, I want to check if the selected word is the odd one. I can't figure out how to do it.
Any suggestions? Thanks!

Use the $_SESSION variable to handle this to find out if the odd was selected or not
Say the following code is from your Odd.php that displays the radio buttons (assuming you would handle the form element and submit button)
<?php
session_start();
$_SESSION['odd'] = $odd;
$words = array
(
$odd,
$one,
$two,
$three,
$four,
);
shuffle($words);
echo '<form method="POST" action="Next.php">';
foreach ($words as $word)
{
$string = $word;
echo '<input type="radio" name="odd" value="'.$string.'">'.$string.'<br><br>';
}
echo '<input type="submit" /></form>';
?>
On your Next.php file use the code below to validate if the odd was selected or not
<?php
session_start();
$odd = $_SESSION['odd'];
if ($_REQUEST['odd'] == $odd) { // $_REQUEST handles both $_POST and $_GET
echo "Odd was selected";
} else {
echo "Odd was not selected";
}
?>
Hope this helps!

You need to carry the odd word to the next page somehow. There are many different ways of doing this, arguably the easiest one is by saving the odd word in a variable in your form
<input type="hidden" name="realodd" value="<?php print $odd; ?>" />
On the next page, you can then check whether the chosen word is right by comparing it to the hidden word.
if ($_POST['realodd'] == $_POST['odd']) {
print "You found the odd word.";
}
This could easily be broken by just looking at the source code. A better solution could be saving the odd word in a session cookie:
session_start();
$_SESSION['realodd'] = $odd;
And then verify on the next page almost like before
if ($_SESSION['realodd'] == $_POST['odd']) {
print "You found the odd word.";
}

session_start();
if(isset($_POST['odd'])&& isset($_SESSION['odd'])&& $_POST['odd']==$_SESSION['odd']){
exit ("You're a genius, you got the right word");
}else{
if (isset($_POST['odd'])){ echo "Sorry, try again";}
}
//sql query goes here
$words = array
(
$odd,
$one,
$two,
$three,
$four,
);
$_SESSION['odd'] = $odd;
shuffle($words);
echo '<form method="POST">';
foreach ($words as $word)
{
echo '<input type="radio" name="odd" value="$word"/>$word<br><br>';
}
echo '<input type="submit" value="Submit"/>';
echo '</form>';

Related

Store checkbox group values as a variable

I am trying to store the values of selected checkboxes on a multi page form so I can include these on the final page of the form (and in the email that is sent to the site owner).
I have worked out how to display the values, but saving them for later has got me stumped. I'm learning as I go so I wouldn't be surprised if this is quite easy...
This is the code I'm using:
<?php foreach ($_POST['fooby'] as $key => $entry) {
if(is_array($entry)){
print $key . ": " . implode(',',$entry) . "<br>";
}
else {
print $key . ": " . $entry . "<br>";
}
} ?>
And this is the result I get:
1: Minor Service £129
2: plus MOT £35
That's exactly what I'm after - though I don't need the numbers at the beginning. How do I save that information for later?
With the updated code below, I now get the following result:
Minor Service £129
plus MOT £35
That's perfect, but I'm struggling to work out how to store that information to a session variable. I should point out that the values returned from the form are dynamic and unknown beforehand. There might also be 10 items in the array, not just the two shown above.
What I have so far:
<?php if (isset($_POST['fooby'])){
foreach ($_POST['fooby'] as $entry) {
if(is_array($entry)){
$dokval = implode(',',$entry) . "<br>";
echo $dokval; //echoes the expected result on the page
$_SESSION['dokvalues'] = $dokval; //only stores the last item
}
else {
print $entry . "<br>"; //not rewritten this part yet
}
}
} ?>
Simply insert these values in hidden input elements in a form on the following pages to use them again:
<input type="hidden" name="<?php echo $key1; ?>" value="<?php echo $value1; ?>" />
<input type="hidden" name="<?php echo $key2; ?>" value="<?php echo $value2; ?>" />
...
The foreach loop iterates through the array and for each iteration $key variable is the current index and $entry is the value of that index. The numbers in the list are just representation of index values. If you don't need them, you can go for this:
<?php foreach ($_POST['fooby'] as $entry) {
if(is_array($entry)){
print implode(',',$entry) . "<br>";
}
else {
print $entry . "<br>";
}
} ?>
The keys will still stay in $_POST['fooby'] array.
The variable $entry holds one value of the array each time the foreach loop iterates. So the variable $dokval will also hold only one value, which it echos each time the loop iterates. By the time you look at the session variable it's value is going to be the last value that $dokval held. Make $dokval an array and push the $entry value into it. array_push. Also, make sure you start a session at the beginning of every page you want to use the $_SESSION variable.
Jeff

Having Trouble with PHP Word Guessing Game

<?php
if(isset($_POST['submit'])) {
$guess = $_POST['guess'];
$count = isset($_POST['count']) ? $_POST['count']:0;
$count++;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Guess the Word Game</title>
</head>
<body>
<div id = "header">
</div>
<div id = "word">
<?php
//create array
$words = array("aardvarks", "determine", "different", "greatness", "miserable");
$random = array_rand($words);
//choose a random word from array
$newWord = $words[$random];
$change = str_split($newWord);
//prints out array
/*foreach($change as $list) {
echo $list;
}*/
$masked = str_replace($change, '*', $change);
//prints masked array
foreach($masked as $hide) {
echo $hide;
}
?>
</div>
<div id = "guess">
<form name="guessLetter" method="POST" action=""
<p>Please input your guess below</p>
<input type="text" name="guess" id="guess"/><br />
<input type="hidden" name="count" id="count" value="<?php echo $count; ?>" />
<?php
?>
<input type="submit" name="submit" id="submit" value="Submit" />
</form>
<?php
if(isset($_POST['submit'])) {
echo "Guess: ".$guess."<br />";
echo "Count: ".$count;
}
?>
</div>
</body>
</html>
Hi everyone
I am relatively new to PHP and in the process of creating a word guessing game.
I have created an array of words and then randomized them. Once a word has been chosen, I have split the word into an array. I have then created another array for the masked version of the word which appears on the screen.
I have been ok up to here, but I now need to use a loop to iterate through array to see if the letter guessed is actually in the word. I also want to tell the user how many times the letter appears and also update the masked version of the word, with the actual letter.
I have included my code so far and would really appreciate some help as I am stuck!!
I now need to use a loop to iterate through array to see if the letter guessed is actually in the word
$letter_is_in_word = stristr($selected_word, $guess);
// returns either false if not found, or a section of the string
// where it was found ($letter_is_in_word == true)
I also want to tell the user how many times the letter appears
$number_of_occurences = substr_count($selected_word, $guess);
... and also update the masked version of the word, with the actual letter.
// get your random word
$random = array_rand($words);
$selected_word = $words[$random];
// set up temporary array to store output letters or *
$output = array();
// split word into each letter
$letters = str_split($selected_word);
foreach($letters as $letter) {
// if the letter was guessed correctly, add it to the output array,
// otherwise add a *
$output[] = ($letter == $guess) ? $letter : '*';
}
// output the results (implode joins array values together)
echo implode($output);
Something to note here is that while you are tracking the guess count via hidden input field, you aren't tracking previous guesses. I would suggest you use a hidden input field to store previous guesses also.
At the top of your page:
$count = 0;
$guesses = array();
if(isset($_POST['guesses']))
$guesses = explode('|', $_POST['guesses']);
if(isset($_POST['submit'])) {
$guess = trim(strtolower($_POST['guess']));
if(!in_array($guess, $guesses))
$guesses[] = $guess;
$count = isset($_POST['count']) ? (int) $_POST['count'] : 0;
$count++;
}
Then further down:
<input type="hidden" name="guesses" id="guesses" value="<?=implode('|', $guesses)?>">
This allows you to track previous guesses (hidden field in this example is delimited by | characters). You'll then need to check that array when you decide which letters to * out:
foreach($letters as $letter) {
// if the current letter has already been guessed, add it to
// the output array, otherwise add a *
$output[] = in_array($letter, $guesses) ? $letter : '*';
}

Getting Parse Error Unexpected "

I am getting an error with the following message :-
Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in C:\xampp\htdocs\game.php on line 12
Here is the source code :-
<?php
$words=$_GET['words'];
$array=explode(",",$words);
$j=count($array)-1;
goto a;
a: shuffle($array);
$num=$array[0];
echo "The Number Is = $num";
echo "<br />";
echo "Please Enter The Number Within 10 Seconds";
echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" "; **<--Line 12**
echo "<input type=\"text\" name=\"num\"";
echo "<input type=\"submit\" value=\"Press Me! \"";
$input=$_GET['num'];
goto b;
b: if($input==$array[0] && $array!=NULL)
{
array_pop($array);
goto a;
}
elseif($array!=NULL)
{
goto a;
}
else
break;
?>
Please don't say about the GOTO but rather on how to fix the error as I am only experimenting with it to see if it would solve the given question.
Change
echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" ";
Into
echo '<form method="get" action="'.$_SERVER['PHP_SELF'].'">';
It's much more simpler for the eyes.
I'll comment on all of it.
First, to fix your syntax error (and the later HTML errors you'll have). The single-quotes in the PHP_SELF substitution don't need escaped, you need to complete your opening tags, and you need to close your form tag.
<?php
$words=$_GET['words'];
$array=explode(",",$words);
$j=count($array)-1;
goto a;
a: shuffle($array);
$num=$array[0];
echo "The Number Is = $num";
echo "<br />";
echo "Please Enter The Number Within 10 Seconds";
echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" >";
echo "<input type=\"text\" name=\"num\" />";
echo "<input type=\"submit\" value=\"Press Me! \" />";
echo "</form>";
$input=$_GET['num'];
goto b;
b: if($input==$array[0] && $array!=NULL)
{
array_pop($array);
goto a;
}
elseif($array!=NULL)
{
goto a;
}
else
break;
Now, to make it not spaghetti code and to simplify your logic:
<?php
$words=$_GET['words'];
$array=explode(",",$words);
while (sizeOf($array) > 0) {
shuffle($array);
$num = $array[0];
echo "The Number Is = $num";
echo "<br />";
echo "Please Enter The Number Within 10 Seconds";
echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" >";
echo "<input type=\"text\" name=\"num\" />";
echo "<input type=\"submit\" value=\"Press Me! \" />";
echo "</form>";
$input = $_GET['num'];
if($input === $array[0]) {
array_pop($array);
}
}
Now it's at least clear what the code does - that is, the form is provided with a comma-delimited list of numbers on the query parameter "words". The list is shuffled, and the user is asked to enter the new "first" item - effectively a random item from the list. When submitted by the user, "num" is passed. If this number is the same as the first in the list, it removes the last number. Either way, as long as the array is non-null, then loops back on itself (effectively ad infinitum, spitting out the same form for each number on the list. I'm not sure this is what you wanted, since you're not handling $_GET[num] as an array.
Assuming you actually get a form, rather than just peg your server, the script then checks if "num" is present and, if so, removes it from the numbers list.
This is where it gets interesting; on submission, the script is started again. "words" is empty, so the form asks the user to enter "". If it wasn't, the list would have been re-randomized, so even if the user dutifully entered what was asked, the script wouldn't recognize it.
This is one of the reasons we don't use GOTO; it obfuscates your code flow. What's clear in a while loop is inscrutable using GOTO.
So what I assume is supposed to be the requirement:
You're presented with a number to enter. You enter it and submit the form. The number is removed from the list, and you're asked to enter another one. Once it's empty, it would be nice if you're told that.
So, to do this in a way that makes sense, let's do this using some OOP.
I know what you're going to say: this appears to be more complex - however, I want you to note that what baking everything into a class does: it encapsulates the stuff you're doing into one place, and separates out each phase of the request into separate functions.
Additionally, comments notwithstanding, it effectively documents nonobvious and repetitive tasks, like getting items off the $_REQUEST (or $_GET) object, or getting an item from an array (if it's an array and if the item exists on it) in a way that is safe and predictable.
Lastly, it's readable. It's a bit of work to look at the contents of the while loop and work out what it does; in this class, you can tell: it checks that the array is not empty and that the submitted number is the same as the requested number; if so, it removes that number.
Additionally, rather than shuffle the list each time, we just pick each one off at random.
<?php
class RandomNumberGame {
private $startCount;
private $numberMax;
private $numbers;
private $index;
/**
Produce an array containing $count random numbers between 0 and $max
*/
public function generateRandoms($count, $max) {
$nums = array();
for ($i = 0; $i < $count; $i += 1) {
$nums[] = rand(0, $max);
}
return $nums;
}
/**
Get an item from an array if it exists; if not, or if the array doesn't exist, return null
*/
public function getIfExists($array, $item) {
if (empty($array)) return null;
if (!array_key_exists($item, $array)) return null;
return $array[$item];
}
/**
returns a random number from the list of numbers
*/
function pickRandomNumber() {
return rand(0, sizeof($this->numbers) - 1);
}
/**
Handle the request data
$request
['nums'] - list of numbers with which to populate $this->numbers
['index'] - the index of the currently-selected number
['num'] - the user's entry
If nums[index] == num, that item is removed and a new index is selected.
*/
public function processRequest($request) {
$nums = $this->getIfExists($request, 'nums');
if (empty($nums)) {
$this->numbers = $this->generateRandoms($this->startCount, $this->numberMax);
} else {
$this->numbers = explode(',', $nums);
}
$this->index = $this->getIfExists($request, 'index');
if (empty($this->index)) {
$this->index = $this->pickRandomNumber();
}
$num = $this->getIfExists($request, 'num');
if (empty($num)) return;
while (!empty($this->numbers) && $this->getCurrentNumber() === $num) {
$this->removeCurrentNumber();
}
}
/**
Removes the entry in $this->numbers pointed to by $this->index, and assigns $this->index a new random position
*/
public function removeCurrentNumber() {
// In $nums, replace 1 items at $index with [] - effectively, remove item $index from $num
array_splice($this->numbers, $this->index, 1, array());
// Pick a new random item
$this->index = $this->pickRandomNumber();
}
/**
Get the currently selected number
*/
public function getCurrentNumber() {
return $this->getIfExists($this->numbers, $this->index);
}
/**
Generate the form for output to the user
If there are no numbers left, provide a congratulation, and a link to start over
*/
public function getForm($endpoint) {
if (sizeof($this->numbers) === 0) {
return "Hey, you're done! Start over.";
}
$nums = join(',', $this->numbers);
return <<<HEREDOC
<form method="post" action="{$endpoint}">
<input type="hidden" name="nums" value="{$nums}" />
<input type="hidden" name="index" value="{$this->index}" />
<label for="num">
The number is {$this->getCurrentNumber()}<br />
Please enter the number within 10 seconds<br />
<input id="num" type="text" name="num" autofocus/>
</label>
<input type="submit" value="Press Me!" />
</form>
<!-- Optional: define some Javascript to disable the form in 10 seconds -->
HEREDOC;
}
public function RandomNumberGame($startCount = 10, $numberMax = 100) {
//Basic initialization
$this->startCount = $startCount;
$this->numberMax = $numberMax;
}
}
//Finally, the program:
$rng = new RandomNumberGame();
$rng->processRequest($_REQUEST);
echo $rng->getForm($_SERVER['PHP_SELF']);
You should wrap server variable with brackets:
echo "<form method=\"get\" action=\"{$_SERVER['PHP_SELF']}\">";
printf ("<form method=\"get\" action=\"{$_SERVER['PHP_SELF']}\" ");
Two errors. You can't escape single quotes in a double quoted string, and when you are working with an array inside a string, you need to surround it with {}.
The answer is you're putting in single quotes for the array of $_SERVER:
echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" ";
simply use
echo "<form method=\"get\" action=\"$_SERVER[PHP_SELF]\" ";
instead. the idea of the '' inside the array is to pass the string. no need to pass it within a quotes.
You're missing closing > in three lines
echo "Please Enter The Number Within 10 Seconds";
echo "<form method=\"get\" action=\"$_SERVER[PHP_SELF]\">";
echo "<input type=\"text\" name=\"num\">";
echo "<input type=\"submit\" value=\"Press Me! \">";
Yours:
echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" ";
^-- here
echo "<input type=\"text\" name=\"num\"";
^-- here
echo "<input type=\"submit\" value=\"Press Me! \"";
^-- here
Plus, [\'PHP_SELF\'] You should not be escaping single quotes.
Use [PHP_SELF] or {$_SERVER['PHP_SELF']} wrapping the variable in curly braces.
Doesnt it need a space before the != and after
From
b: if($input==$array[0] && $array!=NULL)
to this
b: if(($input==$array[0]) && ($array != NULL))
Have wrapped it in extra brackets for good measure too

Dynamically Generated delete button

I'm new to php and I was wondering how I would be able to create something like a delete button for deleting items in a list that would be generated from a dynamically growing array.
An example of what I mean is this:
<?php
if (isset($_REQUEST['foo']))
{
if (isset($_SESSION['words']))
{
$_SESSION['words'][] = 'added word';
}
else
{
$_SESSION['words'] = array('cat', 'dog', 'you', 'me');
}
foreach ($_SESSION['words'] as $key => &$value)
{
echo "<p>" .
$value .
" - <input type='submit' name='delete_" .
$value .
"' value='Delete Entry' /></p>";
}
if (isset($_REQUEST['clear']))
{
session_destroy();
}
?>
Where, on every button click that gets sent to my script it would echo out the array with the buttons.
I'd like to link the delete buttons to a function that looked something like:
function delete_entry( $index )
{
unset($_SESSION['words'][$index]);
$_SESSION['words'] = array_values($_SESSION['words']);
}
Is what I'm asking even possible?
Your array of words seem to be stored in your session variable, so I'm assuming that you want to remove/add words to it. How about this...?
Have a separate form for each word with a hidden field saying what the word is:
So in the for loop:
echo "<form><p>".$value." - <input type='submit' value='Delete Entry' /></p><input type=\"hidden\" name=\"delword\" value=\"".$value."\"/></form>";
if(isset[$_REQUEST['delword']]) remove it from the session array (do this before you do your echoing for loop. (You could use array_search to find the element, then run unset as you suggested)
Let me know if you want me to elaborate on this suggestion.

php checkbox array access

$i=0;
while (db_data) {
$i++;
echo '<input type="checkbox" name="v['.$i.']" value="'.$url.'"';
if ($v[$i]) {
echo ' checked';
$s .= $url;
}
echo '/>';
}
I have the above array of checkboxes. It worked on my pc, but not on the server; it seems like the confusing part is on $v[$i].
$v is not defined, but sure used no where else. the problem is my checkbox selection never restored, and code never get into the if statement.
however, if i add the following, i can see the value. just the checkbox lost after the processing
$v=$_POST['v'];
while (list ($key,$val) = #each ($v)) {
$x .= ' 11*'.$key.'-'.$val.'*22 ';
}
my goal is to preserve the checkbox checked on the form, and i need the $s elsewhere. any solution to replace $v[$i]?
Can anybody help me fix this? Thank you.
The issue seems to be $v = $_POST. If you are just doing that then your conditional statement would need to be
if ($v['v'][$i]) {
///Checkbox
}
or just do $v = $_POST['v'].
Sorry, ignore above as you did mention you did that part. See below.
Here is working code.
<form action="" method="post">
<?php
$v = $_POST['v'];
$i=0;
while ($i < 4) {
$i++;
$url = "test.com/".$i;
echo '<input type="checkbox" name="v['.$i.']" value="'.$url.'"';
if ($v[$i]) {
echo ' checked="checked"';
$s .= $url;
}
echo '/> '.$url.'<br />';
}
?>
<input type="submit" name="submit" value="submit" />
</form>
I left the code pretty much the same to show you where you went wrong, but you should be checking the $_POST variable for exploits before using. If I were doing this as well, I would use a for count, but it's setup as a placeholder for your database code. Make sure that $url gets populated as well.
You could also do away with the $i variable like:
<?php
$v = $_POST['v'];
while (db_data) {
echo '<input type="checkbox" name="v[]" value="'.$url.'"';
if (is_array($v)) {
if (in_array($url,$v)) {
echo ' checked="checked"';
$s .= $url;
}
}
echo '/> '.$url.'<br />';
}
?>
Try to print_r($_POST) and then print_r($v) and see if anything comes up. If the $_POST works, then you know that it is being posted back to the page correctly. Then if the $v is working, then you know you set $v = $_POST correctly. Due to the fact that you don't actually give us any information on the db_data, I assume this is working correctly and displaying all the checkboxes on first load, so as long as it is posted and you are setting the $v variable, it should be working.
A side note is that you should validate the $_POST variables before using, but do that after you get things working.
change
name="v['.$i.']"
to
name="v[]"
the fact that PHP picks that up as an array is a unintended feature of PHP that wasn't intentionally designed. you don't need to set the indexes, just define it as an array.

Categories