- A simple filtering library for PHP
- reserved «Object» name
- Want some help triaging simple PRs?
- Email validation doesn’t work on an empty string
- Can I achieve optional keys by using a pool of maps?
- What’s the best way to allow strings to be null?
- Renamed reserved class names to Type
- Possible bug? Invalid outcome of validation
- Класс FilterIterator
- Обзор классов
- User Contributed Notes 3 notes
A simple filtering library for PHP
Simple filters can be specified using a comma-separated-value list. So a filter specifying a string with minimum length of 5 could be represented as:
$filter = Filter::factory('string,min:5');
$filter = new Filters\String(array('min' => 5));
If you pass a filter to Filter::factory() , it will be returned unmodified. So you can write functions like:
function foo($bar, $filter) < // do something with $bar and set in $baz return Filter::factory($filter)->filter($baz); >
Complex chaining can also be supported. So if you wanted to check if an array with a minimum size of 4, with numeric keys and containing strings of minimum length 5, that could be built like so:
$filter = Filter::array('min:4', 'int', 'string,min:5');
If we wanted to validate an associative array, we would use a «map» filter:
$array = array( 'foo' => 2, 'bar' => 'test', ); $filter = Filter::map(array( 'foo' => 'int', 'bar' => 'string,min:4', )); var_dump($filter->validate($array)); // true
Filterus also ships with a procedural interface for calling filters.
\Filterus\validate($var, $filter);
Any filter is supported (both are basically simple wrappers):
function \Filterus\filter($var, $filter) < return \Filterus\Filter::factory($filter)->filter($var); >
Both are just convenience functions.
If you have found a security issue, please contact the author directly at [email protected] .
Comments
reserved «Object» name
PHP Fatal error: Cannot use 'Object' as class name as it is reserved
I am planning to refactor it and submit a pull request, but before I make any changes do you have any ideas on what class name should it be changed to?
Want some help triaging simple PRs?
Hi @ircmaxell There’s some PRs that have languished for a while in this repo. If you are willing to make me a committer, I’d be happy to go through the trivial docs ones, check their validity, and merge them down if they are OK.
Email validation doesn’t work on an empty string
There isn’t an implementation for validate for emails, so although an empty string will be correctly filtered to null , it will validate as true , which is not desirable. Repro code:
$filter = \Filterus\Filter::factory('email'); $result = $filter->filter(''); var_dump($result); // Returns NULL, correct $ok = $filter->validate(''); echo $ok ? 'Passed' : 'Failed'; // Incorrectly returns Passed
$filter = \Filterus\Filter::chain('email', 'string,min:1'); $result = $filter->filter(''); var_dump($result); // Returns NULL, correct $ok = $filter->validate(''); echo $ok ? 'Passed' : 'Failed'; // Correctly returns Failed
Can I achieve optional keys by using a pool of maps?
[ 'name' => 'string', 'from_address' => 'email', 'from_name' => 'string', 'subject' => 'string', 'body_plain' => 'string', 'to_address' => 'email', ] // Differs just in this key [ 'name' => 'string', 'from_address' => 'email', 'from_name' => 'string', 'subject' => 'string', 'body_plain' => 'string', 'to_address_field' => 'string', ] // Differs just in this key
My strategy is that, since there is no way to specify keys as optional, I could run a map for each one, and accept if either returns true . On that basis, I thought I could use a pool as well.
use Filterus\Filter as F; $baseValidator = [ 'name' => 'string', 'from_address' => 'email', 'from_name' => 'string', 'subject' => 'string', 'body_plain' => 'string', ]; // Use a pool of maps, should work? $eitherValidators = F::pool([ F::map($baseValidator + ['to_address_field' => 'string', ]), F::map($baseValidator + ['to_address' => 'email', ]), ]);
explode() expects parameter 2 to be string, array given . /vendor/ircmaxell/filterus/lib/Filterus/Filter.php:98 . /vendor/ircmaxell/filterus/lib/Filterus/Filter.php:52 . /vendor/ircmaxell/filterus/lib/Filterus/Filters/Map.php:21 . /vendor/ircmaxell/filterus/lib/Filterus/Filters/Map.php:45
What’s the best way to allow strings to be null?
Hi, thanks for providing this library. I have the following solution to allow «string or null», and will provide it below. However, if there is a better way to do this, please let me know. First a null validator:
/** * Class to allow nulls */ class AllowNull extends \Filterus\Filter < public function filter($var) < return $var; >public function validate($var) < return is_null($var); >>
use Filterus\Filter as F; F::registerFilter('null', AllowNull::class);
$validator = F::pool('string', 'null');
Renamed reserved class names to Type
In PHP7 some classnames are reserved and requires a change. This is discussed in https://github.com/Respect/Validation/issues/362 Their suggestion is to use the prefix Type on the classes.
Possible bug? Invalid outcome of validation
array(19) < 'sku' =>string(2) "SW" '_type' => string(6) "simple" '_attribute_set' => string(18) "xxxxx" '_product_websites' => string(10) "xxxxx" 'name' => NULL 'description' => string(8) "TESTTEST" 'short_description' => string(8) "TESTTEST" 'price' => int(0) 'url_key' => NULL 'cost' => NULL 'status' => int(1) 'visibility' => int(4) 'manufacturer' => string(9) "xxxx" 'tax_class_id' => int(2) 'base_price_unit' => string(3) "PCS" 'base_price_base_unit' => string(3) "PCS" 'country_of_manufacture' => string(11) "xxxxx" 'qty' => int(0) 'is_in_stock' => int(1) >
$filter = Filter::map(array( 'name' => 'string,min:1', //anything above 1 should do 'sku' => 'string,min:3', //prefix is hardcoded, so anything above strlen 2 will do '_attribute_set' => 'string,min:1', //TODO Should be hardcoded to whatever is in $conf '_product_websites' => 'string,min:1', '_type' => 'string,min:1', //TODO Either configurable or simple ));
I would suspect that $filter->validate($product) would throw back false since «name» is clearly a) not a string and b) is not having a stringlengh of atleast 1. But I do get true as a result, which is false.
Класс FilterIterator
Этот абстрактный итератор фильтрует нежелательные значения. Этот класс следует расширить для реализации пользовательских фильтров итератора. Метод FilterIterator::accept() должен быть реализован в подклассе.
Обзор классов
User Contributed Notes 3 notes
The code below is a simple example of usage . Note that the method which does the actual job is accept.
class UserFilter extends FilterIterator
private $userFilter ;
public function __construct ( Iterator $iterator , $filter )
parent :: __construct ( $iterator );
$this -> userFilter = $filter ;
>
public function accept ()
$user = $this -> getInnerIterator ()-> current ();
if( strcasecmp ( $user [ ‘name’ ], $this -> userFilter ) == 0 ) return false ;
>
return true ;
>
>
$array = array(
array( ‘name’ => ‘Jonathan’ , ‘id’ => ‘5’ ),
array( ‘name’ => ‘Abdul’ , ‘id’ => ’22’ )
);
$object = new ArrayObject ( $array );
// Note it is case insensitive check in our example due the usage of strcasecmp function
$iterator = new UserFilter ( $object -> getIterator (), ‘abdul’ );
foreach ( $iterator as $result ) echo $result [ ‘name’ ];
>
A little test about the function call order:
class TestIterator extends IteratorIterator
public function key ()
echo __FUNCTION__ , PHP_EOL ;
return parent :: key ();
>
public function next ()
echo __FUNCTION__ , PHP_EOL ;
return parent :: next ();
>
public function rewind ()
echo __FUNCTION__ , PHP_EOL ;
return parent :: rewind ();
>
public function valid ()
echo __FUNCTION__ , PHP_EOL ;
return parent :: valid ();
>
>
class TestFilterIterator extends FilterIterator
public function accept ()
echo __FUNCTION__ , PHP_EOL ;
return true ;
>
>
$iterator = new ArrayIterator (array( ‘a’ , ‘b’ , ‘c’ ));
foreach (new TestFilterIterator (new TestIterator ( $iterator )) as $k => $v ) echo PHP_EOL ;
>
?>
This will output the following: