删除除我想要的所有数组元素?

我有一个控制器,从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_intersectarray_intersect_key是好的,他们可能会矫枉过正。 在我的情况下,我只想要一个元素,所以最简单的select只是基于我需要的键/值重build我想要的数组。 我想知道在什么时候array_intersect是不值得的,你只需要更好的$new = array('whatI'=>'want'); 。 我相信在OP这是值得的,但在较小的情况下,这可能是矫枉过正。

unset($post['one'],$post['two'],$post['three'])可能是一个更便宜的选项。 同样,它涉及到这个效率太低的点,而array_intersect函数更好。