I`m wonder why this not working
echo gettype($_GET['id']); //returns string
if(is_int($_GET['id']))
{
echo 'Integer';
}
How to validate data passing from GET/POST if it is integer ?
Can use
$validatedValue = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
See http://php.net/filter_input and related functions.
The manual says:
To test if a variable is a number or a
numeric string (such as form input,
which is always a string), you must
use is_numeric().
Alternative you can use the regex based test as:
if(preg_match('/^\d+$/',$_GET['id'])) {
// valid input.
} else {
// invalid input.
}
What about intval?
$int = intval($_GET['id']);
To validate form data (string) as an integer, you should use ctype_digit()
It returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
(PHP 4 >= 4.0.4, PHP 5)
Reference: http://php.net/manual/en/function.ctype-digit.php
Try:
if(isNumeric($_GET['id'])) {
$cast_int = (int)$_GET['id'];
}
if(isset($cast_int)) {
echo gettype($cast_int)."<br />\n";
if(is_int($cast_int))
{
echo 'Integer'."<br />\n";
}
} else {
echo gettype($_GET['id'])." was passed<br />\n";
}
function isNumeric($numeric) {
return preg_match("/^[0-9]+$/", $numeric);
}
It sounds like you are checking if a string contains an integer, rather than if that variable is an integer. If so, you should check out php's regex (regular expression) functionality. It allows you to check for very specific patterns in a string to validate it for whatever criteria. (such as if it contains only number characters)
Here's the php page
http://php.net/manual/en/function.preg-match.php
and here's a cheat sheet on regular expressions (to make the $pattern string)
http://regexpr.com/cheatsheet/
I take a slightly more paranoid approach to sanitizing GET input
function sanitize_int($integer, $min='', $max='')
{
$int = intval($integer);
if((($min != '') && ($int < $min)) || (($max != '') && ($int > $max)))
return FALSE;
return $int;
}
To be even safer, you can extract only numbers first and then run the function above
function sanitize_paranoid_string($string, $min='', $max='')
{
$string = preg_replace("/[^a-zA-Z0-9]/", "", $string);
$len = strlen($string);
if((($min != '') && ($len < $min)) || (($max != '') && ($len > $max)))
return FALSE;
return $string;
}
Code from: http://libox.net
Related
Basically I want to validate user input to ensure they are entering integer values. My if statement works well but my assignment is to change it to a for loop. Thanks!
my original if statement;
if (empty($scores[0]) ||
empty($scores[1]) ||
empty($scores[2]) ||
!is_numeric($scores[0]) ||
!is_numeric($scores[1]) ||
!is_numeric($scores[2])) {
$scores_string = 'You must enter three valid numbers for scores.';
break;
}
If you must use a for loop to validate the scores, then you just need to test each value in the $scores array in it:
$scores_string = '';
$len = count($scores);
for ($i = 0; $i < $len; $i++) {
if (empty($scores[$i]) || !is_numeric($scores[$i])) {
$scores_string = 'You must enter three valid numbers for scores.';
break;
}
}
if ($scores_string != '') {
echo $scores_string;
// do anything else you need
}
else {
// all is OK!
}
Demo on 3v4l.org
Note that the break in the if after you assign $scores_string saves iterating the entire array after a non-numeric value was found. If you wanted to count the number of non-numeric values, you'd increment a counter there instead.
It's better to define a function that returns a boolean to validate the parameters. If one variable of the parameters is invalid, return false immediately. Otherwise, return true.
Then use the function directly.
Check out the code below:
function isNumberScores($scores) {
foreach($socres as $score) {
if (empty($score) || !is_numeric($score)) {
return false
}
}
return true
}
if (!isNumberScores($socres)) {
$scores_string = 'You must enter three valid numbers for scores.';
// your code here
}
I am developing my own encryption and decryption algorithms. My encryption function is working fine, but my decryption function is not working properly. The following are my functions:
<?php
function encrypt($os,$mode=64,$pattern="tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[(strpos($pattern,$os[$i])+$mode)%strlen($pattern)];
}
return $ns;
}
function decrypt($os,$mode=64,$pattern="tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[abs(strpos($pattern,$os[$i])-$mode)%strlen($pattern)];
}
return $ns;
}
echo decrypt(encrypt("abcde"));
?>
My expected output is: abcde
But the output returned is: ejUPa
The encryption works in this way:
$new_char_index = ($char_index + $shift) % $alphabet_length;
where the modulo % handles the wrap around so that the new index is still in the alphabet range. This works well for positive numbers, but doesn't work like you would expect it to for negative numbers. Here are some examples:
echo -3 % 7; // -3
echo -11 % 7; // -4
That is why simply changing + for - doesn't work:
$new_char_index = ($char_index - $shift) % $alphabet_length;
This can lead to negative numbers. You can't access arrays with negative numbers in PHP, but you could do that in Python.
The easy fix is to make sure that the resulting index is always a positive numbers. You've tried that with abs(), but the problem is that this doesn't correctly wrap around from the other side of the alphabet, but only removes the sign which is wrong.
An easy fix is adding the alphabet length before the modulo operation in order to get a positive number:
$new_char_index = ($char_index - $shift + $alphabet_length) % $alphabet_length;
This works, because $alphabet_length % $alphabet_length == 0. It wraps to the correct position of the alphabet.
Now you only have to make sure that $shift is already in the alphabet range:
$shift = $shift % $alphabet_length;
One final improvement: you can use the same function for encryption and decryption, because the $enc_shift == -$dec_shift and the last formula should give you work for both.
This is not encryption. This is a variation on a Caeser cipher. Simply put, you should never implement your own encryption (unless you know exactly what you're doing...). This would do for obfuscation and nothing more.
As for the code itself, I suspect its an order of operations issue. Simply replacing a + with a - won't reverse the operator precedence in the encrypt() function. A handy generic string rotation function you could adapt is in the comments of this php documentation page.
If you want encryption there are many good articles about solid encryption; this is my personal opinion of a good starting point.
Here is a solution that works with every $mode and $pattern size.
You have to notice that you can only "encrypt" chars that are contained in $pattern.
<?php
function encrypt($os,$mode=64,$pattern=" tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$patternLength = strlen($pattern);
if($mode < 0) {
$mode = ($patternLength - $mode) % $patternLength;
}
if($mode >= $patternLength) {
$mode %= $patternLength;
}
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[(strpos($pattern,$os[$i])+$mode)%strlen($pattern)];
}
return $ns;
}
function decrypt($os,$mode=64,$pattern=" tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$patternLength = strlen($pattern);
if($mode < 0) {
$mode = ($patternLength - $mode) % $patternLength;
}
if($mode >= $patternLength) {
$mode %= $patternLength;
}
$ns="";
for($i=0;$i<strlen($os);$i++){
$pos = strpos($pattern,$os[$i]);
if($pos >= $mode ) {
$ns .= $pattern[$pos - $mode];
} else {
// $pos - $mode is negative so we need + sign
$ns .= $pattern[$patternLength + ($pos - $mode)];
}
}
return $ns;
}
To test this, you could do something like that:
$failed = false;
for($mode = -128; $mode <= 128; $mode++) {
// include all possible chars in the test to see if encryption and
// decryption works for all.
$allChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
if(decrypt(encrypt($allChars, $mode), $mode) != $allChars) {
echo "mode ".$mode." failed<br>";
$failed = true;
};
}
if(!$failed) {
echo "success";
}
Fixed it:
$ns.=$pattern[abs(strpos($pattern,$os[$i]))-$mode%strlen($pattern)];
In your decrypt ^^.
Just a matter of bracket placing.
Full fixed code:
function encrypt($os,$mode=64,$pattern="tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[(strpos($pattern,$os[$i])+$mode)%strlen($pattern)];
}
return $ns;
}
function decrypt($os,$mode=64,$pattern="tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[abs(strpos($pattern,$os[$i]))-$mode%strlen($pattern)];
}
return $ns;
}
echo decrypt(encrypt("abcde"));
Hopefully you can understand the difference yourself.
And now to fix the issue with spaces:
$pattern=" tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7Cu"
Take note of the space at the beginning of the string.
An additional note due to comments...
Should you wish to change $mode to let's say 62, you would need to shorten $pattern appropriately.
e.g.
function encrypt($os,$mode=62,$pattern=" tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[(strpos($pattern,$os[$i])+$mode)%strlen($pattern)];
}
return $ns;
}
function decrypt($os,$mode=62,$pattern=" tyv9xXa2iUEMhZLD6YlF4BOjg8AdJz0nVHKPRTpb5smfQ1WwroIkqcN3eSG7"){
$ns="";
for($i=0;$i<strlen($os);$i++){
$ns.=$pattern[abs(strpos($pattern,$os[$i]))-$mode%strlen($pattern)];
}
return $ns;
}
echo decrypt(encrypt("abcde"));
Works just fine, notice $pattern is now missing the last 2 characters.
I want to find the most lightweight solution to validate a string as a letter or number + ?. Eg: a? or 1? etc.
if (preg_match('/^[a-z0-9]\?$/', $str)) {
// yup, it's a letter or number + ?
}
slighty faster than regular expression is function:
// return true or false
function validate($str) {
$str0 = ord($str[0]);
return(
(
($str0 >= 97 && $str0 <= 122) or
($str0 >= 48 && $str0 <= 57)
) &&
(
$str[1] == '?'
)
);
}
Some time ago, i've written a lightweight-validation class. Maybe you can use it.
For example:
$oValidator = new Validator();
$oValidator->isValid('a', 'alpha_numeric|max_length[1]'); //true
$oValidator->isValid('1', 'alpha_numeric|max_length[1]'); //true
$oValidator->isValid('ab', 'alpha_numeric|max_length[1]'); //false
$oValidator->isValid('1337', 'alpha_numeric|max_length[1]'); //false
Example:
http://sklueh.de/2012/09/lightweight-validator-in-php/
github:
https://github.com/sklueh/Lightweight-PHP-Validator
OK This is the fastest way
$allowed_char = Array();
for($i=ord('a');$i<=ord('z');$i++) $allowed_char[chr($i)] = true;
for($i=ord('0');$i<=ord('9');$i++) $allowed_char[chr($i)] = true;
function validate($str) {
global $allowed_char;
return $allowed_char[$str[0]] && $str[1] == '?' && !isset($str[2]);
}
Regexp = 2.0147299766541s
This solution = 1.6041090488434s
So it's 20% faster than Regexp solution :)
I was wondering if there is any way to detect if a number is negative in PHP?
I have the following code:
$profitloss = $result->date_sold_price - $result->date_bought_price;
I need to find out if $profitloss is negative and if it is, I need to echo out that it is.
if ($profitloss < 0)
{
echo "The profitloss is negative";
}
Edit: I feel like this was too simple an answer for the rep so here's something that you may also find helpful.
In PHP we can find the absolute value of an integer by using the abs() function. For example if I were trying to work out the difference between two figures I could do this:
$turnover = 10000;
$overheads = 12500;
$difference = abs($turnover-$overheads);
echo "The Difference is ".$difference;
This would produce The Difference is 2500.
I believe this is what you were looking for:
class Expression {
protected $expression;
protected $result;
public function __construct($expression) {
$this->expression = $expression;
}
public function evaluate() {
$this->result = eval("return ".$this->expression.";");
return $this;
}
public function getResult() {
return $this->result;
}
}
class NegativeFinder {
protected $expressionObj;
public function __construct(Expression $expressionObj) {
$this->expressionObj = $expressionObj;
}
public function isItNegative() {
$result = $this->expressionObj->evaluate()->getResult();
if($this->hasMinusSign($result)) {
return true;
} else {
return false;
}
}
protected function hasMinusSign($value) {
return (substr(strval($value), 0, 1) == "-");
}
}
Usage:
$soldPrice = 1;
$boughtPrice = 2;
$negativeFinderObj = new NegativeFinder(new Expression("$soldPrice - $boughtPrice"));
echo ($negativeFinderObj->isItNegative()) ? "It is negative!" : "It is not negative :(";
Do however note that eval is a dangerous function, therefore use it only if you really, really need to find out if a number is negative.
:-)
if(x < 0)
if(abs(x) != x)
if(substr(strval(x), 0, 1) == "-")
You could check if $profitloss < 0
if ($profitloss < 0):
echo "Less than 0\n";
endif;
if ( $profitloss < 0 ) {
echo "negative";
};
Don't get me wrong, but you can do this way ;)
function nagitive_check($value){
if (isset($value)){
if (substr(strval($value), 0, 1) == "-"){
return 'It is negative<br>';
} else {
return 'It is not negative!<br>';
}
}
}
Output:
echo nagitive_check(-100); // It is negative
echo nagitive_check(200); // It is not negative!
echo nagitive_check(200-300); // It is negative
echo nagitive_check(200-300+1000); // It is not negative!
Just multiply the number by -1 and check if the result is positive.
You could use a ternary operator like this one, to make it a one liner.
echo ($profitloss < 0) ? 'false' : 'true';
I assume that the main idea is to find if number is negative and display it in correct format.
For those who use PHP5.3 might be interested in using Number Formatter Class - http://php.net/manual/en/class.numberformatter.php. This function, as well as range of other useful things, can format your number.
$profitLoss = 25000 - 55000;
$a= new \NumberFormatter("en-UK", \NumberFormatter::CURRENCY);
$a->formatCurrency($profitLoss, 'EUR');
// would display (€30,000.00)
Here also a reference to why brackets are used for negative numbers:
http://www.open.edu/openlearn/money-management/introduction-bookkeeping-and-accounting/content-section-1.7
Can be easily achieved with a ternary operator.
$is_negative = $profitloss < 0 ? true : false;
I wrote a Helper function for my Laravel project but can be used anywhere.
function isNegative($value){
if(isset($value)) {
if ((int)$value > 0) {
return false;
}
return (int)$value < 0 && substr(strval($value), 0, 1) === "-";
}
}
I'm writing an amfPHP function which should take string input. It takes alphanumeric characters without a problem, but unfortunately it returns data as "2" if I send "2.UgnFl4kAWovazp_tVo6fHg__.86400.1260025200-571701419" as parameter.
here is the function (real simple as you can see)
function checkOpenSession($guid, $session_key) {
return $session_key;
}
To bypass this service browser bug, double quote your entry on the service browser if you expect a string on an argument and this string starts with a number. I was having the same problem testing some methods via service browser and it worked fine.
I just tried this with a simple setup, and just writing the results to a file from the service browser and it seems to be ok for me. So the problem would seem to be in the calling end.
Another possibility is that amfphp changes the datatype of the returned value from a string to an int because of the leading integer. Try putting a some alphanumeric character at the start of the return string and see what that does.
This behavior is actually present in the AMFPHP service browser(bug), so it is easy to mistake it as the AMFPHP that is converting number-leading strings to int. However the problem is in the sending code. For instance sending a urlencoded string through the json gateway works properly (Objective C code):
NSString *theUrl = [[NSString alloc] initWithFormat:#"%#/modules/amfphp/amfphp/json.php/MysqlRemoting.checkAuth/%#/%#/1", kServerBaseUrl, userName, passMD5];
NSString *encodedUrl = [theUrl stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];
Where passMD5 may have a leading number. But if I enter appropriate values for the checkAuth method in the service browser, it is broken.
[edit]
$value = urldecode($value);
if($value != "") {
if($value[0] != '[' && $value[0] != '{' && $value != "null" && $value != "false" && $value != "true") {
$hasAlpha = false;
//check to see if it is a number
$sl = strlen($value);
for ($i = 0; $i < $sl; $i++) {
$char1 = ord($value[$i]);
if($char1 >= 0x30 && $char1 <= 0x39) {
//Then this is a number
} else { //Else leave value as is */
$hasAlpha = true;
}
}
if (!$hasAlpha) $value = json_decode($value, true);
}
else
{
$value = json_decode($value, true);
}
}
double quote your strings... that will work it out.