我通过Windows身份验证登录用户,然后将该用户的权限存储在会话变量中。我在数据库中使用分隔的权限存储方法,即:
$rights //retrieved from database
= 'read,edit,delete,admin'
所以我的问题应该是我;
//generate variable
$_SESSION['userrights'] = $rights ($rights is retrieved from database)
//use strpos to find if right is allowed
if (strpos($_SESSION['userrights'],"admin") !== false) { // do the function }
OR
//make array of rights
$_SESSION['userrights'] = explode(',',$rights)
//use in_array to find if right is allowed
if (in_array("admin",$_SESSION['userrights'])) { // do the function }
OCD问题的一点,因为我认为差异对于我正在做的事情来说几乎可以忽略不计,但这会更快(使用更少的资源)方法?
除了侮辱我的权利存储方法之外,任何答案都会受到赞赏!
答案 0 :(得分:11)
由于我经常使用大型数据集,我会在关联数组上使用isset
或!empty
并检查密钥,就像@Barmar建议的那样。以下是Intel®Core™i3-540(3.06 GHz)的快速1M基准测试
$test = array("read", "edit", "delete", "admin");
echo "<pre>";
// --- strpos($rights,$test[$i%4]) ---
$rights = 'read,edit,delete,admin';
$mctime = microtime(true);
for($i=0; $i<=1000000; $i++) { if (strpos($rights,$test[$i%4]) !== false) { }}
echo ' strpos(... '.round(microtime(true)-$mctime,3)."s\n";
// --- in_array($test[$i%4],$rights) ---
$rights = array("read", "edit", "delete", "admin");
$mctime = microtime(true);
for($i=0; $i<=1000000; $i++) { if (in_array($test[$i%4],$rights)) { }}
echo 'in_array(... '.round(microtime(true)-$mctime,3)."s\n";
// --- !empty($rights[$test[$i%4]]) ---
$rights = array('read' => 1, 'edit' => 1, 'delete' => 1, 'admin' => 1);
$mctime = microtime(true);
for($i=0; $i<=1000000; $i++) { if (!empty($rights[$test[$i%4]])) { }}
echo ' !empty(... '.round(microtime(true)-$mctime,3)."s\n";
// --- isset($rights[$test[$i%4]]) ---
$rights = array('read' => 1, 'edit' => 1, 'delete' => 1, 'admin' => 1);
$mctime = microtime(true);
for($i=0; $i<=1000000; $i++) { if (isset($rights[$test[$i%4]])) { }}
echo ' isset(... '.round(microtime(true)-$mctime,3)."s\n\n";
echo "</pre>";
获胜者是isset
:
strpos(... 0.393s
in_array(... 0.519s
!empty(... 0.232s
isset(... 0.209s
答案 1 :(得分:5)
strpos是搜索文本指针的最快方法,php.net网站:
If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos()....
答案 2 :(得分:1)
证明strpos
不是最快的方法,但速度超过in_array
的基准:
<?php
echo phpversion() . PHP_EOL;
// build random array
$array = array_fill(0, 10000, 16);
$array = array_map('openssl_random_pseudo_bytes', $array);
$array = array_map('bin2hex', $array);
$array_flipped = array_flip($array);
$string = implode($array);
$random_keys = array_rand($array_flipped, 10);
$loops = 10000;
$start = microtime(true);
for ($i = 0; $i < $loops; $i++) {
strpos($string, $random_keys[ rand(0, 9) ]);
}
echo __LINE__ . ': ' . round(microtime(true) - $start, 5) . PHP_EOL;
$start = microtime(true);
for ($i = 0; $i < $loops; $i++) {
in_array($random_keys[ rand(0, 9) ], $array);
}
echo __LINE__ . ': ' . round(microtime(true) - $start, 5) . PHP_EOL;
$start = microtime(true);
for ($i = 0; $i < $loops; $i++) {
isset($array_flipped[ $random_keys[ rand(0, 9) ] ]);
}
echo __LINE__ . ': ' . round(microtime(true) - $start, 5) . PHP_EOL;
$start = microtime(true);
for ($i = 0; $i < $loops; $i++) {
$array_flipped = array_flip($array);
isset($array_flipped[ $random_keys[ rand(0, 9) ] ]);
}
echo __LINE__ . ': ' . round(microtime(true) - $start, 5) . PHP_EOL;
?>
结果:
5.6.31
19: 1.11484
25: 1.3109
31: 0.00237
38: 13.64204
正如您所看到的那样,重要的是不要动态地翻转数组以从isset
中受益。
答案 3 :(得分:-1)
如果数据库中存在$_SESSION['userrights']
,您是否考虑过对数据库进行查询的可能性?您已经在查询以获取示例中的权限列表,为什么不查询特定的$_SESSION['userrights']
并检查是否有任何行返回?