PHP - несколько пользователей редактируют одно и то же изображение одновременно - PullRequest
1 голос
/ 28 ноября 2009

Я хочу, чтобы несколько пользователей редактировали одно и то же изображение с помощью функции imagecopymerge библиотеки gd.

Я обеспокоен тем, что два пользователя могут выбрать редактирование изображения одновременно. Затем приложение объединяет изображения двух пользователей по отдельности и, наконец, сохраняет их, но одно перезаписывает другое, и поэтому одно из изображений пользователей отсутствует.

Я не уверен, как проверить вышеизложенное ... возможно ли это, и если да, то как с этим бороться?

Ответы [ 2 ]

2 голосов
/ 28 ноября 2009

Сохранить последнюю измененную временную метку, когда пользователь начинает редактировать изображение. когда они отправляют свои изменения, снова сверяйтесь с последней измененной отметкой времени. Если он отличается, сообщите пользователю, что другой пользователь уже изменил изображение.

Возможно, вы захотите позволить пользователю увидеть новую версию изображения, прежде чем выбрать перезапись. Кроме того, вы можете захотеть предоставить систему контроля версий (а-ля Википедия), чтобы люди могли откатывать изменения.

РЕДАКТИРОВАТЬ (В ответ на комментарии ниже)

  1. В отличие от сохранения последней измененной отметки времени (или, возможно, в дополнение к), сохраняйте хэш исходного изображения. и сравните их непосредственно перед перезаписью. В остальном то же, что и выше.

  2. Другой вариант, как вы предложили, также будет работать хорошо. на шаге 3 вашего рабочего процесса создайте файл [imagefilename] .lock (или измените поле в БД, если они там хранятся) в начале процесса, если он еще не существует, конечно, если он существует, так же, как и выше.

  3. Чтобы расширить опцию DB в пункте 2 выше, было бы намного проще иметь такую ​​таблицу: image_id | image_data

    запрос, включая md5, когда вы начинаете (опционально вместо этого вычисляйте md5 в php, чтобы уменьшить нагрузку на вашу базу данных)

    select image_data, md5(image_data) from image_table where image_id=1
    

    Затем, когда вы хотите написать обратно, выполните

    update image_table set image_data=? where image_id=? and md5(image_data)=?
    

    Это делает условие обновления для md5 идентичным перед перезаписью, и оно остается в одном простом запросе.

    Тогда проверь пострадавшего. Если ни одна строка не была затронута, проверьте хеш. Если хеш отличается, то, вероятно, запрос не удалось обновить из-за проверки md5. (Примечание: вы, вероятно, также захотите проверить наличие ошибок mysql)

0 голосов
/ 28 ноября 2009

Ах, то, что вы в основном хотите, это сохранение дельта относительно исходных изображений.

В одну сторону:

  1. Пользователь Фред выбирает исходное исходное изображение I1 и редактирует его. Фред отправляет обратно совершенно новое изображение N1
  2. Вы вычисляете дельту изображения D1, то есть {N1 - O}. Вместо сохранения только перезаписи N1 вы извлекаете текущее изображение I2 с диска, которое могло бы быть изменено за это время (I1 не обязательно должно быть равно I2). Вы применяете D1 к I1 и перезаписываете изображение полученным изображением, которое мы называем I3.
    Осторожно, вам нужно помнить I1, чтобы это работало в $ _SESSION, например.
  3. Теперь другая Риа может редактировать то же изображение на предыдущих шагах. Например, вскоре после того, как Фред получил I1, Риа тоже получила его. Незадолго до того, как Риа закончила свою работу, Фред сохранил свою дельту на диске, что привело к I3, как мы видели. И что теперь? Вы слепо применяете шаг 2. Я покажу, что происходит: пользователь2 представляет свою работу N2, дельта D2 вычисляется путем сравнения I1 с N2 (сеанс для Ria содержит I1). Текущее изображение извлекается с диска, который является I3, как вы, возможно, правильно помните. Эта дельта D2 применяется к I3, в результате чего получается I4, который сохраняется на диск. В результате Риа переписала I3, но только те части, которые она на самом деле редактировала.

Этот рецепт будет работать, потому что сохранение файла является атомарной операцией в php.

Чтобы это заработало :

  1. вам нужно убедиться, что когда пользователь А извлекает изображение I для редактирования, я должен быть сохранен в сеансе А. Легко.
  2. Вы должны иметь возможность вычислить разность изображения и применить этот различие к изображению. Это должно быть возможно с функцией сравнения imagemagick например. Посмотрев на пример этого URL, вы увидите, что в разных белых пикселях нетронутые.
...