Verification: a143cc29221c9be0

Php array filter array of objects

3.7.3.1. Creating A Subject Filter

First, create a SubjectFilter via the FilterFactory:

$filter_factory = new FilterFactory();

$filter = $filter_factory->newSubjectFilter();

Next, add rule specifications to validate and/or sanitize each subject field:

// the username must be alphanumeric
// but not *only* numeric,
// at least 6 characters long,
// and cast it to a string
$filter->validate('username')->is('alnum');
$filter->validate('username')->isNot('int');
$filter->validate('username')->is('strlenMin', 6);
$filter->sanitize('username')->to('string');

// the password must be at least 6 characters long, and must match a
// confirmation field
$filter->validate('password')->is('strlenMin', 6);
$filter->validate('password_confirm')->is('equalToField', 'password');

We can call one of the following methods after validate():

  • is(...) to specify that the value must match the rule
  • isNot(...) to specify that the value must not match the rule
  • isBlank() to specify that the value must be blank (note that using other rules with isBlank() may not make sense)
  • isBlankOr(...) to specify that the value may be blank, or that it must match the rule
  • isBlankOrNot(...) to specify that the value may be blank, or that it must not match the rule
  • isNotBlank() to specifiy that the value must not be blank (note that this makes sense only if you don't care about other validations)

We can call one of the following methods after sanitize():

  • to(...) to specify the value should be changed according to the rule
  • toBlankOr(...) to specify that a blank field should be changed to null, and that non-blank fields should be changed according to the rule
  • useBlankValue(...) to specify what value blank fields should be changed to (default null)

For more about blanks, see the section on Blank Fields.

3.7.3.2. Applying The Subject Filter

We can then apply the filter specifications to the subject. A true result means all the rules passed, while false means one or more failed.

// the data to be filtered; could also be an object
$subject = array(
    'username' => 'bolivar',
    'password' => 'p@55w0rd',
    'password_confirm' => 'p@sword', // not the same!
);

// filter the object and see if there were failures
$success = $filter->apply($subject);
if (! $success) {
    // get the failures
    $failures = $filter->getFailures();
    var_dump($failures->getMessages());
}

3.7.3.3. Filter Failures

When we get the failures via getFailures(), we can examine in detail which fields failed, and what the failure messages were. The getFailures() method returns a FailureCollection (essentially an ArrayObject keyed on the field names). Each field in the FailureCollection has an array of Failure objects, each with these methods:

  • Failure::getField() -- the field that failed
  • Failure::getMessage() -- the failure message
  • Failure::getArgs() -- arguments passed to the rule specification

These can be combined in various ways to generate output regarding the filter failures.

3.7.3.4. Failure Modes

Normally, the filter will stop filtering any field that fails one of its rules, but will continue applying rules to the rest of the fields. Also, the filter specification will provide a default message when a rule fails.

We can modify that behavior by specifying a failure mode, with an optional custom message:

  • $filter->...->asSoftRule('custom message') will cause the filter to keep applying rules to the field, even when a field rule fails.

  • $filter->...->asHardRule('custom message') is the default behavior. If the rule fails, the filter will not apply any more rules to that field, but it will keep filtering other fields.

  • $filter->...->asStopRule('custom message') will cause the filter to stop applying rules to all fields and return immediately if the rule fails. That is, the filter will not apply any more rules to any more fields.

In each case, the custom message will be used instead of the default one for the specified rule. If we want to just set a custom message without changing the failure mode, we can use $filter->...->setMessage('custom message').

3.7.3.5. Field-Specific Failure Messages

If a field fails multiple rules, there will be multiple failure messages (one for each failed rule). To specify a single failure message for a field, regardless of which rule(s) it fails, call $filter->useFieldMessage():

$filter->validate('field')->isNot('blank')->asSoftRule();
$filter->validate('field')->is('alnum')->asSoftRule();
$filter->validate('field')->is('strlenMin', 6)->asSoftRule();
$filter->validate('field')->is('strlenMax', 12)->asSoftRule();

$filter->useFieldMessage('field', 'Please use 6-12 alphanumeric characters.');

3.7.3.6. Blank Fields

This library incorporates the concept of "blank" fields, as distinct from isset() and empty(), to allow for input elements that are missing or have not been filled in. A field is blank if it is:

  • not set in the subject being filtered,
  • set to null,
  • an empty string (''), or
  • a string composed of only whitespace characters.

Integers, floats, booleans, resources, arrays, and objects are never "blank" even if they evaluate to zero or are empty:

$not_blank = array(
    0,                // integer
    0.00,             // float
    false,            // boolean false
    array(),          // empty array
    new StdClass,     // an object
);

Generally, a blank field will fail to validate. To allow a validate rule to pass even if the field is blank, call isBlankOr() or isBlankOrNot() on its rule specification:

// either an alphanumeric value *or* a blank value will validate
$filter->validate('field')->isBlankOr('alnum');

Likewise, a blank field may fail to sanitize properly. To allow for a blank field with a sanitize rule, call toBlankOr() on its rule specification:

// both an alphanumeric field *and* a blank field will pass
$filter->sanitize('field')->toBlankOr('alnum');

This will cause blank values to be sanitized to null, and non-blank values to be sanitized using the alnum rule.

Finally, if we want blank values to be sanitized to something other than null, call useBlankValue() to specify the value to use when blank:

// both an alphanumeric field *and* a blank field will pass
$filter->sanitize('field')->toBlankOr('alnum')->useBlankValue('');

That will cause blank values to be sanitized to an empty string. Additionally, please note that useBlankValue() implies toBlankOr(), so the following has the same effect as the above:

// both an alphanumeric field *and* a blank field will pass
$filter->sanitize('field')->to('alnum')->useBlankValue('');

3.7.3.7. Extending And Initializing A Subject Filter

Sometimes it may be useful to extend the Filter class for a specific purpose, one that can initialize itself. This can be useful when filtering a specific kind of object or dataset.

To do so, override the the init() method on the extended Filter class; the above examples remain instructive, but use $this instead of $filter since you are working from inside the filter object:

namespace Vendor\Package;

use Aura\Filter\SubjectFilter;

class EntityFilter extends SubjectFilter
{
    protected function init()
    {
        $this->validate('field')->isNot('blank')->asSoftRule();
        $this->validate('field')->is('alnum')->asSoftRule();
        $this->validate('field')->is('strlenMin', 6)->asSoftRule();
        $this->validate('field')->is('strlenMax', 12)->asSoftRule();

        $this->useFieldMessage('field', 'Please use 6-12 alphanumeric characters.');
    }
}

You can then create a new instance of your extended filter class through the FilterFactory:

$entity_filter = $filter_factory->newSubjectFilter('Vendor\Package\EntityFilter');
$success = $entity_filter->apply($entity);

Инициализация

Чтобы использовать SQL ODM, создайте соединение SQL DB. Например:

$mapper = new \DB\SQL\Mapper(\DB\SQL $db, string $table [, array|string $fields = NULL [, int $ttl = 60 ]] )
 

Аргумент $fields позволяет указать только те поля , которые нужно отобразить. $fields представляет собой либо массив, либо список (в соответствии с функцией F3 split) имен столбцов, которые необходимо включить в mapper. По умолчанию для всех столбцов.

Когда $ttl! = 0, запускается проверка кэша для предыдущей схемы, и если срок ее действия истек или не найден, текущий результат сохраняется в бэкэнде кэша при условии, что система CACHE включена.

Eсли вы хотите создать класс модели, вы можете завершить его:

$f3->set('DB',new DB\SQL('sqlite:db/database.sqlite'));
 
class User extends \DB\SQL\Mapper {
	public function __construct() {
		parent::__construct( \Base::instance()->get('DB'), 'users' );
	}
}
 
$user = new User();
$user->load('id = 1');
// etc.

Синтаксис

$ filter

Аргумент $filter для SQL принимает следующую структуру:

  • строковое значение для простых строк where

string $whereClause
 
  • значение массива для параметризованных запросов

array ( string $whereClause [, string $bindValue1 [, string $bindValue2 [, ... ]]] )
 

Параметризованные запросы

Рекомендуется использовать параметризованные запросы для всех условий where, которые вводит пользователь.

Пример с параметром в виде вопросительного знака:

$mapper->load(array('username = ? and password = ? and deleted = 0','John','acbd18db4cc2f85cedef654fccc4a4d8'));

И с именованными параметрами:

$mapper->load(array(
	'username = :user and password = :pass and deleted = 0',
	':user'=>'John',':pass'=>'acbd18db4cc2f85cedef654fccc4a4d8'
));

Из-за ограничения PDO нельзя использовать именованный параметр более одного раза в запросе. Вам нужно создать 2 параметра :user1 и :user2 и передать им одинаковое значение.

В одном операторе SQL нельзя использовать и именованные параметры, и вопросительные знаки как параметры; выберите тот или иной вид параметра, но не смешивайте.

Тип данных, определяемый пользователем

Обычно тип данных определяется автоматически, но чтобы значение привязки было определенным типом PDO, используйте следующий синтаксис:

array(
	'prize > :prize and active = 1',
	':prize' => array(123, \PDO::PARAM_INT)
)
 

Когда вы используете оператор LIKE в условии where, обратите внимание, что знак % не входит в критерии where, но входит в параметр привязки следующим образом:

$user->find(array('email LIKE ?','%gmail%')); // returns all users with an email address at GMAIL

Полнотекстовый поиск

Если вы хотите выполнить полнотекстовый поиск ключевых слов по одному или нескольким полям в MySQL, вы можете использовать функцию MATCH AGAINST, которая выглядит так:

$text = 'some text';
$mapper->find(["MATCH (name,code) AGAINST (:search IN BOOLEAN MODE)", ':search' => $text ]);

Если вы также хотите отсортировать результаты по актуальности, вам нужно добавить это выражение соответствия как специальное поле, например:

$mapper->relevance = "MATCH (name,code) AGAINST (:search1 IN BOOLEAN MODE)";
$mapper->find(["MATCH (name,code) AGAINST (:search2 IN BOOLEAN MODE)", ':search1' => $text, ':search2' => $text ], ['order'=>'relevance desc']);

И если вы хотите сопоставить сразу несколько ключевых слов, вам нужно обернуть и экранировать ключевые слова

$mapper->find(["(MATCH(fieldA,fieldB) AGAINST('(".implode('") ("',$keywords).")' IN BOOLEAN MODE )"]);

или вставьте несколько заполнителей:

$mapper->find(["(MATCH(fieldA,fieldB) AGAINST('(?) (?) (?)' IN BOOLEAN MODE )", $a, $b, $c]);

$ option

$option для SQL принимает следующую структуру:

array(
	'order' => string $orderClause,
	'group' => string $groupClause,
	'limit' => integer $limit,
	'offset' => integer $offset
)
 

то есть:

array(
	'order' => 'score DESC, team_name ASC',
	'group' => 'score, player',
	'limit' => 20,
	'offset' => 0
)
 

Инициализация

Чтобы использовать Jig ODM, создайте соединение Jig DB. Например:

$mapper = new \DB\Jig\Mapper(\DB\Jig $db, string $file);

Если вы хотите создать класс модели, то:

$f3->set('DB',new DB\Jig('data/'));
 
class User extends \DB\Jig\Mapper {
    public function __construct() {
        parent::__construct( \Base::instance()->get('DB'), 'users.json' );
    }
}
 
$user = new User();
$user->load(array('@_id = ?','515c570f28de6'));
// etc.

Первичный ключ документов Jig назван _id.

Синтаксис

$ filter

$filter в Jig имеет следующую структуру:

// array value for parameterized queries
array( string $expr [, string $bindValue1 [, string $bindValue2 [, ...]]] )

Часть $expr должна содержать допустимый кода, где все поля mapper'а начинается с символа @. Вы можете привязать к ним значения с помощью позиционных или именованных токенов. Вот пример:

// positional tokens
array('@username = ? and @password = ?','John','acbd18db4cc2f85cedef654fccc4a4d8')
// named tokens
array('@username = :user and @password = :pw',':user'=>'John',':pw'=>'acbd18db4cc2f85cedef654fccc4a4d8')

Важно: Jig - это средство сопоставления документов без схемы, поэтому поля документа могут отличаться от одной записи к другой. Чтобы создать допустимую строку $expr, не забудьте добавить дополнительные проверки существования полей, чтобы предотвратить появление странных ошибок неопределенных переменных. Для этого используется isset:

array(
    '(isset(@username) && @username == ?) && (isset(@password) && @password = ?)',
    'John','acbd18db4cc2f85cedef654fccc4a4d8'
    )

Вы можете использовать все распространенные операторы сравнения в своем выражении, одиночное работает =.

Лучший способ поиска в Jig - использовать следующие условия preg_match:

$userList = $user->find(array('(isset(@email) && preg_match(?,@email))','/gmail/'));
// returns all users with an email address that contains GMAIL
 
// ends with gmail.com => /gmail\.com$/
// starts with john  => /^john/

Эквивалент оператора IN в SQL выглядит так:

$user->find(array('in_array('_id',array(1,2,3))'));

Если в вашем документе используется поле массива, то есть теги, вы можете найти все сообщения по тегу, просто меняя параметры in_array:

$post->find(array('isset(@tags) && in_array("fat-free",@tags)'));

$ option

Аргумент Jig $option принимает имеет структуру:

array(
	'order' => string $orderClause,
	'limit' => integer $limit,
	'offset' => integer $offset
)
 

то есть:

array(
	'order' => 'score SORT_DESC, team_name SORT_ASC',
	'limit' => 20,
	'offset' => 0
)