我正在开发一些API方法,需要认真验证输入数据和性能(因为将有数百个API客户端,有数千条记录被查询和更新)
作为示例,这里有一些代码,用于了解我如何使用array_diff和array_key函数来验证来自 JSON(API 客户端在 HTTP 请求正文中发送的)的解码对象是否具有有效字段:
// Obtener campos
$humano = file_get_contents('php://input');
$campos = json_decode($humano, true);
if (!is_array($campos))
{
throw new ExcepcionApi(400, 'ERR_C_HUM_CREAR_001',
'Petición inválida al tratar de crear un nuevo cliente ',
'El campo POST "cliente" no contiene JSON válido, para '
. 'que pueda ser registrado el cliente se necesita '
. 'que el objeto esté en la raíz del documento JSON.');
}
// Definir campos permitidos y requeridos
$campos_permitidos = [
'id', 'cuenta_id', 'nombre', 'apellidos', 'sexo',
'codigo_postal', 'email', 'telefono', 'celular',
'direccion', 'ciudad', 'empresa', 'fecha_creacion', 'fecha_modificacion',
];
$campos_requeridos = [
'nombre', 'apellidos', 'email',
];
$campos_recibidos = array_keys($campos);
// Verificar que sólo se definan campos permitidos
$campos_ilegales = array_diff($campos_recibidos, $campos_permitidos);
if (!empty($campos_ilegales))
{
throw new ExcepcionApi(400, 'ERR_C_HUM_CREAR_002',
'Petición inválida al tratar de crear un nuevo cliente ',
'El campo POST "cliente" contiene JSON válido, pero '
. 'los siguientes campos no pueden ser parte del objeto: '
. implode(', ', $campos_ilegales) . '.');
}
// Verificar que cada campo requerido exista en $campos
$campos_faltantes = array_diff($campos_requeridos, $campos_recibidos);
if (!empty($campos_faltantes))
{
throw new ExcepcionApi(400, 'ERR_C_HUM_CREAR_003',
'Petición inválida al tratar de crear un nuevo cliente ',
'El campo POST "cliente" contiene JSON válido, pero '
. 'los siguientes campos hacen falta en el objeto: '
. implode(', ', $campos_faltantes) . '.');
}
foreach ($campos_requeridos as $requerido)
{
if (strlen($campos[$requerido]) === 0)
{
throw new ExcepcionApi(400, 'ERR_C_HUM_CREAR_004',
'Petición inválida al tratar de crear un nuevo cliente ',
'El campo POST "cliente" contiene JSON válido, pero '
. "el campo requerido '$requerido' tiene un valor vacío. "
. 'Los siguientes campos son requeridos: '
. implode(', ', $campos_requeridos) . '.');
}
}
例如,在数据库中创建行之前验证输入的前面代码将接受此 JSON:
{
"nombre":"Juan",
"apellidos":"Castellon",
"sexo":null,
"codigo_postal":"13061",
"email":"juan.castellon@yopmail.com",
"telefono":"8877994",
"celular":null,
"direccion":null,
"ciudad":"Managua",
"empresa":"EL UNIVERSO INC."
}
这将不被接受(因为缺少必填字段):
{
"nombre":"Juan",
"apellidos":"Castellon"
}
这将不被接受(因为不存在字段):
{
"nombre":"Juan",
"apellidos":"Castellon"
}
从性能的角度来看,使用array_diff和array_key是否正确?
由于您的 JSON 返回对象,我建议您使用 property_exists() 函数来确定对象是否具有特定属性(术语中的字段)。
您必须保留一组有效或必填字段,如下所示。
<?php
$required = ('nombre', 'apellidos');
foreach($required_fields as $required) {
if(property_exists($campos, $required) {
// the field exists, do what you want
} else {
// the field does not exist throw exception
throw new Exception('Whoops the field '.$required.' does not exist in the response from the server.';
}
当然,使用一个函数调用与两个函数调用对性能更好。