我正在构建一个获取数据数组的Web API。我想检查此数组是否存在某些键,如果所需的键不存在,则返回false,如果不存在可选键,则在数组中设置该键值对。
混淆来自我的输入数组,可能有数组作为值。例如,假设我输入一个这样的数组:
$input_array = array(
’name’ => ‘Adam’,
‘address’ => array(
‘number’ => 12,
‘street’ => ‘My Street’
)
);
我需要密钥:
$required_keys = array(
‘name’,
‘address’ => array(
‘number’,
‘street’
)
);
可选键:
$optional_keys = array(
‘address’ = array(
‘postcode’ => ‘WA1'
)
);
我正在努力测试我的输入数组对这两种类型的测试数组(输入和可选)。
应该发生的事情是: 1)应匹配所有必需的密钥。 2)如果不存在任何可选键,请将它们设置为可选键阵列中的键值对。
我知道(但我没有经验)正则表达式。但是,我知道PHP有一个名为http_build_query(mixed $array);
的函数,它接受一个数组并将其转换为URL查询字符串。我的想法是,我可以将输入数组转换为URL字符串,然后将其与我的两个测试数组(必需和可选)组成的正则表达式进行比较。这会有用吗?
如果有人有任何其他想法,我很想知道。 感谢
更新:附加未预期的输出
更新2:附加新输出
更新3:当前代码:
static public function static_test_required_keys(Array $required_keys_array, Array $input_array)
{
$missing = array();
foreach ($required_keys_array as $key => $value)
{
if (empty($input_array[$key]))
{
$missing[] = $key;
}
else if (isset($input_array[$key]) && is_array($input_array[$key]))
{
$missing = array_merge(Inputter::static_test_required_keys($value, $input_array[$key]), $missing);
}
}
return $missing;
}
更新4:新代码。
tatic public function static_test_required_keys(Array $required_keys_array, Array $input_array)
{
$missing = array();
foreach ($required_keys_array as $key => $value)
{
if (! isset($input_array[$key]))
{
$missing[] = $key;
}
else if (isset($input_array[$key]) && is_array($input_array[$key]))
{
$missing = array_merge(Inputter::static_test_required_keys($value, $input_array[$key]), $missing);
}
}
return $missing;
}
将代码从isempty()
更改为isset()
。此页面给出了两者之间的差异。 https://www.virendrachandak.com/techtalk/php-isset-vs-empty-vs-is_null/
答案 0 :(得分:1)
带有对称输入+所需键的新改进版......
$input_array = array(
'name' => 'Adam',
'address' => array(
'number' => 12,
'street' => '',
'phones' => array('home_phone'=>'','fax'=>'555-1212')
)
);
$required_keys = array(
'name' => '',
'address' => array(
'number' => '',
'street' => '',
'phones' => array('home_phone'=>'')
)
);
function check_required( $input, $required ){
$missing = array();
foreach ($required as $k=>$v) {
if (empty($input[$k])) {
$missing[] = $k;
} else if (is_array($v)) {
$missing = array_merge( check_required( $input[$k], $v ), $missing );
}
}
return $missing;
}
$missing = check_required( $input_array, $required_keys );
if (!empty($missing)) echo 'Please enter your '. implode(', ', $missing);
请在此处查看沙箱... http://sandbox.onlinephpfunctions.com/code/23b908b873b053aefb37770f636b63bba2db960b
答案 1 :(得分:1)
您可以使用array_diff检查输入中是否缺少任何必填字段。
您可以使用array_merge来设置缺失字段的默认值。
$requiredKeys = [
'foo',
'baz',
];
// Take the keys from input
$inputKeys = array_keys($input);
$missingRequiredKeys = array_diff($requiredKeys, $inputKeys)
if (!empty($missingRequiredKeys)) {
throw new InvalidArgumentException(...);
}
// Setup default values for missing optional keys
$defaultValues = [
'bar' => 'bas',
];
$result = array_merge($defaultValues, $input);
对于检查必填字段或设置默认值,重要的是在单个函数中重复上面的代码。
function validateInput(array $input) {
// Above code
// Validate field subkeys from a parent required field.
// or optional field with default value.
validateFoo($input['foo']);
// Validate field subkeys from a parent optional field without default value.
if (array_key_exists('optional_input_without_default', $input)) {
validateAnotherFooInput($input['optional_input_without_default']);
}
}
您可以通过多种方式使用数组交集,差异和合并来检查Array Book
中的这些函数系列array_diff_assoc - 使用附加索引检查计算数组的差异
array_diff_key - 使用用于比较的键计算数组的差异
array_diff_uassoc - 使用用户提供的回调函数执行附加索引检查来计算数组的差异
array_diff_ukey - 使用键上的回调函数计算数组的差异以进行比较
array_diff - 计算数组的差异
array_intersect_assoc - 使用附加索引检查计算数组的交集
array_intersect_key - 使用密钥计算数组的交集
array_intersect_uassoc - 使用附加索引检查计算数组的交集,通过回调函数比较索引
array_intersect_ukey - 使用键上的回调函数计算数组的交集以进行比较
array_intersect - 计算数组的交集
array_udiff_assoc - 使用附加索引检查计算数组的差异,通过回调函数比较数据
array_udiff_uassoc - 使用附加索引检查计算数组的差异,通过回调函数比较数据和索引
array_udiff - 通过使用回调函数进行数据比较来计算数组的差异
array_uintersect_assoc - 使用附加索引检查计算数组的交集,通过回调函数比较数据
array_uintersect_uassoc - 使用附加索引检查计算数组的交集,通过回调函数比较数据和索引
array_uintersect - 计算数组的交集,通过回调函数比较数据
答案 2 :(得分:0)
// Check if required keys exist
foreach( $required_keys as $req_key => $req_val )
{
if( !array_key_exists( $req_key, $input_array )
{
// if key exists check if it has values set in an array and if
// these are also in $input_array
if( is_array( $req_val ) )
{
foreach( $req_val as $inner_req_key )
{
if( !isset( $input_array[$req_val][$inner_req_key] )
{
echo "Required key '$req_key' is missing value '$inner_req_key'.";
}
}
}
echo "Required key '$req_key' is missing.";
}
}
// Check if optional keys are defined
foreach( $optional_keys as $opt_key => $opt_val )
{
// Check if key exists, if not copy optional key=>value as whole
if( !array_key_exists( $opt_key, $input_array )
{
$input_array[ $opt_key ] = $opt_val;
}
else // key exists
{
// if key exists check if it is an array and if optional elements
// exist, else add them
if( is_array( $opt_key ) )
{
foreach( $opt_key as $inner_opt_key => $inner_opt_val )
{
// key is not set, so get from %optional_keys
if( !isset( $input_array[$opt_key][$inner_opt_key] )
{
$input_array[$opt_key][$inner_opt_key] = $inner_opt_val;
}
}
}
}
}
很久没有PHP,但也许这会有所帮助。 PS:未测试并添加了一些解释。 HTH
答案 3 :(得分:0)
所以这是我最终的代码,任何人偶然发现这个/想知道我是怎么做到的。随意提交改进意见。
static protected function static_test_required_keys(Array $required_keys_array, Array $input_array, &$error)
{
// Loop through each required key and value
//
foreach ($required_keys_array as $key => $value)
{
// Check the corresponding value in the input array is not set
//
if (! isset($input_array[$key]))
{
// If it isn't set return false with a missing error
//
$error = Error::withDomain(INPUTTER_ERROR_DOMAIN,
INPUTTER_ERROR_CODE_KEY_MISSING,
'Missing a required key: ' . $key);
return false;
}
//
// Check corresponding value in the input array is set and is an array
//
else if (isset($input_array[$key]) && is_array($input_array[$key]))
{
// Recurse the function for sub arrays
//
if (! Inputter::static_test_required_keys($value, $input_array[$key], $error))
{
// If we return false from this one, we've found at least one error and don't need to continue
//
return false;
}
}
}
// If we get here then it must be valid
//
return true;
}
static protected function static_set_optional_key_values(Array $optional_dictionary, Array &$input_array, &$error)
{
// Loop through each optional key/value
//
foreach ($optional_dictionary as $key => $value)
{
// Check the key doesn't exist in the input array OR the corresponding value in the input array is not set
//
if (! array_key_exists($key, $input_array) || ! isset($input_array[$key]))
{
// Set the new key/value
//
$input_array[$key] = $value;
}
//
// Check corresponding value in the input array is set and is an array
//
else if (isset($input_array[$key]) && is_array($input_array[$key]))
{
// Recurse the function for sub arrays
//
Inputter::static_set_optional_key_values($value, $input_array[$key], $error);
}
}
}
答案 4 :(得分:0)
我不知道您要在哪里运行此代码。
如果它在浏览器中或在Javascript中。
由于我有疑问,我已经做到了这一点:
function array_extend() {
//Detects if we are running in Javascript or PHP
//In PHP, this will be false because PHP only parses
//escape sequences in double-quoted strings (except the sequence \')
$javascript = '\0' == "\0";
//PHP arrays support 'key=>value' pairs, JS arrays don't.
$result = $javascript ? new Object() : array();
$arguments = $javascript? arguments : func_get_args();
$get_keys = function($elem){
if('\0' == "\0")//PHP complains if I use the var $javascript
{
$object = Object;
return $object['keys']($elem); //PHP doesn't like the Object.keys syntax
}
else
{
return array_keys($elem);
}
};
for($j = 0, $length_args = $javascript? $arguments['length']: count($arguments); $j < $length_args; $j++)
{
$keys = $get_keys( $arguments[$j] );
for($i = 0, $length_keys = $javascript? $keys['length']: count($keys); $i < $length_keys; $i++)
{
$result[$keys[$i]] = $arguments[$j][$keys[$i]];
}
}
return $result;
}
它在PHP和Javascript中运行。
目前,我在另一个网站上有一个已打开的问题,展示了该功能。