I am using 2 regex functions here and I wanna make another function which returns false when the 2 regex are both false and if not, then true.
The problem here is when I wanna use the 2 regex functions in the third one, I have to give them parameters, which is not necessary I think, because the third function will only return a simple true or false. I get an undefined variable whenever I give parameters to the 2 regex functions in the 3rd one.
I tried using global variables which works but since its a bad practice I am looking for a better solution.
Code:
function regex1($input)
{
$regex= "/^[A-Za-z0-9 ]*$/";
if (!preg_match($regex, $input))
{
return false;
}
else
{
return true;
}
}
function regex2($input)
{
$regex= "/^[A-Za-z0-9 ]*$/";
if (!preg_match($regex, $input))
{
return false;
}
else
{
return true;
}
}
function checkBoth()
{
if (regex1($input) === false || regex2($input) === false)
{
return false;
}
else
{
return true;
}
}
EDIT:
The checkBoth function I am using in my other file like this together with the other 2 regex functions:
if (!regex1($input))
{
// show error at the same time
}
if (!regex2($input))
{
// show error at the same time
}
if(checkBoth())
{
// success
}
function regex2($input,$secondVar=false)
{....
Later in code in place where you need just add:
if($secondVar !== false){
// do whatever...
}
If you can't user "false" you can just empty string '' or any other value that will not appear there.
Related
I'm trying to check for if a string contains any blacklisted words from an array of string.
This is my current code - the focus is efficiency, string from list may be empty, the string we search in is never empty:
public static function includes_from_array($stringArray, $searchInMe, $offset=0) : bool {
// if not array just check if $stringArray exists in our $searchInMe string.
if(!is_array($stringArray)) {
return strpos($stringArray, $searchInMe) !== false;
}
foreach($stringArray as $query) {
if ($query === '') {
continue;
}
else if(strpos($searchInMe, strtolower($query), $offset) !== false) {
return true;
}
}
return false;
}
Is there a way to shorten the code quickly without harming efficiency or even improving it?
The code was written as it is currently to be able to retrieve the position if required (changing from true or false to pos returned in check), however it is not required in the shortened version.
Thanks!
As per my understanding you soul purpose is to check any bad word is present in sentence or URL and if present then return Boolean true.
Kindly try like this:
<?php
function includes_from_array($stringArray, $searchInMe){
if(is_array($stringArray)){
foreach($stringArray as $arr){
if(strpos($searchInMe,$arr) !== false){
return true;
}
}
}else{
if(strpos($searchInMe,$stringArray) !== false){
return true;
}
}
return false;
}
Sample Output : https://3v4l.org/3Pefn
I want to check all elements of an array and find out, whether at least one of them is prefixed by a given string:
public function validateStringByPrefix(string $string, $prefix)
{
$valid = false;
if (is_string($prefix)) {
if (strpos($string, $prefix) === 0) {
$valid = true;
}
} elseif (is_array($prefix)) {
foreach ($prefix as $partPrefix) {
if (strpos($string, $partPrefix) === 0) {
$valid = true;
break;
}
}
}
return $valid;
}
Is it possible / How to to achieve the same a more efficient way?
(It's a cheap method, but it's called a lot of times in my application, so even a minimal improvement might appreciably increase the application's performance.)
You can try next solution:
public function validateStringByPrefix(string $string, $prefix)
{
return (bool)array_filter((array)$prefix, function($prefix) use ($string) {
return strpos($string, $prefix)===0;
});
}
P.S. In case you have few large arrays (with prefixes), my solution is less efficient and you can combine our approaches like this:
public function validateStringByPrefix(string $string, $prefix)
{
if($string=='') {
return false;
}
foreach ((array)$prefix AS $subprefix) {
if (strpos($string, $subprefix)===0) {
return true;
}
}
return false;
}
There are many ways to rome....
//your array to test for
$array=[];
//set valid to false
$valid=false;
//setup prefixes array or not
$prefix='whatever';
//make array if you dont have one
!is_array($prefix) AND $prefix=array($prefix);
//prepare for use as REGEX
$prefix=implode('|',$prefix);
//do the work
array_walk($array,function($val,$key) use(&$valid,$prefix){
if (!$valid && preg_match("#^($prefix)#",$key)) {
$valid = true;
}
});
var_export($valid);
I used preg_match here, because $prefix can be an array, so the math would be: n+ strpos() calls vs. one preg_match() call
And after a single item matches, no more preg_match are called, just iteration to the end and out.
Is it possible to return an array, but also tell php it's supposed to mean false?
Example:
if ($res = a_function()) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
a_function:
function a_function() {
// do fancy stuff
if (xy) return true;
return array('err_no' => 1);
}
I guess its not possible, since php will always take an array for return true, right?
Lot's of ways. Probably the preferred one, compare to true with type checking ===:
if(($res = a_function()) === true) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
A non-empty array will always be true:
if($res = a_function() && !is_array($res)) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
Or flip it around:
if(is_array($res)) { //or isset($res['err_no'])
echo getErrorByNumber($res['err_no']);
}
else {
// all good
}
I would solve this problem with a byref parameter:
function foo(&$errors)
{
if (allWentWell())
{
$errors = null;
return true;
}
else
{
$errors = array('err_no' => 007);
return false;
}
}
// call the function
if (foo($errors))
{
}
else
{
echo getErrorByNumber($errors['err_no']);
}
This way you do not have to distinguish between different possible return types and you will not run into type juggling problems. It is also more readable, you know what's inside the $errors variable without documentation. I wrote a small article explaining why mixed-typed return values can be so dangerous.
Is there a way to stop an array_walk from inside the anonymous function ?
Here is some sample code (that works) to show what I mean, that checks if an array has only numeric values.
$valid = true;
array_walk($parent, function ($value) use (&$valid) {
if (!is_numeric($value)) {
$valid = false;
}
});
return $valid ? 'Valid' : 'Invalid';
If I have a big enough array, and the first entry is invalid, the rest of the (redundant) checks are still done, so I would like to stop the execution.
Using break / continue doesn't work (error: Fatal error: Cannot break/continue 1 level in ...).
Note: I don't want to rewrite the code, I just want to know IF this is possible.
As stated, theoretically it's possible but I'd advise against it. Here's how to use an Exception to break out of the array_walk.
<?php
$isValid = false;
$array = range(1, 5);
try {
array_walk($array, function($value) {
$isAMagicNumber = 3 === $value;
if ($isAMagicNumber) {
throw new Exception;
}
});
}catch(Exception $exception) {
$isValid = true;
}
var_dump($isValid);
/*
bool(true)
*/
You can put a static flag inside the anonymous function:
array_walk($ary, function($item) {
static $done = false;
if($done) {
return;
}
// … your code
if($myBreakCondition) {
$done = true;
return;
}
});
This doesn’t actually stop the iteration, but all further cycles after the flag is set simply do nothing. Not very efficient, but it might work without any greater performance impact if the arrays iterated are not too large.
In your case, the code would be:
$valid = true;
array_walk($parent, function($value) use(&$valid) {
static $done = false;
if($done) {
return;
}
if(!is_numeric($value)) {
$valid = false;
$done = true;
return;
}
});
return $valid ? 'Valid' : 'Invalid';
But actually it won’t be much difference if there was no “break” at all. Only the “false” would be assigned for every invalid value, which does not matter as the result would be still false. Maybe it would be even more efficient that my static variable cheat.
Personally in your case I would use array_filter instead:
$valid = count(array_filter($parent, 'is_numeric')) == count($parent);
or just
$valid = array_filter($parent, 'is_numeric')) == $parent;
If all values in the $parent array are numeric, they would be all present after the filtering. On the other hand, any non-numeric value in the array would affect the contents (decreasing the item count) in the filtered array and the comparison would yield false.
I am looking for the correct way to handle a return statement with a bool/string. For example I do all my checking inside the function and return true if it all passes. However if something went wrong I would like to return a string of what went wrong rather than just return false; with a general string. Does php assume false if a var is set to anything besides true? What is the correct way to handle this? Here's an example of what I'm doing
<?php
$a = 2;
$result = CheckVar($a);
if ($result)
{
echo 'Correct!';
}
else
{
echo $result;
}
function CheckVar($var)
{
if ($var == 1)
{
return true;
}
else
{
return 'This is not the correct answer. You supplied '.$var;
}
}
?>
It seems this method works, however is this good programming etiquette? Or is there another way I should be doing this? Thank you for your time.
Does php assume false if a var is set to anything besides true?
Not at all. PHP will return whatever the variable was set to. And actually since you have a non-empty string, that's a "truthy" value (ie: true in a boolean context). Since you used if ($result) as your check and you return a "truthy" value, the condition is always true. You need to change that check to:
if ($result === true) {
...
What is the correct way to handle this?
I think it's a good enough way to handle it. An alternative would be to pass an error string variable by reference, and have the fail part of your code fill that, eg:
function check($var, &$error) {
if ($var == 1) {
return true;
} else {
$error = 'This is not the correct answer. You supplied ' . $var;
return false;
}
}
Some native PHP functions behave like this (eg: exec().) Yet another alternative is to return an array with the errors, like Jared suggested. I personally use this option when I expect multiple errors (eg: a form validation routine):
function check_stuff($stuff) {
$errors = array();
if (!$condition1) {
$errors[] = 'Condition 1 failed';
}
if (!$condition2) {
$errors[] = 'Condition 2 failed';
}
return $errors;
}
Now you can also take advantage of the fact that empty arrays are falsy:
$errors = check_stuff($your_stuff);
if (!$errors) {
echo 'No errors!';
} else {
print_r($errors);
}
You can use === to check if the returned value is boolean true. === checks the type as well the value.
if ($result === true)
{
echo 'Correct!';
}
else
{
echo $result;
}
I came up against this recently, my function would either return an error message as a string or return true like this:
function check_something(){
if(condition){
return 'error message';
}
// if we got this far all is good!
return true;
}
I would call it and check the outcome like this:
$var = check_something();
if($var !== true){
// $var is not boolean true, so it must be a string
echo $var;
}
This checks that the outcome of the function is not just a truthy string, but is explicitly a boolean true
This could be useful to someone returning true or returning false as a string.
if (is_bool($result))
{
echo 'Result is a true bool';
}
else
{
echo $result.'returning a string';
}