如何在客户端上传shell脚本文件,并利用PHP调用执行脚本

php 专栏收录该内容
2 篇文章 0 订阅

题目中的上传包含两部分,一部分是上传文件,一部分是利用PHP执行脚本

上传文件到指定文件夹

所谓文件上传是指将本地文本文件,图片视频或者音频等文件上传到服务器上,以供后续操作的过程。
上传文件有几种方式,包括:
- 单纯的form表单上传提交
使用form表单的input[type=”file”]控件,打开系统的文件对话选择框,选择文件然后利用submit和form中跳转的action设置实现上传。
优点:多浏览器兼容,简单
缺点:PHP会限制浏览器上传文件的大小,而且form表单提交后会刷新页面,用户体验不好
【注意】
1. input中type要设置成type=”file”;
2. 设置form中method=”post”;
3. form中enctype中有三种取值
image

如果是文件上传,需要将enctype=”multipart/form-data”

如果上传文件较大,需要配置php.ini文件(以上传500M以下大小的文件为例)
查找以下选项并修改->
file_uploads = On ;打开文件上传选项
upload_max_filesize = 500M ;上传文件上限

如果要上传比较大的文件,仅仅以上两条还不够,必须把服务器缓存上限调大,把脚本最大执行时间变长
post_max_size = 500M ;post上限
max_execution_time = 1800 ; Maximum execution time of each script, in seconds脚本最大执行时间
max_input_time = 1800 ; Maximum amount of time each script may spend parsing request data
memory_limit = 128M ; Maximum amount of memory a script may consume (128MB)内存上限

上代码:

    <form action="upload_file.php" method="post"
    enctype="multipart/form-data">
    <input type="file" name="file" id="file" /> 
    <input type="submit" name="submit" id="submit" value="Submit" />
    </form>

效果如图:
image
原始的样子不太好看,为了美观大家可以使用label调整样式,例如

css部分
.btn {
    display: inline-block;
    margin-bottom: 0;

    user-select: none;
}
.btn-info {
    padding:8px;
    color: #ffffff;
    background-color: #40bbea;
    border-color: #29b3e7;
}
html部分    
<div>
    <label for="fileName1" >文件上传:</label>
    <input type="text" name="fileName1" id="fileName1" style="height: 32px;width: 300px;" />
    <label class="btn btn-info" for="updateFile" style="margin-bottom: 3px;">浏览</label>
    <label class="btn btn-info" style="margin-bottom: 3px;" for="submit" >上传</label>
    <div class="col-xs-12">
        <form id= "uploadForm">
            <input type="file" id="updateFile" name="file"  style="position:absolute;clip:rect(0 0 0 0);">
            <input type="text" id="submit"  hidden="hidden">
        </form>
    </div>
</div>

修改后样式如图:
image
-html5的formdata、fileReader
利用FormData模拟表单数据,然后通过ajax提交,用FileReader的readAsDataURL方法拿到base64地址来预览。

html部分

    <div id= "uploadForm">
        <input type="text"  id="fileName" style="height: 32px;width: 300px;" />
        <label class="btn btn-info" for="file" style="margin-bottom: 3px;">
            <span>浏览</span>
        </label>
        <label  class="btn btn-info" style="margin-bottom: 3px;" for="submit">
            <span>上传</span>
        </label>
        <input type="file" id="file" name="file"     onchange="showPreview(this)"   style="position:absolute;clip:rect(0 0 0 0);">
        <input type="text" id="submit" onclick="doUpload()" hidden="hidden">
    </div> 

JavaScript部分

    function showPreview(source) {  
        var arrs = $(source).val().split('\\'); 
        var filename=arrs[arrs.length-1]; 
        $("#fileName").val(filename);                
    }
    function doUpload() {  
        var formData = new FormData($( "#uploadForm" )[0]);  // 要求使用的html对象
        $.ajax({  
              url: 'upload_file.php' ,  
              type: 'POST',  
              data: formData,  
              async: true,  
              // 下面三个参数要指定,如果不指定,会报一个JQuery的错误 
            cache: false,  
              contentType: false, //不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码 
              processData: false,//不处理数据  
              success: function (returndata) { 
                /*result = JSON.parse(returndata);*/
                alert(returndata);  
              },  
              error: function (returndata) {  
                  alert(returndata);  
              }  
         });
    }

需要注意的部分:
使用jQuery提供的ajax方法来发送二进制文件,还需要附加两个参数:

processData: false // 不要对data参数进行序列化处理,默认为true
contentType: false // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码
upload_file.php

<?php

$url=realpath(dirname(__FILE__).'/../../'); //从当前位置退回到www文件夹目录,这一块儿可根据自己文件所在位置做修改
if ($_FILES["file"]["error"] > 0)
{
    switch($_FILES["file"]["error"])
    {
        case 1:
        echo "上传文件的大小超出了约定值";
        break;
        case 2:
        echo "上传文件太大 ";
        break;
        case 3:
        echo "文件只被部分上传";
        break;
        case 4:
        echo "没有上传任何文件";
        break;
        case 6:
        echo "未指定临时目录";
        break;
        case 7:
        echo "文件写入磁盘失败" ;
        break;
    }

}
else
{
    $storePath = $url. "/upload" ;
    // 判断当期目录下的 upload 目录是否存在该文件
    // 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
    if (!file_exists($storePath))
    {
        mkdir($storePath); 
    }
    else if (file_exists($storePath.'/'.$fileName))
    {
        echo $fileName . " 文件已经存在,如需更新,请点击下方'更新系统'按钮";
    }
    else
    {
        //如果 upload 目录不存在该文件则将文件上传到 upload 目录下
        //判断文件上传是否采用的POST方式
        if(is_uploaded_file($_FILES['file']['tmp_name']))
        { 
            if(move_uploaded_file($_FILES['file']['tmp_name'],$storePath.'/'.$fileName))
            {
                chmod($storePath.'/'.$fileName,0755);//
                echo "更新文件存储成功,如需更新,请点击下方'更新系统'按钮";

            }else{  
                echo '更新文件存储失败';  
            }  
        }else{  
            echo '没有可存储的更新文件';  
        }
    }

}
?>

关于PHP上传文件

通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。

第一个参数是表单的 input name,第二个下标可以是 “name”, “type”, “size”, “tmp_name” 或 “error”。就像这样:

FILES[file][name] F I L E S [ “ f i l e ” ] [ “ n a m e ” ] − 被 上 传 文 件 的 名 称 _FILES[“file”][“type”] - 被上传文件的类型
FILES[file][size] F I L E S [ “ f i l e ” ] [ “ s i z e ” ] − 被 上 传 文 件 的 大 小 , 以 字 节 计 _FILES[“file”][“tmp_name”] - 存储在服务器的文件的临时副本的名称
$_FILES[“file”][“error”] - 由文件上传导致的错误代码
这是一种非常简单文件上传方式。基于安全方面的考虑,您应当增加有关什么用户有权上传文件的限制,例如上传格式和大小。

保存上传的文件到指定文件夹

使用move_uploaded_file( FILES[file][tmpname], F I L E S [ ′ f i l e ′ ] [ ′ t m p n a m e ′ ] , storePath.’/’. fileName)moveuploadedfile(file,newloc)chmod( f i l e N a m e ) m o v e u p l o a d e d f i l e ( f i l e , n e w l o c ) , 两 个 参 数 都 是 必 需 项 , 前 者 指 需 要 保 存 的 文 件 , 后 者 是 你 设 置 的 新 的 保 存 路 径 c h m o d ( storePath.'/'.$fileName,0755);这个是为了修改上传文件的权限,因为上传文件的权限默认是644,所以如果有执行该文件的需求则需要自己手动修改权限;
而标题的第二部分是利用php执行linux命令,shell脚本函数

PHP执行外部命令的几个函数

  1. exec()
    string exec ( string command [, array &output [, int &return_var]] )
    说明
    前面是要执行的命令,但是exec执行系统外部命令时不会输出结果,而是返回结果的最后一行。如果想得到结果,可以使用第二个参数,让其输出到指定的数组。此数组一个记录代表输出的一行。即如果输出结果有20行,则这个数组就有20条记录,所以如果需要反复输出调用不同系统外部命令的结果,最好在输出每一条系统外部命令结果时清空这个数组unset($output),以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0
  2. shell_exec()
    string shell_exec ( string cmd) c m d ) 直 接 执 行 命 令 cm,输出命令执行结果,如果执行过程中发生错误或者进程不产生输出,则返回 NULL,所以,使用本函数无法通过返回值检测进程是否成功执行。
  3. system()
    string system ( string command [, int & command [, int & return_var ] )
    说明:system和exec的区别在于,system在执行系统外部命令时,它执行给定的命令,输出和返回结果。第二个参数是可选的,用来得到命令执行后的状态码。
    状态码介绍
    如果返回0是运行成功,
    在Bash中,当错误发生在致命信号时,bash会返回128+signal number做为返回值。
    如果找不到命令,将会返回127。
    如果命令找到了,但该命令是不可执行的,将返回126。
    除此以外,Bash本身会返回最後一个指令的返回值。
    若是执行中发生错误,将会返回一个非零的值。
    Fatal Signal : 128 + signo
    Can’t not find command : 127
    Can’t not execute : 126
    Shell script successfully executed : return the last command exit status
    Fatal during execution : return non-zero
  4. passthru()
    void passthru ( string command [, int & command [, int & return_var ] )
    说明: passthru与system的区别,passthru直接将结果输出到浏览器,不返回任何值,且其可以输出二进制,比如图像数据。第二个参数可选,是状态码。
    当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。 常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。 通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值