My php code skips a user request please look inside

  • #1
Femme_physics
Gold Member
2,547
1
Hey folks! Wow...been a while since I posted here.
So this ought to be a simple script I'm running in Command Prompt, but it completely skips the part where it asks the user to enter a number (after asking how much would you like to withdraw (or deposit) )

What gives?

PHP:
<?php
$balance=1000;
echo "Welcome to your bank. Your balance is " . $balance . " Which action would you like to take? (w=withdraw, d=deposit) \n" ;
$user=fgetc(STDIN);

	if ($user=="w")
	{
	echo "How much would you like to withdraw? \n";
	(int)$sum=fgets(STDIN);
	$balance = $balance-$sum;
	echo "Money successfully withdrawn. Your balance now stands at" . $balance . "";
	}
	
else if ($user=="d")
{
echo "How much would you like to deposit? \n";
(int)$sum=fgets(STDIN);
$balance=$balance+$sum;
echo "Money successfully deposited. Your balance now stands at" . $balance . "" ; 
}
	else
	{
	echo "You can only use enter 'w' or 'd'";
    }
?>
 

Answers and Replies

  • #2
chiro
Science Advisor
4,790
132
Hey Femme_physics.

I've never really done much web programming (most of my background is C++) but with regards to PHP this is an extension to normal HTML. To illustrate my point I got this:

http://www.php.net/manual/en/tutorial.firstpage.php

See if adding the standard HTML tags helps.
 
  • #3
Femme_physics
Gold Member
2,547
1
Hi chiro! It's a tad different since we're working from command prompt, so I'm not sure we can integrate HTML yet until we start working with php via browsers. Oh well, I've been refraining to ask my teacher for help to be more independant, maybe it's about time I'll hassle him.
 
  • #4
Borg
Science Advisor
Gold Member
1,885
2,379
You are using the fgets function in the if statements instead of the fgetc function after the first question. Are you sure that you want to load the amount from a file? Don't you want to use the fgetc function again?

Fgets () PHP Function

BTW, I don't know PHP so I could be wrong.

EDIT: I'm probably wrong. Maybe this link will help.
how do I write a command-line interactive php script?
 
Last edited:
  • #5
Femme_physics
Gold Member
2,547
1
I used fgetc because it seems to approved of me using characters instead of numbers. The funny thing is that I actually got it to work by only working with numbers. I used "1" and "2" instead of "w" and "d" to be my user input and voila, now the program works. Go figure, right?

I still haven't figured out how to make it work with characters as oppsoed to numbers...I'll have to see about that. Surprisingly enough it's not easy to find answers and guides about basic PHP when operated in command prompt (What you linked, is a rare command-prompt-relevant example! Those are not easy to find), all the examples and even the main documentation site php.net already integrate HTML. Not as beginner friendly as I thought.

Thanks for the replies though! If anyone is interested in my full code, posting it here

PHP:
<?php
$balance=1000;
echo "Welcome to your bank. Your balance is " . $balance . " Which action would you like to take? (1=withdraw, 2=deposit) \n" ;
$user=fgets(STDIN);

	if ($user==1)
	{
	{
	echo "How much would you like to withdraw? \n";
	(int)$sum = fgets(STDIN);
	}
	If ($sum>$balance)
	{
	echo "Error! You cannot withdraw more than " . $balance . "";
	}
else if ($sum<$balance)
	{
$balance=$balance-$sum;
echo "Money successfully withdrawn. Your balance now stands at " . $balance . "" ; 
	}
	}
	if ($user==2)
{
echo "How much would you like to deposit? \n";
(int)$sum=fgets(STDIN);
$balance=$balance+$sum;
echo "Money successfully deposited. Your balance now stands at " . $balance . "" ; 
}
	else if ($user!=1 && $user!=2)
	{
	echo "please choose either 1 (to withdraw) or 2 (to deposit)";
	}
?>
 
  • #6
Borek
Mentor
28,530
2,963
When it comes to variables and types PHP is a source of constant frustration to me. It tries to be clever, and juggle types trying to guess what you mean, but its cleverness introduces inconsistencies, which lead to problems, so it tries to overcome them by introducing even more clever and more inconsistent solutions. This produces a mess described here:

http://pl1.php.net/manual/en/types.comparisons.php

Question is - what is the type of the $user variable? What is compared to what? Is == enough, or should you use ===? Honestly - I have no idea, but that's where I would search for an answer.
 
  • #7
jhae2.718
Gold Member
1,161
20
PHP? I am so, so sorry.
 
  • #8
Femme_physics
Gold Member
2,547
1
PHP? I am so, so sorry.
Haha! Yes I moved from mechanical engineering to PHP. I didn't like this manly field to be honest. I was the only girl in class. At least now there are 6 others with boobs. :P yay for not feeling the odd one out..

Question is - what is the type of the $user variable? What is compared to what? Is == enough, or should you use ===? Honestly - I have no idea, but that's where I would search for an answer.
Well since the last program I posted works, I assume I did that part right. I guess there is just another function for user input via latin alphabet that I haven't been briefed about yet. I'll wait with that, this is good enough for a beginner ;)
 
  • #9
jhae2.718
Gold Member
1,161
20
If you're interested in seeing the problem, I'd try the $user == "w" comparison in the REPL and see what it gives you.

You could also try strcmp($user, "w"). (I don't know PHP, but I do know C!)
 
  • #10
34,783
10,943
When it comes to variables and types PHP is a source of constant frustration to me. It tries to be clever, and juggle types trying to guess what you mean, but its cleverness introduces inconsistencies, which lead to problems, so it tries to overcome them by introducing even more clever and more inconsistent solutions. This produces a mess described here:

http://pl1.php.net/manual/en/types.comparisons.php

Question is - what is the type of the $user variable? What is compared to what? Is == enough, or should you use ===? Honestly - I have no idea, but that's where I would search for an answer.
I never worked with user inputs from the command line, but usually you can take care of types without problems - inputs are strings, if you want to use them as integer or some special formats you should use intval or similar functions to make sure they are of the right type (and to avoid malicious inputs). Every variable you define in your code is in your code, so just keep in mind which format it has.


Concerning the original question, var_dump($user) should tell you what happened.
 
  • #11
I like Serena
Homework Helper
6,577
176
When asked what to do, you type for instance "w" followed by "Enter".
The call fgetc(STDIN) only reads "w" and leaves the "Enter" key unread.
After that the call to fgets(STDIN) reads a string until "Enter"... which is an empty string. :eek:

To fix it you can call fgets(STDIN) immediately after fgetc() to "flush" the "Enter".
Calling fgets(STDIN) after that should give you the number you want.
 
  • #12
Borek
Mentor
28,530
2,963
I never worked with user inputs from the command line, but usually you can take care of types without problems - inputs are strings, if you want to use them as integer or some special formats you should use intval or similar functions to make sure they are of the right type (and to avoid malicious inputs). Every variable you define in your code is in your code, so just keep in mind which format it has.
I had to code php page that was checking entered value for a number of significant digits entered (string) and if the value was correct (or rather if it was close enough to the expected value). Sometimes that required a string, sometimes a float. Dealing with variables that are automatically changing type was a nightmare. I wasted a lot of time just trying to keep track of what type is the variable at any given moment. Sure, I come from Pascal, C, C++ background, so I automatically assume variables have assigned types, which most likely sometimes makes me think in wrong categories.

IMHO PHP is a great idea, coded in a lousy, inconsistent way.
 
  • #13
.Scott
Homework Helper
2,636
960
I believe "I like Serena" has the correct solution.

I suspect that fgetc() will not read a single character until a full line has been entered. So your original program should work if you enter "w123" or "d345" followed by an Enter.
 
  • #14
Femme_physics
Gold Member
2,547
1
@ I Like Serena! :)
I'd have liked to say it works but it didn't, again it skips my if's. If your idea were true then PHP is clumsier than I would've imagined... I mean the program works perfectly fine using 1 or 2 instead... why can't a similar function work the same way for letters?

@mfb

Vardump is an interesting cat, it told me that $user is
Code:
string(1)"w"[/quote].  That's when using fgetc. Ironically if I use fgets I get [code]string(3)"w
"
... The second quotation mark seems to run off to a new line. That's good, because "w" and "d" are technically strings.

@jhae2.718

I read some about strcmp, which appears to be useful for string comparisons. Right now I'm not really able to implement it in my code (I tried), and going over if I'm doing it right will take too long. Being a n00bie and that my class is today, I'll give myself the privilege ask my teacher.

I suspect that fgetc() will not read a single character until a full line has been entered. So your original program should work if you enter "w123" or "d345" followed by an Enter.
I see, interesting, though I'm trying to get it to work with just "w" or "d".



PHP:
<?php
$balance=1000;
echo "Welcome to your bank. Your balance is " . $balance . " Which action would you like to take? (1=withdraw, 2=deposit) \n" ;
$user=fgetc(STDIN);
$user=fgets(STDIN);

	if ($user=="w")
{
	{
	echo "How much would you like to withdraw? \n";
	(int)$sum = fgets(STDIN);
	}
If ($sum>$balance)
{
echo "Error! You cannot withdraw more than " . $balance . "";
}
	else if ($sum<$balance)
	{
	$balance=$balance-$sum;
	echo "Money successfully withdrawn. Your balance now stands at " . $balance . "" ; 
	}
}
	
	if ($user=="d")
{
echo "How much would you like to deposit? \n";
(int)$sum=fgets(STDIN);
$balance=$balance+$sum;
echo "Money successfully deposited. Your balance now stands at " . $balance . "" ; 
}
	else if ($user!="w" && $user!="d")
	{
	echo "please choose either 1 (to withdraw) or 2 (to deposit)";
	}
?>
 
  • #15
AlephZero
Science Advisor
Homework Helper
6,994
291
... The second quotation mark seems to run off to a new line.
fgets reads the whole line, including the "newline" character at the end. Printing the newline character is what made the second " start a new line.

So, if you compare reading fgets with a constant like "w", it will never be equal, because the "w" doesn't end with a newline character.

You probably need to compare the first character of the string with "w". Can you do something like
Code:
if ($user[0]=="w")
(assuming PHP is like C and the first character is numbered 0, not 1)
 
  • #16
191
3
Be VERY careful with fgetc and fgets, for reasons already mentioned (the consumption, or non-consumption of the newline '\n' character. I'm not sure if PHP has the concept of buffer overflow, but if it does, you should watch out for that too (someone enters an essay instead of the small number you expected, what happens?) It's not ideal to simply cast the input to the type that you want, (int)$sum = fgets(STDIN); is really bad, what happens if you can't cast that essay they entered to int?)

Find the function references on PHP.net and make sure to fully understand fgetc() and fgets() in terms of the input they expect, what they do to it, what they return to you and how they handle (or ignore) exceptions or errors.
 
  • #17
Femme_physics
Gold Member
2,547
1
AlephZero - how did you know that was the answer? That all I needed was to add [0]? Yes the program works now! :) Much appreciated!

But seriously, how did you know?


Be VERY careful with fgetc and fgets, for reasons already mentioned (the consumption, or non-consumption of the newline '\n' character. I'm not sure if PHP has the concept of buffer overflow, but if it does, you should watch out for that too (someone enters an essay instead of the small number you expected, what happens?) It's not ideal to simply cast the input to the type that you want, (int)$sum = fgets(STDIN); is really bad, what happens if you can't cast that essay they entered to int?)

Find the function references on PHP.net and make sure to fully understand fgetc() and fgets() in terms of the input they expect, what they do to it, what they return to you and how they handle (or ignore) exceptions or errors.
Yep, my assumption of fgetc made things more complicated than expected.
 
  • #18
I like Serena
Homework Helper
6,577
176
@ I Like Serena! :)
I'd have liked to say it works but it didn't, again it skips my if's. If your idea were true then PHP is clumsier than I would've imagined... I mean the program works perfectly fine using 1 or 2 instead... why can't a similar function work the same way for letters?
You should have:
PHP:
$user=fgetc(STDIN);
fgets(STDIN);
Instead of:
PHP:
$user=fgetc(STDIN);
$user=fgets(STDIN);
You were overwritng the value of $user before checking if it was "w".
 
  • #19
191
3
$user[0] is array notation for the first (0th) element of an array (and a 'string' of characters can be thought of, and accessed, as a character array). The start of the string you received from the input is the first character they typed (and remember, a newline '\n' character is appended to their input when they press Enter, so you could access it and compare it like so $user[1] == '\n' and expect to see 'true'.
 
  • #20
Femme_physics
Gold Member
2,547
1
I see, Adyssa, thank you. Although it turns out there is a slightly more elegant solution. I just needed to do trim

PHP:
<?php
$balance=1000;
echo "Welcome to your bank. Your balance is " . $balance . " Which action would you like to take? (w=withdraw, d=deposit) \n" ;
$user=trim(fgets(STDIN));

	if ($user=="w")
{
	{
	echo "How much would you like to withdraw? \n";
	$sum = (int)fgets(STDIN);
	}
If ($sum>$balance)
{
echo "Error! You cannot withdraw more than " . $balance . "";
}
	else if ($sum<$balance)
	{
	$balance=$balance-$sum;
	echo "Money successfully withdrawn. Your balance now stands at " . $balance . "" ; 
	}
}
	
	if ($user=="d")
{
echo "How much would you like to deposit? \n";
$sum=(int)fgets(STDIN);
$balance+=$sum;
echo "Money successfully deposited. Your balance now stands at " . $balance . "" ; 
}
	else if ($user!="w" && $user!="d")
	{
	echo "please choose either 'w' (to withdraw) or 'd' (to deposit)";
	}
?>
 
  • #21
34,140
5,762
fgets reads the whole line, including the "newline" character at the end. Printing the newline character is what made the second " start a new line.

So, if you compare reading fgets with a constant like "w", it will never be equal, because the "w" doesn't end with a newline character.

You probably need to compare the first character of the string with "w". Can you do something like
Code:
if ($user[0]=="w")
(assuming PHP is like C and the first character is numbered 0, not 1)
If PHP is anything like C, the code above wouldn't work correctly. I don't know anything about PHP, but I do know a lot about C. The constant "w" is a string literal, whereas the constant 'w' (single quotes) is a character literal.

In C, the value of a string literal is the address of its first byte, not the first character in the string. I believe the code above should be like so:
Code:
if ($user[0]=='w') 
{
    ...
}
If AlephZero's version works, it means that PHP doesn't treat strings the same as C does.
 
  • #22
34,783
10,943
PHP does not distinguish between characters and single-character strings.
Single and double quotation marks do exactly the same here. They just differ in the parsing of stuff inside (e. g. in "w=$w" PHP will replace $w with its value, while 'w=$w' is interpreted as a string), which is not relevant for a string 'w'.
Code:
$w="s";
var_dump ($w[0]); //returns a 1-character string "s"
 
  • #23
I like Serena
Homework Helper
6,577
176
PHP is a script language. That means that it does not support pointers or addresses the way C does.
A string is just a string. A character is indeed also a string.
 

Related Threads on My php code skips a user request please look inside

  • Last Post
Replies
8
Views
6K
Replies
1
Views
2K
Replies
7
Views
4K
  • Last Post
Replies
0
Views
2K
Replies
4
Views
917
Replies
5
Views
3K
  • Last Post
Replies
15
Views
5K
Replies
13
Views
3K
Replies
13
Views
3K
Top