PHP-多个用户同时编辑同一图像

PHP-多个用户同时编辑同一图像,php,image-processing,gd,Php,Image Processing,Gd,我希望有多个用户使用gd库的imagecopymerge功能编辑相同的图像 我担心两个用户可能会选择同时编辑图像。然后应用程序分别合并两个用户的图像,最后保存它们,但其中一个覆盖了另一个,因此其中一个用户图像丢失 我不知道如何测试以上。。。有可能吗?如果有,我该如何应对?在用户开始编辑图像时存储上次修改的时间戳。当他们提交更改时,再次对照上次修改的时间戳进行检查。如果不同,则通知用户其他用户已修改图像 在选择覆盖之前,您可能希望让用户看到图像的新版本。此外,您可能希望提供一个版本控制系统(维基百

我希望有多个用户使用gd库的imagecopymerge功能编辑相同的图像

我担心两个用户可能会选择同时编辑图像。然后应用程序分别合并两个用户的图像,最后保存它们,但其中一个覆盖了另一个,因此其中一个用户图像丢失


我不知道如何测试以上。。。有可能吗?如果有,我该如何应对?

在用户开始编辑图像时存储上次修改的时间戳。当他们提交更改时,再次对照上次修改的时间戳进行检查。如果不同,则通知用户其他用户已修改图像

在选择覆盖之前,您可能希望让用户看到图像的新版本。此外,您可能希望提供一个版本控制系统(维基百科),让人们回滚更改

编辑(回应以下评论)

  • 与存储上一次修改的时间戳(或者除此之外)不同,存储原始图像的散列。并在覆盖之前立即进行比较。否则同上

  • 正如你所建议的,另一个选择也会很好。在工作流的第3步中,创建一个[imagefilename]。在流程开始时锁定文件(或修改数据库中存储的字段,如果该文件不存在),当然,如果确实存在,则如上所述

  • 要扩展上面第2点中的DB选项,使用如下表会简单得多: 图像|标识|图像|数据

    查询开始时包含md5(可选地使用php计算md5,以减少数据库的负载)

    那么当你想回信的时候,就去做吧

    update image_table set image_data=? where image_id=? and md5(image_data)=?
    
    这使得更新的条件是md5在被覆盖之前是相同的,并且它保留在一个简单的查询中

    然后检查受影响的_行。如果没有行受到影响,则检查哈希。如果散列不同,则可能由于md5检查,查询更新失败。(注意:您可能还需要检查任何mysql错误)


  • 啊,你基本上想要的是保存相对于原始图像的增量

    单向:

  • 用户Fred获取原始源图像I1并对其进行编辑。弗雷德发回了整个新形象
  • 计算图像D1的增量,即{N1-O}。您可以从磁盘中检索当前映像I2,而不是只保存覆盖N1(I1不需要等于I2)。将D1应用于I1,并用结果图像覆盖图像,我们称之为I3。
    注意,您需要记住I1,以便在$\u会话中使用它
  • 现在,另一个Ria可以在前面的步骤中编辑相同的图像。例如,弗雷德得到I1后不久,里娅也得到了。就在Ria完成工作之前,Fred将他的增量保存在磁盘上,生成了I3,正如我们所看到的。那现在呢? 你盲目地应用步骤2。我将展示发生了什么:User2提交了他的工作N2,通过比较I1和N2来计算delta D2(Ria的会话包含I1)。当前映像是从磁盘中检索的,您可能正确地记得,磁盘是I3。此增量D2应用于I3,生成I4,并保存到磁盘。结果是Ria覆盖了I3,但只覆盖了她实际编辑的部分
  • 这个方法会起作用,因为文件保存在php中是一个原子操作

    要使其正常工作

  • 您需要确保当用户a检索到要编辑的图像时,我需要存储在a的会话中。简单
  • 您需要能够计算图像的差异,并将此差异应用于图像。例如,这应该是可能的。看看这个url的例子,你会发现在diff中,白色像素是那些未被触动的
    很抱歉,我没有说清楚-编辑实际上只是将一张图片添加到一张大图中,所以需要几毫秒的时间。。。因此,我认为时间戳不会有什么不同。理想情况下,我会有某种交易系统。@Mark:这当然是一种选择。不过,我认为您可能需要更详细地解释工作流程。是:1)用户选择大图像添加;2) 用户选择要添加到图像中的图片;3) 用户选择要添加图片的位置。在第3步完成时,大图像会被修改?抱歉,不清楚。1) 用户选择大图像2)他们上传自己的图像3)(这是危险的部分)打开大图像,插入他们的图像,覆盖旧的大图像。我担心两个用户可能同时达到第三步。因此,这意味着我的应用程序将打开一个没有添加任何用户的大映像版本,然后将用户映像添加到其大映像版本中,从而生成两个不同版本的大映像(一个包含usr1的添加,另一个包含usr2的添加)表示最后一次保存将覆盖其他内容谢谢您的输入。您关于在数据库中检查md5的想法大大减少了机会,但仍然不是真正的事务性的,因为仍然需要节省映像的时间。但是,我喜欢修改数据库中的字段的想法。我甚至没有想过使用数据库。考虑到这一点,我可以使用innodb表,在与大图像相关的行上启动一个事务,然后合并并保存图像,然后解锁它。这意味着它是真正的事务性的,不需要在数据库中更改任何数据……只需要一个毫秒的行锁。
    update image_table set image_data=? where image_id=? and md5(image_data)=?