PHP validate string lightweight - php

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 :)

Related

Is this a good way of writing long conditions in PHP?

I have to evaluate a very long condition in PHP, so, to avoid errors and trying to write more readable code, I did the following:
//this returns 1 when true, and nothing when false, although expected TRUE or FALSE
$isNameValid=strlen($dataDecoded['nombre'])>=3;
$isDescriptionValid=(strlen($dataDecoded['descripcion'])>=10) && strlen($dataDecoded['descripcion'])<=300;
$isPriceValid=$dataDecoded['precio'] >0;
$isImageValid=(($dataDecoded['imagen'] != "") && ($dataDecoded['imagen'] != NULL) );
And now, I can make the following:
if($isNameValid==1 && $isDescriptionValid==1 && $isPriceValid==1 && $isImageValid==1)
{
echo "ok";
}
else{
echo "no";
}
It seems to work fine, but maybe is a weird way of doing things. I wanted to avoid the following, which I find more confusing and easy to make a mistake
if(strlen($dataDecoded['nombre'])>=3 && ... && ...)
Is there a better way to do that? Is wrong what I did? Thanks
I don't care for creating extra variables here; this makes code difficult to maintain and unreusable. I'd recommend breaking your validation logic into easy-to-read, maintainable, reusable functions:
function valid($data) {
return validName($data['nombre']) &&
validDescription($data['descripcion']) &&
validPrice($data['precio']) &&
validImage($data['imagen']);
}
function validName($name) {
return strlen($name) >= 3;
}
function validDescription($desc) {
return strlen($desc) >= 10 && strlen($desc) <= 300;
}
function validPrice($price) {
return $price > 0;
}
function validImage($image) {
return $image !== "" && $image != NULL;
}
$dataDecoded = [
"nombre" => "foo",
"descripcion" => "foo bar foo bar",
"precio" => 15,
"imagen" => "foo.png"
];
// now your main code is beautiful:
echo (valid($dataDecoded) ? "ok" : "no") . "\n";
Yes, that is acceptable. However, your variables there are all boolean, so you don't even need the ==1.
if($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid)
It really depends on how you want to handle it.
Is switch an option or a viable one?
Is ternary if prettier or handy?
From what I see, I'm guessing you have a validation purpose and a operating incoming depending on the validation. Why not create a function or a class that handles your input and validates? And in there, you can have all the dirty code you'd want. On your logical code, you'd just have to do (e.g of a class)
$someClass = new SomeClass();
$someClass->validate($fields);
if ($someClass->isValidated()) ...
This way, you'd actually follow some standards whereas the purpose of it would be to work as a validator for (all of? depends on your needs) your data
E.g of ternary ifs
$isNameValid = count($dataDecoded['nombre'])>=3 ? true : false;
$isDescriptionValid = count($dataDecoded['descripcion']) >= 10 && count($dataDecoded['descripcion']) <= 300 ? true : false;
$isPriceValid = count($dataDecoded['precio']) > 0 ? true : false;
$isImageValid = empty($dataDecoded['imagen']) === false ? true : false;
if ($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid) ...

Please help! How to express the cases in if clause?

I have string $a,$b,$c
I know if all of them not null express in this way:
if($a!="" && $b!="" && $c!="")
But if either 2 of them not null then go into the true caluse
if($a!="" && $b!="" && $c!=""){
** do the things here **
}else if(either 2 are not null){
**do another things here**
}
How to express it?
I would write a simple function like this to check:
function checkInput($var)
{
$nulls=0;
foreach($var as $val)
{
if(empty($val))
{
$nulls++;
}
}
return $nulls;
}
Then access it like this:
$inputs=array($a, $b, $c.... $z);
$nullCount=checkInput($inputs);
if($nullCount==0)
{
// All nulls
}
if($nullCount>2)
{
// More than 2 nulls
}
or for an one-off test, just pop the function into the actual if statement like this:
if(checkInput($inputs)>2)
{
// More than 2 nulls...
}
etc etc. You can then use the one function to check for any number of nulls in any number of variables without doing much work - not to mention change it without having to rewrite a long if statement if you want to modify it.
Other answers are good, but you can expand this to easily handle more variables:
$variables = array($a, $b, $c, $d, ....);
$howManyNulls = 0;
foreach($variables as $v){
if($v == ''){
$howManyNulls++;
}
}
if($howManyNulls == count($variables) - 2){
// do stuff
}
you can try this
if($a!="" && $b!="" && $c!="")
{
** do the things here **
}
else if(($a!="" && $b!="") || ($b!="" && $c!="") || ($a!="" && $c!=""))
{
**do another things here**
}
Try:
if($a!="" && $b!="" && $c!=""){
** do the things here **
}else if(($a!="" && $b!="") || ($a!="" && $c!="") || ($b!="" && $c!="")){
**do another things here**
}
$var[] = empty($a) ? 0:$a;
$var[] = empty($b) ? 0:$b;
$var[] = empty($c) ? 0:$c;
$varm = array_count_values($var);
if ($varm[0] === 0) {
//Code for when all aren't empty!
} elseif ($varm[0] === 1) {
//Code for when two aren't empty!
}
N.B; You may need to replace the 0 for a string/integer that will never crop up, if your variables are always strings or empty then 0 will do for this. The method for using bools within this would require more code.
$nullCount = 0
if($a!=""){ ++$nullCount; }
if($b!=""){ ++$nullCount; }
if($c!=""){ ++$nullCount; }
if($nullCount == 3){ // all are null
// do smth
}else if($nullCount == 2){ // only two are null
// do other
}
Just for fun, here's something potentially maintainable, should the list of arguments increase:
function countGoodValues(...$values) {
$count = 0;
foreach($values as $value) {
if($value != "") {
++$count;
}
}
return $count;
}
$goodValues = countGoodValues($a, $b, $c); // Or more... or less
if($goodValues == 3) {
// Do something here
}
else if($goodValues == 2) {
// And something else
}
Reference for the ... construct (examples #7 and #8 in particular) are available on php.net.
You can use double typecasting (to boolean, then to number) in conjunction with summing:
$count = (bool)$a + (bool)$b + (bool)$c;
if ($count == 3)
// ** do the things here **
else if ($count == 2)
//**do another things here**
There is also possible such solution:
<?php
$a= 'd';
$b = 'a';
$c = '';
$arr = array( (int) ($a!=""), (int) ($b!=""), (int) ($c!=""));
$occ = array_count_values($arr);
if ($occ[1] == 3) {
echo "first";
}
else if($occ[1] == 2) {
echo "second";
}
If you have 3 variables as in your example you can probably use simple comparisons, but if you have 4 or more variables you would get too big condition that couldn't be read.
if (($a!="") + ($b!="") + ($c!="") == 2) {
// two of the variables are not empty
}
The expression a!="" should return true (which is 1 as an integer) when the string is not empty. When you sum whether each of the strings meets this condition, you get the number of non-empty strings.
if (count(array_filter([$a, $b, $c])) >= 2) ...
This is true if at least two of the variables are truthy. That means $var == true is true, which may be slightly different than $var != "". If you require != "", write it as test:
if (count(array_filter([$a, $b, $c], function ($var) { return $var != ""; })) >= 2) ...
if($a!="" && $b!="" && $c!="") {
echo "All notnull";
} elseif(($a!="" && $b!="") || ($b!="" && $c!="") || ($a!="" && $c!="")) {
echo "Either 2 notnull";
}

Detecting negative numbers

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) === "-";
}
}

php validate integer

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

If statement structure in PHP

I keep getting an error with the following bit of code. It is probably some small thing but I don't see what is wrong.
while($row = mysql_fetch_array($result))
{
$varp = $row['ustk_retail'];
if ($varp<80000) { $o1 = 1; }
if (($varp=>80000) && ($varp<100000)) { $o2 = "1"; }
if (($varp=>100000) && ($varp<120000)) { $o3 = "1"; }
if (($varp=>120000) && ($varp<140000)) { $o4 = "1"; }
if (($varp=>140000) && ($varp<160000)) { $o5 = "1"; }
if (($varp=>160000) && ($varp<180000)) { $o6 = "1"; }
if (($varp=>180000) && ($varp<200000)) { $o7 = "1"; }
if (($varp=>200000) && ($varp<220000)) { $o8 = "1"; }
if (($varp=>220000) && ($varp<240000)) { $o9 = "1"; }
if (($varp=>240000) && ($varp<260000)) { $o10 = "1"; }
if (($varp=>260000) && ($varp<280000)) { $o11 = "1"; }
if (($varp=>280000) && ($varp<300000)) { $o12 = "1"; }
if ($varp>=300000) { $o13 = "1"; }
}
Running php -l (lint) on your code I get a
Parse error: syntax error, unexpected T_DOUBLE_ARROW
The T_DOUBLE_ARROW token is what PHP expects when assigning array values to array keys.
When comparing for Greater than or equal to the PHP Parser expects T_IS_GREATER_OR_EQUAL, meaning you have to use >= instead of =>.
See
the chapter on Comparison Operators in the PHP Manual and
the List of Parser Tokens in the PHP Manual
Greater than or equal to is >= sign, not =>
Update:
You are right. It's small but hard to find mistake.
It took me to split whole line into pieces to see where the problem is:
<?php
if
(
$varp
=>
80000
)
So, it says parse error on line 5 and I had to doublecheck this operator.
Of course, at first I separated the problem line from the rest of the code to be certain.
You have an expression error.
$varp=>220000 // is not a valid php expression
=> operator is used to assign values in arrays like:
$x = array( 'foo' => 'bar');
>= is the comparation assigment greater than or equal
You have made a mistake in the if conditions. The greater than Equal to sign is >= and not =>.
The answer has already been given but thought this was neat enough to share:
PHP accepts boolean expressions in it's switch statement.
switch(TRUE) {
case $range <= 10: echo "range below or equal to 10"; break;
case $range <= 20: echo "range above 10 below or equal to 20"; break;
case $range <= 30: echo "range above 20 below or equal to 30"; break;
default: echo "high range";
}
In my opinion this generates the cleanest most readable code.
This is more readable and compact way to do the same:
$ranges = range(300000, 80000, -20000);
$index = 1;
$varp = 220001;
foreach ($ranges as $i => $range) {
if ($varp >= $range) {
$index = 13 - $i;
break;
}
}
${'o' . $index} = 1;
Anyway - I think you're doing something wrong with using variable name of result.
You probably want to change ($varp=300000) to ($varp==300000) and it might help to enclose the full if-statement inside (), like this
if($varp80000 && $varp100000 && $varp120000 && $varp140000 && $varp160000 && $varp180000 && $varp200000 && $varp220000 && $varp240000 && $varp260000 && $varp280000 && $varp==300000) { $o13 = "1"; }
On another note, where to these strange $varp#### variables come from?
Not sure whether the code you've posted has gotten messed up somehow, but it looks like you're missing "==" in some of the if conditions. Also, as Skilldrick pointed out, the whole if condition should be in parentheses
"Greater than or equal to is >= NOT =>. You use => for arrays for keys/values.
Add one more bracket around the conditions in if....
if ( ($varp80000) && ($varp100000) && ($varp120000) && ($varp140000) && ($varp160000) && ($varp180000) && ($varp200000) && ($varp220000) && ($varp240000) && ($varp260000) && ($varp280000) && ($varp=300000) ) { $o13 = "1"; }

Categories