var_export([
'count([132, 21, 3836, 7874])' => count([132, 21, 3836, 7874]),
'count(["xx", "yy", "zz"])' => count(["xx", "yy", "zz"]),
'count(false)' => count(false),
'count(true)' => count(true),
'count(0)' => count(0),
'count(1)' => count(1),
'count(3)' => count(3),
'count("abc")' => count("abc"),
'count($obj)' => count(new stdClass()),
'count(null)' => count(null),
官方的count函数手册 在返回值里提到:如果 var 不是数组类型或者实现了Countable 接口的对象,将返回 1,有一个例外,如果 var 是 NULL 则结果是 0
(相关阅读:官方手册 - Countable接口)
所以估计你要抽空审查一下以前用过的count函数了,只要count的参数不是个数组就会出问题
常见场景:
db类的查询代码是这样设计的:
public function select(){
$data = $this->query($this->buildSql());
if($data){
return $data;
}else{
return false;
然后调用的地方就这么写:
$userList = $db->table('user')->where(['sex' => 2])->select();
if(count($userList) == 0){
showMessage('没有数据');
于是其实这个count的结果永远不会为0,至少是1
解决办法:
$userList = $db->table('user')->where(['sex' => 2])->select();
if(!$userList){
showMessage('没有数据');
if(empty($userList)){
showMessage('没有数据');
跟场景1有点类似,但确实也很常见。这一般是封装了一个函数去获取某种业务数据的数据列表,而不是直接调用db去查询,主要是函数的逻辑是:如果没有数据就返回false
* 一个获取今天或最近7天新注册用户的列表
* @param int $beforeTime 距离现在多少秒,默认1个星期
* @return array|boolean
function getNewUserList($beforeTime = 604800){
$userList = $db->table('user')->where(['add_time' => time() - $beforeTime])->select();
if(!$userList){
return false;
}else{
return $userList;
//在模板里:
$newUserNums = count(getNewUserList());
if($newUserNums){ ?>
<label>一共有<?php echo $newUserNums; ?>个新用户<label>
<?php }else{ ?>
<label>这一周来都没有新用户<label>
<?php } ?>
结果就是:永远都不会提示“这一周来都没有新用户”
解决办法:
* 一个获取今天或最近7天新注册用户的列表
* @param int $beforeTime 距离现在多少秒,默认1个星期
* @return array
function getNewUserList($beforeTime = 604800){
$userList = $db->table('user')->where(['add_time' => time() - $beforeTime])->select();
if(!$userList){
return [];
}else{
return $userList;
致我的团队成员们:这就是为什么我总是要求 获取列表 这类的业务方法必须总是返回数组的原因了
被胡乱伪造的请求参数绕过简单的判断逻辑:
这是一个文章批量删除接口,服务端预期如下:
$_POST = [
'ids' => [888, 999, 101010]
然而实际上遭遇非预期格式的请求参数就报错了:
$_POST = [
'ids' => [
'搞屎你1' => 11,
'搞屎你2' => 22,
'搞屎你X' => [1, 2, 3, 45, 5, 5, 543],
$ids = post('ids');
if(count($ids) == 0){
showError('请选择要删除的文章');
$db->table('article')->where(['in', 'id', $ids])->delete();
解决办法:
$ids = (array)post('ids');
if(count($ids) == 0){
showError('请选择要删除的文章');
foreach($ids as &$id){
$id = (int)$id;
$db->table('article')->where(['in', 'id', $ids])->delete();