图片上传不适用于php7

时间:2018-02-02 13:59:49

标签: nginx php-7

我使用nginx作为服务器和php7。我遵循了一些指示,一定是犯了错误。

表格:

<div class="collapse" id="upload_avatar">
    <div class="card card-body">
        <form enctype="multipart/form-data" action="" method="post">
            <p class="text-left">Upload Avatar:</p>
            <input type="hidden" name="MAX_FILE_SIZE" value="300000" />
            <input name="image" type="file" /><br>
            <button class="form-control mr-sm-2 btn btn-outline-success my-2 my-sm-0" type="submit" name="avatar_upload" aria-controls="collapse_upload_avatar">
                Upload
            </button>
        </form>
    </div>
</div>

php部分:

if(isset($_POST["avatar_upload"])){
    $verifyimg = getimagesize($_FILES['image']['tmp_name']);

    if($verifyimg['mime'] != 'image/png') {
        echo "Only PNG images are allowed!";
        exit;
    }    

    $uploaddir = '/members/3/';
    $uploadfile = $uploaddir . basename($_FILES['image']['name']);

    if (move_uploaded_file($_FILES['image']['tmp_name'], $uploadfile)) {
        echo "File is valid, and was successfully uploaded.<br>";
    } else {
        echo "Possible file upload attack!<br>";
    }

    echo '<pre>';
    echo 'info:';
    print_r($_FILES);
    print "</pre>";
}

打印出来:

Possible file upload attack!
info:Array
(
    [image] => Array
        (
            [name] => Selection_001.png
            [type] => image/png
            [tmp_name] => /tmp/phpGpp3rB
            [error] => 0
            [size] => 299338
        )
)

没有/tmp/php* file

/members/3/目录中没有文件

777/members

的权限为/members/3
  

nginx / error.log显示:   PHP消息:PHP警告:move_uploaded_file(/members/3/Selection_001.png):无法打开流:没有这样的文件或目录......在第197行   PHP消息:PHP警告:move_uploaded_file():无法移动&#39; / tmp / phpGpp3rB&#39; to&#39; /members/3/Selection_001.png'

缺少nginx设置???

2 个答案:

答案 0 :(得分:3)

删除/在您的成员目录中。

$ uploaddir ='members / 3 /';

答案 1 :(得分:0)

关于你的上一个问题,不,这绝对听起来像PHP或编码问题。 Nginx几乎不是让PHP处理请求的代理。但是,如果没有更多信息,很难确定您的问题。我的代码中没有提到的一些项目可能会导致罪魁祸首。

  1. 你真的有/members/3/的绝对路径吗?该目录实际上位于文件系统的顶部?大多数设置都在webroot中的某个位置上传文件,而不是在文件系统层次结构中的显着位置。例如,Wordpress将其上传内容放在wp-content/uploads/中,该内容本身存在于webroot内(例如/var/www/)。

    PHP说什么?

    if ( file_exists ( '/members/3/' ) )
        echo "/members/3/ truly does exist, anchored to the root";
    else
        echo "NOPE!  Can't find this directory!";
    
  2. 文件$_FILES['image']['name']是否确实存在?使用getimagesize()作为explicitly cautioned in the documentation是不够的。特别是:

      

    注意此功能要求文件名为有效的图像文件。如果提供了非图像文件,则可能会将其错误地检测为图像,并且该函数将成功返回,但该数组可能包含无意义的值。

         

    请勿使用getimagesize()检查给定文件是否为有效图像。请使用专用解决方案,例如Fileinfo扩展名。

  3. 其他注意事项:

    1. MAX_FILE_SIZE的误解已经超出了时间。

      <input type="hidden" name="MAX_FILE_SIZE" value="300000" />
      

      这恰好在互联网上的一个权威点中引用:PHP文档,并且旧的浏览器一次性使用可能来检查文件大小。今天,任何我不知道的浏览器都没有使用它。来自the documentation

        

      MAX_FILE_SIZE隐藏字段(以字节为单位)必须位于文件输入字段之前,其值是PHP接受的最大文件大小。应始终使用此表单元素,因为它可以节省用户等待传输大文件的麻烦,只是发现它太大而传输失败。 请记住:在浏览器端愚弄此设置非常简单,因此不要依赖此功能阻止更大尺寸的文件。它仅仅是应用程序客户端用户的便利功能。但是,最大尺寸的PHP设置(在服务器端)不能被愚弄。

      在2018年,这个隐藏项目的价值恰好为零 - 如果您的脚本完全依赖它,则可能是有害的。你应该删除它。

    2. 您的代码段或许为了简洁而剔除了它,但我看不到包装

      if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
      

      这是正确的方法,用于检查请求是否为POST。在90%的情况下,足以知道设置了$_POST[...]变量,但有时$_POST变量完全为空(例如if the post exceeds post_max_size)。

    3. 在缺乏设置和安全性知识的情况下,盲目信任用户输入是危险的:

      $uploaddir = '/members/3/';
      $uploadfile = $uploaddir . basename($_FILES['image']['name']);
      

      一个简单的破解可能会看到一个倒霉的用户覆盖已经存在的文件。更狡猾的攻击可能会将此向量与特制图像文件一起使用来利用您的服务器。

    4. 您是否启用了所有错误消息?将这些行放在脚本中的适当位置:

      ini_set('display_errors', 1);
      ini_set('display_startup_errors', 1);
      error_reporting(E_ALL);
      
    5. 您的相关PHP变量是什么?您的文件看起来像&lt; 300K左右可能很好,但同样,post_max_sizeupload_max_filesizefile_uploads的价值是多少。

    6. 您是否仔细阅读了phpinfo()的输出?有什么突出的吗?

    7. 您是否尝试在脚本退出之前输入sleep(30)命令,并手动验证文件是否确实存在(例如,在/tmp/php...中)?如果确实存在,命令行file会说什么:

      $ file /tmp/php...
      
    8. 如果以上都不富有成效,请浏览“PHP file uploading checklist”。