Building a php calculator application and I'm a little confused on how I would do a specific case.
In general, I'm checking the input via a regular expression using preg_match but
what I'm confused about is how to cover the case of 09+0, I want to make sure that no number has a zero and then a number to the right of it.
On the left, it can be anything other than / sign. Some more examples include the following : 01+100, 33+011 etc (essentially, I want to let the user know this is bad input but having a difficult time figuring what the best way to check for it would be.
Edit 1 (Code so far) :
$input=$_GET["expr"];
$nospace_input=str_replace(' ', '', $input);
$input = str_replace('--','+',$input);
$correct_format=preg_match("/^[-.,0-9][-+*.\/, 0-9]+$/",$input);
if ($correct_format==0 && $nospace_input=="") {
//do nothing
}
elseif ($divby_zero==1) {
echo "Can't do div by zero!";
}
elseif($correct_format==1) {
$result = eval('return ' .$input. ';');
echo $input . " = " . $result;
}
else {
echo "Not valid";
}
Related
I recently switched a input form from a text to a textarea so that I could have multiple lines of text.
The form is working fine except when I go to validate. If it is one line, there is no problem but when I enter text that wraps to the second line, i get an error from my form validator (only letters and numbers are allowed) here is my code:
private function validate_alnum($var, $min=0, $max=0, $required=false, $err="") {
if($required==false && strlen($this->source[$var]) == 0) {
return true;
}
if(isset($this->source[$var])){
if(strlen($this->source[$var]) < $min) {
$this->errors[$var] = $err . ' is too short. It has to be at least '.$min. ' character(s)';
} elseif(strlen($this->source[$var]) > $max) {
$this->errors[$var] = $err . " is too long. It can't be more than ".$max. " characters";
} elseif(!preg_match("/^[a-zA-Z0-9 -.:,]*$/", $this->source[$var])) {
$this->errors[$var] = $err . ' is invalid. Only letters and numbers are allowed';
}
}
}
Your regex doesn't allow new lines. Try:
^[-a-zA-Z0-9\s.:,]*$
also - should be the first or last character if you want it to be literal, otherwise it makes a range.
The \s here will allow for single spaces, new lines, and tabs. ( Additional reading on the \s)
If you change the quantifier to + you can be sure there is more than 1 character in the string, which would take out your default $min requirement (the error message would be less specific though).
For a project, I have an input, which consists of numbers and letters, in a specific order, send from another web page. E.g. 7 numbers for an ID, a number followed by 2 letters for groups, and 1, 2, or 3 numbers for a room number.
To seperate them, I think I have to iterate through the whole string, see for each char if it is a number or a letter, and then use a lot of if/then functions to get the correct type.
Is there a better way to do this, or is this a good way to do it.
Using a regular expression should be the best solution here, as it would both tell you if the ID does match the wanted syntax, as well as getting the several parts of this ID in an array.
For the example you gave:
$idList = [
'1AB12', // OK
'1AB123', // OK
'1AB1234', // KO
'AB1234', //KO
'12AB12', //KO
];
foreach ($idList as $id) {
$isOk = preg_match('/^([0-9])([a-zA-Z]{2})([0-9]{1,3})$/', $id, $match);
if ($isOk) {
echo 'OK : ' . $id;
var_dump($match);
} else {
echo 'KO : ' . $id;
}
}
I'm trying to split a line of PHP up, the reason being I don't actually always need some of the code and so that I can reuse parts of it.
The main reason I'm doing this is because the currency I get shows more digits for some currencies e.g. 1.2562 instead of 1.25, so I want to use the substr function only on certain GET's and be able to modify it for other GET's.
http://prntscr.com/6ttw8o
symbol is always required, substr isn't, $converter always required, end part of substr isn't however it can change, new currency is required.
$symbol[2] . substr(($converter->convert($defaultCurrency, $newCurrency) * 1), 0, 4) . " <b>" .$newCurrency. "</b>";
I've tried doing this with explode, however I'm not entirely sure how to do it as I have never really had to split anything up before so I'm a little puzzled on how to go about it.
Once the code has gone through the GET checking which is the current one set, I want it to grab the specified split up code pieces and then output it.
Put your code in a function like this:
function formatCurrency($symbol, $converter, $defaultCurrency, $newCurrency, $factor=1.0, $suffix="", $substrChars=0) {
if($substrChars>0) {
return $symbol . substr(($converter->convert($defaultCurrency, $newCurrency) * $factor), 0, $substrChars) . $suffix . " <b>" . $newCurrency. "</b>";
} else {
return $symbol . ($converter->convert($defaultCurrency, $newCurrency) * $factor) . $suffix . " <b>" . $newCurrency. "</b>";
}
}
If you call it without the $substrChars parameter, it will omit the substr() call, otherwise it will strip all but the first $substrChars characters:
if( $_GET['currency'] === "GBP" ){
$newCurrency = $_GET['currency'];
$string = formatCurrency($symbol[1], $converter, $defaultCurrency, $newCurrency, 2.0, ".00", 0);
} elseif( $_GET['currency'] === "USD" ){
$newCurrency = $_GET['currency'];
$string = formatCurrency($symbol[2], $converter, $defaultCurrency, $newCurrency, 1.0, "", 4);
}
This solution is very readable because you immediately see the difference between the two branches in the conditional statement.
I'm trying to validate an input for Account number in php form. It should contain 8 numbers and '-' optionally. If there is '-' - it should be ignored.
After pressing the Submit button, the warning message suppose to be displayed above the form in case input is invalid.
Please help.
This is what I got so far, but I'm not sure if this is correct and don't know how to display a warning message above the form.
$acctnum= "$acctnum";
if(empty($acctnum)){
echo "You did not enter an account number, please re-enter"; }
else if(!preg_match("\-^[0-9]{8}", $acctnum)){
echo "Your account number can only contain eight numbers. Please re-enter."; }
Thank you!
You don't appear to be trying. No documentation or tutorial will tell you to make a Regex like that. For starters, where are the delimiters? Why is - escaped when it's outside a character class and therefore has no special meaning? What is that ^ doing there?
This should do it:
$acctnum = str_replace("-","",$acctnum);
if( !preg_match("/^\d{8}$/",$acctnum)) echo "Error...";
Since regex are quite expensive I'd go like that instead:
$acctnum = (int) $acctnum; // this automatically ignore the '-'
if ($acctnum < 0) $acctnum = -$acctnum;
$digits = ($acctnum == 0) ? log10($acctnum) + 1 : 1;
if ($digits === 8) { ... }
Split the task in two. First get rid of the "-" with str_replace and then check for the numbers.
$match = preg_match("/^\d{8}$/", str_replace("_", "", $str));
if ($match > 0) {
// Correct
} else {
// incorrect
}
I am trying to validate a phone number and require it to have 10 digits only no spaces or special characters allowed (example: 0123456789) and the same goes with zip code except 5 digits only (example: 01234).
This is what I have for the phone number field so far.
$phone = stripslashes($_POST['phone']);
if(!$phone || $phone == "Phone Number*")
{
$error .= "Please enter your phone number.<br />";
}
The next if statement should retrieve an error similar to "Please enter a valid phone number. Example: "0123456789".
If you don't want to use regular expressions, take a look at ctype_digit
For example:
if(strlen($phone)==10 && ctype_digit($phone)) {
//valid
} else {
//invalid
}
I can't testify to whether this will be faster or slower than regular expressions, but I would reckon it's probably moot. It's more or less what makes the most sense to you.
You can try regex here:
if(preg_match('/^[0-9]{10}$/', $phone)){
// valid
}else{
// Not valid
}
Something a little like that will ensure only numerical characters and 10 of them. Just change the 10 to 5 for zip code.
One more thing if $_POST['phone'] is not set when you access it you will get a E_NOTICE so just a tip here for you do:
$phone = isset($_POST['phone']) ? stripslashes($_POST['phone']) : null;
if(!$phone) // ERROR
$phone = stripslashes($_POST['phone']);
if(!$phone || $phone == "Phone Number*")
{
$error .= "Please enter your phone number.<br />";
}
if(!preg_match('/^\d{10}$/', $phone)) $error .= "Please enter phone number as ##########.<br />";
And for zip code
if(!preg_match('/^\d{5}$/', $zip)) $error .= "Please enter your zip code as #####.<br />";
Keep in mind that this will not allow foreign zip codes (which may be of different lengths or include letters)
Just some other suggestions too (to prevent unnecessary error messages)
You may want to process your user input such that 123-456-7890 becomes 1234567890 by doing something like
preg_replace('/[^\d]/','',$input)
Maybe do a trim($input) to strip leading/trailing whitespace
Finally, is there any particular reason you are using stripslashes on $_POST['phone']?
If they are all digits like you expect, then this shouldnt be necessary.
If they aren't all digits, then you will throw an error regardless
how about:
function check($number,$length)
{
if(ctype_digit ($number) && strlen($number)==$length)
return true;
else
return false;
}
if(check("1234",4))
echo "ok";
else
echo "Please enter a valid phone number. Example: "0123456789";
Well, this an old post but I will throw in some comments here anyway.
1) you should really not force the user to put in the right numbers, of course your validation on the front end will cover this but never assume it to be case coming into the "backend" .
Consider the following instead of putting the on the user:
// remove chars
$number = preg_replace('/[\D]/', '', $number);
//unit test sanitizer
filter_var($number, FILTER_SANITIZE_NUMBER_INT)
// check number
preg_match('/^[0-9]{10}$/', $zip)
Example : Read in user input if enough digits entered in look up closest matching zipcode etc.. (I actually used this on a site once) Of course setting the frontend to check is useful, but in case that fails .
$number = 'z 02012s';
// remove chars
$number = preg_replace('/[\D]/', '', $number);
//unit test sanitizer
$number = filter_var($number, FILTER_SANITIZE_NUMBER_INT);
// check number
if (preg_match('#^[0-9]{5}$#', $number) === 1) {
//(optional) lookup closest zip using your DB.
$look_zip = $db->getClosestZipMatch($number);
} else {
echo $number . " isn't 5 digits only, do something.";
}