简体   繁体   English

PHP上传-500 Internal Server Error

[英]PHP Upload - 500 Internal Server Error

The Issue 问题

When uploading files of around 8MB or over, I recieve a 500 Internal Server Error. 上传大约8MB或以上的文件时,出现500内部服务器错误。

  1. All PHP settings in php.ini are correct php.ini中的所有PHP设置均正确
  2. maxAllowedContentLength has been set in the web.config 在web.config中设置了maxAllowedContentLength

Server Info 服务器信息

As one can probably tell from the maxAllowedContentLength , I am running IIS 7.5 , with FastCGI and PHP 5.3.17 maxAllowedContentLength可以看出,我正在使用IIS 7.5和FastCGI和PHP 5.3.17运行

Additional Info 附加信息

I have tried so many different things to get this working but simply cannot find the issue. 我已经尝试了许多不同的方法来使它正常工作,但是根本找不到问题。

However, I have found the following bits of info that may help figure out the root of this problem: 但是,我发现以下一些信息可能有助于弄清此问题的根源:

  1. When uploading files (larger ones) using the Media Wiki that I have on the server, I receive the same error, this goes to show that it is not an error in my code. 使用服务器上的Media Wiki上传文件(较大的文件)时,我收到相同的错误,这表明它不是我的代码中的错误。
  2. Most importantly - I managed to upload an 18MB file in the Plesk File Manager, this obviously means that Plesk was able to get around this config issue. 最重要的是 -我设法在Plesk文件管理器中上传了18MB的文件,这显然意味着Plesk能够解决此配置问题。 I have tried to copy all of the Plesk Control Panel settings over to this domain in IIS but this does not seem to work. 我试图将所有Plesk控制面板设置复制到IIS中的此域,但这似乎不起作用。
  3. The error is being returned before the script is executed, as I have tried writing exit; 由于我已尝试编写exit; ,因此在执行脚本之前将返回错误exit; at the top to try to get a blank screen, but this is ignored and the 500 error is returned. 在顶部尝试获取空白屏幕,但此操作将被忽略,并返回500错误。

I think that the issue lies within the configure command part of the PHP configuration , because when I change the handler mapping of the .php files to use the Plesk php-cgi.exe instead of the usual one, I do not get the 500 Internal Error. 我认为问题出在PHP配置的configure command部分内 ,因为当我更改.php文件的处理程序映射以使用Plesk php-cgi.exe而不是通常php-cgi.exe ,我没有得到500 Internal错误。 Having said that, I cannot leave it on this PHP version as it is Plesk's own exe and there are other configuration issues. 话虽如此,我不能将其保留在此PHP版本上,因为它是Plesk自己的exe并且还有其他配置问题。

The reason why I think it may be to do with the configure command, is simply because this differs hugely from one phpinfo() to the other. 我认为可能与configure命令有关的原因仅仅是因为这从一个phpinfo()到另一个phpinfo()很大的不同。

If you have any ideas or suggestions, please post them. 如果您有任何想法或建议,请发布它们。 I have tried everything to my knowledge and cannot seem to fix this. 我已尽一切努力尝试了一切,但似乎无法解决。 If only it was Linux... 如果只是Linux ...

Thanks in advance 提前致谢

UPDATE 1 更新1

Forgot to add, there are no errors being returned in the PHP error log. 忘记添加,PHP错误日志中没有返回任何错误。 As for IIS errors, I do not know where to look 至于IIS错误,我不知道在哪里看

UPDATE 2 更新2

This is what I have placed in my web.config file: 这是我放置在web.config文件中的内容:

<security>
    <requestFiltering>
        <requestLimits maxAllowedContentLength="2147483647" /> 
    </requestFiltering>
</security>

UPDATE 3 更新3

With your help, we have managed to get the error displayed by IIS. 在您的帮助下,我们设法使IIS显示错误。 This is what I am receiving: 这是我收到的:

PHP Warning: POST Content-Length of 12221448 bytes exceeds the limit of 8388608 bytes in Unknown on line 0 PHP警告:12221448字节的POST内容长度超出了第0行上Unknown中的8388608字节的限制

Is that to do with post_max_size ? 这与post_max_size吗?

UPDATE 4 更新4

PHP settings as follows (from phpinfo() ): PHP设置如下(来自phpinfo() ):

 post_max_size = 64M memory_limit = 128M max_file_uploads = 20 max_execution_time = 6000 upload_max_filesize = 64M 

UPDATE 5 更新5

Lastly, just in case anybody can spot any potential issues, Plesk is able to upload large files absolutely fine, so I assumed that their php-cgi.exe was compiled differently. 最后,以防万一有人发现任何潜在的问题,Plesk可以绝对上传大文件,因此我认为他们的php-cgi.exe是用不同的方式编译的。 When I read a phpinfo() of their configuration the configure command information was very different: 当我阅读其配置的phpinfo()时, configure command信息非常不同:

My configuration: 我的配置:

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,shared" "--with-oci8=C:\\php-sdk\\oracle\\instantclient10\\sdk,shared" "--with-oci8-11g=C:\\php-sdk\\oracle\\instantclient11\\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--with-mcrypt=static" "--disable-static-analyze" cscript / nologo configure.js“ --enable-snapshot-build”“ --disable-isapi”“ --enable-debug-pack”“ --without-mssql”“ --without-pdo-mssql”“-没有-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 =共享“” --with-mcrypt = static“” --disable-static-analyze“

Plesk's Configuration: 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-sockets" "--enable-shmop" "--enable-soap" 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“”-启用-mbstring“” --enable-mbregex“” --with-imap = shared“” --enable-sockets“” --enable-shmop“” --enable-soap“

UPDATE (ANSWER) This is extremely weird as the phpinfo() info is saying one thing, but it is obviously being ignored, not sure why. 更新(ANSWER)这非常奇怪,因为phpinfo()信息在说一件事,但是显然它被忽略了,不知道为什么。

If I change the post_max_size in Plesk, for that particular domain/sub-domain, then nothing is changed (although it appears to have changed in the phpinfo() ). 如果我在Plesk中更改了post_max_size ,对于该特定域/子域,则什么都没有更改(尽管phpinfo()似乎已更改)。 However, if I actually change the post_max_value in the php.ini then this fixes the issue. 但是,如果我实际上更改了php.ini中的post_max_value ,则可以解决此问题。

The reason why this is not a good way to fix this, is simply because when Plesk updates, the php.ini is overwritten as PHP is updated and resultantly the changes made to the php.ini are lost. 之所以不是解决此问题的好方法,原因仅在于当Plesk更新时,由于更新PHP而覆盖了php.ini,因此丢失了对php.ini所做的更改。 Which means that everytime that Plesk updates I will need to make changes tot he php.ini. 这意味着每次Plesk更新时,我都需要对php.ini进行更改。 This is why Plesk offers the ability to change PHP settings without making changes to the php.ini. 这就是为什么Plesk可以更改PHP设置而无需更改php.ini的原因。

Can anybody think of why PHP is ignoring the local value and reverting to the value in the php.ini, even though the php.ini states that the local value is different? 谁能想到PHP为什么忽略了本地值并恢复为php.ini中的值,即使php.ini声明本地值不同吗?

If you look at the source code of PHP , you can see on the file php-5.4.8-src\\main\\rfc1867.c line 706-709 this: 如果查看PHP源代码 ,则可以在文件php-5.4.8-src\\main\\rfc1867.c行中看到:

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;
}

Same is there also in file php-5.4.8-src\\main\\SAPI.c . php-5.4.8-src\\main\\SAPI.c文件中也存在相同的php-5.4.8-src\\main\\SAPI.c So, the message PHP Warning: POST Content-Length of 12221448 bytes exceeds the limit of 8388608 bytes in Unknown on line 0 is about post_max_size setting. 因此,消息PHP Warning: POST Content-Length of 12221448 bytes exceeds the limit of 8388608 bytes in Unknown on line 0设置有关。 You have confirmed from using phpinfo() that you have this setting configured correctly, but it seems to be using the default value of 8M anyway. 您已经通过使用phpinfo()确认已正确配置了此设置,但是无论如何它似乎正在使用默认值8M。

As to why, see this thread : 至于为什么,请看这个线程

As it turns out, on Windows, you can only set ini directives that are marked PHP_INI_USER per directory. 事实证明,在Windows上,您只能在每个目录中设置标记为PHP_INI_USER ini指令。 Unfortunately, upload_max_filesize and post_max_size are both PHP_INI_PERDIR . 不幸的是, upload_max_filesizepost_max_size都是PHP_INI_PERDIR From the PHP docs at http://php.net/manual/en/configuration.changes.php 来自位于http://php.net/manual/zh/configuration.changes.php的PHP文档

The settings for the directory would be active for any script running from this directory or any subdirectory of it. 从该目录或该目录的任何子目录运行的任何脚本的目录设置均处于活动状态。 The values under the key should have the name of the PHP configuration directive and the string value. 键下的值应具有PHP配置指令的名称和字符串值。 PHP constants in the values are not parsed. 不解析值中的PHP常量。 However, only configuration values changeable in PHP_INI_USER can be set this way, PHP_INI_PERDIR values can not. 但是,只能以这种方式设置PHP_INI_USER中可更改的配置值,而不能设置PHP_INI_PERDIR值。

So even though Plesk has an interface to change those directives, and even though phpinfo() picks up on them, they do nothing to change the actual max upload sizes. 因此,即使Plesk具有更改这些指令的接口,即使phpinfo()了这些指令, 它们也不会更改实际的最大上传大小。 Plesk should not allow you to change those on Windows, and phpinfo() should not report the change, but what can you do. Plesk不允许您在Windows上进行更改,并且phpinfo()不应报告更改,但是您可以做什么。

So, it's post_max_size, and it needs to be set on php.ini. 因此,它是post_max_size,需要在php.ini中设置。 Plesk setting simply will not work, even though phpinfo says otherwise. 即使phpinfo另有说明,Plesk设置也无法正常工作。 I also opened a bug entry on phpinfo behaviour as there didn't seem to be an entry for it. 我也打开了一个关于phpinfo行为的错误条目 ,因为似乎没有它的条目。

This is a fairly common error and is due to the fact that the size of data being uploaded does not match file size : even if you POST max size is not exceeded by the file size , it could be by the uploaded data size . 这是一个相当常见的错误,是由于正在上传的数据大小与文件大小不匹配 :即使POST最大大小未超出文件大小 ,也可能是已上传的数据大小

See this page in the PHP manual. 请参阅PHP手册中的此页面

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

Another source of troubles (for VERY large texts) is UTF8 encoding. 麻烦的另一个来源(对于非常大的文本)是UTF8编码。 You might find yourself with a "six megabytes" TEXTAREA that is actually 6 mega*characters*, and with international codepoints it might run to, say, 8.2 megabytes. 您可能会发现自己拥有一个“ 6兆字节”的TEXTAREA,实际上是6兆*个字符*,而使用国际代码点,它可能会达到8.2兆字节。 Thus you get an apparently contradictory situation of "six megabytes data exceed the configured 8 megabytes limit". 因此,您会看到“ 6兆字节数据超出配置的8兆字节限制”的明显矛盾的情况。

Update 更新资料

You report two apparently contradictory facts: 您报告了两个明显矛盾的事实:

PHP settings as follows (from phpinfo()):

    post_max_size = 64M

and

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

It is clear from the PHPINFO that the limit for POST is 64M . 从PHPINFO可以明显看出POST的限制是64M Yet the error says that the limit is 8M (the default). 但是该错误表明限制为8M (默认值)。 So it seems to me that your code is talking to two different PHP implementations (Two different virtual hosts? A CGI version and a non-CGI version in the same host? Two different machines ?) 因此在我看来,您的代码正在与两个不同的PHP实现进行对话 (两个不同的虚拟主机?同一主机中的一个CGI版本和一个非CGI版本?两个不同的机器 ?)

IIS will re-use the FastCGI processes. IIS将重新使用FastCGI进程。 You will need to kill off any old processes to get php.ini to reload. 您将需要杀死所有旧进程才能重新加载php.ini。

Edit the FastCGI module and edit 'monitor changes to file' and select the php.ini file. 编辑FastCGI模块并编辑“监视文件更改”,然后选择php.ini文件。 This will force the child processes to restart whenever you save an edit. 每当您保存编辑时,这将强制子进程重新启动。

You could turn the limits to -1, that way, you won't ever have troubles about the size of the files. 您可以将限制设置为-1,这样就永远不会遇到文件大小的麻烦。 It is probably no the best solution as you are basically saying "if I don't see it, it doesn't exist", but believe, it's really reliable and will always work. 这可能不是最好的解决方案,因为您基本上是在说“如果我看不到它,它就不存在”,但是请相信,它确实可靠并且将始终有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM