Tải bản đầy đủ (.pdf) (5 trang)

Plug in PHP 100 POWER SOLUTIONS- P30 pptx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (316.54 KB, 5 trang )

CHAPTER 6
Forms and User Input

112
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

112
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s
E
ven with the growth in Web 2.0 Ajax techniques, most people still interact with web
sites using forms. They are a tried and tested means of obtaining user input and are
likely to retain an important position for a long time to come.
Receiving user input is all well and good—that’s the easy part. But turning that input
into usable and secure data is another matter. In this chapter, you’ll find a collection of
solutions for helping you with expression evaluation, validation of credit card details,
e-mail addresses and text strings, identifying spam, preventing automated input from
“bots,” and ways of supporting user-supplied text formatting.
Evaluate Expression
You might think that offering support for evaluating expressions would be a simple matter
of calling the PHP eval() function with a user supplied input. Unfortunately, though,
eval() is an extremely powerful function that will interpret any string supplied to it as if it
were a PHP program; using it could completely open up your web site to any intruder with
a minimum of PHP knowledge.
However, with this plug-in the user input is completely sanitized by stripping out any
characters and functions that are not safe, leaving only a selection of 22 mathematical
functions and the basic math operators (plus, minus, multiply, and divide), and only then
is the input passed to eval(). Figure 6-1 shows a variety of expressions being calculated.
About the Plug-in
This plug-in accepts a string containing a mathematical expression and returns the result of
evaluating it. It takes this argument:
• $expr A string containing an expression


Variables, Arrays, and Functions
$f1
Array containing the 22 mathematical function names supported
$f2
Array containing tokens that the function names are temporarily converted to
FIGURE 6-1 This plug-in enables powerful calculator functionality on your web site.

31
C h a p t e r 6 : F o r m s a n d U s e r I n p u t
113
C h a p t e r 6 : F o r m s a n d U s e r I n p u t
113
How It Works
To allow the use of PHP’s build-in eval() function, it is necessary to remove any harmful
expressions before passing them to the function. To achieve this, the array $f1 contains
22 function names (out of the hundreds supported by PHP) that are considered safe. Using
the $f2 array, which contains a matching set of tokens, any of the 22 functions found in the
argument $expr are converted to a corresponding token. This means that any remaining
alphabetical characters may form other function names and therefore are stripped out.
The preceding is achieved by first converting the string $expr to lowercase using the
function strtolower() and then employing str_replace() to replace all occurrences of
the allowed function names with their tokens.
Next preg_replace() is called to strip out anything remaining that is not required,
using the regular expression /[^\d\+\*\/\-\.()! ]/. Okay, I know it looks like I just
dropped the keyboard on the floor but this is actually a powerful expression which I’ll now
break up for you.
The outer / characters denote the start and end of a regular expression.
The square brackets, [], state that a match should be made against any single character
enclosed within them.
The ^ symbol, when immediately following a [ symbol, forces negation, so that the

expression will match anything that is not one of the characters following.
Next comes a sequence of characters, which are all escaped by prefacing them with a \
symbol, because otherwise they would be interpreted as special regular expression operators:
• \d Any digit (0–9)
• \+ An addition symbol
• \* A multiplication symbol
• \/ A division symbol
• \- A subtraction symbol
• \. A decimal point symbol
So, if any symbol is not one of these escaped symbols, it will be considered a match and
the second argument to preg_replace(), '', will replace it with nothing—in other words,
the symbol will be removed.
Finally, a few other symbols are also allowed through. These are the left and right brackets,
the comma, the exclamation mark, and a space.
You might wonder why the exclamation mark is allowed within a mathematical
expression. Well, the answer isn’t that the exclamation mark is needed for use in expressions,
because it isn’t. Instead, it’s there because it forms part of each of the 22 tokens in the array
$f2. Once the mathematical functions have been converted to tokens, the ! symbols remain
there so that the tokens can be converted back again after stripping the remaining unwanted
characters out, which is done using another call to the str_replace() function. I chose the
exclamation mark at random and could equally have used any one of many other symbols.
After all this processing, the resulting sanitized string is passed to the eval() function,
the result of which is returned to the calling statement. If you wish to see what the sanitized
expression looks like, you can uncomment the line shown in the source code.

114
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

114
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

How to Use It
To evaluate a user-supplied expression, just call the function PIPHP_EvaluateExpression(),
passing the expression to be calculated, in the following manner, which calculates the area
of a circle with a radius of 4:
echo PIPHP_EvaluateExpression("pi() * pow(4, 2)");
The Plug-in
function PIPHP_EvaluateExpression($expr)
{
$f1 = array ('abs', 'acos', 'acosh', 'asin', 'asinh',
'atan', 'atan2', 'atanh', 'cos', 'cosh',
'exp', 'expm1', 'log', 'log10', 'log1p',
'pi', 'pow', 'sin', 'sinh', 'sqrt',
'tan', 'tanh');

$f2 = array ('!01!', '!02!', '!03!', '!04!', '!05!',
'!06!', '!07!', '!08!', '!09!', '!10!',
'!11!', '!12!', '!13!', '!14!', '!15!',
'!16!', '!17!', '!18!', '!19!', '!20!',
'!21!', '!22!');

$expr = strtolower($expr);
$expr = str_replace($f1, $f2, $expr);
$expr = preg_replace("/[^\d\+\*\/\-\.(),! ]/", '', $expr);
$expr = str_replace($f2, $f1, $expr);

// Uncomment the line below to see the sanitized expression
// echo "$expr<br />\n";

return eval("return $expr;");
}

Validate Credit Card
Sometimes people make mistakes when entering credit card numbers in web forms, or even
just make numbers up to see what will happen. Using this plug-in you can at least ensure that
a credit card number and expiration date you have been provided with has an acceptable
number sequence, a correct checksum, and a valid expiration date.
This enables you to only pass on sensible-looking details to your card pr
ocessing
organization, and possibly limit any additional fees that may be charged. In Figure 6-2 you
can see a made-up card number that has not validated.
About the Plug-in
This plug-in accepts a credit card number and expiration date and returns TRUE if they
validate, otherwise it returns FALSE. It takes these arguments:
• $number A string containing a credit card number
• $expiry A credit card expiration date in the form 07/12 or 0712

32
C h a p t e r 6 : F o r m s a n d U s e r I n p u t
115
C h a p t e r 6 : F o r m s a n d U s e r I n p u t
115
Variables, Arrays, and Functions
$left String containing the left four digits of $number
$cclen Integer containing the number of characters in $number
$chksum
Integer containing the credit card checksum
$j
Loop counter
$d Character containing individual digits extracted from $number
How It Works
In the 1950s, Hans Peter Luhn, a scientist working at IBM, created the Luhn checksum

algorithm, also known as the modulus 10 or mod 10 algorithm. It will detect any single-digit
error, as well as almost all transpositions of adjacent digits in a string of digits. This makes it
very useful for verifying whether a credit card number has been successfully entered by
using the simple method of adding a checksum digit at the number’s end.
All major credit
companies use this system, and so can we.
The first thing the plug-in does is remove any non-digit characters from $number; the
same is done for the expiration date in $expiry. Then, the contents of the first four digits of
$number are placed in the variable $left, the length of $number is placed in $cclen, and
$checksum is initialized to 0.
Each card issuer has their own initial sequences of numbers, and card number length
can vary between 13 and 16 digits depending on the issuer. So, using the contents of $left,
the next main section of code looks up the type of card and, based on the result, returns
FALSE if $number does not contain the correct number of digits for that card.
Once all the known sequences of initial digits have been processed, if no card has yet
been matched, then FALSE is returned because $number represents the number for a card
type the program is unaware of—most likely it’s a made-up number.
Otherwise, the card type has been identified and $number has been found to have the
right number of digits, so the next portion of code runs the Luhn algorithm to see whether
the sequence of numbers appears valid. It does this by checking alternate digits and adding
them together in a pre-set manner. If the result is exactly divisible by 10, then the sequence
is valid. If not, FALSE is returned.
Lastly, the expiration date is checked against the date of the last day of the current
month, and if the card has expired, FALSE is returned.
If all these tests pass, a value of TRUE is returned.
FIGURE 6-2 Credit card numbers have a built-in checksum that this plug-in will validate.

×