PHP中的标准输入STDIN,标准输出STDOUT,标准错误STDERR
因为PHP是专注WEB开发的领域的,所以很大一部分都是CRUD的操作,对于标准输入流,输出流,错误流这一块并不是很熟悉。这也就是很多PHPer的基础不行的所在。
如果想要深入的学习PHP的话,那么这肯定是必须要掌握的。
首先,我们得先了解下,什么是标准输入流,输出流,错误流?它们是干什么的?有什么用?
说一个比较容易理解的解释。
如果我们要执行一个命令 command
,如果我们需要给这个命令输入一些自定义的内容该怎么办呢?这个命令是如何获取到我们输入的内容的呢?这里就是用到了标准输入,而在PHP当中,也就是内置的 STDIN
,它可以在PHP程序中直接使用。
现在,这个命令在接收到我们输入的内容之后,想要输出结果怎么办呢?如何输出呢?这里就用到了标注输出,而在PHP中也就是 STDOUT
。
那么现在有个问题了,如何判断一个命令是否执行成功呢?这个简单,通过命令的返回状态是否为0即可判断。
那我们如何读取在命令执行失败后的错误信息呢?有的小伙伴说,从标准输出读取呀?如果从标准输出读取的话,那么有个问题必须得考虑,我们如果仅仅只需要错误的信息怎么办呢?因为一道程序可能输出的内容非常多,如果将所有的输出信息都通过标准输出输出出来的话,那么这些信息就太混乱了。
于是,标准错误流就出现了,在这个标准错误里面,仅输出程序执行的错误信息,而标准输出则输出程序执行的非错误信息。这样的话,就好分辨了。如果我们只需要错误信息,那么直接从标准错误流读取就可以了。
OK,上面做了一个简单的解释。应该不是很难明白吧。
说了这么多,我们来实际操作下,首先,我们执行下这个命令:
~ ls -al
total 80
drwxr-xr-x 12 xiaoteng staff 384 8 8 15:27 .
drwxr-xr-x 26 xiaoteng staff 832 8 7 20:03 ..
-rw-r--r-- 1 xiaoteng staff 15 8 8 15:27 std.txt
-rw-r--r-- 1 xiaoteng staff 274 6 11 12:30 test.php
我们执行的 ls -al
命令的输出结果就是通过标准输出展示在命令行界面的。我们也可以通过这样操作将输出的结果写到文件:
~ ls -al > list.txt && cat list.txt
total 80
drwxr-xr-x 13 xiaoteng staff 416 8 8 15:30 .
drwxr-xr-x 26 xiaoteng staff 832 8 7 20:03 ..
-rw-r--r-- 1 xiaoteng staff 15 8 8 15:27 std.txt
-rw-r--r-- 1 xiaoteng staff 274 6 11 12:30 test.php
通过 cat
命令,我们看到 ls
命令的执行结果已经写入到 list.txt
这个文件了。这里就涉及到重定向的知识了。在命令行的执行中,我们可以通过 >
符号将标准输出的结果重定向到某个存储中。比如说,这里我们将结果重定向到了 list.txt
文件中。
再来看下这个:
~ ls -al >> list.txt && cat list.txt
total 80
drwxr-xr-x 13 xiaoteng staff 416 8 8 15:30 .
drwxr-xr-x 26 xiaoteng staff 832 8 7 20:03 ..
-rw-r--r-- 1 xiaoteng staff 15 8 8 15:27 std.txt
-rw-r--r-- 1 xiaoteng staff 274 6 11 12:30 test.php
total 88
drwxr-xr-x 13 xiaoteng staff 416 8 8 15:30 .
drwxr-xr-x 26 xiaoteng staff 832 8 7 20:03 ..
-rw-r--r-- 1 xiaoteng staff 15 8 8 15:27 std.txt
-rw-r--r-- 1 xiaoteng staff 274 6 11 12:30 test.php
我们可以通过 >>
符号将输出的结果追加到某个存储中。也就是如果是 >
的话那么会清空原先的内容,但是 >>
仅仅是追加内容。
我们再来看下标注错误的演示,执行下下面命令:
~ ls /lll
ls: /lll: No such file or directory
因为 /lll
这个目录是不存在的,所以报错了。不过在命令行之中无法直观的看到到底是标准输出还是标准错误。我们可以这样测试下:
~ ls /lll > result.txt
ls: /lll: No such file or directory
我们通过 >
将标准输出的结果重定向到 result.txt
这个文件,这样的话,命令行界面就不会直接输出标准输出的结果了。不过可以看到的是,错误的信息依旧展示出来了,所以,这里的错误信息并不是通过的标准输出,所以它肯定是标准错误流的了。
我们可以利用重定向将标准错误的结果保存到文件中:
~ ls /lll 2>error.txt
然后执行:
~ cat error.txt
ls: /lll: No such file or directory
这样我们就将错误信息转储到文件了。这里我们需要明白的是:
stdout
是标准输出流 ,它显示来自命令的输出。它拥有文件描述符 1。stderr
是标准错误流 ,它显示来自命令的错误输出。它拥有文件描述符 2。stdin
是标准输入流 ,它向命令提供输入。它拥有文件描述符 0。
上面的命令
ls /lll 2>error.txt
中的2
就是代表的标准错误流。
好了,说了这么多基础的,应该有了足够的了解了。现在,我们在PHP中来操作下。
首选,PHP的标准输出,创建个 std.php
:
<?php
echo 'hello xiaoteng';
执行下:
~ php std.php
hello xiaoteng
默认情况下,在PHP当中通过像 echo
,var_dump
等函数输出的内容,最终都会重定向到这个标准输出。我们也可以直接向标准输出写入内容:
<?php
fwrite(STDIN, 'hello xiaoteng.hello world');
执行:
~ php std.php
hello xiaoteng.hello world
可以看到,也可以在命令行当中看到输出的信息。
再来看下,PHP的标准输入:
<?php
echo fread(STDOUT, 1024);
执行:
~ php std.php
123123
123123
执行后,我们在键盘输入了 123123
,回车,然后程序将输入的值打印出来。所以,通过 STDIN 我们可从命令行读取用户的输入。
在来看下标准错误:
<?php
fwrite(STDERR, '我是错误');
执行:
~ php std.php
我是错误
如果抛出一个异常话会怎么样:
<?php
throw new Exception('我是错误');
执行:
php std.php >result 2>error
然后在目录下面,可以看到生成了 result
和 error
两个文件,执行:
cat result && cat error
Fatal error: Uncaught Exception: 我是错误 in /Users/xiaoteng/work/test/std.php:3
Stack trace:
#0 {main}
thrown in /Users/xiaoteng/work/test/std.php on line 3
PHP Fatal error: Uncaught Exception: 我是错误 in /Users/xiaoteng/work/test/std.php:3
Stack trace:
#0 {main}
thrown in /Users/xiaoteng/work/test/std.php on line 3
可以看到,两个文件的内容是一样的。也就是PHP的异常在标准输出和标准错误都有输出。
好了,就先写到这里。有不理解的可以留言。
参考资料:
https://www.runoob.com/linux/linux-shell-io-redirections.html
https://developer.ibm.com/zh/tutorials/l-lpic1-103-4/
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭