namespace Application\Filter;
class Result
{
public $item; // (mixed) filtered data | (bool) result of validation
public $messages = array(); // [(string) message, (string) message ]
public function __construct($item, $messages)
{
$this->item = $item;
if (is_array($messages)) {
$this->messages = $messages;
} else {
$this->messages = [$messages];
}
}
4. 我们还定义了一个方法,允许我们将这个 Result 实例与另一个合并。这一点很重要,因为在某些时候,我们将通过一连串的过滤器来处理同一个值。在这种情况下,我们希望新过滤的值覆盖现有的值,但我们希望消息被合并。
public function mergeResults(Result $result)
{
$this->item = $result->item;
$this->mergeMessages($result);
}
public function mergeMessages(Result $result)
{
if (isset($result->messages) && is_array($result->messages)) {
$this->messages = array_merge($this->messages, $result->messages);
}
}
public function getCallbacks()
{
return $this->callbacks;
}
public function getOneCallback($key)
{
return $this->callbacks[$key] ?? NULL;
}
public function setCallbacks(array $callbacks)
{
foreach ($callbacks as $key => $item) {
$this->setOneCallback($key, $item);
}
}
public function setOneCallback($key, $item)
{
if ($item instanceof CallbackInterface) {
$this->callbacks[$key] = $item;
} else {
throw new UnexpectedValueException(self::BAD_CALLBACK);
}
}
public function removeOneCallback($key)
{
if (isset($this->callbacks[$key]))
unset($this->callbacks[$key]);
}
public function getResults()
{
return $this->results;
}
public function getItemsAsArray()
{
$return = array();
if ($this->results) {
foreach ($this->results as $key => $item)
$return[$key] = $item->item;
}
return $return;
}
public function getMessages()
{
if ($this->results) {
foreach ($this->results as $key => $item)
if ($item->messages) yield from $item->messages;
} else {
return array();
}
}
public function getMessageString($width = 80, $format = NULL)
{
if (!$format)
$format = self::DEFAULT_MESSAGE_FORMAT . $this->separator;
$output = '';
if ($this->results) {
foreach ($this->results as $key => $value) {
if ($value->messages) {
foreach ($value->messages as $message) {
$output .= sprintf(
$format, $key, trim($message));
}
}
}
}
return $output;
}
15. 最后,我们定义了一组mixed的getter和setter。
public function setMissingMessage($message)
{
$this->missingMessage = $message;
}
public function setSeparator($separator)
{
$this->separator = $separator;
}
public function getSeparator()
{
return $this->separator;
}
public function getAssignments()
{
return $this->assignments;
}
public function setAssignments(array $assignments)
{
$this->assignments = $assignments;
}
// closing bracket for class AbstractFilter
}
<?php
use Application\Filter\Messages;
Messages::setMessages(
[
'length_too_short' => 'Length must be at least %d',
'length_too_long' => 'Length must be no more than %d',
'required' => 'Please be sure to enter a value',
'alnum' => 'Only letters and numbers allowed',
'float' => 'Only numbers or decimal point',
'email' => 'Invalid email address',
'in_array' => 'Not found in the list',
'trim' => 'Item was trimmed',
'strip_tags' => 'Tags were removed from this item',
'filter_float' => 'Converted to a decimal number',
'phone' => 'Phone number is [+n] nnn-nnn-nnnn',
'test' => 'TEST',
'filter_length' => 'Reduced to specified length',
]
);
'callback_key' => new class () implements CallbackInterface
{
public function __invoke($item, $params) : Result
{
$changed = array();
$filtered = /* perform filtering operation on $item */
if ($filtered !== $item) $changed = Messages::$messages['callback_key'];
return new Result($filtered, $changed);
}
}
回调本身必须实现该接口并返回一个 Result 实例。我们可以利用 PHP 7 的匿名类功能,让我们的回调返回一个实现 CallbackInterface的匿名类。下面是一个过滤回调数组的样子。
use Application\Filter\ { Result, Messages, CallbackInterface };
$config = [ 'filters' => [
'trim' => new class () implements CallbackInterface
{
public function __invoke($item, $params) : Result
{
$changed = array();
$filtered = trim($item);
if ($filtered !== $item)
$changed = Messages::$messages['trim'];
return new Result($filtered, $changed);
}
},
'strip_tags' => new class ()
implements CallbackInterface
{
public function __invoke($item, $params) : Result
{
$changed = array();
$filtered = strip_tags($item);
if ($filtered !== $item)
$changed = Messages::$messages['strip_tags'];
return new Result($filtered, $changed);
}
},
// etc.
]
];