PHP - Exit For Loop After Wrong Answer - php

I'm trying to teach myself PHP. My current exercise combines a form (not included in the code, but it works) that requires the user to enter the name of a city. The loop and the if statement compare the entry with an array of state capitals to return an answer that states whether that city is a state capital or not.
If I leave out the elseif part, the code runs ok, but I have no alternative when the user has entered a city that is not in the array. But with the elseif, the first part of the loop doesn't execute. For example, if I enter "Albany" without the elseif, I get "Albany is the capital of New York." But if I enter it with the elseif statement, it runs the loop until it finds "New York" and it prints "Albany is the capital of New York."
I've googled this, and I've read the books on PHP that I have. And I also know that I'm making a very basic mistake. Any guidance would be greatly appreciated.
for ($i = 0 ; $i < count($stateCapitalNames); $i++)
if ($enteredCity == $stateCapitalNames[$i]) {
print "<p>$enteredCity is the capital of <b>$stateNames[$i]</b>. </p>";
} elseif ($enteredCity != $stateCapitalNames[$i]){
print "<p>$enteredCity is not the capital of a state.</p>";
}
?>

You can use break to leave the for loop.
You should look at array_search to find the index you are looking for. array_search returns false if the capital does not exist.
For instance
$i = array_search($enteredCity, $stateCapitalNames);
if($i !== false)
{
echo "<p>$enteredCity is the capital of <b>",$stateNames[$i],"</b>. </p>";
}

You are missing your brackets in your for loop. I'm surprised the elseif is the culprit and that the code doesn't fail anyways. But here is what I would do, errors aside:
$correct = false;
for ($i = 0 ; $i < count($stateCapitalNames); $i++){
if ($enteredCity == $stateCapitalNames[$i]) {
$correct = true;
$stateNames = $stateNames[$i]; // Updated $stateNames variable
break;
}
}
//You can check $correct here...
if($correct){
print "<p>$enteredCity is the capital of <b>$stateNames[$i]</b>. </p>"; /*Removed [$i] from $stateNames. For some reason, $stateNames[$i] wasn't updating outside the loop, but now it is.
}
This way, no matter what, until the code finds a correct answer, the user is wronge. Once it finds the right answer, it sets it as correct and exits the loop by setting $i to the length of the array.

Related

PHP code supposed to check a file for an ID not working correctly

So I'm working on a PHP app receiving a student ID from an input and searching through a file to find if the ID is present or not. If it's present, the name of the student and whether hes present or not should be printed out, and if the ID doesn't exist, it should say that there are no students with this ID.
Here is an example of what the txt file looks like:
1234|Sally Simon|1
4321|Larry Lonbottom|0
7364|Hannah Harrow|1
I made a solution and tested it, but it prints out a student name even when the ID I enter is false. Could someone give me an idea of what I'm doing wrong?
Here is my code:
<?php
$student=$_GET["student"];
$lines = file('students.txt');
foreach ($lines as $line){
$var = explode("|", $line);
}
if($student == $var[0] || $var[2] == "1"){
echo "$var[1]($var[0]): has signed up";
}else if($student == $var[0] || $var[2] == "0"){
echo "$var[1]($var[0]): hasn't signed up";
}else{
echo "No students with that id!";
}
?>
1) Your $var will always have the last line in the file, wrap everything with the foreach;
2) You should use && instead of ||
EDIT: updated code
<?php
$student=$_GET["student"];
$lines = file('students.txt');
$missing = true;
foreach ($lines as $line){
$var = explode("|", $line);
if($student == $var[0]){
$missing = false;
if($var[2] == "1"){
echo "$var[1]($var[0]): has signed up";
}else if($var[2] == "0"){
echo "$var[1]($var[0]): hasn't signed up";
}
}
}
if($missing){
echo "No students with that id!";
}
?>
As OPs said you need to change your conditional logic (if elses) and place it within the foreach loop (i.e. before the foreach's closing }.
However: (php.net file) "Each element of the array corresponds to a line in the file, with the newline still attached." so you have to remove the EOL/NL marker (invisible whitespace) from $var[2]. This can be achieved changing your file function to file('students.txt', FILE_IGNORE_NEW_LINES) however it is probably best to use trim as per example below.
It may help simplify things for you if you get rid of else conditions. try this:
<?php
$student=trim($_GET["student"]); // should also check and exit if ! digits
$lines = file('students.txt');
$isRegistered = array( "hasn't signed up", "has signed up");
$invalidID = TRUE;
foreach ($lines as $line){
$var = explode("|", $line);
if( $student == trim($var[0]) ) {
echo "$var[1]($var[0]): " . $isRegistered[ trim($var[2]) ];
$invalidID = FALSE;
break; // prevent unnecessary processing, exit foreach loop
}
}
if ( $invalidID ) echo "No students with that id!";
?>
Note: the above assumes file only contains valid content.
(1) Put the if statements inside the loop since you want to use those conditionals with every line.
(2) You are using logical 'or' operators. This means that only one of the conditions for that line need to be met.
This is what you are saying
if $student == $var[0] OR if $var[2] == 1
So regardless of what ID you enter, you always match the 0 or 1 condition.
Use the && operator instead of || if you need both conditions to be met instead of just one of the two.
(3) By using the == operator, the string will have to match with the value you are looking for exactly. You might have spaces in $student or there might be additional character in between the |. Just to air on the side of caution, remove all chances of there being hidden whitespace with your variables.
Do this: $student[0] = preg_replace('/\s+/', '', $student[0]); and do that with var[0] and var[2] as well. Do this before you run them through the if statements but still inside the loop.
Here is a link that talks about logical operators in php. It might be nice to use as a reference for future conditional statements that you need to build!
This link explains what you are doing to these values with preg_replace. It becomes very handy when you need to remove characters from a string that otherwise might difficult to deal with.

How do you print a variable in PHP that's either one element of an array, or the whole variable if it's not an array

Say I have $exampleVariable, which I want to print. $exampleVariable may be an array, in which case I have this set up to get the right array element, which I can then print with print $exampleVariable[$i].
if ($_GET) {
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} elseif (is_array($exampleVariable)) {
$i = 0;
} else {
$i = "";
}
My problem is that last else, if $exampleVariable is NOT an array, because then I get print $exampleVariable[] which doesn't work. So is there something I can put as $i to print the whole variable?
Alternatively, I considered including the brackets in $i, so I'd have for example $i = [0];, but in that case I don't know how I'd print it. $exampleVariable$i certainly won't work.
I have a good number of variables besides $exampleVariable I'll need to print, all with the same $i or lack thereof, so I'd like to not have to do anything longwinded to set each of them up individually.
This sounds way more complicated than I feel like it should, so hopefully it makes sense!
You can always do a nifty thing that is called type casting. That means, that you can always make a variable an array even if it is not, by prepending its name by (array):
$exampleVariable = (array)$exampleVariable;
So you don't need three if branches at all:
if ($_GET) { 
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} else {
$i = 0;
$exampleVariable = (array)$exampleVariable;
}
You could apply the (array) cast, which will have no effect if the target is already an array:
$i = array_search($_GET["exampleQueryString"], (array)$exampleVariable);

Pass variable value through nested if() statements - PHP

I want to be able to do the below but unable to since the values are not passed to the next if statement.
if(something){
$x=SomeValue;
if(something){
$y=SomeValue;
if($x==$y){
echo"x & y matches";
}
}
}
I also tried $GLOBALS in the respective if statements but still doesn't work.
How do I pass the values of $x & $y to the third if() statement
Actual code
if($i%2) {
$dx1 = $row['sec1'];
echo $dx1;
if($i%2==0){
$dx2 = $row['sec2'];
echo $dx2;
if($dx1==$dx2){echo $dx1." do not match ".$dx2;}
}
}
}
In PHP, any value which is not "empty" is considered "truthy"; in the case of an integer, that means 0 is false, and everything else is true. So if($i%2) means the same as if( $i % 2 != 0 ).
Later, you nest inside that if a similar-looking condition, if($i%2==0), which is actually the exact opposite. To reach the inner if, you have to first have gone into the outer if, so both conditions need to be true to reach the innermost code.
As you say, the conditions are equivalent to "$i is odd" and "$i is even". To get into the first if statement, $i must be odd; but to get into the second, it must also be even. No value of $i will ever meet both conditions, so the innermost code will never be reached.

for loop not processing first element of array [duplicate]

This question already has answers here:
The 3 different equals
(5 answers)
Closed 6 years ago.
I am puzzled by an issue in my code and hoping someone else can help me shed some light on why my loop is omitting the first element (array[0]) of the array.
the Code
foreach ($a as $key => $val) {
for ($i=0; $i<count($val); $i++) {
$x = $i; //this helps me jump logical arguments without the use of else
// First Test
if (isset($val[$i+2]) && $x = $i) {
//Do a bunch of stuff
if (isset(the stuff done above)) {
// do other things and reset $i to jump through the array
$i=$i+2;
}
else {
unset($things);
unset($otherthings);
}
}
}
// Second Test
if (isset($val[$i+1]) && $x = $i) {
//Do a bunch of stuff
if (isset(the stuff done above)) {
// do other things and reset $i to jump through the array
$i=$i+1;
}
else {
unset($things);
unset($otherthings);
}
}
}
// Third and final test
if ($x = $i) {
//do other things
}
}
}
the Problem
I can't seem to understand why but the for loop or the IF statements (I am not 100% sure which one) fail to run through the first element of the array[0].
It runs fine from array[1] onward but even though i have tested that $x is indeed = to $i and therefore test 3 at the very least should work, the loop seems to run one loop past all the IF's and then start working from array[1].
What I have tried
I have changed for ($i=1; $i<$val; $i++) and this works fine (e.g. does not omit anything) from the start (but of course does not solve my problem as I am still missing array[0])
I have tested in the code if echo $val[0] prints out at the beginning of the code and it does
I have also tested $x = $i and these also work
It is one of those issues that feel too silly to change everything in my code but having searched a lot throughout stack overflow and google for similar issues, I cannot seem to find out why.
There must be something wrong I cannot see in the way I have written the loop?
Use $x == $i to test for equality, not $x = $i, which is an assignment.

Why This Loop Always Produce N+1 Output?

Let's say I have this inputs :
<input type="hidden" name="block-1" value="001"/>
<input type="hidden" name="block-2" value="012"/>
<input type="hidden" name="block-3" value="002"/>
<input type="hidden" name="block-4" value="005"/>
<input type="hidden" name="block-5" value="008"/>
and I want to process those input using this PHP loop
$i = 1;
do {
$x = 'block-'.$i;
$webBlock = $_POST[$x];
//some codes here
$i++;
}
while (!empty($webBlock));
why I always have 6 outputs? and the last one is blank output. seems that loop always doing n+1. how to make correct loop based on number of inputs given? thanks!
Do you need while?
I'd go with:
$i=0;
foreach($_POST as $name => $value)
{
if( strpos($name , 'block-') !== false ) echo $i . " - " . $name . ": " . $value;
$i++;
}
Believe that should account for items named 'block-n'. The if statement basically says "if block- is anywhere in the name of the field, echo out such and such".
Let me know if you get an error and will amend.
Because you are using a repeat loop, you should use a while loop:
while (!empty($webBlock)){
$x = 'block-'.$i;
$webBlock = $_POST[$x];
//some codes here
$i++;
}
beacause do will get executed at least once what ever may be in while expression .do while is an exit control loop.
Try this:
$i = 0;
do {
$i++;
$x = 'block-'.$i;
$webBlock = $_POST[$x];
//some codes here
}
while (!empty($webBlock));
UPD: The best approach is this:
for ($i = 1; $i <= count($_POST); $i++) {
$webBlock = $_POST['block-'.$i];
//some code here
}
Because You are using Do While loop.I am not sure about your data but i must say that it will execute one more time as you expected.Let us check it by iterating
It will run first time because $webBlock is not empty and same as for 5 times.Now here you want to close the loop but your 5th iteration's condition gets true.Now it will execute once more and show nothing (because there is nothing in $webBlock)and now condition will find that $webBlock is empty.I suggest you to use while loop here.It will solve your issue
I am not a PHP developer so I will just give you general idea about what you are doing.
Actually you are using Do-while loop which is sometimes called Exit Control loop. So, in case of Do-While after executing code your condition will be checked. So, even you didn't get any value in 'webBlock' your code will be executed. So, this is your bug.
Instead of this you can use While loop, Entry control loop. You code is executed if and only if condition is true.
$i = 1;
while (i>0) {
$x = 'block-'.$i;
$webBlock = $_POST[$x];
if(empty($webBlock))
{
break;
}
$i++;
}

Categories