PHP上传 - 500内部服务器错误

时间:2012-10-22 08:56:50

标签: php iis upload fastcgi internal-server-error

问题

上传大约8MB或更大的文件时,我收到500内部服务器错误。

  1. php.ini中的所有PHP设置都是正确的
  2. maxAllowedContentLength已在web.config
  3. 中设置

    服务器信息

    正如人们可以从maxAllowedContentLength看到的那样,我运行 IIS 7.5 ,使用FastCGI和PHP 5.3.17

    其他信息

    我已经尝试了很多不同的东西来使这个工作,但根本找不到问题。

    但是,我发现以下信息可能有助于找出问题的根源:

    1. 使用我在服务器上的Media Wiki上传文件(较大的文件)时,我收到同样的错误,这表明我的代码中没有错误。
    2. 最重要的是 - 我设法在Plesk文件管理器中上传了一个18MB的文件,这显然意味着Plesk能够解决这个配置问题。我试图将所有Plesk控制面板设置复制到IIS中的此域,但这似乎不起作用。
    3. 在执行脚本之前返回错误,因为我尝试在顶部编写exit;以尝试获取空白屏幕,但这会被忽略并返回500错误。
    4. 我认为问题出在PHP配置的configure command部分,因为当我更改.php文件的处理程序映射以使用Plesk {{ 1}}而不是通常的,我没有得到500内部错误。话虽如此,我不能把它留在这个PHP版本上,因为它是Plesk自己的php-cgi.exe,还有其他配置问题。

      我认为可能与configure命令有关的原因仅仅是因为它与exe之间存在很大差异。

      如果您有任何想法或建议,请发布。我已经尝试了所有知识,似乎无法解决这个问题。如果只是Linux ......

      提前致谢

      更新1

      忘记添加,PHP错误日志中没有返回错误。至于IIS错误,我不知道在哪里看

      更新2

      这是我放在phpinfo()文件中的内容:

      web.config

      更新3

      在您的帮助下,我们设法获得IIS显示的错误。这就是我收到的内容:

        

      PHP警告:POST Content-Length为12221448字节超出限制   第0行的未知数为8388608字节

      <security> <requestFiltering> <requestLimits maxAllowedContentLength="2147483647" /> </requestFiltering> </security> 有关吗?​​

      更新4

      PHP设置如下(来自post_max_size):

      phpinfo()

      更新5

      最后,为了防止任何人发现任何潜在问题,Plesk能够绝对正常上传大文件,所以我认为他们的php-cgi.exe编译方式不同。当我读取其配置的phpinfo()时,post_max_size = 64M memory_limit = 128M max_file_uploads = 20 max_execution_time = 6000 upload_max_filesize = 64M 信息非常不同:

      我的配置:

        

      cscript / nologo configure.js“--​​enable-snapshot-build”   “--disable-isapi”“ - enable-debug-pack”“ - without-mssql”   “--without-pdo-mssql”“ - without-pi3web”   “--with-PDO-OCI = C:\ PHP-SDK \ ORACLE \ instantclient10 \ SDK,共享”   “--with-OCI8 = C:\ PHP-SDK \ ORACLE \ instantclient10 \ SDK,共享”   “--with-oci8-11g = C:\ PHP-SDK \ ORACLE \ instantclient11 \ SDK,共享”   “--enable-object-out-dir = .. / obj /”“ - enable-com-dotnet = shared”   “--with-mcrypt = static”“ - disable-static-analyze”

      Plesk的配置:

        

      cscript / nologo configure.js“--​​enable-debug-pack”“ - enable-cli”   “--enable-cgi”“ - enable-isapi”“ - enable-one-shot”“ - enable-pdo”   “--enable-intl”“ - with-openssl = shared”“ - with-pdo-odbc”   “--with-iconv”“ - with-xml”“ - with-xsl”“ - with-mysql”   “--with-mysqlnd”“ - with-mysqli”“ - with-pdo-sqlite”   “--with-pdo-mysql”“ - with-curl = shared”“ - enable-mbstring”   “--enable-mbregex”“ - with-imap = shared”“ - enable-socket”   “--enable-shmop”“ - enable-soap”

      更新(答案) 这是非常奇怪的,因为configure command信息说了一件事,但显然被忽略了,不知道为什么。

      如果我更改Plesk中的phpinfo(),针对该特定域/子域,则不会更改任何内容(尽管它在post_max_size中似乎已更改)。但是,如果我实际更改了php.ini中的phpinfo(),那么这就解决了这个问题。

      这不是一个解决这个问题的好方法的原因,仅仅是因为当Plesk更新时,php.ini会被覆盖,因为PHP会更新,结果对php.ini所做的更改就会丢失。这意味着每次Plesk更新我都需要对php.ini进行更改。这就是为什么Plesk能够在不更改php.ini的情况下更改PHP设置的原因。

      有人可以想到为什么PHP忽略本地值并恢复到php.ini中的值,即使php.ini声明本地值不同吗?

4 个答案:

答案 0 :(得分:3)

如果您查看source code of PHP,可以在文件php-5.4.8-src\main\rfc1867.c第706-709行看到:

if (SG(post_max_size) > 0 && SG(request_info).content_length > SG(post_max_size)) {
    sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size));
    return;
}

同样存在于文件php-5.4.8-src\main\SAPI.c中。 因此,消息PHP Warning: POST Content-Length of 12221448 bytes exceeds the limit of 8388608 bytes in Unknown on line 0与post_max_size设置有关。您已使用phpinfo()确认已正确配置此设置,但无论如何它似乎都使用默认值8M。

至于原因,请参阅this thread

  

事实证明,在Windows上,您只能设置ini指令   每个目录标记PHP_INI_USER。不幸,   upload_max_filesizepost_max_size都是PHP_INI_PERDIR。   来自PHP文档   http://php.net/manual/en/configuration.changes.php

     
    

对于从此目录或其任何子目录运行的任何脚本,该目录的设置都将处于活动状态。价值     在key下面应该有PHP配置指令的名称     和字符串值。不解析值中的PHP常量。     但是,只有PHP_INI_USER中可更改的配置值可以这种方式设置,PHP_INI_PERDIR值不能。

  
     

所以尽管Plesk有一个改变这些指令的界面,并且   即使phpinfo()接受了它们,它们也无法改变   实际的最大上传大小。 Plesk不允许您更改   那些在Windows上,phpinfo()不应该报告更改,但是   你能做什么。

所以,它是post_max_size,需要在php.ini上设置。即使phpinfo另有说法,Plesk设置也无法正常工作。我还在phpinfo行为上打开了一个bug entry,因为它似乎没有一个条目。

答案 1 :(得分:2)

这是一个相当常见的错误,是由于正在上传的数据大小与文件大小不匹配:即使文件未超过POST最大大小大小,可以是上传的数据大小

请参阅PHP手册中的this page

; Maximum size of POST data that PHP will accept.
post_max_size = 8M

另一个麻烦来源(非常大的文本)是UTF8编码。你可能会发现自己有一个“6兆字节”TEXTAREA,实际上是6兆*字符*,而国际代码点可能会运行到8.2兆字节。因此,您会看到“六兆字节数据超出配置的8兆字节限制”这一明显矛盾的情况。

更新

你报告两个明显矛盾的事实:

PHP settings as follows (from phpinfo()):

    post_max_size = 64M

PHP Warning: POST Content-Length of 12221448 bytes exceeds the limit of 8388608 bytes

从PHPINFO可以清楚地看出,POST的限制是 64M 。然而,错误表示限制 8M (默认值)。所以在我看来你的代码正在与两个不同的PHP实现交换(两个不同的虚拟主机?一个CGI版本和一个非CGI版本在同一个主机中?两个不同的机器?)

答案 2 :(得分:0)

IIS将重用FastCGI进程。你需要杀掉任何旧的进程才能让php.ini重新加载。

编辑FastCGI模块并编辑'监视器对文件的更改'并选择php.ini文件。这将在您保存编辑时强制子进程重新启动。

答案 3 :(得分:0)

你可以将限制转为-1,这样你就不会遇到文件大小的麻烦。 它可能不是最好的解决方案,因为你基本上是在说“如果我没有看到它,它就不存在”,但相信它确实可靠并且永远有效。