PHP Array交叉表实现代码

  如果使用sql语句做的话 工作量太大了,于是尝试自己写一个交叉表的类,好二话不说,我们看看代码

  

复制代码 代码如下:

  /**

  * 基本交叉表

  * @author hugh

  *

  */

  class Pivot

  {

  private $HORIZONTAL_TOTAL_FIELD = 'total';

  private $VERTICAL_TOTAL_FIELD = 'total';

  private $data;

  private $topPivot;

  private $leftPivot;

  private $measure;

  private $horizontalColumn = array ();

  private $verticalColumn = array ();

  private $pivotValue = array ();

  private $isHorizontalTotal = true;

  private $isVerticalTotal = true;

  private $horizontalTotal = null;

  private $verticalTotal = null;

  private $title = 'PivotTab';

  /**

  * 初始化交叉表

  */

  private function InitPivot()

  {

  $this->topPivot;

  foreach ( $this->data as $d )

  {

  $this->horizontalColumn [] = $d [$this->leftPivot];

  $this->verticalColumn [] = $d [$this->topPivot];

  }

  $this->horizontalColumn = array_unique ( $this->horizontalColumn );

  $this->verticalColumn = array_unique ( $this->verticalColumn );

  $reasult = array ();

  foreach ( $this->horizontalColumn as $h )

  {

  foreach ( $this->verticalColumn as $v )

  {

  $this->pivotValue [$h] [$v] = 0;

  }

  }

  }

  /**

  * 填充数据

  */

  private function fillData()

  {

  foreach ( $this->data as $row )

  {

  $this->pivotValue [$row [$this->leftPivot]] [$row [$this->topPivot]] += $row [$this->measure];

  }

  if ($this->isHorizontalTotal)

  {

  $this->setHorizontalTotal ();

  }

  if ($this->isVerticalTotal)

  {

  $this->setVerticalTotal ();

  }

  }

  /**

  * 设置纵向合计

  */

  private function setVerticalTotal()

  {

  $this->verticalColumn [] = $this->VERTICAL_TOTAL_FIELD;

  foreach ( $this->horizontalColumn as $i )

  {

  $rowsum = 0;

  foreach ( $this->verticalColumn as $j )

  {

  $rowsum += $this->pivotValue [$i] [$j];

  }

  $this->pivotValue [$i] [$this->TOTAL_FIELD] = $rowsum;

  }

  }

  /**

  * 设置横向合计

  */

  private function setHorizontalTotal()

  {

  $this->horizontalColumn [] = $this->HORIZONTAL_TOTAL_FIELD;

  foreach ( $this->verticalColumn as $i )

  {

  $rowsum = 0;

  foreach ( $this->horizontalColumn as $j )

  {

  $rowsum += $this->pivotValue [$j] [$i];

  }

  $this->pivotValue [$this->HORIZONTAL_TOTAL_FIELD] [$i] = $rowsum;

  }

  }

  /**

  * 渲染

  */

  function Render()

  {

  echo '<pre>';

  print_r ( $this->pivotValue );

  }

  /**

  * 渲染为table

  */

  function RenderToTable()

  {

  $resault = "<table border='1' width='250'>\n";

  $resault .= "<tr><td>$this->title</td>\n";

  foreach ( $this->verticalColumn as $value )

  {

  $resault .= "<td>$value</td>\n";

  }

  $resault .= "</tr>\n";

  foreach ( $this->horizontalColumn as $i )

  {

  $resault .= "<tr><td>$i</td>\n";

  foreach ( $this->pivotValue [$i] as $value )

  {

  $resault .= "<td>$value</td>\n";

  }

  $resault .= "</tr>\n";

  }

  $resault .= "</table>";

  return $resault;

  }

  /**

  * 构造交叉表

  * @param $data 数据源

  * @param $topPivot 头栏目字段

  * @param $leftPivot 左栏目字段

  * @param $measure 计算量

  */

  function __construct(array $data, $topPivot, $leftPivot, $measure)

  {

  $this->data = $data;

  $this->leftPivot = $leftPivot;

  $this->topPivot = $topPivot;

  $this->measure = $measure;

  $this->horizontalColumn = array ();

  $this->verticalColumn = array ();

  $this->InitPivot ();

  $this->fillData ();

  }

  }

  重点在于InitPivot方法及fillData方法。

  InitPivot里面保证了所有的item都会有值(默认为0)

  fillData方法使用选择填充添加的方法,将数据填充入我们装数据的$pivotValue里面。

  然后喜欢怎么输出都可以了