123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <?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();
- }
- }
- }
|