检测PHP脚本是否正在以交互方式运行 [英] Detect if a PHP script is being run interactively or not

查看:96
本文介绍了检测PHP脚本是否正在以交互方式运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个旨在同时作为网页和通过控制台运行的脚本.

I have a script that is designed to be run both as a web page, and via the console.

检测使用哪种方法来调用脚本似乎很简单,但是当从控制台运行脚本时,我需要知道脚本是否以交互方式运行(用户键入命令或从中重定向输入)文件).

Detecting which method was used to invoke the script seems pretty straight forward, but when the script is being run from the console, I need to know if the script is being run interactively or not (user typing commands, or input redirected from a file).

php script.php 相对 php script.php < input_file

这可能吗?

推荐答案

I also needed a slightly more flexible solution than posix_isatty that could detect:

  • 该脚本是否正在从终端运行
  • 脚本是通过管道还是从文件接收数据
  • 输出是否被重定向到文件

经过一些libc标头的试验和挖掘之后,我想到了一个非常简单的类,可以完成上述所有操作以及更多操作.

After a bit of experimenting and digging around through libc headers, I came up with a very simple class that can do all of the above and more.

class IOMode
{
    public $stdin;
    public $stdout;
    public $stderr;

    private function getMode(&$dev, $fp)
    {
        $stat = fstat($fp);
        $mode = $stat['mode'] & 0170000; // S_IFMT

        $dev = new StdClass;

        $dev->isFifo = $mode == 0010000; // S_IFIFO
        $dev->isChr  = $mode == 0020000; // S_IFCHR
        $dev->isDir  = $mode == 0040000; // S_IFDIR
        $dev->isBlk  = $mode == 0060000; // S_IFBLK
        $dev->isReg  = $mode == 0100000; // S_IFREG
        $dev->isLnk  = $mode == 0120000; // S_IFLNK
        $dev->isSock = $mode == 0140000; // S_IFSOCK
    }

    public function __construct()
    {
        $this->getMode($this->stdin,  STDIN);
        $this->getMode($this->stdout, STDOUT);
        $this->getMode($this->stderr, STDERR);
    }
}

$io = new IOMode;

一些示例用法,以显示它可以检测到的内容.

Some example usage, to show what it can detect.

输入:

$ php io.php
// Character device as input
// $io->stdin->isChr  == true

$ echo | php io.php
// Input piped from another command
// $io->stdin->isFifo == true

$ php io.php < infile
// Input from a regular file (name taken verbatim from C headers)
// $io->stdin->isReg  == true

$ mkdir test
$ php io.php < test
// Directory used as input
// $io->stdin->isDir  == true

输出:

$ php io.php
// $io->stdout->isChr  == true

$ php io.php | cat
// $io->stdout->isFifo == true

$ php io.php > outfile
// $io->stdout->isReg  == true

错误:

$ php io.php
// $io->stderr->isChr  == true

$ php io.php 2>&1 | cat
// stderr redirected to stdout AND piped to another command
// $io->stderr->isFifo == true

$ php io.php 2>error
// $io->stderr->isReg  == true

我没有提供链接,套接字或块设备的示例,但是没有理由它们不起作用,因为它们的设备模式掩码在类中.

I've not included examples for links, sockets, or block devices, but there's no reason they shouldn't work, as the device mode masks for them are in the class.

(未在Windows上进行测试-里程可能会有所不同)

(Not tested on Windows - mileage may vary)

这篇关于检测PHP脚本是否正在以交互方式运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆