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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10122801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:25:51  来源:igfitidea点击:

Remove all array elements except what I want?

phparrays

提问by Stan

I have controller that takes post parameters from HTML form, it will then send them to model that will insert the array into Cassandra database.

我有一个控制器,它从 HTML 表单中获取 post 参数,然后它将它们发送到将数组插入到 Cassandra 数据库中的模型。

It is SQLInjection proof, because it's NoSQL, however what I'm afraid is that user can just simulate 100k post parameters or just add some that I don't need and it will be inserted into database. How can I make sure that only the values I need will stay in my array.

它是 SQLInjection 证明,因为它是 NoSQL,但是我担心用户只能模拟 10 万个帖子参数,或者只是添加一些我不需要的参数,然后将其插入到数据库中。我如何确保只有我需要的值才会保留在我的数组中。

Example:

例子:

$post = ['parent_id', 'type', 'title', 'body', 'tags']; // Good
$post = ['parent_id', 'type', 'title', 'body', 'tags', 'one', 'two', 'three'] // Bad

How do I make sure that my array will unset all the elements that are not in goodexample?

我如何确保我的数组将取消设置所有不在好的示例中的元素?

采纳答案by Jon

You are looking for array_intersect:

您正在寻找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));

See it in action.

看到它在行动

Of course this specific example does not make much sense because it works on array values, but there is also array_intersect_keythat does the same based on keys.

当然,这个特定的例子没有多大意义,因为它适用于数组values,但也有array_intersect_key基于键的方法。

回答by Berry Langerak

By whitelisting the entries you doexpect.

通过白名单,你的项目期待。

<?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 );

Anyway, using Cassandra as a data-store is of course not a reason not to do validation on the data you're receiving.

无论如何,使用 Cassandra 作为数据存储当然不是不对您收到的数据进行验证的理由。

回答by Georgy Sharapov

What about multidimensional array? I was researched for a couple of hours for this solution, nowhere found an optimal solution. so, i wrote it by myself

多维数组呢?我为此解决方案研究了几个小时,但没有找到最佳解决方案。所以,我自己写的

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;
    }

use: example

使用:示例

$array = [
        'key1' => 'kw',
        'loaa'=> ['looo'],
        'k'    => [
            'prope' => [
                'prop'  => ['proo', 'prot', 'loolooo', 'de'],
                'prop2' => ['hun' => 'lu'],
            ],
            'prop1' => [

            ],
        ],
    ];

call: example

调用:示例

allow_keys($array, ['key1', 'k' => ['prope' => ['prop' => [0, 1], 'prop2']]])

output:

输出:

Array ( [key1] => kw [k] => Array ( [prope] => Array ( [prop] => Array ( [0] => proo [1] => prot ) [prop2] => Array ( [hun] => lu ) ) ) ) 

so you get only needed keys from the multidimensional array. it is not limited only for "multidimensional", you can use it by passing an array like

所以你只从多维数组中得到需要的键。它不仅限于“多维”,您可以通过传递类似的数组来使用它

['key1', 'loaa']

output you get:

你得到的输出:

Array ( [key1] => kw [loaa] => Array ( [0] => looo ) )

cheers!

干杯!

回答by Christian Riesen

This will output the same as $post_allowed. What it does is only allow the values in $post_input that are also present in $post_allow.

这将输出与 $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);

回答by TarranJones

This is called white listing, your example is misleading as the $_POSTis an association array.

这称为白名单,您的示例具有误导性,因为它$_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);

This is a whitelisting function I created for associative arrays.

这是我为关联数组创建的白名单函数。

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)); 
    }
}

回答by danillonunes

In case you're dealing with associative arrays and you don't want to use array_intersect_key()for any reason, you can also do a simpler approach of manually build a new array using the values you want from the old one.

如果您正在处理关联数组并且array_intersect_key()出于任何原因不想使用,您还可以使用更简单的方法使用旧数组中的值手动构建新数组。

$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']
);

回答by Antony

Its worth remembering that while array_intersectand array_intersect_keyare good they might well be overkill. In my situation I only wanted 1 element left, therefore the simplest option was just to rebuild the array I wanted based on the key/values I needed. I wonder at what point therefore the array_intersect's don't become worth it and you are simply better off with $new = array('whatI'=>'want');. I believe in the OP this is worth it but in smaller cases it might be overkill.

它的值得记住的是,虽然array_intersectarray_intersect_key好,他们很可能是矫枉过正。在我的情况下,我只想要 1 个元素,因此最简单的选择就是根据我需要的键/值重建我想要的数组。我想知道在什么时候 array_intersect 变得不值得,你只是更好地使用$new = array('whatI'=>'want');. 我相信在 OP 中这是值得的,但在较小的情况下它可能会矫枉过正。

Alternatively in response to the original question simply using unsetmight have been a cheaper option - unset($post['one'],$post['two'],$post['three']). Again though, it relates to the point at which this becomes too inefficient and the array_intersect functions are better.

或者,为了回答最初的问题,简单地使用unset可能是一个更便宜的选择 - unset($post['one'],$post['two'],$post['three']). 不过,这与这变得太低效和 array_intersect 函数更好的点有关。

回答by ime.devdesks

Use array intersection. array intersect, it will help you.

使用数组交集。数组相交,它会帮助你。