我正在为我的网站制作一个代码编辑器,它应该获取用户的代码,编译和运行它,并通过将代码的输出与正确的预定输出相匹配来给用户带来成功或失败。
假设我有一个文件editor.php
:
<?php echo `dir` ?>
这在网页上完美地显示了我目录的内容:
Volume in drive C is OS Volume Serial Number is D239-CB9C Directory of C:UsersChander ShekharOneDriveDocumentsProjectsPHPProjectAlgoLandcampaigncode 05/03/2020 07:35 PM
. 05/03/2020 07:35 PM
.. 03/15/2020 09:45 PM 4,068 color-mode.png 05/03/2020 07:06 PM 4,060 editor.css 05/03/2020 04:49 PM 3,709 editor.js 05/03/2020 07:35 PM 19 editor.php 05/03/2020 07:04 PM 2,415 l1q1.php 05/03/2020 07:34 PM 86 sample.cpp 6 File(s) 14,357 bytes 2 Dir(s) 242,218,971,136 bytes free
以可读性更强的形式(注意sample.cpp(:
Volume in drive C is OS
Volume Serial Number is D239-CB9C
Directory of C:UsersChander ShekharOneDriveDocumentsProjectsPHPProjectAlgoLandcampaigncode
05/03/2020 07:35 PM <DIR> .
05/03/2020 07:35 PM <DIR> ..
03/15/2020 09:45 PM 4,068 color-mode.png
05/03/2020 07:06 PM 4,060 editor.css
05/03/2020 04:49 PM 3,709 editor.js
05/03/2020 07:35 PM 55 editor.php
05/03/2020 07:04 PM 2,415 l1q1.php
05/03/2020 07:34 PM 86 sample.cpp
6 File(s) 14,393 bytes
2 Dir(s) 242,215,878,656 bytes free
然而,
<?php echo `g++ -std=c++14 sample.cpp -o sample.exe` ?>
没有显示任何错误
事实,甚至是:
<?php echo `g++` ?>
没有给我任何输出。
sample.cpp
的内容为:
#include <iostream>
应该输出:
C:/Program Files (x86)/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/5.1.0/../../../libmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
在命令行编译时。什么东西?
我还可以运行其他程序
如果我将sample.cpp
更改为:
#include <iostream>
int main(){
std::cout << "Hello World!";
return 0;
}
并将editor.php
更改为:
<?php echo `sample.exe` ?>
这提供了正确的输出:
Hello World!
编译器可能在stderr
而不是stdout
上给出输出。回溯标记读取stdout
。您需要将proc_open
与管道一起使用,如您在https://www.php.net/manual/en/function.proc-open.php
经过询问,我终于找到了解决这个问题的另一种方法。
问题是,如上@Derick
所述,g++正在输出到stderr
。因此,解决方案是将此输出重定向到stdout
。
这可以通过在命令末尾添加2>&1
来完成,如下所示:
<?php echo `g++ -std=c++14 sample.cpp -o sample.exe 2>&1` ?>
这个命令告诉shell:
1( 取g++
的错误流(2(,
2(将其重定向(>(
3(到stdout
的文件描述符(&1(。
因此,输出在适当的通道上传输,并由执行操作员接收。