How to get a subset of $_POST array with keys starting with a prefix
Asked Answered
R

8

10

Let's say my $_POST variable looks like:

<?php

Array
(
    [user_ID] => 65
    [action] => editpost
    [originalaction] => editpost
    [post_author] => 154
    [empl_bd_dd] => 6
    [empl_bd_mm] => 5
    [empl_bd_yy] => 1987
    [empl_gen] => 1
    [empl_height] => 155
    [empl_weight] => 61
    [empl_arra] => 2
    [save] => Update
    [post_it] => 2
    [empl_pay] => J77
    [empl_cust] => Married
    [empl_lang] => Array
        (
            [0] => EN
            [1] => FR
        )
    [empl_rent] => 1
    [name] => Jimmy Nathan
    [empl_text] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sed interdum leo. Sed et elit quam, tempor placerat neque. Nullam sapien odio, egestas iaculis dictum ut, congue ullamcorper tellus.
    [empl_sk_0] => 6
    [empl_sk_1] => 7
    [empl_sk_2] => 5
)

?>

As you can see I prefixed all my form variables with empl_. Short of having to specify all of them one by one, how do I get all my form variables from $_POST into an array in the least-cost hopefully elegant way? Is there a PHP array function or a combination of them that I can use for this?

Like in CSS where you can select all elements with a class that starts with empl using [class*="empl_"], is there a way I can do this with the array keys in PHP, e.g.

$empl_post = $_POST['empl_*']

EDITED ANSWER - impt correction to @chris 's answer: $_POST has to be the first argument to array_intersect_key, e.g.:

$empl_POST = array_intersect_key($_POST, array_flip(preg_grep('/^empl_/', array_keys($_POST))));
Ramsdell answered 14/5, 2012 at 12:43 Comment(1)
thanks for all the answers. chose @chris 's answer below. exactly what i was lookin for. thanks again, everyone, y'all rock.Ramsdell
D
17
$r = array_intersect_key($_POST, array_flip(preg_grep('/^empl_/', array_keys($_POST))));

they really need to add a PREG_GREP_KEYS flag to preg_grep() so we don't have to do all that mess...

As a function:

function preg_grep_keys($pattern, $input, $flags = 0) {
    return array_intersect_key(
        $input,
        array_flip(preg_grep(
           $pattern,
           array_keys($input),
           $flags
        ))
    );
}

Edit - since php 5.6 array_filter now has some new flags that let you access the array key in the filter callback.

function preg_grep_keys($pattern, $input, $flags = 0) {
    return array_filter($input, function($key) use ($pattern, $flags) {
           return preg_match($pattern, $key, $flags);
    }, ARRAY_FILTER_USE_KEY);
}

use

$filtered = preg_grep_keys('/^empl_/', $_POST);
Daw answered 14/5, 2012 at 13:17 Comment(2)
"they really need to add a PREG_GREP_KEYS flag..." - ikr?? one function less. :DRamsdell
one important change: $_POST has to be the first argument for array_intersect_key. thanks again, @chrisRamsdell
M
6
function GetPrefixedItemsFromArray($array, $prefix)
{
    $keys = array_keys($array);
    $result = array();

    foreach ($keys as $key)
    {
        if (strpos($key, $prefix) === 0)
        {
            $result[$key] = $array[$key];
        }
    }

    return $result;
}

Then simply call with $myArray = GetPrefixedItemsFromArray($_POST, "empl_");.

Membranophone answered 14/5, 2012 at 12:47 Comment(1)
This is a nice way. I have given a regex version of it, just incase you want to try something more than just prefix.Uplift
J
2
$empl_post = array();
foreach ($_POST as $k => $v) {
    if (strpos($k, 'empl_') !== 0) continue;
    $empl_post[substr($k, 5)] = $v
}

print_r($empl_post);
Jeanniejeannine answered 14/5, 2012 at 12:45 Comment(1)
And even easier with strpos($k, 'empl_') !== 0Enuresis
H
0

Another method:

$formVars = $_POST;
foreach ($formVars as $key=>$value) {
    if (strpos($key, 'empl_')===false) 
        unset($formVars[$key]);
}
Hiroshima answered 14/5, 2012 at 13:4 Comment(0)
U
0

If you want something like this

$keyPattern = '/^empl_*/';
$matching_array = getArrayElementsWithMatchingKeyPattern($_POST,$keyPattern);

Then I dont think there is an inbuilt way to that. Best way would be a foreach loop with a regex match.

function getArrayElementsWithMatchingKeyPattern($array,$keyPattern){
    $matching_array = array();

    foreach ($keyPattern as $k => $v) {
       if (preg_match($array[$k],$keyPattern) > 0)
             $matching_array[$k] = $v;
    }

    return ($matching_array);

}
Uplift answered 14/5, 2012 at 13:6 Comment(0)
P
0

Here's a cool ultra-php-neat way to use php array_walk to specify a generic prefix to remove:

$foo = array('k_foo' =>"bar", 
              'k_bar' =>"b0r", 
              'y_foo' =>"b5r",
              'y_not' =>"b7r", 
             'k_not' =>"b1r");

$subsetArray = $foo;
$key_prefix = "k_";

array_walk($foo, 'removeUnwanted', array(&$subsetArray, $key_prefix));
var_dump ($subsetArray);

function removeUnwanted($value, $key, $array){
    $prefix = $array[1];
    $testArray = &$array[0];
    if(strpos($key,$prefix) ===0){
        unset($testArray[$key]); 
    } 
}

Now you can just call array walk, with a copy of the array of values, and the prefix string.

Pacificia answered 14/5, 2012 at 13:18 Comment(0)
P
0
function GetPrefixedItemsFromArray($array, $prefix, $remplacePref=FALSE)    {
    $keys = array_keys($array);
    $result = array();

    foreach ($keys as $key) {
        if (strpos($key,$prefix) === 0) {
            if($remplacePref===TRUE){
                $result[str_replace($prefix, "", $key)] = $array[$key];
            }
            elseif($remplacePref!==FALSE && $remplacePref!==""){
                $result[str_replace($prefix, $remplacePref, $key)] = $array[$key];
            }
            else{
                $result[$key] = $array[$key];
            }               
        }
    }
    return $result;
}

Then simply call with $myArray = GetPrefixedItemsFromArray($POST, "empl");.

Pacificia answered 17/2, 2014 at 10:48 Comment(0)
D
0

Starting from PHP 5.6 you can use array_filter along with the option ARRAY_FILTER_USE_KEY.

$employee = array_filter(filter_input_array(INPUT_POST), function($key) {
  return strpos($key, 'empl_') === 0;
}, ARRAY_FILTER_USE_KEY);

For security concerns, you may add FILTER_SANITIZE_* to the filter_input_array function according to your needs, accessing $_POST directly is disadvised and filter_input_array without second parameter falls back to FILTER_UNSAFE_RAW.

Downwards answered 4/10, 2018 at 8:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.