Initial commit
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
namespace OT;
|
||||
class DataDictionary{
|
||||
|
||||
public function __construct($table){
|
||||
$this->headers = $table['header'];
|
||||
$this->rows = $table['rows'];
|
||||
$this->crossingChar = '+';
|
||||
$this->horizontalBorderChar = '-';
|
||||
$this->verticalBorderChar = '|';
|
||||
$this->borderFormat = '%s';
|
||||
$this->cellHeaderFormat = '%s';
|
||||
$this->cellRowFormat = '%s';
|
||||
$this->paddingChar = ' ';
|
||||
$this->padType = STR_PAD_RIGHT;
|
||||
}
|
||||
/**
|
||||
* Renders table to output.
|
||||
*
|
||||
* Example:
|
||||
* +---------------+-----------------------+------------------+
|
||||
* | ISBN | Title | Author |
|
||||
* +---------------+-----------------------+------------------+
|
||||
* | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
* +---------------+-----------------------+------------------+
|
||||
*
|
||||
*/
|
||||
public function render($out = true){
|
||||
if(!$this->rows)
|
||||
exit('invalid table content');
|
||||
//获得表头行首 +---------------+-----------------------+------------------+
|
||||
$output = $this->renderRowSeparator();
|
||||
//获取头部输出| ISBN | Title | Author |
|
||||
$output .= $this->renderRow($this->headers, $this->cellHeaderFormat);
|
||||
//header存在的话再输出行分割符
|
||||
if ($this->headers) {
|
||||
$output .= $this->renderRowSeparator();
|
||||
}
|
||||
//渲染每一行
|
||||
foreach ($this->rows as $row) {
|
||||
$output .= $this->renderRow($row, $this->cellRowFormat);
|
||||
}
|
||||
if ($this->rows) {
|
||||
$output .= $this->renderRowSeparator();
|
||||
}
|
||||
if($out){
|
||||
exit($output);
|
||||
}else{
|
||||
$this->cleanup();
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
public function renderWitoutHeadTail($out = true){
|
||||
if(!$this->rows)
|
||||
exit('invalid table content');
|
||||
//获取头部输出| ISBN | Title | Author |
|
||||
$output .= $this->renderRow($this->headers, $this->cellHeaderFormat);
|
||||
//header存在的话再输出行分割符
|
||||
if ($this->headers) {
|
||||
$output .= $this->renderRowSeparator();
|
||||
}
|
||||
//渲染每一行
|
||||
foreach ($this->rows as $row) {
|
||||
$output .= $this->renderRow($row, $this->cellRowFormat);
|
||||
}
|
||||
if($out){
|
||||
print($output);
|
||||
}else{
|
||||
$this->cleanup();
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
//渲染表格行起始分割行
|
||||
private function renderRowSeparator(){
|
||||
if (0 === $count = $this->getNumberOfColumns()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$markup = $this->crossingChar;
|
||||
for ($column = 0; $column < $count; $column++) {
|
||||
$markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column))
|
||||
.$this->crossingChar
|
||||
;
|
||||
}
|
||||
|
||||
return sprintf($this->borderFormat, $markup).PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染表格行.
|
||||
*
|
||||
* Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
*
|
||||
* @param array $row
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderRow(array $row, $cellFormat){
|
||||
if (empty($row)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$output = $this->renderColumnSeparator();
|
||||
for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
|
||||
$output .= $this->renderCell($row, $column, $cellFormat);
|
||||
$output .= $this->renderColumnSeparator();
|
||||
}
|
||||
$output .= $this->writeln('');
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 带边距的渲染单元格.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderCell(array $row, $column, $cellFormat){
|
||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||
return sprintf(
|
||||
$cellFormat,
|
||||
$this->str_pad(
|
||||
$this->paddingChar.$cell.$this->paddingChar,
|
||||
$this->getColumnWidth($column),
|
||||
$this->paddingChar,
|
||||
$this->padType
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染水平列分隔符.
|
||||
*/
|
||||
private function renderColumnSeparator(){
|
||||
return(sprintf($this->borderFormat, $this->verticalBorderChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表格的列数.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNumberOfColumns() {
|
||||
if (null !== $this->numberOfColumns) {
|
||||
return $this->numberOfColumns;
|
||||
}
|
||||
|
||||
$columns = array(0);
|
||||
$columns[] = count($this->headers);
|
||||
foreach ($this->rows as $row) {
|
||||
$columns[] = count($row);
|
||||
}
|
||||
|
||||
return $this->numberOfColumns = max($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列宽.
|
||||
*
|
||||
* @param integer $column
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getColumnWidth($column) {
|
||||
if (isset($this->columnWidths[$column])) {
|
||||
return $this->columnWidths[$column];
|
||||
}
|
||||
|
||||
$lengths = array(0);
|
||||
$lengths[] = $this->getCellWidth($this->headers, $column);
|
||||
foreach ($this->rows as $row) {
|
||||
$lengths[] = $this->getCellWidth($row, $column);
|
||||
}
|
||||
|
||||
return $this->columnWidths[$column] = max($lengths) + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单元格宽度.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getCellWidth(array $row, $column) {
|
||||
if ($column < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isset($row[$column])) {
|
||||
return $this->strlen($row[$column]);
|
||||
}
|
||||
|
||||
return $this->getCellWidth($row, $column - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of a string, using mb_strlen if it is available.
|
||||
*
|
||||
* @param string $string The string to check its length
|
||||
*
|
||||
* @return integer The length of the string
|
||||
*/
|
||||
protected function strlen($string) {
|
||||
// if (!function_exists('mb_strlen')) {
|
||||
return (strlen($string) + mb_strlen($string,'UTF8')) / 2;
|
||||
// }
|
||||
|
||||
// if (false === $encoding = mb_detect_encoding($string)) {
|
||||
// return strlen($string);
|
||||
// }
|
||||
|
||||
// return mb_strlen($string, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after rendering to cleanup cache data.
|
||||
*/
|
||||
private function cleanup(){
|
||||
$this->columnWidths = array();
|
||||
$this->numberOfColumns = null;
|
||||
}
|
||||
|
||||
public function writeln($line=''){
|
||||
return $line.PHP_EOL;
|
||||
}
|
||||
|
||||
public function str_pad($input , $pad_length ,$pad_string , $pad_type){
|
||||
$strlen = $this->strlen($input);
|
||||
if($strlen < $pad_length){
|
||||
$difference = $pad_length - $strlen;
|
||||
switch ($pad_type) {
|
||||
case STR_PAD_RIGHT:
|
||||
return $input . str_repeat($pad_string, $difference);
|
||||
break;
|
||||
case STR_PAD_LEFT:
|
||||
return str_repeat($pad_string, $difference) . $input;
|
||||
break;
|
||||
default:
|
||||
$left = $difference / 2;
|
||||
$right = $difference - $left;
|
||||
return str_repeat($pad_string, $left) . $input . str_repeat($pad_string, $right);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
||||
//生成当前数据库指定表的数据字典(字符串)
|
||||
public function generate($tableName=''){
|
||||
$this->crossingChar = '|';
|
||||
$out_array = array();
|
||||
$output = '';
|
||||
if($tableName){
|
||||
echo substr($tableName, strlen(C('DB_PREFIX'))).PHP_EOL;
|
||||
$rows = array();
|
||||
$array = M()->query('SHOW FULL COLUMNS FROM '.$tableName);
|
||||
foreach ($array as $key => $value) {
|
||||
$rows[] = array($value['Field'], $value['Type'], $value['Comment']);
|
||||
}
|
||||
|
||||
$this->headers = array('字段','类型','注释');
|
||||
$this->rows = $rows;
|
||||
$this->renderWitoutHeadTail();
|
||||
}
|
||||
echo PHP_EOL;
|
||||
}
|
||||
|
||||
public function generateAll(){
|
||||
$tables = M()->query('SHOW TABLE STATUS;');
|
||||
$tables = array_column($tables,'Name');
|
||||
foreach ($tables as $value) {
|
||||
$this->generate($value);
|
||||
$this->cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user