在线运行C++、java、python代码的小项目实现

本网站在2019年8月12日之前用的代码演示功能是借用了 https://tool.lu/coderunner/ 的在线运行代码工具,在此致谢。

有一段时间这个工具突然失效了,我就在想能不能自己模仿着做一个类似的出来,简单分析了一下就想挑战一下自己,然后就开始动手了。

做出来的成果链接:点击此处

做的过程中查阅了很多网络资料,现整理如下:

需求分析:前端为一个实用的代码编辑器,通过ajax请求将写好的代码提交给服务器,服务器编译运行后把输出结果送回客户端显示。

其中使用的代码编辑器:CodeMirror,现在类似的工具使用的应该都是这款功能强大,可以自定样式的代码编辑器,官网: https://codemirror.net/

CodeMirror搭建前端界面

先从官网下载下来CodeMirror的压缩包,解压之后得到下图目录

在线运行C++、java、python代码的小项目实现

要在html中创建一个CodeMirror编辑器,必须添加的css和js文件是

 <link href=./codemirror-5.48.2/lib/codemirror.css rel=stylesheet/>
 <script src=./codemirror-5.48.2/lib/codemirror.js></script>

(5.48.2为版本号,因人而异)

然后需要添加需要编辑的语言相关的js文件,可以在mode目录下找到,这里我用了两个文件:

实现JAVA和C++代码高亮(这个文件可以实现C,C++,JAVA,C#等语言):

<script src=./codemirror-5.48.2/mode/clike/clike.js></script>

实现python的代码高亮:

<script src=./codemirror-5.48.2/mode/python/python.js></script>

需要更改编辑器主题样式的可以在theme目录下找到对应的主题css文件添加进去,我觉得默认主题就很好看了就没用其他主题。

为了实现括号匹配和代码折叠功能,还要添加的文件有:

<link rel=stylesheet href=./codemirror-5.48.2/addon/fold/foldgutter.css/>

<script src=./codemirror-5.48.2/addon/fold/foldcode.js></script>
<script src=./codemirror-5.48.2/addon/fold/foldgutter.js></script>
<script src=./codemirror-5.48.2/addon/fold/brace-fold.js></script>
<script src=./codemirror-5.48.2/addon/fold/comment-fold.js></script>

创建编辑器的过程:

在html中使用一个textarea占位,配置好id:

<textarea id=code name=code></textarea>

通过对应的js代码创建编辑器:

var editor = CodeMirror.fromTextArea(document.getElementById(code), {
    mode: text/x-java, //实现Java代码高亮
    //mode: text/x-c++src, //实现C++代码高亮
    //mode: text/x-python, //实现Python代码高亮
    indentUnit:4,//以四个空格的长度缩进
    indentWithTabs: true,//以tab代替空格缩进
    lineNumbers: true,  //显示行号
    lineWrapping: true, 
    foldGutter: true, //代码折叠
    gutters: [CodeMirror-linenumbers, CodeMirror-foldgutter],
    matchBrackets: true //括号匹配      
});

这里需要什么语言高亮需要在官网找到对应语言的 MIME types ,写在mode参数中

其他相关js函数:

编辑器的大小通过 editor.setSize(width, height) 方法设置

获取编辑器内的代码:editor.getValue()

设置编辑器内的代码:editor.setValue()

设置编辑器的配置选项: editor.setOption()

最终搭配上bootstrap样式做出来的效果是这样的:

在线运行C++、java、python代码的小项目实现

js实现前端逻辑

使用JQuery简化js的写法

关键代码:

切换语言事件

//选择语言事件
("#lang").on('change', () => {
    lang =("#lang").val()
    if (lang == 'java') {
        editor.setOption("mode", "text/x-java")
        editor.setValue(javacode)
    } else if (lang == "cpp") {
        editor.setOption("mode", "text/x-c++src")
        editor.setValue(cppcode)
    } else if (lang == "python") {
        editor.setOption("mode", "text/x-python")
        editor.setValue(pythoncode)
    }
})

发送POST请求

$(function(){
    //点击运行按钮后的事件
    $("#run").on("click",()=>{
        var codesrc = editor.getValue();
        //给源代码编码
        var codeEncoded = encodeURIComponent(codesrc);
        $("output").html = 'console>>' + '正在努力执行中...';
        //发出post请求
        $.post( "/runcode.php", { lang:lang,codesrc:codeEncoded }, (data)=>{
            var outputs = data.output;
            var status1 = data.status1;
            var output = '';
            //拼接输出结果
            if(status1 !== 1){
              for(var i in outputs)
              {
                output = output + outputs[i] + '<br/>';
              }data
            }else{
                var outputs1 = data.output1;
                for(var i in outputs1)
                {
                  output = output + outputs1[i] + '<br/>';
                } 
            }
            $("output").html = 'console>>' + output;
        }, "json");
    })
});

注: 由于代码中可能出现 +& 等符号,其在post的请求中经过urlencode会分别被解析为空格和参数连接符,需先将代码源码用js的encodeURIComponent()函数编码,传递到php后端后再用rawurldecode()函数进行解码操作。

php实现后端

php的任务是在服务器上运行代码,核心的思想是将接收到的代码写入文件,使用各种环境去执行,并返回结果

其中用到了exec函数

具体参阅 【php】php使用exec总结

做的时候遇到了个问题:php在调用exec执行gcc命令时,会出现各种毛病,例如ld链接器找不到,后来发现原因是php不会使用系统设置的环境变量,在php文件开头添加这样一句话就能解决问题:

putenv(PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin);//设置环境变量

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e5%9c%a8%e7%ba%bf%e8%bf%90%e8%a1%8cc%e3%80%81java%e3%80%81python%e4%bb%a3%e7%a0%81%e7%9a%84%e5%b0%8f%e9%a1%b9%e7%9b%ae%e5%ae%9e%e7%8e%b0/

发表评论

电子邮件地址不会被公开。