簡體   English   中英

PHP 檢查數組是否包含白名單以外的任何鍵

[英]PHP check if array contains any key other than some whitelisted

我想檢查全局 GET 數組的所有鍵並做一些事情,如果它包含鍵,而不是數組中一些列入白名單的鍵。

假設當前的 url 是:

.../index.php?randomekey1=valueX&randomkey2=valueY&acceptedkey1=valueZ&randomkey3=valueA&acceptedkey2=valueB

只是為了更好的可視化:這些 GET 參數都在全局 GET 變量中可用,看起來像這樣:

$GET = array(
    "randomekey1" => "valueX",
    "randomkey2" => "valueY",
    "acceptedkey1" => "valueZ",
    "randomkey3" => "valueA",
    "acceptedkey2" => "valueB"
);

我接受並希望通過的密鑰,我也放入了一個數組中:

$whitelist = array(
    "acceptedkey1",
    "acceptedkey2",
    "acceptedkey3",
);

現在我想檢查 $GET 是否包含白名單以外的任何密鑰。 因此,在上面的 URL 示例中,它應該返回“true”,因為 $GET 數組中的鍵不在白名單中。

這樣一個未知(未列入白名單)密鑰的存在不僅應該觸發 true,而且還應該為空!


另一個示例是以下 url:

.../index.php?acceptedkey1=valueZ&acceptedkey3=valueB

這應該返回 false,因為除了白名單中的密鑰之外沒有找到其他密鑰。

不幸的是,我無法找到符合這些要求的 in_array function 或 array_search 的任何修改,因為據我所知,這些功能只是在尋找特定的東西,而在我的要求中,我也在尋找特定的東西(白名單鍵),但同時我必須檢查是否存在一些未知的鍵。

謝謝你。

似乎您想確定數組是否包含白名單中不存在的鍵。
找到數組之間差異的一種方法是使用array_diff()

array_diff(array $ array1,array $ array2 [,array $ ...]):數組
返回一個數組,其中包含array1中所有其他數組中不存在的所有條目。

因此,它可以用於從URL中返回白名單中不存在的所有鍵:

$extrasExist = !empty( array_diff( array_keys($GET), $whitelist ) );
var_dump($extrasExist);

這是一個示范:

$get1 = array(
    "randomekey1" => "valueX",
    "randomkey2" => "valueY",
    "acceptedkey1" => "valueZ",
    "randomkey3" => "valueA",
    "acceptedkey2" => "valueB"
);

$get2 = array(
    "acceptedkey1" => "valueZ",
    "acceptedkey2" => "valueB"
);

$whitelist = array(
    "acceptedkey1",
    "acceptedkey2",
    "acceptedkey3"
);

$extrasExist = !empty(array_diff(array_keys($get1),$whitelist));
var_dump($extrasExist);

$extrasExist = !empty(array_diff(array_keys($get2),$whitelist));
var_dump($extrasExist);

布爾(真)
布爾(假)

PHP中的所有內容都不必全部都是“讓查找功能完全符合我的期望”。 只需執行一個簡單的foreach循環即可完成您要查找的內容:

function clear_filter() {
    $whitelist = array( "project", "table_name", "filterDates", );
    foreach ($_GET as $gkey => $gval) {
        if (!in_array($gkey, $whitelist)) {
            return false;
        }
    }
    return true;
}

您還可以使用如下所示的一個foreach循環來更簡單地編寫它:

function isValid() {
    // Copy the array
    $temp = $_GET;

    // Loop through the array, and remove any whitelisted elements
    foreach ($whitelist as $wkey) {
        unset($temp[$wkey]);
    }
    // If count($temp) > 0, there are non whitelisted entries in the array.
    return count($temp) === 0;
}

您可以使用以下功能。

$check = checkWhitliest( $_GET, $whitelist ) );
var_dump ($check );

您可以將上述函數調用為

function checkWhitliest( $array, $whitelist ) {

    $allKeys = array_keys ( $array); //Get all Keys from the array.
    $diff = array_diff( $allKeys, $whitelist); //Get the values which are not in whitelist.
    if( count ( $diff ) > 0 ) {     //If the count is greater than 0, then there are certain extra kesy in $_GET
        return true;
    }
    return false;

}

對於此任務,我只推薦兩種技術,並且都出於性能原因進行了關鍵比較。 使用array_diff()in_array()總是比array_diff_key()isset()慢,因為 PHP 如何將 arrays 視為 hash 映射。

如果您不介意迭代整個$GET數組(因為它的數據相對較小),那么您可以簡潔地翻轉白名單數組並檢查任何關鍵差異。

var_export(
    (bool)array_diff_key($GET, array_flip($whitelist))
);

如果性能比代碼簡潔更重要,那么您應該設計一種技術,在遇到非白名單鍵時立即使用條件breakreturn ——這可以避免在確定結果后進行無意義的迭代。

$hasNotWhitelisted = false;
$lookup = array_flip($whitelist);
foreach ($GET as $key => $value) {
    if (isset($lookup[$key])) {
        $hasNotWhitelisted = true;
        break;
    }
}
var_export($hasNotWhitelisted);

或者

function hasNotWhitelisted($array, $whitelist): bool {
    $lookup = array_flip($whitelist);
    foreach ($array as $key => $value) {
        if (isset($lookup[$key])) {
            return true;
        }
    }
    return false;
}
var_export(hasNotWhitelisted($GET, $whitelist));

上述所有技術都為示例數據提供了true的結果。 所有三個片段的演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM