Filter¶
概览¶
对用户输入进行清理是软件开发中的关键部分。信任或忽视对用户输入的清理可能导致对应用程序内容的未经授权访问,主要是用户数据,甚至托管应用程序的服务器。
可以通过使用Phalcon\Filter\Filter和Phalcon\Filter\FilterFactory类来实现内容清理。
FilterFactory¶
该组件创建一个带有预定义过滤器的新定位器。每个过滤器都延迟加载以获得最佳性能。要实例化工厂并检索预设清理器的Phalcon\Filter\Filter需要调用newInstance()
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
现在你可以在任何需要的地方使用定位器,并根据应用程序的需求清理内容。
Filter¶
The Phalcon\Filter\Filter组件实现了一个定位器服务,可以作为独立组件使用,而无需初始化内置过滤器。
<?php
use MyApp\Sanitizers\HelloSanitizer;
use Phalcon\Filter\Filter;
$services = [
'hello' => HelloSanitizer::class,
];
$locator = new Filter($services);
$text = $locator->hello('World');
注意
The Phalcon\Di\FactoryDefault容器已经加载了一个带有预定义清理器的Phalcon\Filter\Filter对象。该组件可以通过filter
名称访问。
Built-in¶
注意
在适当的情况下,清理器会将值转换为期望的类型。例如,absint
清理器将从输入中删除所有非数字字符,将输入转换为整数,并返回其绝对值。
注意
要使用预定义过滤器,你需要获取一个Phalcon\Filter\Filter
实例,使用Phalcon\Filter\FilterFactory
如上所示。
以下是由该组件提供的内置过滤器:
absint
¶
删除所有非数字字符,将值转换为整数,并返回其绝对值。内部使用filter_var处理整数部分,intval用于转换, 并且使用absint. alnum
¶
删除所有不是数字或字母的字符。它使用preg_replace,也可以接受字符串数组作为参数。 alpha
¶
删除所有不是字母的字符。它使用preg_replace,也可以接受字符串数组作为参数。 bool
¶
将值转换为布尔值。 如果值是:true
则也返回
true
on
yes
y
1
如果值是:false
则也返回
false
off
no
n
0
email
¶
删除所有字符,除了字母、数字和!#$%&*+-/=?^_`{\|}~@.[]
。内部使用filter_var的文件FILTER_FLAG_EMAIL_UNICODE
. float
¶
删除所有字符,除了数字、点、加号和减号,并将值转换为double
。内部使用filter_var和(double)
. int
¶
删除所有字符,除了数字、加号和减号,并将值转换为整数。内部使用filter_var和(int)
. lower
¶
将所有字符转换为小写。如果加载了mbstring扩展,则使用mb_convert_case进行转换。否则,它使用strtolowerPHP 函数,带有utf8_decode. lowerFirst
¶
将输入的第一个字符转换为小写。内部使用lcfirst. regex
¶
使用正则表达式替换输入的内容pattern
和replace
参数。内部使用preg_replace. remove
¶
替换输入内容,将replace
参数替换为空字符串,从而有效地将其移除。内部使用str_replace. replace
¶
根据from
和to
传递的参数执行替换操作。内部使用str_replace. special
¶
转义所有 HTML 字符以及'"<>&
和 ASCII 值小于 32 的字符。内部使用filter_var. specialFull
¶
将输入的所有特殊字符转换为 HTML 实体(包括双引号和单引号)。内部使用filter_var. string
¶
编码 HTML 实体。内部使用 [htmlspecialchars][htmlspecialchars]。 stringlegacy
¶
此过滤器仅适用于 PHP 版本低于 8.1 的情况。它是向后兼容性提供。内部使用filter_var. striptags
¶
从输入中删除所有 HTML 和 PHP 标签。内部使用strip_tags. trim
¶
从输入中删除所有前导和尾随空白。内部使用trim. upper
¶
将所有字符转换为大写。如果加载了mbstring扩展,则使用mb_convert_case进行转换。否则,它使用strtoupperPHP 函数,带有utf8_decode. upperFirst
¶
将输入的第一个字符转换为大写。内部使用ucfirst. upperWords
¶
将输入中每个单词的第一个字符转换为大写。内部使用ucwords. url
¶
清理 URL。内部使用filter_var. 常量¶
可用常量可用于定义所需的清理类型:
<?php
const FILTER_ABSINT = 'absint';
const FILTER_ALNUM = 'alnum';
const FILTER_ALPHA = 'alpha';
const FILTER_BOOL = 'bool';
const FILTER_EMAIL = 'email';
const FILTER_FLOAT = 'float';
const FILTER_INT = 'int';
const FILTER_LOWER = 'lower';
const FILTER_LOWERFIRST = 'lowerfirst';
const FILTER_REGEX = 'regex';
const FILTER_REMOVE = 'remove';
const FILTER_REPLACE = 'replace';
const FILTER_SPECIAL = 'special';
const FILTER_SPECIALFULL = 'specialfull';
const FILTER_STRING = 'string';
const FILTER_STRING_LEGACY = 'stringlegacy';
const FILTER_STRIPTAGS = 'striptags';
const FILTER_TRIM = 'trim';
const FILTER_UPPER = 'upper';
const FILTER_UPPERFIRST = 'upperfirst';
const FILTER_UPPERWORDS = 'upperwords';
const FILTER_URL = 'url';
方法¶
The Phalcon\Filter\Filter作为服务定位器工作并实现了__call()
方法。因此,你可以直接在定位器上调用任何过滤器作为方法。方法名称与常量定义的名称相同。要使用内置过滤器,你需要获取一个Phalcon\Filter\Filter
实例,使用Phalcon\Filter\FilterFactory
.
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$filter = $factory->newInstance();
$source = -123;
echo $filter->absint($source); // 123
<?php
$filter->absint(mixed $input): int
$filter->alnum(mixed $input): string
$filter->alpha(mixed $input): string
$filter->bool(mixed $input): bool
$filter->email(string $input): string
$filter->float(mixed $input): float
$filter->int(string $input): int
$filter->lower(string $input): string
$filter->lowerfirst(string $input): string
$filter->regex(mixed $input, mixed $pattern, mixed $replace): mixed
$filter->remove(mixed $input, mixed $replace): mixed
$filter->replace(mixed $input, mixed $source, mixed $target): mixed
$filter->special(string $input): string
$filter->specialfull(string $input): string
$filter->string(string $input): string
$filter->stringlegacy(mixed $input): string
$filter->striptags(string $input): string
$filter->trim(string $input): string
$filter->upper(string $input): string
$filter->upperfirst(string $input): string
$filter->upperwords(string $input): string|null
$filter->url(string $input): string|null
```
## Sanitizing Data
Sanitizing is the process that removes specific characters from a value, that are not required or desired by the user or application. By sanitizing input, we ensure that application integrity will be intact.
```php
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
// 'someone@example.com'
$locator->sanitize('some(one)@exa\mple.com', 'email');
// 'hello'
$locator->sanitize('hello<<', 'string');
// '100019'
$locator->sanitize('!100a019', 'int');
// '100019.01'
$locator->sanitize('!100a019.01a', 'float');
控制器¶
你可以从控制器中访问Phalcon\Filter\Filter对象时(通过请求对象访问输入数据)。第一个参数是要获取的变量名称;第二个参数是要应用的清理器。第二个参数还可以是一个包含任意数量清理器的数组。GET
或POST
input data (through the request object). The first parameter is the name of the variable to be obtained; the second is the sanitizer to be applied on it. The second parameter can also be an array with any number of sanitizers that you want to apply.
<?php
use Phalcon\Filter\Filter;
use Phalcon\Http\Request;
use Phalcon\Mvc\Controller;
/**
* Class ProductsController
*
* @property Request $request
*/
class ProductsController extends Controller
{
public function saveAction()
{
if (true === $this->request->isPost()) {
$price = $this->request->getPost('price', 'double');
$email = $this->request->getPost(
'customerEmail',
Filter::FILTER_EMAIL
);
}
}
}
动作参数¶
如果您在应用程序中使用了Phalcon\Di\FactoryDefault作为你的依赖注入容器,该Phalcon\Filter\Filter已经为你注册了默认的过滤器。要访问它,我们可以使用名称filter
。如果你不使用Phalcon\Di\FactoryDefault容器,你需要在其中设置服务,以便可以在控制器中访问。
我们可以通过以下方式清理传递到控制器动作中的值:
<?php
use Phalcon\Filter\Filter;
use Phalcon\Mvc\Controller;
/**
* Class ProductsController
*
* @property Filter $filter
*/
class ProductsController extends Controller
{
public function showAction($productId)
{
// $productId = $this->filter->sanitize($productId, Filter::FILTER_ABSINT);
$productId = $this->filter->sanitize($productId, 'absint');
}
}
过滤数据¶
The Phalcon\Filter\Filter根据使用的过滤器,既可以过滤也可以清理数据。例如,trim
过滤器将删除所有前导和尾随空格,保留其余输入不变。每种过滤器的描述(参见内置过滤器)可以帮助你根据需求理解和使用这些过滤器。
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
// 'Hello'
$locator->sanitize('<h1>Hello</h1>', 'striptags');
// 'Hello'
$locator->sanitize(' Hello ', 'trim');
添加过滤器¶
你可以向Phalcon\Filter\Filter添加自定义过滤器。初始化定位器时,过滤器可以是一个匿名函数:
<?php
use Phalcon\Filter\Filter;
$services = [
'md5' => function ($input) {
return md5($input);
},
];
$locator = new Filter($services);
$sanitized = $locator->sanitize($value, 'md5');
如果你已经有一个实例化的过滤器定位器对象(例如,如果你使用了Phalcon\Filter\FilterFactory和newInstance()
),那么你可以简单地添加自定义过滤器:
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
$locator->set(
'md5',
function ($input) {
return md5($input);
}
);
$sanitized = $locator->sanitize($value, 'md5');
或者,如果你更喜欢,可以在类中实现过滤器:
<?php
use Phalcon\Filter\FilterFactory;
class IPv4
{
public function __invoke($value)
{
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}
}
$factory = new FilterFactory();
$locator = $factory->newInstance();
$locator->set(
'ipv4',
new Ipv4()
);
// Sanitize with the 'ipv4' filter
$filteredIp = $locator->sanitize('127.0.0.1', 'ipv4');
组合使用过滤器¶
有时单个过滤器不足以满足你的数据需求。例如,一个非常常见的用法是striptags
和trim
文本输入的过滤器。组件Phalcon\Filter\Filter提供了接受过滤器名称数组的功能,可以将其应用于输入值。以下示例演示了这一点:
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
// Returns 'Hello'
$locator->sanitize(
' <h1> Hello </h1> ',
[
'striptags',
'trim',
]
);
注意,此功能同样适用于Phalcon\Http\Request对象,当你调用方法从GET
和POST
中检索数据时,例如getQuery()
和getPost()
.
<?php
use Phalcon\Filter\Filter;
use Phalcon\Http\Request;
use Phalcon\Mvc\Controller;
/**
* Class ProductsController
*
* @property Request $request
*/
class ProductsController extends Controller
{
public function saveAction()
{
if (true === $this->request->isPost()) {
$message = $this->request->getPost(
' <h1> Hello </h1> ',
[
'striptags',
'trim',
]
);
}
}
}
自定义过滤器¶
自定义过滤器可以实现为匿名函数。然而,如果你更喜欢为每个过滤器使用一个类,只需要通过实现__invoke方法,并传递相关参数使其可调用即可。
<?php
use Phalcon\Filter\FilterFactory;
$factory = new FilterFactory();
$locator = $factory->newInstance();
$locator->set(
'md5',
function ($input) {
return md5($input);
}
);
$sanitized = $locator->sanitize($value, 'md5');
或者,如果你更喜欢,可以在类中实现过滤器:
<?php
use Phalcon\Filter\FilterFactory;
class IPv4
{
public function __invoke($value)
{
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}
}
$factory = new FilterFactory();
$locator = $factory->newInstance();
$locator->set(
'ipv4',
function () {
return new Ipv4();
}
);
// Sanitize with the 'ipv4' filter
$filteredIp = $locator->sanitize('127.0.0.1', 'ipv4');