I am doing a tictactoe on php for homework, and I am stuck on the logic that changes from player to player, as it always put a X on the cell and never changes to O whenever the submit button is hit. My question is about how to make it work.
What I have so far for this is:
$position = filter_input(INPUT_GET, 'Position');
$player = "C_$position";
//Problem
if(!isset($_SESSION[$player])){ //Also tried the function empty before using !isset
$_SESSION[$player]="X";
}
if($_SESSION[$player]=="X"){
$_SESSION[$player]="O";
}
if($_SESSION[$player]=="O"){
$_SESSION[$player]="X";
}
//END PROBLEM
I've been looking for answers and I found this Initialize the variable only once in php however it doesn't work as I applied it to my php code. If anyone got a solution I would totally appreciate it.
Use an else rather than another if because with the second if you revert to the original value. Currently you run into a TRUE conditional chain, every conditional is met so you end up with the last conditional's value. A rough demo of your code can be seen here, https://3v4l.org/Lv7CK.
This should correct your logic.
$position = filter_input(INPUT_GET, 'Position');
$player = "C_$position";
if(empty($_SESSION[$player]) || $_SESSION[$player]=="O"){
$_SESSION[$player]="X";
} else {
$_SESSION[$player]="O";
}
This should set the player to X if the session isn't set or if the current player is O, otherwise it sets the player to O (this assumes there are only two values for $player if there are multiples use an elseif, or possibly a switch).
Related
In a project of mine I am working with a sequence of pages that each give information that is used in the next, with POST and session variables. Simple example:
Page 1: enter name -> page 2 display name; ask birth date -> page 3 display name and birth date.
If a user goes directly to page 3 I want to display a message that s/he has not entered a name and/or birth date and should try again. Currently I am still doing it like so. On page 2:
if (isset($_POST['name'])) $_SESSION['name'] = $_POST['name'];
and page 3:
if (isset($_SESSION['name'])) $name = $_SESSION['name'];
if (isset($_POST['bday'])) $_SESSION['bday'] = $_POST['bday'];
as declarations and in the body an if-clause like
if (isset($name) && isset($_SESSION['bday'])) {
// do main stuff
else {
// display error message
}
The example is simple enough, but in the real world my code has a lot more variables and data from the forms, and putting all this first in variable assignments and then in an if-clause is tiring and seems not efficient to me. Is there a better, more straightforward way to check things like this? Or is what I posted the best, most-used way to go?
You can use one call to isset to check several variables.
isset($_SESSION['name'], $_SESSION['bday'], ...)
Or you can write your own function like
if (variablesFilled(['name', 'bday', ...])) { }
function variablesFilled($array) {
foreach ($array as $entry) {
if (!isset($_SESSION[$entry])) {
return false;
}
}
return true;
}
I believe you just need to write some helper methods. One to rewrite $_POST data to $_SESSION, dumb as this:
function copyPostToSession(array $fields) {
foreach($fields as $field) {
if(isset($_POST[$field])) {
$_SESSION[$field] = $_POST[$field];
}
}
}
so instead of if forest, you do:
copyPostToSession(array('name','bday'));
(additionally you can count how many fields were present and return true or false if there's mismatch) and the other (pretty similar) to check if you got all the required data in $_SESSION.
PHP's isset() function is a variadric function.
You can put as many arguments as you want:
isset($a, $b, $c)
...which translates to:
isset($a) && isset($b) && isset($c)
Hope it helped!
Seperate functions tend to differ a bit on a per server case. You could try calculating the time to perform a function a large number of times and compare which is faster.
But, yeah, that looks like fairly fast code there.
Might be worth trying a switch case statement as an alternative perhaps?
I'm setting $_SESSION['showroom'] to 'active' when a particular page in Wordpress is displayed:
if(get_the_ID()==6470||get_the_ID()==252){
$_SESSION['showroom']='active';
}
I then set 2 arrays of pages to check against. If the next page displayed is NOT in one of these arrays, $_SESSION['showroom'] gets changed to 'inactive'.
$allowed_templates = array('template-A.php',
'template-B.php',
'template-C.php',
'template-E.php',
'template-G.php');
$allowed_ids = array(6470,252);
$template_name = get_page_template_slug();
$page_id = get_the_ID();
if(in_array($template_name,$allowed_templates)==false && in_array($page_id,$allowed_ids)==false){
$_SESSION['showroom']='inactive';
}
The if statement works most of the time, but sometimes my $_SESSION['showroom'] changes to inactive EVEN though one of the arrays is returning true! After several hours of testing I am unable to locate where the problem is. Echoing out the two parts of the if statement ALWAYS gives me 2 trues or 1 true + 1 false, but never 2 falses:
if(in_array($template_name,$allowed_templates)==false){echo 'TFALSE';}
if(in_array($template_name,$allowed_templates)){echo 'TTRUE';}
if(in_array($page_id,$allowed_ids)==false){echo 'IFALSE';}
if(in_array($page_id,$allowed_ids)){echo 'ITRUE';}
What am I missing here?
Thanks in advance for any help!
EDIT: Have continued testing and found the following anomaly:
if(in_array($template_name,$allowed_templates)==false && in_array($page_id,$allowed_ids)==false){
$_SESSION['showroom']='inactive';
echo 'SET TO INACTIVE';
}
The if statement changes $_SESSION['showroom'] to 'inactive' but DOES NOT echo out 'SET TO INACTIVE'!
There's something strange going on here!
Problem solved. My code was fine. Two missing images files were causing WordPress to crash my sessions. Took 10 hours to find out but happy I found it. Thanks to everyone for their help.
You can try the following;
if(!in_array($template_name,$allowed_templates) && !in_array($page_id,$allowed_ids)){
$_SESSION['showroom']='inactive';
}
Edit: lets try and break it down further... similar to your examples
if(!in_array($template_name,$allowed_templates){
echo "not in templates,";
}
if(!in_array($page_id,$allowed_ids)){
echo "not in ids,";
}
if(!in_array($template_name,$allowed_templates) && !in_array($page_id,$allowed_ids)){
echo "not in both\n";
}
then see if we get a result with not in templates,not in ids, but no trailing not in both
The problem is pure logical. Lets look at this statement:
if (in_array($template_name,$allowed_templates)==false && in_array($page_id,$allowed_ids)==false)
Which translates to "If the template is not valid AND page is not valid"
This means that both statements needs to be fulfilled in order to mark session as inactive. What if the template is fine, but the page is not valid? That definitely should be marked as inactive as well.
By changing the statement to read "If the template is not valid OR page is not valid", we cover up the invalid cases. Because either of them counts as an invalid state, and thus, only one of them needs to be false in order for everything to be false. (the OR-statement)
So code-wise it would be
if (in_array($template_name,$allowed_templates)==false || in_array($page_id,$allowed_ids)==false)
And you are set.
As and addition. I would structure the code as you noted works. Which is more logical. That is, mark it as inactive whenever it's should be treated as inactive, in all other cases mark it as 'active'. Or vice-versa.
I'm new to JavaScript and have had some success in basic validation but i cannot work out how to do this.
What i have is form which can have between 1 and 10 drop down boxes depending on the users selection. the values in these boxes a retrieved from my database.
What I am trying to do is maake sure the user has not selected the same values more than once before i put this data back into my database.
The code below is what I have come up with so far. When the JavaScript function is run it returns to the same page but the alert appears on the site, but not in a popup box as it previously has when i have used it on other pages. It does see that the values have been selected more than once, but i have done something wrong as I get an undifined index error for php variables which previously had data in them.
<script type="text/javascript">
<!--
var nov = "document.getElementById("
NOV
").value == ''";
var checknov = new Array();
checknov[] == 0;
function validate_reg() {
while (nov > 0) {
for (var veh = checknov) {
if (document.getElementById("FLT").value == '' == veh) {
window.alert("You Cannot Assign The Same Vehicle More Than Once");
}
else {
checknov[] = document.getElementById("FLT").value == '';
}
}
nov--;
}
}
-->
</script>
I have added the Varible nov to the id as this is how it is defined in the form.
<script type="text/javascript">
<!--
var nov = document.getElementById("NOV").value == '';
var checknov=new Array();
checknov[]==0;
function validate_reg()
{
while (nov>0)
{
for (var veh=checknov)
{
if (document.getElementById("FLT"nov).value == '' == veh)
{
window.alert("You Cannot Assign The Same Vehicle More Than Once");
}
else
{
checknov[] = document.getElementById("FLT"nov).value == '';
}
}
nov--;
}
}
-->
</script>
This code is awful... First things first, you should NOT be validating on the client side! That's very easy to get around, and as you can already see, if the validation doesn't work, the server side struggles. All validation should be done server side. Or both, if you prefer (makes it possible to alert users before they waste time waiting on server requests).
Anyway, you have countless flaws in your code. Let's go over them first. I'm referring to the second code example. First of all, you assign a string to nov, when it appears you clearly intended to use a function. Then you performed a boolean check on checknov. Never mind that it's a syntax error which should be apparent from the browser's warnings, but it wouldn't do anything even if it worked!
Then you have a function that checks if nov is greater than zero... but nov is a string. That kind of comparison makes no sense! And then you try and perform a for loop on conditions that are completely invalid. For loops have three parts: the initialization, the looping condition, and the post-loop operation. You may have intended a while loop, but even then your condition is invalid, as you're assigning a value instead of checking for equivalence. I'm not even sure what you intended from the rest of your code.
I'll be honest, you've demonstrated you know almost nothing about JavaScript. I'd recommend putting this down and learning JS first.
But anyway, a more correct method of validation would be to use something like document.getElementsByClassName(), which would return an array of the DOM objects in a class (and give all your form elements that class). As a result, you'd get the elements of your form select boxes (what you call drop down boxes). You could then loop through this (recall that .length can be used to find the size of the array) with a for loop. Although you're also going to need to understand how a for loop works, and your code demonstrates you do not.
Inside that loop, you'd have to loop through all the elements again, since you'd have to compare each element to all the other elements. A bit inefficient and oversimplified, but suitable enough in this case.
EDIT:
I should also point out that you can get the value of a select element with <DOM element>.options[<DOM element>.selectedIndex].value.
Finally, again, I stress, do not do just client side validation.
EDIT2:
Also, don't use HTML comments inside script tags.
Let me first say I've spent a day reading three google pages of articles on this subject, as well as studied this page here.
Ok, here's my dilemma. I have two functions. Both called upon via AJAX. This first one assigns a value to the variable and the second one uses that variable. Both functions are triggered by two separate buttons and need to stay that way. The AJAX and the firing off of the functions work fine, but the variable isn't passed. Here is my code:
if( $_REQUEST["subjectLine"] ) //initiate first function
{
$CID = wpCreateChimpCampaign();
echo $CID; //this works
}
if( $_REQUEST["testEmails"] ) //initiate second function
{
echo $CID; //does not return anything but should contain "apple"
wpSendChimpTest($CID);
}
function wpCreateChimpCampaign () //first function
{
$CID = "apple";
return $CID;
}
function wpSendChimpTest ($CID) //second function
{
echo $CID; //does not return anything but should contain "apple"
}
I'm open to using a class but I haven't had much luck there either. I was hoping to solve this issue without using classes. Thanks for the help in advance!
If you are making 2 separate calls to this file, it may be helpful for you to visualise this as being 2 functions in 2 totally separate files. Although they exist in the same PHP file, because they used called in different calls, they don't retain the value of the variable $CID. Once the file has run, the variable is destroyed and when you call the file again, the value is null again.
So you need to store that variable between calls. You can either store it in a database or store it in a session variable.
So call session_start(); at the beginning of the file, then rather than use $CID, just use $_SESSION['CID'];
I'm not sure where the hold up is. The code you have will work:
$CID = wpCreateChimpCampaign(); // returns 'apple'
wpSendChimpTest($CID); // echos 'apple'
The code looks fine, but are you certain that all requirements are being met so both functions execute?
In other words are you supplying values for both $_REQUEST["subjectLine"] and $_REQUEST["testEmails"]?
I hope these lines would explain the question:
//in javascript
function foo(sessionName){
var u = "test.php?q="+sessionName+"&r="+parseInt(Math.random()*9999999);
xmlHttpObj.open("get", u, true);
xmlHttpObj.send();
}
//in php
$q = $_GET['q'];
unset($_SESSION[$q]);
Like you see, I don't want any value returned, I just want to unset the specific session.
You don't ever have to return a value, if you access and run the script it will do it's job. The problem will be that you will have no way of knowing if it succeeded, so it's best to return a success/failure value in general. However, since unset() doesn't actually return a value there is no need in this case.
Yes, this works. I suppose your problem is a typo in the variable name?
var u = "test.php?q="+sessionName+"&r="+parseInt(Math.random()*9999999);
^
$n = $_GET['n'];
^
It is probably better to still return a value indicating wether it worked or not. Even though this code should work just fine.
Adding this to the end of your script will give you an indicator wether it worked or not.
if (isset($_SESSION[$n])) {
echo 'success';
}
else {
echo 'fail';
}