跳至主要内容
版本:5.1

输入

Joomla 输入 - 简介

Joomla 输入功能提供了一个易于使用的界面,用于获取和清理多个PHP 超全局变量的数据。

  • HTTP GET 和 POST 参数
  • 路由参数(“option”、“view”、“layout”等),这些参数是解析传入的 SEF URL 的结果。
  • 与上传文件相关的信息。
  • PHP $_SERVER 数据 - 服务器和执行环境信息。

要开始使用,您必须获取 Joomla Input 类的实例。

use Joomla\CMS\Factory;
$input = Factory::getApplication()->getInput();

如果您的代码位于继承自 Joomla\CMS\MVC\Controller\BaseController 的控制器中,那么这已经为您完成了,并存储在一个受保护的变量 $input 中,因此您只需在下面的函数调用中使用 $this->input 即可,而无需先设置 $input

本文档说明了如何获取上面列出的数据项。

使用过滤器获取单个参数

要获取特定参数的值,请使用

$val = $input->get(param_name, default_value, filter);

其中

  • param_name 是一个包含要检索的参数名称的字符串。
  • default_value 是如果未找到参数则要返回的值;它可以是字符串、整数、数组、null 等 - 任何您想要的值。
  • filter 是一个指定以下列表中某个过滤器的字符串。如果您未指定此参数,则使用默认值“cmd”。

您可以使用此方法获取任何 GET、POST 或路由参数的值 - Input 为获取任何这些类型的参数提供了通用接口。获取特定 GET 或 POST 参数的方法在本文档后面进行了描述。

可用过滤器

下面列出了可用的过滤器,并在适当情况下进行了一些说明。过滤器可以用小写或大写指定,如果下面同一行上列出了 2 个过滤器,则表示它们是等效的。如果您需要过滤器方面更多详细信息,您可以检查 libraries/vendor/joomla/filter/src/InputFilter.php 中的源代码。

  • “INT”,“INTEGER” - 返回参数值中找到的第一个整数。例如,如果参数为“abc123def456”,则应用此过滤器后返回的值将为 123(作为整数)。

  • “UINT” - 返回一个无符号整数。例如,如果参数指定为 ?p1=-2,则此过滤器将丢弃减号,您将获得 2 作为 p1 值的返回值。

  • “FLOAT”,“DOUBLE” - 返回找到的第一个浮点数。

  • “BOOL”,“BOOLEAN” - 注意这一点!如果您在 URL 中指定 ?p1=false,则 p1 的值实际上是字符串“false”,并且由于这是一个非空字符串(布尔值),因此 p1 将返回 true

  • “WORD” - 过滤掉任何不是字母或下划线的字符。

  • “ALNUM” - 字母数字 - 过滤掉任何不是字母或数字的字符。

  • “CMD” - 过滤掉任何不是字母、数字、下划线、点或破折号的字符,并删除结果中的任何前导点。这是 get() 方法的默认过滤器,通常用于在 Joomla 组件中获取 ?option=controller.task 参数。

  • “BASE64” - 过滤掉任何不是字母、数字、正斜杠、加号或等号的字符。base64 可用于将 URL 编码为文本字符串,然后将其存储在请求参数中。例如,如果用户访问受保护的 URL,则他/她可能会被重定向到登录页面 URL,原始 URL 将被 base64 编码并作为重定向 URL 中的(返回)参数存储。用户正确登录后,将检索返回参数,并将其重定向回访问的原始 URL。(请注意,您仍然需要自己解码 base64,过滤器不会为您执行此操作)。

  • “STRING” - 将任何 HTML 实体转换为其对应的字符(例如 &lt; 转换为 <&quot; 转换为双引号),然后删除任何 HTML 标签(包括属性)。例如,"<br>&lt;test&gt;filter" 将返回“filter”。

  • “HTML” - 删除 HTML 标签,但无需事先转换 HTML 实体。例如,"<br>&lt;test&gt;filter" 将返回 "&lt;test&gt;filter"

  • “ARRAY” - 不执行任何过滤,只是尝试将参数转换为数组。

  • “PATH” - 将输入转换为字符串并将其验证为文件路径(例如 path/to/file.png 或 path/to/dir),首先根据 Linux 路径模式进行检查,然后根据 Windows 路径模式进行检查。注意:不接受绝对路径或以尾部斜杠结尾的路径。如果它无法与有效路径匹配,则返回空字符串。

  • “RAW” - 不执行任何过滤;使用此方法时要小心,以避免对您的网站进行注入攻击!

  • “USERNAME” - 过滤掉 Joomla 用户名中不允许的字符。

或者,您可以使用特定于 Input 类型的函数,例如,而不是添加过滤器。

// Instead of:
$input->get('name', '', 'STRING');
// you can use:
$input->getString('name', '');

// Instead of:
$input->get('memberId', 0, 'INT');
// you can use:
$input->getInt('memberId', 0);

除了 getArray() 不同之外;见下文。

要检索对象,您可以使用

$obj = $input->get(param_name, null, null);

数组

只要以下情况,数组就会发挥作用。

  • 数据以数组的形式从客户端发送 - 当您使用 Joomla 表单时,情况将如此,并且表单字段数据(默认情况下)以数组 jform[] 发送到服务器。
  • 发送的数据以单个参数的形式,但您希望将其读入数组。

我们先考虑第二种类型。

将单个参数读入数组

有几种方法可以做到这一点,它们在应用的过滤器方面有所不同。

选项 1

$value = $input->get('p1', array(), "array");

如上所述,右侧将返回一个数组,$value[0] 将设置为 p1 的字符串值。不会对参数“p1”应用任何过滤。

选项 2

$values = $input->getArray();

这将返回所有参数作为关联数组,将参数名称映射到值。“STRING”过滤器将应用于所有参数,并且每个参数的值为

  • 对于单个参数,为字符串,或者
  • 对于作为数组的参数,为关联数组(同样,对每个元素应用“STRING”过滤器)。

虽然 get() 方法的默认过滤器为“CMD”,但 getArray() 方法的默认过滤器为“STRING”。

选项 3

您可以指定希望检索到数组中的参数。

$values = $input->getArray(array('p1' => '', 'p2' => '', 'p3' => ''));

这将返回一个关联数组,其中元素“p1”、“p2”和“p3”指向其值。“STRING”过滤器将应用于所有参数。这实际上与在选项 2 中调用 getArray() 相同,但限制了将返回的参数集。

选项 4

除了指定希望检索的参数外,您还可以指定要应用于每个参数的过滤器。

$values = $input->getArray(array('p1' => 'string', 'p2' => 'int', 'p3' => 'cmd'));

$values 将是一个关联数组,其中元素“p1”、“p2”和“p3”指向其值。每个参数都将根据请求的过滤器进行过滤,并且类型将设置为与过滤器匹配(例如 $value['p2] 将为 int)。

您还可以嵌套数组以获取更复杂的值层次结构。

$values = $input->getArray(array(
'jform' => array(
'title' => 'string',
'quantity' => 'int',
'state' => 'int'
)
));

读取数组参数

如果要读取的参数已以数组的形式存在,则可以使用几种方法将其读入 PHP 数组,其中一些方法与上述方法重叠。同样,应用的过滤器可能会有所不同。在下面的选项中,假设 jform 是发送到服务器的一组值。

选项 1

$value = $input->get('jform');

$value 将是一个关联数组,其键与 jform 数组的键匹配。“CMD”过滤器将应用于所有数组元素的值,并且它们都将具有 string 类型。

选项 2

您可以定义应用于每个元素的过滤器,例如

$value = $input->get('jform', array(), "STRING");

与选项 1 一样,$value 将是一个关联数组,其键与“jform”数组的键匹配,但在这种情况下,“STRING”过滤器将应用于每个条目。

选项 3

您可以定义要捕获的 jform 数组的哪些元素,并为每个元素指定要应用的过滤器。

$values = $input->getArray(array(
'jform' => array(
'title' => 'string',
'quantity' => 'int',
'state' => 'int'
)
));

这与上一节相同。

GET 和 POST 参数

Inputgetpost 属性允许您访问 HTTP GET 和 POST 参数。

$input->get     // property to retrieve GET parameters
$input->post // property to retrieve POST parameters

您可以对这些属性调用get()getArray() 方法来获取参数的值,如上所述,“CMD” 是 get() 的默认过滤器,“STRING” 是 getArray() 的默认过滤器。

如果您的网站使用 SEF URL,请注意这些 URL **不包含**由 Joomla 路由器解析 SEF URL 时生成的路由参数“option”、“view”等。仅返回真实的 GET 和 POST 参数。

例如,要检索 GET 参数 'p1',请使用以下代码

$value = $input->get->get('p1');

$value 将包含 GET 参数 'p1' 的值,该值使用“CMD”过滤器进行过滤。

要检索 GET 参数 'p1' 并使用“INT”过滤器,请使用(例如)以下代码

$value = $input->get->get('p1', 0, "int");

要检索所有 GET 参数

$value = $input->get->getArray();

$value 将包含 GET 参数的关联数组,其值使用“STRING”过滤器进行过滤。

要检索 POST 参数 'p1',请使用以下代码

$value = $input->post->get('p1');

$value 将包含 POST 参数 'p1' 的值,该值使用“CMD”过滤器进行过滤。

要检索所有 POST 参数

$value = $input->post->getArray();

$value 将包含 POST 参数的关联数组,其值使用“STRING”过滤器进行过滤。

要检索未应用任何过滤器数据的jform的 POST 参数

$value = $input->post->get("jform", array(), "array");

此方法用于 Joomla 核心 MVC 代码中以检索原始表单数据。然后将数据数组传递给 Model 的validate函数,该函数处理数据的过滤和验证。过滤使用在表单工作原理中描述的表单过滤器通过bind()函数进行(请注意,这些过滤器与我们在此部分中讨论的Input过滤器不同),然后根据服务器端验证中所述执行验证。

文件

您的 Joomla 表单中可能包含一个类型为“file”的 HTML 输入元素,以允许用户将文件上传到您的网站。在这种情况下,PHP 将 POST 请求的内容写入其临时目录中的文件,并提供有关上传的信息。Joomla 提供了一个易于使用的界面来访问此信息。(无法通过 GET/POST 参数获取信息)。

假设您有一个这样的表单

<form action="<?php echo Route::_('index.php?option=com_example&task=file.submit'); ?>" enctype="multipart/form-data" method="post">
<input type="file" name="jform1[test][]" />
<input type="file" name="jform1[test][]" />
<input type="submit" value="submit" />
</form>

然后您可以使用

$files = $input->files->get('jform1');

$files 然后变为类似以下内容

Array
(
[test] => Array
(
[0] => Array
(
[name] => youtube_icon.png // filename on local system
[type] => image/png // mime type
[tmp_name] => /tmp/phpXoIpSD // name given by PHP in tmp directory
[error] => 0 // should be 0 for no error
[size] => 34409 // in bytes
)

[1] => Array
(
[name] => Younger_Son_2.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpWDE7ye
[error] => 0
[size] => 99529
)
)
)

JSON

当您在 Ajax 请求的 POST 数据中以 json 字符串的形式发送数据时,您可以使用以下代码将数据检索为关联数组

$jsonArray = $input->json->get(param_name);

对于您有多个 POST 参数且其中一个是 json 字符串的情况,此方法将不起作用 - 整个主体必须是 json 字符串。Joomla 从php://input捕获数据,并对数据调用json_decode()

此外,如果您使用此方法,建议将安全令牌作为 URL 中的 GET 参数之一发送。

有关工作示例,请查看 Joomla 如何处理全局配置中权限值的更新

  • 在 js 文件 media/system/fields/joomla-field-permissions.js 中的 sendPermissions() 函数中
  • 在 php 文件 administrator/components/com_config/src/Model/ApplicationModel.php 中的 storePermissions() 函数中。

服务器数据

您可以使用以下代码检索和清理 PHP $_SERVER 数据

$val = $input->server->get(param_name, default_value, filter);

设置值

函数set()def()允许您设置输入参数及其值。

$input->set('p2', "someval");

将参数p2的值设置为字符串“someval”(如果p2不存在则创建它)。

$input->def('p2', "someval");

创建一个参数p2并将其值设置为字符串“someval”,但前提是p2不存在。如果p2已存在,则def('p2', "someval");不执行任何操作。

模块代码示例

以下是您可以安装和运行以演示参数值检索的简单 Joomla 模块的代码。

在文件夹mod_input中创建以下 2 个文件

mod_input.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
<name>Input demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla Input class to obtain HTTP parameters</description>
<files>
<filename module="mod_input">mod_input.php</filename>
</files>
</extension>
mod_input.php
<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Factory;

$app = Factory::getApplication(); // equivalent of $app = JFactory::getApplication();
$input = $app->getInput();

if ($input->exists('p1'))
{
$v1 = $input->get('p1', 0, "INT"); // rhs equivalent to $input->getInt('p1', 0);
echo "<p>Int value of p1 is $v1</p>";
$v1 = $input->get('p1', 0, "UINT"); // uint
echo "<p>Uint value of p1 is $v1</p>";
$v1 = $input->get('p1', 0, "string");
echo "<p>String Value of p1 is $v1</p>";
}
else
{
echo "<p>Parameter p1 not specified</p>";
}

将 mod_input 目录压缩为mod_input.zip

在您的 Joomla 管理员中,转到“安装扩展”,然后通过“上传程序包文件”选项卡上传此 zip 文件以安装此示例模块。

通过编辑此模块使其可见(在“模块”页面中单击它),然后

  • 将其状态设置为“已发布”
  • 选择页面上要显示它的位置
  • 在菜单分配选项卡上指定它应显示的页面

显示此模块出现的网页。然后将p1参数添加到 URL 中

  • 如果 URL 没有现有参数,则附加?p1=123abc
  • 如果 URL 有现有参数,则附加&p1=123abc

您应该会看到检索p1参数并将其传递给不同过滤器的结果。您可以尝试为p1指定不同的值,应用不同的过滤器,并且可以使用诸如curl之类的实用程序发送 HTTP POST 参数以确认它也适用于这些参数。

组件代码示例

您还可以下载并使用此示例组件代码作为试验检索 POST 参数、文件等的依据。src/Controller/PostController.php 使用 Input 检索 POST 参数并将它们存储在会话数据中

// name of array 'jform' must match 'control' => 'jform' line in the model code
$data = $this->input->post->get('jform', array(), 'array');
// store this in the session so that we can display it in DisplayController
$app->setUserState('com_sample_form_field.post', $data);

重定向回显示表单后,View 在 src/View/Sample/HtmlView.php 中读取此存储的数据

// check if there's any POST data from the previous form submission
$this->postdata = Factory::getApplication()->getUserState('com_sample_form_field.post', null);
// and clear it, ready for the next submission
Factory::getApplication()->setUserState('com_sample_form_field.post', array());

然后在 tmpl/sample/default.php 文件中显示。

ob_start();
var_dump($this->postdata);
$post = ob_get_contents();
ob_end_clean();
...
<?php echo '<pre>' . htmlspecialchars($post, ENT_QUOTES) . '</pre>'; ?>

通过遵循此模式,您可以在 PostController 中尝试不同的方法和过滤器,然后将结果存储在会话中。然后在重定向后,您可以在 View 文件中从会话中提取数据,并在 tmpl default.php 文件中显示它。