针对二维数组,模拟SQL方式查数据
核心类
/**
* 数组模型,可模拟数据库做字段筛选、排序、分组、聚合运算操作
* Class ArrayModel
* @package sdk\func
*/
class ArrayModel
{
const GROUP_KEY = '_group_';
const GROUP_CONCAT_KEY = '_group_concat_';
private $grouped = false;
private $tmpArray = [];
/**
* 转入二维数组数据
* @param $data
* @return ArrayModel
*/
public static function data($data){
return new ArrayModel($data);
}
/**
* @param $array
* @return ArrayModel $this
*/
private function __construct($array)
{
$this->tmpArray =$array;
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function eq($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return $item[$key] == $val;
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function ge($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return $item[$key] >= $val;
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function le($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return $item[$key] <= $val;
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function gt($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return $item[$key] > $val;
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function lt($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return $item[$key] < $val;
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function in($key, $val)
{
if ($this->testKey($key)) {
if (is_string($val)) {
$val = explode(',', $val);
}
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return in_array($item[$key], $val);
});
}
return $this;
}
/**
* @param $key
* @param $val
* @return $this
*/
public function like($key, $val)
{
if ($this->testKey($key)) {
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val) {
return strstr($item[$key], $val);
});
}
return $this;
}
/**
* @param $key
* @param $val1
* @param $val2
* @return void
*/
public function between($key, $val1, $val2)
{
$this->tmpArray = array_filter($this->tmpArray, function ($item) use ($key, $val1, $val2) {
return $item[$key] >= $val1 && $item[$key] <= $val2;
});
}
/**
* @param $key
* @return number
*/
public function max($key)
{
$tmp = array_column($this->tmpArray, $key);
return max($tmp);
}
/**
* @param $key
* @return number
*/
public function min($key)
{
$tmp = array_column($this->tmpArray, $key);
return min($tmp);
}
/**
* @param $key
* @return number|array
*/
public function count($key='*')
{
if($this->grouped){
$keyAlia = $key = trim($key);
if(strstr($key,' ')){
$arr = explode(' ',$key,2);
$key = $arr[0];
$keyAlia = $arr[1];
}
foreach ($this->tmpArray as $idx => &$item){
$group = array_column($item[self::GROUP_KEY],$key);
if(count($group)>0){
$item[$keyAlia] = count($group);
}
unset($item[self::GROUP_KEY]);
}
return $this->tmpArray;
}else{
return count($this->tmpArray);
}
}
/**
* 取和,带group操作的会返回数组
* @param $key
* @return array|float|int
*/
public function sum($key)
{
if ($this->testKey($key)) {
if($this->grouped){
foreach ($this->tmpArray as $idx => &$item){
$group = array_column($item[self::GROUP_KEY],$key);
if(count($group)>0){
$item[$key] = round(array_sum($group),2,PHP_ROUND_HALF_UP);
}
unset($item[self::GROUP_KEY]);
}
return $this->tmpArray;
}else{
$tmp = array_column($this->tmpArray, $key);
return array_sum($tmp);
}
}
return 0;
}
/**
* 取平均值,带group操作的会返回数组
* @param $key
* @return array|float|int
*/
public function avg($key)
{
if ($this->testKey($key)) {
if($this->grouped){
foreach ($this->tmpArray as $idx => &$item){
$group = array_column($item[self::GROUP_KEY],$key);
if(count($group)>0){
$item[$key] = bcdiv(array_sum($group),count($group),2);
}
unset($item[self::GROUP_KEY]);
}
return $this->tmpArray;
}else{
$tmp = array_column($this->tmpArray, $key);
$count = count($tmp);
if ($count <= 0) {
return 0;
} else {
return array_sum($tmp) / $count;
}
}
}
return 0;
}
/**
* @param $key
* @param string $concat
* @param string $sep
* @param string $sep2
* @return $this
*/
public function group($key,$concat='',$sep='|',$sep2=',')
{
if ($this->testKey($key)) {
if($concat){
if(is_string($concat)){
$concat = explode(',',$concat);
}
}
$tmp = [];
foreach ($this->tmpArray as $item) {
if($item[$key]){
if (!array_key_exists($item[$key], $tmp)) {
$tmp[$item[$key]] = [];
}
if(array_key_exists($item[$key], $tmp)){
$tmp[$item[$key]][] = $item;
}
}
}
$rows = [];
foreach ($tmp as $k=>$v){
$row = $v[0];
$row[self::GROUP_KEY] = $v;
if($concat){
$concatArr = [];
foreach ($v as $vv){
$_concat = [];
foreach ($vv as $idx=>$val){
if(in_array($idx,$concat)){
$_concat[] = $val;
}
}
$_concat = implode($sep2,$_concat);
$concatArr[] = $_concat;
}
$row[self::GROUP_CONCAT_KEY] = implode($sep,$concatArr);
}
$rows[] = $row;
}
$this->tmpArray = $rows;
$this->grouped = true;
unset($tmp,$rows);
}
return $this;
}
/**
* @param $key
* @param string $type
* @return $this
*/
public function order($key,$type='asc'){
if ($this->testKey($key)) {
usort($this->tmpArray,function($a,$b) use($key,$type){
$val1 = $a[$key];
$val2 = $b[$key];
if(!is_numeric($val1)){
if($type=='asc'){
return strcmp($val1,$val2);
}else{
return strcmp($val2,$val1);
}
}else{
if($type=='asc'){
return $a[$key] - $b[$key];
}else{
return $b[$key] - $a[$key];
}
}
});
}
return $this;
}
/**
* 返回第一条数据
* @return mixed
*/
public function find(){
return reset($this->tmpArray);
}
/**
* 返回列表
* @return array
*/
public function select(){
foreach ($this->tmpArray as &$row){
if (array_key_exists(self::GROUP_KEY, $row)) {
unset($row[self::GROUP_KEY]);
}
}
return $this->tmpArray;
}
/**
* @param $key
* @return mixed
*/
public function getField($key){
return $this->find()[$key];
}
/**
* @param string $key
* @return $this
*/
public function field($key='*'){
if($key!='*'){
$keys = explode(',',$key);
foreach ($this->tmpArray as &$row){
foreach ($row as $idx=> $col){
if(!in_array($idx,$keys)){
unset($row[$idx]);
}
}
}
}
return $this;
}
/**
* @param int $start 开始或长度
* @param null $size 长度
* @return $this
*/
public function limit($start, $size=null){
if(!$size){
$size = $start;
$start = 0;
}
if(count($this->tmpArray) > $start){
$this->tmpArray = array_slice($this->tmpArray,$start,$size);
}
return $this;
}
/**
* @param $key
* @return bool
*/
private function testKey($key)
{
return $this->tmpArray && in_array($key, array_keys($this->tmpArray));
}
private function filter()
{
}
}
使用示例
class DemoController{
public function testModelOp()
{
$data = Model('market')->select();
//限制条数
var_dump(ArrayModel::data($data)->limit(5,5)->select());
//分组拼接
var_dump(ArrayModel::data($data)->field('market_id,market_name_zh_cn,lang,currency')->group('lang', 'market_name_zh_cn,currency')->select());
//分组计算总数
var_dump(ArrayModel::data($data)->field('market_id,market_name_zh_cn,lang')->group('lang')->count('market_id counts'));
//取和
var_dump(ArrayModel::data($data)->sum('market_id'));
//均值
var_dump(ArrayModel::data($data)->avg('market_id'));
//按字段排序
var_dump(ArrayModel::data($data)->field('market_id,market_name_zh_cn,country_id')->order('country_id')->select());
//按字段反序
var_dump(ArrayModel::data($data)->field('market_id,market_name_zh_cn,country_id')->order('country_id', 'desc')->select());
}
} 
评论列表(1条)