【问题标题】:Is it OK for performance to use PHP array_keys and array_diff functions to validate fields of a JSON?使用 PHP array_keys 和 array_diff 函数来验证 JSON 的字段是否可以提高性能?
【发布时间】:2015-06-16 22:22:52
【问题描述】:

我正在开发一些 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是否正确?

【问题讨论】:

  • 你可以通过基准测试回答你自己的问题

标签: php arrays json performance security


【解决方案1】:

由于您的 JSON 正在返回对象,因此我建议您使用 property_exists() 函数来确定该对象是否具有某个属性(在您的术语中为字段)。

您必须保留一组 VALID 或 REQUIRED 字段,如下所示。

<?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.';
    }

当然,使用一个函数调用与两个函数调用相比,性能会更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    相关资源
    最近更新 更多