Skip to content

Instantly share code, notes, and snippets.

@DriftwoodJP
Forked from Thingmand/array-to-texttable.php
Last active December 20, 2015 05:29
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save DriftwoodJP/6078532 to your computer and use it in GitHub Desktop.
PHP: Array to Text Table Generation Class Japanese Multibyte
<?php
/**
* Array to Text Table Generation Class
*
* @author Tony Landis <tony@tonylandis.com>
* @link http://www.tonylandis.com/
* @copyright Copyright (C) 2006-2009 Tony Landis
* @license http://www.opensource.org/licenses/bsd-license.php
*/
class ArrayToTextTable
{
/**
* @var array The array for processing
*/
private $rows;
/**
* @var int The column width settings
*/
private $cs = array();
/**
* @var int The Row lines settings
*/
private $rs = array();
/**
* @var int The Column index of keys
*/
private $keys = array();
/**
* @var int Max Column Height (returns)
*/
private $mH = 2;
/**
* @var int Max Row Width (chars)
*/
private $mW = 30;
private $head = false;
private $pcen = "+";
private $prow = "-";
private $pcol = "|";
/**
* @var string Text encoding
*/
private $encoding = 'UTF-8';
/** Prepare array into textual format
*
* @param array $rows The input array
* @param bool $head Show heading
* @param int $maxWidth Max Column Height (returns)
* @param int $maxHeight Max Row Width (chars)
*/
public function ArrayToTextTable($rows)
{
$this->rows =& $rows;
$this->cs=array();
$this->rs=array();
if(!$xc = count($this->rows)) return false;
$this->keys = array_keys($this->rows[0]);
$columns = count($this->keys);
for($x=0; $x<$xc; $x++)
for($y=0; $y<$columns; $y++)
$this->setMax($x, $y, $this->rows[$x][$this->keys[$y]]);
}
/**
* Show the headers using the key values of the array for the titles
*
* @param bool $bool
*/
public function showHeaders($bool)
{
if($bool) $this->setHeading();
}
/**
* Set the maximum width (number of characters) per column before truncating
*
* @param int $maxWidth
*/
public function setMaxWidth($maxWidth)
{
$this->mW = (int) $maxWidth;
}
/**
* Set the maximum height (number of lines) per row before truncating
*
* @param int $maxHeight
*/
public function setMaxHeight($maxHeight)
{
$this->mH = (int) $maxHeight;
}
/**
* Prints the data to a text table
*
* @param bool $return Set to 'true' to return text rather than printing
* @return mixed
*/
public function render($return=false)
{
if($return) ob_start(null, 0, true);
$this->printLine();
$this->printHeading();
$rc = count($this->rows);
for($i=0; $i<$rc; $i++) $this->printRow($i);
$this->printLine(false);
if($return) {
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
}
private function setHeading()
{
$data = array();
foreach($this->keys as $colKey => $value)
{
$this->setMax(false, $colKey, $value);
$data[$colKey] = strtoupper($value);
}
if(!is_array($data)) return false;
$this->head = $data;
}
private function printLine($nl=true)
{
print $this->pcen;
foreach($this->cs as $key => $val)
print $this->prow .
$this->mb_str_pad('', $val, $this->prow, STR_PAD_RIGHT) .
$this->prow .
$this->pcen;
if($nl) print "\n";
}
private function printHeading()
{
if(!is_array($this->head)) return false;
print $this->pcol;
foreach($this->cs as $key => $val)
print ' '.
$this->mb_str_pad($this->head[$key], $val, ' ', STR_PAD_BOTH) .
' ' .
$this->pcol;
print "\n";
$this->printLine();
}
private function printRow($rowKey)
{
// loop through each line
for($line=1; $line <= $this->rs[$rowKey]; $line++)
{
print $this->pcol;
for($colKey=0; $colKey < count($this->keys); $colKey++)
{
print " ";
print $this->mb_str_pad(
// $maxWidth を越えた文字をsubstrで丸めているため文字化ける
// 【変更】substr ではなく、mb_strcut を使う
mb_strcut(
$this->rows[$rowKey][$this->keys[$colKey]],
($this->mW * ($line-1)),
$this->mW,
$this->encoding),
$this->cs[$colKey],
' ',
STR_PAD_RIGHT);
print " " . $this->pcol;
}
print "\n";
}
}
private function setMax($rowKey, $colKey, &$colVal)
{
// $colVal の文字数を数える
// 【変更】SJISに変換し、全角を2文字と数える
$w = strlen(mb_convert_encoding($colVal, "sjis", "auto"));
$h = 1;
if($w > $this->mW)
{
$h = ceil($w % $this->mW);
if($h > $this->mH) $h=$this->mH;
$w = $this->mW;
}
if(!isset($this->cs[$colKey]) || $this->cs[$colKey] < $w)
$this->cs[$colKey] = $w;
if($rowKey !== false && (!isset($this->rs[$rowKey]) || $this->rs[$rowKey] < $h))
$this->rs[$rowKey] = $h;
}
// Multibyte str_pad function
private function mb_str_pad ($input, $pad_length, $pad_string, $pad_style)
{
return str_pad(
$input,
// strlen でバイト数を数えているが、日本語全角は2-3byte
// 【変更】SJISに変換し、全角を2文字と数える
strlen(mb_convert_encoding($input, "sjis", "auto"))
- mb_strlen($input,$this->encoding)
+ $pad_length,
$pad_string,
$pad_style);
}
}
?>
@DriftwoodJP
Copy link
Author

日本語全角文字が混ざっていても、罫線がずれたり、文字化けしないように修正してみました。

@DriftwoodJP
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment