@@ -22,6 +22,7 @@ class Show
2222 const CHAR_SPACE = ' ' ;
2323 const CHAR_HYPHEN = '- ' ;
2424 const CHAR_UNDERLINE = '_ ' ;
25+ const CHAR_VERTICAL = '| ' ;
2526 const CHAR_EQUAL = '= ' ;
2627 const CHAR_STAR = '* ' ;
2728
@@ -100,19 +101,43 @@ public static function error($messages, $quit = false)
100101
101102 /**
102103 * @param string $title The title text
103- * @param int $width The title section width
104- * @param string $char
104+ * @param array $opts
105105 */
106- public static function title ($ title , $ width = 80 , $ char = self :: CHAR_EQUAL )
106+ public static function title ($ title , array $ opts = [] )
107107 {
108+ $ opts = array_merge ([
109+ 'width ' => 80 ,
110+ 'char ' => self ::CHAR_EQUAL ,
111+ 'titlePos ' => self ::POS_LEFT ,
112+ 'indent ' => 2 ,
113+ 'showBorder ' => true ,
114+ ], $ opts );
115+
116+ // list($sW, $sH) = Helper::getScreenSize();
117+ $ width = (int )$ opts ['width ' ];
118+ $ char = trim ($ opts ['char ' ]);
119+ $ indent = (int )$ opts ['indent ' ] > 0 ? $ opts ['indent ' ] : 2 ;
120+ $ indentStr = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
121+
108122 $ title = ucwords (trim ($ title ));
109- $ msgLength = mb_strlen ($ title , 'UTF-8 ' );
110- $ width = is_int ($ width ) && $ width > 10 ? $ width : 80 ;
123+ $ tLength = Helper::strLen ($ title );
124+ $ width = $ width > 10 ? $ width : 80 ;
125+
126+ // title position
127+ if ($ tLength >= $ width ) {
128+ $ titleIndent = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
129+ } elseif ($ opts ['titlePos ' ] === self ::POS_RIGHT ) {
130+ $ titleIndent = str_pad (self ::CHAR_SPACE , ceil ($ width - $ tLength ) + $ indent , self ::CHAR_SPACE );
131+ } elseif ($ opts ['titlePos ' ] === self ::POS_MIDDLE ) {
132+ $ titleIndent = str_pad (self ::CHAR_SPACE , ceil (($ width - $ tLength )/2 ) + $ indent , self ::CHAR_SPACE );
133+ } else {
134+ $ titleIndent = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
135+ }
111136
112- $ indentSpace = str_pad ( ' ' , ceil ( $ width / 2 ) - ceil ( $ msgLength / 2 ), ' ' ) ;
113- $ charStr = str_pad ($ char , $ width , $ char );
137+ $ titleLine = " $ titleIndent <bold> $ title </bold> \n" ;
138+ $ border = $ indentStr . str_pad ($ char , $ width , $ char );
114139
115- self ::write (" { $ indentSpace }{ $ title } \n { $ charStr }\n" );
140+ self ::write ($ titleLine . $ border );
116141 }
117142
118143 /**
@@ -125,42 +150,46 @@ public static function section($title, $body, array $opts = [])
125150 $ opts = array_merge ([
126151 'width ' => 80 ,
127152 'char ' => self ::CHAR_HYPHEN ,
128- 'pos ' => self ::POS_LEFT ,
153+ 'titlePos ' => self ::POS_LEFT ,
154+ 'indent ' => 2 ,
129155 'topBorder ' => true ,
130156 'bottomBorder ' => true ,
131157 ], $ opts );
132158
133159 // list($sW, $sH) = Helper::getScreenSize();
134160 $ width = (int )$ opts ['width ' ];
135161 $ char = trim ($ opts ['char ' ]);
162+ $ indent = (int )$ opts ['indent ' ] > 0 ? $ opts ['indent ' ] : 2 ;
163+ $ indentStr = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
136164
137165 $ title = ucwords (trim ($ title ));
138166 $ tLength = Helper::strLen ($ title );
139167 $ width = $ width > 10 ? $ width : 80 ;
140- $ indentSpace = '' ;
141168
142169 // title position
143170 if ($ tLength >= $ width ) {
144- $ indentSpace = '' ;
145- } elseif ($ opts ['pos ' ] === self ::POS_RIGHT ) {
146- $ indentSpace = str_pad (self ::CHAR_SPACE , ceil ($ width - $ tLength ), self ::CHAR_SPACE );
147- } elseif ($ opts ['pos ' ] === self ::POS_MIDDLE ) {
148- $ indentSpace = str_pad (self ::CHAR_SPACE , ceil (($ width - $ tLength )/2 ), self ::CHAR_SPACE );
171+ $ titleIndent = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
172+ } elseif ($ opts ['titlePos ' ] === self ::POS_RIGHT ) {
173+ $ titleIndent = str_pad (self ::CHAR_SPACE , ceil ($ width - $ tLength ) + $ indent , self ::CHAR_SPACE );
174+ } elseif ($ opts ['titlePos ' ] === self ::POS_MIDDLE ) {
175+ $ titleIndent = str_pad (self ::CHAR_SPACE , ceil (($ width - $ tLength )/2 ) + $ indent , self ::CHAR_SPACE );
176+ } else {
177+ $ titleIndent = str_pad (self ::CHAR_SPACE , $ indent , self ::CHAR_SPACE );
149178 }
150179
151- $ tpl = " %s \n%s%s \n%s " ;// title topBorder body bottomBorder
180+ $ tpl = "%s \n%s%s \n%s " ;// title topBorder body bottomBorder
152181 $ topBorder = $ bottomBorder = '' ;
153- $ titleLine = "$ indentSpace <bold> $ title</bold> " ;
182+ $ titleLine = "$ titleIndent <bold> $ title</bold> " ;
154183
155184 if ( $ opts ['topBorder ' ] || $ opts ['bottomBorder ' ]) {
156185 $ border = str_pad ($ char , $ width , $ char );
157186
158187 if ($ opts ['topBorder ' ]) {
159- $ topBorder = " $ border \n" ;
188+ $ topBorder = "{ $ indentStr } $ border \n" ;
160189 }
161190
162191 if ($ opts ['bottomBorder ' ]) {
163- $ bottomBorder = " $ border \n" ;
192+ $ bottomBorder = "{ $ indentStr } $ border \n" ;
164193 }
165194 }
166195
@@ -400,13 +429,51 @@ public static function panel($data, $title='Information Panel', $borderChar = '*
400429 * 表格数据信息展示
401430 * @param array $data
402431 * @param string $title
403- * @param bool $showBorder
404- * @return void
432+ * @param array $opts
433+ * @example
434+ *
435+ * ```
436+ * // like from database query's data.
437+ * $data = [
438+ * [ col1 => value1, col2 => value2, col3 => value3, ... ], // first row
439+ * [ col1 => value4, col2 => value5, col3 => value6, ... ], // second row
440+ * ... ...
441+ * ];
442+ * Show::table($data, 'a table');
443+ *
444+ * // use custom head
445+ * $data = [
446+ * [ value1, value2, value3, ... ], // first row
447+ * [ value4, value5, value6, ... ], // second row
448+ * ... ...
449+ * ];
450+ *
451+ * $opts = [
452+ * 'showBorder' => true,
453+ * 'tHead' => [col1, col2, col3, ...]
454+ * ];
455+ * Show::table($data, 'a table', $opts);
456+ * ```
405457 */
406- public static function table (array $ data , $ title ='Info List ' , $ showBorder = true )
458+ public static function table (array $ data , $ title ='Info List ' , array $ opts = [] )
407459 {
460+ $ opts = array_merge ([
461+ 'showBorder ' => true ,
462+ 'leftIndent ' => ' ' ,
463+ 'titlePos ' => self ::POS_LEFT ,
464+ 'rowBorderChar ' => self ::CHAR_HYPHEN , // default is '-'
465+ 'colBorderChar ' => self ::CHAR_VERTICAL , // default is '|'
466+ 'tHead ' => [], // custom head data
467+ ], $ opts );
468+
408469 $ rowIndex = 0 ;
409470 $ head = $ table = [];
471+ $ tableHead = $ opts ['tHead ' ];
472+ $ leftIndent = $ opts ['leftIndent ' ];
473+ $ showBorder = $ opts ['showBorder ' ];
474+ $ rowBorderChar = $ opts ['rowBorderChar ' ];
475+ $ colBorderChar = $ opts ['colBorderChar ' ];
476+
410477 $ info = [
411478 'rowCount ' => count ($ data ),
412479 'columnCount ' => 0 , // how many column in the table.
@@ -418,7 +485,7 @@ public static function table(array $data, $title='Info List', $showBorder = true
418485 foreach ($ data as $ row ) {
419486 // collection all field name
420487 if ($ rowIndex === 0 ) {
421- $ head = array_keys ($ row );
488+ $ head = $ tableHead ?: array_keys ($ row );
422489 $ info ['columnCount ' ] = count ($ row );
423490
424491 foreach ($ head as $ index => $ name ) {
@@ -458,52 +525,53 @@ public static function table(array $data, $title='Info List', $showBorder = true
458525 self ::write (" {$ indentSpace }<bold> {$ title }</bold> " );
459526 }
460527
528+ $ border = $ leftIndent . str_pad ($ rowBorderChar , $ tableWidth + ($ columnCount *3 ) + 2 , $ rowBorderChar );
529+
461530 // output table top border
462531 if ($ showBorder ) {
463- $ border = str_pad ('- ' , $ tableWidth + ($ columnCount *3 ) + 2 , '- ' );
464- self ::write (' ' . $ border );
532+ self ::write ($ border );
533+ } else {
534+ $ colBorderChar = '' ;// clear column border char
465535 }
466536
467537 // output table head
468- $ headStr = ' | ' ;
538+ $ headStr = "{ $ leftIndent }{ $ colBorderChar } " ;
469539 foreach ($ head as $ index => $ name ) {
470540 $ colMaxWidth = $ info ['columnMaxWidth ' ][$ index ];
471541 $ name = str_pad ($ name , $ colMaxWidth , ' ' );
472- $ headStr .= " {$ name } | " ;
542+ $ headStr .= " {$ name } { $ colBorderChar } " ;
473543 }
474544
475545 self ::write ($ headStr );
476546
477547 // border: split head and body
478- if (isset ($ border )) {
479- self ::write (' ' . $ border );
480- }
548+ self ::write ($ border );
481549
482550 $ rowIndex = 0 ;
483551
484552 // output table info
485553 foreach ($ data as $ row ) {
486554 $ colIndex = 0 ;
487- $ rowStr = ' | ' ;
555+ $ rowStr = " $ colBorderChar " ;
488556
489557 foreach ($ row as $ value ) {
490558 $ colMaxWidth = $ info ['columnMaxWidth ' ][$ colIndex ];
491559 $ value = str_pad ($ value , $ colMaxWidth , ' ' );
492- $ rowStr .= " <info> {$ value }</info> | " ;
560+ $ rowStr .= " <info> {$ value }</info> { $ colBorderChar } " ;
493561 $ colIndex ++;
494562 }
495563
496- self ::write ("{ $ rowStr}" );
564+ self ::write ($ rowStr );
497565
498566 $ rowIndex ++;
499567 }
500568
501569 // output table bottom border
502- if (isset ( $ border ) ) {
503- self ::write (' ' . $ border );
570+ if ($ showBorder ) {
571+ self ::write ($ border );
504572 }
505573
506- echo "\n" ;
574+ self :: write ( '' ) ;
507575 }
508576
509577
0 commit comments