简体   繁体   English

PHP文件上传问题

[英]PHP file upload problem

I've got a really annoying problem with file uploads.我在文件上传方面遇到了一个非常烦人的问题。

Users can choose a file in an html file field.用户可以在 html 文件字段中选择文件。 When they submit the form, this file will be uploaded.当他们提交表单时,该文件将被上传。

On the serverside I just use standard PHP code (move_uploaded_file).在服务器端,我只使用标准 PHP 代码(move_uploaded_file)。 I do nothing weird.我没有做任何奇怪的事情。

Everything works perfectly.一切都很完美。

I can see the file on the server, I can download it again, ...我可以在服务器上看到文件,我可以再次下载它,...

However sometimes this doesn't work.但是有时这不起作用。 I upload the file, process it and I get no errors.我上传文件,处理它,我没有收到任何错误。

But the file just doesn't exist on the server.但是该文件在服务器上不存在。

Each time I upload that specific file I get no errors but it never gets saved.每次我上传该特定文件时,我都没有收到任何错误,但它永远不会被保存。

Only if I rename it (test.file to tst.file for example) I can upload it and it'll actually get saved.只有当我重命名它(例如 test.file 到 tst.file)我才能上传它并且它实际上会被保存。

I get this problem very rarely.我很少遇到这个问题。 And renaming always works.重命名总是有效的。 But I can't ask users to rename their files obviously...但我显然不能要求用户重命名他们的文件......

I have no access to the apache tmp file directory, no access to logs or settings so this makes debugging even harder.我无法访问 apache tmp 文件目录,也无法访问日志或设置,因此这使得调试更加困难。 I only have this problem on this particular server (which I don't manage; I don't even have access to it) and I use the exact same code on lots of servers that don't have this problem.我只在这个特定的服务器上遇到这个问题(我不管理它;我什至无权访问它),我在许多没有这个问题的服务器上使用完全相同的代码。

I would be grateful if someone could help me out here or point me in the right direction.如果有人可以在这里帮助我或为我指明正确的方向,我将不胜感激。

Trying adding this debug code:尝试添加此调试代码:

echo '<pre>';
print_r($_FILES);
echo '</pre>';

You should see an error number.您应该会看到一个错误编号。 You can lookup what it means at http://uk3.php.net/manual/en/features.file-upload.errors.php您可以在http://uk3.php.net/manual/en/features.file-upload.errors.php查找它的含义

Might also be worth checking to make sure the destination file doesn't already exist.可能还值得检查以确保目标文件不存在。

My first thought was filesize issues.我的第一个想法是文件大小问题。 In the php.ini, if the post_max_size or upload_max_filesize are too small, you can end up with similar results - where the file just seems to disappear.在 php.ini 中,如果 post_max_size 或 upload_max_filesize 太小,您可能会得到类似的结果 - 文件似乎消失了。 You would get an error in the apache logs (which you mention you've no access to).您会在 apache 日志中收到错误(您提到您无权访问)。

In those cases, the $_FILES array would simply be empty - as if the file never arrived.在这些情况下,$_FILES 数组只是空的——就好像文件从未到达一样。 Since your responses to Gumbo and James Hall show that php is reporting a proper upload, I'm led to wonder about the processing you mention.由于您对GumboJames Hall的回复表明 php 正在报告正确的上传,因此我不知道您提到的处理。

If, during the process, your memory gets maxed or the script runs too long, the script may be dying out before it gets a chance to move it.如果在此过程中,您的 memory 被最大化或脚本运行时间过长,则脚本可能在它有机会移动它之前就消失了。 You'll want to check these:您需要检查这些:

memory_limit内存限制

max_execution_time max_execution_time

max_input_time最大输入时间

Otherwise, without the apache logs, I'd say it might be a good idea to start outputting to a log file of your own throughout your file processing script.否则,如果没有 apache 日志,我会说在整个文件处理脚本中开始输出到您自己的日志文件可能是个好主意。 Try a file_exists on the tmp file, see what info you can get from the file (permissions, etc).在 tmp 文件上尝试 file_exists,看看你可以从文件中获得什么信息(权限等)。

Unfortunately PHP doesn't get involved until the upload is finished, which means you won't get much info during - only after the fact.不幸的是,PHP 在上传完成之前不会参与其中,这意味着您在此期间不会获得太多信息 - 只有在事后才能获得。 You best option might be to talk to the hosting company and get access to the logs - even if for a short time.您最好的选择可能是与托管公司交谈并访问日志 - 即使是很短的时间。 In my experience, I've rarely had trouble getting ot the logs - or at least getting a tech to check the logs for me while I run tests (in the case where a shared server doesn't split their logs - seems ridiculous, but I've seen it before).根据我的经验,我在获取日志时很少遇到麻烦——或者至少在我运行测试时让技术人员为我检查日志(在共享服务器不拆分日志的情况下——看起来很荒谬,但是我以前见过)。

Edit: I realize you can't change those php settings, but you might want to see what they are in order to find out if they're potential problems for your script.编辑:我知道你不能改变那些 php 设置,但你可能想看看它们是什么,以便找出它们是否对你的脚本有潜在的问题。 For instance, a low memory limit will kill your processor script if it's less than the size of the uploaded file.例如,如果 memory 的低限制小于上传文件的大小,它将终止您的处理器脚本。

This is what you said...这就是你说的...

"I have no access to the apache tmp file directory, no access to logs or settings so this makes debugging even harder. I only have this problem on this particular server (which I don't manage; I don't even have access to it) and I use the exact same code on lots of servers that don't have this problem." “我无法访问 apache tmp 文件目录,无法访问日志或设置,因此这使得调试更加困难。我只在这个特定的服务器上遇到这个问题(我无法管理;我什至无法访问它)并且我在许多没有此问题的服务器上使用完全相同的代码。”

According to what you said above, I assume that you are using a server that is shared among many users.根据您上面所说,我假设您正在使用一个在许多用户之间共享的服务器。 If the Apache of this server is configured with something like "mod_suphp", then your PHP scripts will be executed using the privileges of your UNIX user account ("jef1234", for example), which means the files you create will have you ("jef1234") as the owner (instead of "apache" or "www-data"). If the Apache of this server is configured with something like "mod_suphp", then your PHP scripts will be executed using the privileges of your UNIX user account ("jef1234", for example), which means the files you create will have you (" jef1234”)作为所有者(而不是“apache”或“www-data”)。

The system's temporary directory (usually "/tmp") is usually configured with the "sticky bit" on.系统的临时目录(通常是“/tmp”)通常配置有“sticky bit”。 This means everyone can create files in this directory, but the created files are only accessible by the owner (you may treat this as the one who created it).这意味着每个人都可以在此目录中创建文件,但创建的文件只能由所有者访问(您可以将其视为创建它的人)。

As a result, if the server configuration is not careful enough, you may have file naming collisions with other users' files.因此,如果服务器配置不够仔细,您可能会与其他用户的文件发生文件命名冲突。 For example, when you upload "test.file", if another user has already uploaded another file with the same name, the system refuses to overwrite the file created by him, as thus you have to use another name.例如,当您上传“test.file”时,如果另一个用户已经上传了另一个同名文件,系统将拒绝覆盖他创建的文件,因此您必须使用另一个名称。

Usually the problem does not exist because PHP is smart enough to generate temporary names for the uploaded file (ie. $_FILES["html_form_input_name"]["tmp_name"]).通常问题不存在,因为 PHP 足够聪明,可以为上传的文件生成临时名称(即 $_FILES["html_form_input_name"]["tmp_name"])。 If somehow you can confirm that this is really the reason, the server is obviously mis-configured.如果您能以某种方式确认这确实是原因,那么服务器显然配置错误。 Tell your system administrator the problem as ask him to solve it.将问题告诉您的系统管理员,要求他解决。 If this could not be solved, you may do some JavaScript tricks on the name of the file before it is uploaded (not tested, just an idea)...如果这不能解决,您可以在文件上传之前对文件名做一些 JavaScript 技巧(未经测试,只是一个想法)...

When the user submits the form, rename the file from, for example, "test.file" to "jef1234-test.file-jef1234". 当用户提交表单时,将文件重命名,例如从“test.file”改为“jef1234-test.file-jef1234”。 After the file is uploaded, move the file (ie move_uploaded_file() ) to another place and rename it to the original filename by removing the added strings.文件上传后,将文件(即move_uploaded_file() )移动到另一个地方,并通过删除添加的字符串将其重命名为原始文件名。

Hope this helps...希望这可以帮助...

Asuka Kenji明日香健二

If an upload failes you don't get the same kind of error like a PHP syntax error or such.如果上传失败,您不会收到类似 PHP 语法错误等错误。

But you can check the file upload status and report the error to the user yourself.但是您可以自己检查文件上传状态并向用户报告错误。

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

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