I have been toying with PHP filter library. I liked it but I am unable to perform a simple filter function. I essentially want to invalidate those values in my input array that are strings and which are longer than certain value. Is there a way to do this like,
$data = array('input_string_array' => array('aaa', 'abaa', 'abaca'));
$args = array(
'component' => array('filter' => FILTER_DEFAULT,
'flags' => FILTER_REQUIRE_ARRAY,
'options' => array('min_length' => 1, 'max_length' => 10)
)
);
var_dump(filter_var_array($data, $args));
I tried this and its giving me error. because presumably there is no min_length/max_length option available. But then how to implement this? Also is there a place where it is mentioned about all such options like max_range, min_range, regexp.
Also I had another doubt, in filters, in FILTER_CALLBACK filter. I wanted to know if there is a way to pass a parameter other than the data to the called function? something like this,
echo filter_var($string, FILTER_CALLBACK, array("options"=> array("lengthChecker", "5")));
Thanks a lot for the help.
Unless there's a better, more direct filter+option you can use FILTER_VALIDATE_REGEXP
prints
To get rid of the NULL elements you can use e.g. array_filter().
I believe the original problem was that the field in the data array was not named the same as the one in the filter array.
Introduction
You will need at least PHP 5.4+ for this answer to work (due, at minimum, to the array syntax).
If the goal is to do something like this:
... and use the return results of basic PHP functions (along with decision logic) to check the length (
mb_strlen()
,strlen()
) of a string, the key is to have an excellent filter instructions Array`. To pass arguments to your callback function (for reuse, encapsulation, and generalization purposes, etc...), I believe there are at least two scenarios.Scenarios
A) The class/object forms.
B)The procedural form.
Solutions
1) Replace
$this
or$object
in scenario A with anew
instance of an object right then and there, passing in any arguments its constructor. This seems unlikely as it smacks of tightly coupled code.Alternatively, one could inject a pre-populated object into a
Validator
class of some sort and runfilter_input_array()
from within thatValidator
class. Thus, passing arguments to thecallbackMethod
would not be necessary.Or
2) Replace
'callbackFunction'
in scenario B with a PHP anonymous function and implement theuse
syntax to pass arguments / constraints from theValidator
class to it.Attempt #1: Filter Instructions Array with Anonymous Functions
Here is a sequential example for working with scalar values.
Of course, this violates DRY principles. So, you might define the anonymous function as a property of a
Validator
class (or just assign it to a variable), which makes it a named instance of aClosure
object.Or
So, my hope is that one of two things will work.
Attempt #2: Filter Instructions Array with Named Anonymous Functions
Or
Potential Complications
The
Closure
instances$this->checkNameLength
and$checkNameLength
are objects, not normal "methods / functions". But, if PHP does not complain, I will not split hairs. I suppose one could try defining a function inside of an anonymous function.Then, your filter instruction array would look like this.
Or, probably this ...
Conclusion
There is a better way to create a generic string length checker than using PHP's
filter_var_array()
and anonymous functions. Using'filter' => FILTER_VALIDATE_REGEXP
can make it easy to check the length of a single string, but it is not a substitute for adhering to DRY principles. You will end up having many statements in your filter instructions array like this, just to deal with string lengths in an array of input.You can do this if you are trying to make a pure
filter_input_array()
Validator
class, or routine. But, you will have to make multiple passes offilter_var_array()
, with multiple filter instruction arrays (because the length of a string is not the only thing that makes it valid, or invalid).For
website
andemail
, you will want to take advantage of'filter' => FILTER_VALIDATE_URL
and'filter' => FILTER_VALIDATE_EMAIL.
At other times, you are going to want to take advantage of'filter' => FILTER_VALIDATE_IP
. Also, especially in the case ofemail
, you might want to restrict valid email addresses to a subset of the official RFC with a regular expression. To keep things pure, you would not put that regular expression in the$filterLengthInstructions
.The fundamental reasons for wanting to change the
min_length
andmax_length
being able to write the business logic once and use it everywhere.At minimum, my advice is to create an abstract
Validator
super class and define one (1) method that test string lengths.Now, you can divide this method up, or delegate this task to an injected
StringTester
object's method.Whatever, but by defining concrete child classes of
Validator
all you have to do is define your test parameters in an array, create a loop, and call:or
... within the loop. Be sure to account for the $errorMessage.