Remove all array elements except what I want?

后端 未结 8 2018
挽巷
挽巷 2021-01-31 14:13

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.

It is SQLInjection proof

相关标签:
8条回答
  • 2021-01-31 14:36

    Its worth remembering that while array_intersect and array_intersect_key are 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.

    Alternatively in response to the original question simply using unset might 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.

    0 讨论(0)
  • 2021-01-31 14:43

    By whitelisting the entries you do expect.

    <?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.

    0 讨论(0)
  • 2021-01-31 14:45

    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!

    0 讨论(0)
  • 2021-01-31 14:45

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

    0 讨论(0)
  • 2021-01-31 14:47

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

    $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)); 
        }
    }
    
    0 讨论(0)
  • 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.

    $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']
    );
    
    0 讨论(0)
提交回复
热议问题