如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?

Posted

技术标签:

【中文标题】如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?【英文标题】:How to get linux console $COLUMNS and $ROWS from PHP cli? 【发布时间】:2011-01-13 06:58:57 【问题描述】:

我目前正在为 php 创建一个新的整洁的 CLI 库,我想弄清楚它正在运行的控制台的宽度/高度。

我已经尝试过很多方法,例如挖掘 $_ENV、exec("echo $COLUMNS") 等,但没有结果,而如果我在 bash 命令行中键入 echo $COLUMNS 或 $ROWS,它会整齐地显示值。

我需要做什么才能从 PHP 访问这个值?

我正在使用这样的 .sh 脚本:

#!/usr/bin/php -q
<?php

require_once('lib.commandline.php');


class HelloWorld extends CommandLineApp 

  public function main($args) 

       echo('O, Hai.');

    


更新 最终解决方案:

public function getScreenSize()  
      preg_match_all("/rows.([0-9]+);.columns.([0-9]+);/", strtolower(exec('stty -a |grep columns')), $output);
      if(sizeof($output) == 3) 
        $this->settings['screen']['width'] = $output[1][0];
        $this->settings['screen']['height'] = $output[2][0];
      
    

【问题讨论】:

所以,嗯.. 我知道已经快 10 年了,但你还有那个 CLI 库吗? GitHub? :-) 【参考方案1】:

另一个不需要解析的shell选项是tput

$this->settings['screen']['width'] = exec('tput cols')
$this->settings['screen']['height'] = exec('tput lines')

【讨论】:

优秀。在挖掘如何从stty 获取这些信息时,我完全忘记了tput 超级!非常有用且温和地提醒您解决方案的优雅程度。 如果你安装了 Windows 版 Git,这个解决方案甚至可以在 Windows 上运行。另一种方法是解析mode con /status 注意:调整窗口大小后tput返回的值不会更新,但stty会【参考方案2】:

使用 PHP ncurses_getmaxyx 函数。

ncurses_getmaxyx (STDSCR, $Height, $Width)

以前:

http://php.net/manual/en/function.getenv.php

$cols = getenv('COLUMNS');
$rows = getenv('ROWS');

“正确”的方式可能是调用TIOCGSIZE ioctl 来获取内核对窗口大小的想法,或者调用命令stty -a 并解析rowscolumns 的结果

【讨论】:

只想说,在 Mac OS X 上的 Terminal.app 中没有设置 COLUMNS 和 ROWS。我也遇到了不一致的问题(例如,它们在 irb 中工作,但不是在执行一个 ruby​​ 脚本,&c)。 如果在程序运行时调整终端大小,环境变量也不会更新。 Getenv 确实不起作用,$_ENV 也不起作用但是感谢 stty -a 的提示,我会解析它:) 我喜欢我当前解决方案的可移植性 :) 并非所有的盒子都有 PHP 中的 ncurses,所以我希望它尽可能裸露 鉴于您是这个问题的获胜者,并且您的最佳建议目前是“实验”功能(他们的全部大写,不是我的),您能否花点时间在这里整合各种方法,并显示实际正确答案。特别是因为您提到 ioctl 方法是首选方法(没有说明为什么它最好),但您实际上并没有展示如何做到这一点。自我说明:与其抱怨这一点,不如等六个月,然后写一个非常好的答案。记得感谢乔写了一个答案,而不仅仅是遵守……【参考方案3】:

$COLUMNS$LINES 可能没有被导出到您的程序中。您可以在运行应用之前运行export LINES COLUMNS,也可以直接获取此信息:

$fp=popen("resize", "r");
$b=stream_get_contents($fp);
preg_match("/COLUMNS=([0-9]+)/", $b, $matches);$columns = $matches[1];
preg_match("/LINES=([0-9]+)/", $b, $matches);$rows = $matches[1];
pclose($fp);

【讨论】:

【参考方案4】:

我不知道,为什么需要grep 来解析stty 输出:它确实有一个单独的选项来报告“根据内核的行数和列数”。

单行,无错误处理:

list($rows, $cols) = explode(' ', exec('stty size'));

单行,假设两个行/列都为 0 以防出现问题并抑制任何错误输出:

list($rows, $cols) = explode(' ', @exec('stty size 2>/dev/null') ?: '0 0');

【讨论】:

【参考方案5】:

也许这个link 可能是答案,您可以使用ANSI Escape 代码来做到这一点,通过使用echo 使用特定的Escape 代码序列,特别是“查询设备”,我找到了另一个链接here 详细解释。也许使用它可以让您获得屏幕的列和行...

【讨论】:

这个答案指向 2 个死链接。此外,这个答案没有解释如何在发送转义序列后获取控制台大小。【参考方案6】:

作为记录,这是我的函数(PHP 7.2 及更高版本):

它适用于 Windows 和 Linux。如果出现错误,则返回 80。

在一些古怪或太小的值的情况下,它返回最小值(80)

ps:“mode con”确实返回行数,但它基于缓冲区而不是屏幕大小。

ps2:奇怪的是,如果我将它作为网站运行,它会返回 120(Windows 主机)。

   function calculateColSize($min=80) 
       try 
            if (PHP_OS_FAMILY === 'Windows') 
                $a1 = shell_exec('mode con');
                /*
                 * Estado para dispositivo CON:
                 * ----------------------------
                 * Líneas:              9001
                 * Columnas:            85
                 * Ritmo del teclado:   31
                 * Retardo del teclado: 1
                 * Página de códigos:    65001
                 */
                $arr = explode("\n", $a1);
                $col = trim(explode(':', $arr[4])[1]);

             else 
                $col = exec('tput cols');
                /*
                 * 184
                 */
            
         catch (Exception $ex) 
            $col = 80;
        
    

【讨论】:

【参考方案7】:

环境变量可以在$_ENV超级全局变量中找到。

echo $_ENV['ROWS'];

例如。

【讨论】:

“我已经尝试了很多方法,例如挖掘 $_ENV、exec("echo $COLUMNS") 等,但没有结果”,发帖人提到。

以上是关于如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?的主要内容,如果未能解决你的问题,请参考以下文章

linux php cli模式下获取服务器ip

php.ini 在 php-cli 中重新加载

***CI的CLI运行方式

如何在 PHP 中使用 CURL 获取 SSL 证书信息?

PHP cli 不适用于本地路径(突然)

如何从 PHP 脚本运行 linux 命令 [重复]