findAll 与 find 的返回数组改进

#1 redguan

find 返回一条数组。
应该是这样的格式

 
array(
'uid'=>1
'username'=>'admin'
);


而非:

 
array(
0=>array('uid'=>1,'username'=>'admin')
);


findAll 是返回一个多维数组。
根的KEY 应该是主键而非自动加1的数字

SPMODEL.PHP 修改

 
array(
1=>array('uid'=>1,'username'=>'admin');
4=>array('uid'=>4,'username'=>'demo');
);


 
/**
*返回的数组转换成以主键作为数组索引
*
*
**/
protected function changePk($arr){
  foreach($arr as $data)$arr2[$data[$this->pk]] = $data;
  return $arr2;
}
/*
*
*返回的数组转换成单条数组形式
*
*/
protected function changeOne($arr){
  foreach ($arr[0] as $k =>$d) $arr2[$k]=$d;
  return $arr2;
}

protected function make_find_sql($conditions = null, $sort = null, $fields = null, $limit = null){
  $where = "";
  $fields = empty($fields) ? "*" : $fields;
  if(is_array($conditions)){
   $join = array();
   foreach( $conditions as $key => $condition ){
    $condition = $this->__val_escape($condition);
    $join[] = "{$key} = '{$condition}'";
   }
   $where = "WHERE ".join(" AND ",$join);
  }else{
   if(null != $conditions)$where = "WHERE ".$conditions;
  }
  if(null != $sort)$sort = "ORDER BY {$sort}";
  if(null != $limit)$limit = "LIMIT {$limit}";
  $sql = "SELECT {$this->tbl_name}.{$fields} FROM {$this->tbl_name} {$where} {$sort} {$limit}";
  return  $this->_db->getArray($sql);
}
/**
  * 从数据表中查找一条记录
  *
  * @param conditions    查找条件,数组array("字段名"=>"查找值")或字符串,
  * 请注意在使用字符串时将需要开发者自行使用__val_escape来对输入值进行过滤
  * @param sort    排序,等同于“ORDER BY ”
  * @param fields    返回的字段范围,默认为返回全部字段的值
  */
public function find($conditions = null, $sort = null, $fields = null)
{
  return $this->changeOne($this->make_find_sql($conditions, $sort, $fields, 1));
  /*
  if( $record = $this->findAll($conditions, $sort, $fields, 1) ){
   return array_pop($record);
  }else{
   return FALSE;
  }
  */
}

/**
  * 从数据表中查找记录
  *
  * @param conditions    查找条件,数组array("字段名"=>"查找值")或字符串,
  * 请注意在使用字符串时将需要开发者自行使用__val_escape来对输入值进行过滤
  * @param sort    排序,等同于“ORDER BY ”
  * @param fields    返回的字段范围,默认为返回全部字段的值
  * @param limit    返回的结果数量限制,等同于“LIMIT ”,如$limit = " 3, 5",即是从第3条记录开始获取,共获取5条记录
  */
public function findAll($conditions = null, $sort = null, $fields = null, $limit = null)
{
  return $this->changePk($this->make_find_sql($conditions, $sort, $fields, $limit));
}
/**
  * 过滤转义字符
  *
  * @param value 需要进行过滤的值
  */
public function __val_escape($value)
{
  return $this->_db->__val_escape($value);
}


仅供参考

2010-05-26 16:05:20

#2 jake

以上代码建议不要使用,避免引起问题。

1. find的返回就是如同楼主希望的一样的,所以没有改进的说法。
2. findAll返回的数组,键值并非1,2,3。。。而是自动编值,这符合既定逻辑,如果是返回按主键的键值,那么会引起很多问题,比如说排序不能用,还有使用上让人无法适从。而且,这样的返回结果,在实际应用中无任何意义,毕竟在数组内,也同样有着主键值在里面。

2010-05-26 16:44:52

#3 redguan

其实为什么用主键,有一个简单的应用问题。

$category 是一个分类的数组。如果是主键排序。那么通过URL传过来的cid=120
$category[$cid] 就能获得该分类的信息。

如果是按默认自动加1。那就要每次都foreach 一次。我觉得前者应用效率高一些。

2010-05-26 16:50:03

#4 jake

其实为什么用主键,有一个简单的应用问题。

$category 是一个分类的数组。如果是主键排序。那么通过URL传 ...
redguan 发表于 2010-5-26 16:50
类似这种情况,一般会直接通过ID到数据库内find出来结果,很少会有把整个数组的数据查出来保存到内存中再进行对比的情况。

另外,从纯学术性的角度来说:lol,数组在键值不是一个系列的时候,也就是ID:1,2,3,缺4,5,6,其中缺了一个或者几个的时候,效率反而变慢了。

2010-05-26 16:54:13

#5 redguan

类似这种情况,一般会直接通过ID到数据库内find出来结果,很少会有把整个数组的数据查出来保存到内存中再 ...
jake 发表于 2010-5-26 16:54
这样一个简单的应用,其实办法很多。

某些数据,象分类。基本上设定好极少更新。

一、每次需要都 find 一次数据库。虽然通过主键直接读取,对于数据库来说是非常快的操作。但还是增加数据库查询。
例子是,每篇文章一般都会显示位置(所在分类),每看一贴文章,就要多读一次数据库。这个资源花费还是挺高的。

二、其实更改为主键也不是一个好办法。在N年前是比较流行的写法。一般是这样应用:通过主键获得数据,然后保存在缓存了(文件或者内存变量方式)。下次调用时直接调用,不需要再循环数组,不需要查询数据库。

还是觉得,应用小型的话,例如一个企业网站,问题不大。如果本地网站的应用。任何资源花费都要考虑周详。

2010-05-27 09:42:24

#6 johnny_sun

楼主对于findAll的想法和我一样,支持一下
可以将该功能写成另一个函数,分情况使用。


另:验证码用中文真恶心

2010-07-07 14:48:03