PHP中如何处理临时图片上传?
我正在用 PHP 创建一个在线游戏,用户可以在其中创建可玩的角色。每个角色都可以有一个用户上传的肖像。一个玩家可以同时拥有多个角色,并且他们的图片可以随时更改。当然,必须调整图片大小并重新压缩以避免文件过大。这是我的问题:
当玩家更改他的数据(其中包括图片),然后点击“保存”时,服务器端验证就会启动。它会检查诸如非唯一角色名称、空必填字段等内容。如果有任何错误找到后,就会显示它们。在这种情况下,表单应该预先填充玩家输入的数据,因此他只需更改错误位,而不必重新输入所有内容。但如何保存这种“临时”状态的图片呢?
我无法预先填充文件上传字段,浏览器不允许这样做。如果我将其保存在临时文件中,则必须在某个时候清理图片,因为玩家可以简单地关闭浏览器并中止整个过程。那应该是什么时候呢?我应该为临时文件选择什么文件名?如果玩家在两个浏览器选项卡中打开相同的角色进行编辑,它们不应该发生冲突(每个角色都应该有自己的副本)。
你会如何解决这个问题?
I'm creating an online game in PHP where users can create playable characters. Each character can have a user-uploaded portrait. A player can simultaneously have multiple characters, and the pictures for them can be changed anytime. Naturally, the pictures have to be resized and re-compressed to avoid huge files. Here's my problem:
When the player changes his data (among it the picture), and then hits "save", server side validation kicks in. It checks for things like non-unique character names, empty mandatory fields, etc. If any errors are found, they are displayed. In this case the form should be pre-populated with the data the player entered, so he only has to change the faulty bit, not re-type everything. But how do you save the picture in such a "temporary" state?
I cannot pre-populate the file upload field, the browsers don't allow that. If I save it in a temporary file, the picture then has to be cleaned up at some point, because the player can simply close his browser and abort the whole process. When should that be? And what file name should I choose for the temporary file? If the player opens the same character to edit in two browser tabs, they should not conflict (each of them should have their own copy).
How would you solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我将文件保存到临时位置,并在文件名中存储唯一标识符以及当前时间戳。然后将文件名放入用户会话中。当用户成功创建或更新其帐户后,您可以将图像文件保存到其永久位置并删除临时文件。您可以运行 cron 进程来扫描临时目录并检查时间戳,删除任何早于过期时间(可能一小时)的文件。
如果您无法运行 cron 作业,您始终可以在每次成功创建/更新验证时启动目录清理。这可能效率较低(每次成功提交都会进行额外的目录读取和可能的文件操作),但除非您正在处理大量流量,否则您可能不会注意到。
I'd save the file to a temporary location and store both a unique identifier as well as the current timestamp in the filename. Then put the filename in the user's session. When a user has successfully created or updated their account, you save the image file to its permanent location and remove the temporary file. You can run a cron process to scan the temporary directory and check the timestamps, deleting any files older than your expiration (an hour perhaps).
If you're unable to run a cron job, you could always just launch the directory clean-up each time you have a successful create/update validation. This might be a bit more inefficient (extra directory reads and possibly file operations for every successful submission) but unless you're dealing with a lot of traffic, you probably won't even notice.
创建一个表来保存对图像的引用。
上传文件时,如果它是有效图像,请执行所有调整大小等操作,并在表中创建指向该文件的记录。
将参考记录的 ID 与表单数据一起传递。当您重新显示表单时显示图像,以便用户知道他们不必重新上传。
当您最终接受新的角色对象时,设置 avatar_id 或其他内容。
运行常规 cron 作业来剔除孤立的映像记录(同时删除磁盘上的文件)。
Create a table to hold references to images.
When a file is uploaded, if it's a valid image, do all your resizing, etc, and create a record in the table that points at the file.
Pass the id of the reference record around with the form data. Display the image when you redisplay the form, so the user knows they don't have to re-upload.
When you finally accept the new character object, set avatar_id or whatever.
Run a regular cron-job to cull orphaned image records (deleting the files on disk as well).
您始终可以填充禁用的文本框来保存图片的名称 - 它不会填充浏览输入字段,但总比没有好。对于编辑,为了避免冲突,您可以为每个用户的角色创建一些“修改”列,并根据角色编辑请求将值更改为 true。当用户保存该角色时,将其设置回 false。对于每个编辑请求,仅当“修改”为 false 时才授予它。
You could always populate a disabled text box to hold the name of the picture - it won't populate the browse input field, but is better than nothing. For editing, to avoid conflicts you could create some a "modifing" column for each user's characters, and on a character editing request change the value to true. When the user saves the character, set it back to false. For each edit request, grant it only when the "modifing" is false.
我建议立即更新图像,无论表单中是否有错误,或者将图像更新分离到单独的表单中。这样您就可以解决两个问题,而无需复杂的状态机和清理工作。
I'd recommend either updating the image immediately, regardless of error in the form, or separating the image updating to a separate form. That way you'll get rid of two problems without complex state machines and cleaning up.