删除除我想要的所有数组元素?
我有一个控制器,从HTML表单中提取参数,然后将它们发送到将数组插入到Cassandra数据库的模型中。
这是SQLInjection的certificate,因为它是NoSQL,但是我怕用户只能模拟100k的post参数或者只是添加一些我不需要的东西,它会被插入到数据库中。 我怎样才能确保只有我需要的值将留在我的数组中。
例:
$post = ['parent_id', 'type', 'title', 'body', 'tags']; // Good $post = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three'] // Bad
我如何确保我的数组将会取消所有不是很好的例子?
你正在寻找array_intersect
:
$good = ['parent_id', 'type', 'title', 'body', 'tags']; $post = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three']; print_r(array_intersect($good, $post));
看到它的行动 。
当然,这个具体的例子没有多大意义,因为它对数组值有效 ,但是也有基于键的array_intersect_key
。
将您期望的条目列入白名单。
<?php $post = array( 'parent_id' => 1, 'type' => 'foo', 'title' => 'bar', 'body' => 'foo bar', 'tags' => 'foo, bar', 'one' => 'foo', 'two' => 'bar', 'three' => 'qux' ); $whitelist = array( 'parent_id', 'type', 'title', 'body', 'tags' ); $filtered = array_intersect_key( $post, array_flip( $whitelist ) ); var_dump( $filtered );
无论如何,使用Cassandra作为数据存储当然不是不对您所接收的数据进行validation的原因。
使用数组交集。 数组相交 ,它会帮助你。
这将输出与$ post_allowed相同。 它所做的只是允许$ post_input中也存在于$ post_allow中的值。
$post_allowed = ['parent_id', 'type', 'title', 'body', 'tags']; $post_input = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three']; $post = array_intersect($post_input, $post_allowed);
这被称为白名单,你的例子是误导,因为$_POST
是一个关联数组。
$post = [ 'parent_id' => 'val', 'type' => 'val', 'title' => 'val', 'body' => 'val', 'tags' => 'val', 'one' => 'val', 'two' => 'val', 'three'=>'val', ]; $whitelist = ['parent_id', 'type', 'title', 'body', 'tags']; $sanitized_post = array_whitelist_assoc($post, $whitelist);
这是我为关联数组创build的白名单函数。
if(!function_exists('array_whitelist_assoc')){ /** * Returns an associative array containing all the entries of array1 which have keys that are present in all the arguments when using their values as keys. * * @param array $array The array with master keys to check. * @param array $array2 An array to compare keys against its values. * @return array $array2,... A variable list of arrays to compare. * */ function array_whitelist_assoc(Array $array1, Array $array2) { if(func_num_args() > 2){ $args = func_get_args(); array_shift($args); $array2 = call_user_func_array('array_merge', $args); } return array_intersect_key($array1, array_flip($array2)); } }
如果你正在处理关联数组,并且你不想使用array_intersect_key()
出于任何原因,你也可以用一个更简单的方法来使用你想要的旧数组来手动build立一个新的数组。
$post = array( 'parent_id' => 1, 'type' => "post", 'title' => "Post title", 'body' => "Post body", 'tags' => "Post tags", 'malicious' => "Robert'); DROP TABLE students;--" ); $good = array( 'parent_id' => $post['parent_id'], 'type' => $post['type'], 'title' => $post['title'], 'body' => $post['body'], 'tags' => $post['tags'] );
multidimensional array呢? 我为这个解决scheme研究了几个小时,没有find最佳解决scheme。 所以,我自己写了
function allow_keys($arr, $keys) { $saved = []; foreach ($keys as $key => $value) { if (is_int($key) || is_int($value)) { $keysKey = $value; } else { $keysKey = $key; } if (isset($arr[$keysKey])) { $saved[$keysKey] = $arr[$keysKey]; if (is_array($value)) { $saved[$keysKey] = allow_keys($saved[$keysKey], $keys[$keysKey]); } } } return $saved; }
使用:例子
$array = [ 'key1' => 'kw', 'loaa'=> ['looo'], 'k' => [ 'prope' => [ 'prop' => ['proo', 'prot', 'loolooo', 'de'], 'prop2' => ['hun' => 'lu'], ], 'prop1' => [ ], ], ];
调用:例子
allow_keys($array, ['key1', 'k' => ['prope' => ['prop' => [0, 1], 'prop2']]])
输出:
Array ( [key1] => kw [k] => Array ( [prope] => Array ( [prop] => Array ( [0] => proo [1] => prot ) [prop2] => Array ( [hun] => lu ) ) ) )
所以你只需要从multidimensional array中得到所需的密钥。 它不仅限于“多维”,您可以通过传递数组来使用它
['key1', 'loaa']
输出你得到:
Array ( [key1] => kw [loaa] => Array ( [0] => looo ) )
干杯!
值得记住的是,虽然array_intersect
和array_intersect_key
是好的,他们可能会矫枉过正。 在我的情况下,我只想要一个元素,所以最简单的select只是基于我需要的键/值重build我想要的数组。 我想知道在什么时候array_intersect是不值得的,你只需要更好的$new = array('whatI'=>'want');
。 我相信在OP这是值得的,但在较小的情况下,这可能是矫枉过正。
unset($post['one'],$post['two'],$post['three'])
可能是一个更便宜的选项。 同样,它涉及到这个效率太低的点,而array_intersect函数更好。