Server : nginx/1.20.1 System : Linux iZ2ze9ojcl78uluczwag69Z 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64 User : www ( 1000) PHP Version : 7.3.28 Disable Function : passthru,exec,system,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv Directory : /www/wwwroot/0531yanglao.com/vendor/topthink/framework/src/think/console/ |
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: yunwuxin <448901948@qq.com> // +---------------------------------------------------------------------- declare (strict_types = 1); namespace think\console; class Table { const ALIGN_LEFT = 1; const ALIGN_RIGHT = 0; const ALIGN_CENTER = 2; /** * 头信息数据 * @var array */ protected $header = []; /** * 头部对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER * @var int */ protected $headerAlign = 1; /** * 表格数据(二维数组) * @var array */ protected $rows = []; /** * 单元格对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER * @var int */ protected $cellAlign = 1; /** * 单元格宽度信息 * @var array */ protected $colWidth = []; /** * 表格输出样式 * @var string */ protected $style = 'default'; /** * 表格样式定义 * @var array */ protected $format = [ 'compact' => [], 'default' => [ 'top' => ['+', '-', '+', '+'], 'cell' => ['|', ' ', '|', '|'], 'middle' => ['+', '-', '+', '+'], 'bottom' => ['+', '-', '+', '+'], 'cross-top' => ['+', '-', '-', '+'], 'cross-bottom' => ['+', '-', '-', '+'], ], 'markdown' => [ 'top' => [' ', ' ', ' ', ' '], 'cell' => ['|', ' ', '|', '|'], 'middle' => ['|', '-', '|', '|'], 'bottom' => [' ', ' ', ' ', ' '], 'cross-top' => ['|', ' ', ' ', '|'], 'cross-bottom' => ['|', ' ', ' ', '|'], ], 'borderless' => [ 'top' => ['=', '=', ' ', '='], 'cell' => [' ', ' ', ' ', ' '], 'middle' => ['=', '=', ' ', '='], 'bottom' => ['=', '=', ' ', '='], 'cross-top' => ['=', '=', ' ', '='], 'cross-bottom' => ['=', '=', ' ', '='], ], 'box' => [ 'top' => ['┌', '─', '┬', '┐'], 'cell' => ['│', ' ', '│', '│'], 'middle' => ['├', '─', '┼', '┤'], 'bottom' => ['└', '─', '┴', '┘'], 'cross-top' => ['├', '─', '┴', '┤'], 'cross-bottom' => ['├', '─', '┬', '┤'], ], 'box-double' => [ 'top' => ['╔', '═', '╤', '╗'], 'cell' => ['║', ' ', '│', '║'], 'middle' => ['╠', '─', '╪', '╣'], 'bottom' => ['╚', '═', '╧', '╝'], 'cross-top' => ['╠', '═', '╧', '╣'], 'cross-bottom' => ['╠', '═', '╤', '╣'], ], ]; /** * 设置表格头信息 以及对齐方式 * @access public * @param array $header 要输出的Header信息 * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER * @return void */ public function setHeader(array $header, int $align = 1): void { $this->header = $header; $this->headerAlign = $align; $this->checkColWidth($header); } /** * 设置输出表格数据 及对齐方式 * @access public * @param array $rows 要输出的表格数据(二维数组) * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER * @return void */ public function setRows(array $rows, int $align = 1): void { $this->rows = $rows; $this->cellAlign = $align; foreach ($rows as $row) { $this->checkColWidth($row); } } /** * 设置全局单元格对齐方式 * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER * @return $this */ public function setCellAlign(int $align = 1) { $this->cellAlign = $align; return $this; } /** * 检查列数据的显示宽度 * @access public * @param mixed $row 行数据 * @return void */ protected function checkColWidth($row): void { if (is_array($row)) { foreach ($row as $key => $cell) { $width = mb_strwidth((string) $cell); if (!isset($this->colWidth[$key]) || $width > $this->colWidth[$key]) { $this->colWidth[$key] = $width; } } } } /** * 增加一行表格数据 * @access public * @param mixed $row 行数据 * @param bool $first 是否在开头插入 * @return void */ public function addRow($row, bool $first = false): void { if ($first) { array_unshift($this->rows, $row); } else { $this->rows[] = $row; } $this->checkColWidth($row); } /** * 设置输出表格的样式 * @access public * @param string $style 样式名 * @return void */ public function setStyle(string $style): void { $this->style = isset($this->format[$style]) ? $style : 'default'; } /** * 输出分隔行 * @access public * @param string $pos 位置 * @return string */ protected function renderSeparator(string $pos): string { $style = $this->getStyle($pos); $array = []; foreach ($this->colWidth as $width) { $array[] = str_repeat($style[1], $width + 2); } return $style[0] . implode($style[2], $array) . $style[3] . PHP_EOL; } /** * 输出表格头部 * @access public * @return string */ protected function renderHeader(): string { $style = $this->getStyle('cell'); $content = $this->renderSeparator('top'); foreach ($this->header as $key => $header) { $array[] = ' ' . str_pad($header, $this->colWidth[$key], $style[1], $this->headerAlign); } if (!empty($array)) { $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL; if (!empty($this->rows)) { $content .= $this->renderSeparator('middle'); } } return $content; } protected function getStyle(string $style): array { if ($this->format[$this->style]) { $style = $this->format[$this->style][$style]; } else { $style = [' ', ' ', ' ', ' ']; } return $style; } /** * 输出表格 * @access public * @param array $dataList 表格数据 * @return string */ public function render(array $dataList = []): string { if (!empty($dataList)) { $this->setRows($dataList); } // 输出头部 $content = $this->renderHeader(); $style = $this->getStyle('cell'); if (!empty($this->rows)) { foreach ($this->rows as $row) { if (is_string($row) && '-' === $row) { $content .= $this->renderSeparator('middle'); } elseif (is_scalar($row)) { $content .= $this->renderSeparator('cross-top'); $width = 3 * (count($this->colWidth) - 1) + array_reduce($this->colWidth, function ($a, $b) { return $a + $b; }); $array = str_pad($row, $width); $content .= $style[0] . ' ' . $array . ' ' . $style[3] . PHP_EOL; $content .= $this->renderSeparator('cross-bottom'); } else { $array = []; foreach ($row as $key => $val) { $width = $this->colWidth[$key]; // form https://github.com/symfony/console/blob/20c9821c8d1c2189f287dcee709b2f86353ea08f/Helper/Table.php#L467 // str_pad won't work properly with multi-byte strings, we need to fix the padding if (false !== $encoding = mb_detect_encoding((string) $val, null, true)) { $width += strlen((string) $val) - mb_strwidth((string) $val, $encoding); } $array[] = ' ' . str_pad((string) $val, $width, ' ', $this->cellAlign); } $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL; } } } $content .= $this->renderSeparator('bottom'); return $content; } }