使用 Ajax 的拖放命名服务器上的文件

Naming files on server using Ajax's drag and drop

我正在使用不允许重新排序文件的基本多重上传 Javascript。我希望能够拖放图片并将它们的新位置保存在服务器上。 棘手的部分是我没有将这些文件存储在数据库中

上传过程就是这样进行的:如您所见,这是一个简单的循环,将图片从 001.jpg 重命名为 099.jpg 并将它们放在正确的文件夹中。

if(isset($_FILES['images']) && $_FILES['images']['size'] > 0) {
        if(!file_exists('images/upload/' . $id_client . '/photos/' . $gallery)) {
            mkdir('images/upload/' . $id_client . '/photos/' . $gallery);
        }
        else {
            $gallery = $data_m[0]['gallery'];
        }
        $i = htmlspecialchars(trim($_POST['nb_img']) + 1);
        foreach($_FILES['images']['tmp_name'] as $index => $tmpName) {
            if(!empty($tmpName) && is_uploaded_file($tmpName)) {
                if(substr($_FILES['images']['type'][$index], 0, 5) == "image") {
                    if($i < 10) {
                        $img_url = '00' . $i . '.' . pathinfo($_FILES['images']['name'][$index], PATHINFO_EXTENSION);
                    }
                    else {
                        $img_url = '0' . $i . '.' . pathinfo($_FILES['images']['name'][$index], PATHINFO_EXTENSION);    
                    }
                    move_uploaded_file( $tmpName, $dir_upload . '/photos/' . $gallery . '/'. $img_url);
                }
            }
            $i++;
        }
    }

显示非常简单:页面只是检查文件夹并按字母顺序显示内容:

if(!empty($data['gallery']) && file_exists($dir_upload . '/photos/' . $data['gallery'])) {
            $dirname = $dir_upload . '/photos/' . $data['gallery'];
            $gallery = scandir($dirname);
            asort($gallery);
            $row = 1;
            echo '<div class="gallery">';
                echo '<div class="row">';
                foreach($gallery as $pix) {
                    if(!empty($pix) && $pix != '.' && $pix != '..') {
                        if($row >5) { 
                            echo '</div>'; 
                            echo '<div class="row">';
                            $row = 1; 
                        }
                        $url_img = $dirname . '/' . $pix;
                        echo '<a class="col-md mt-1 mr-1 mb-1 ml-1 btn btn-secondary img-'.$row.' disabled" href="' . $url_img . '" rel="clearbox[gallery=' . $data['gallery'] . ']" style="background:url(' . $url_img . ') center; background-size:cover; height:210px;">';
                        echo '</a>';
                        $row++;
                    }
                }
                echo '</div>';
            echo '</div>';
        }

我的直接需求是能够简单地拖放图片并在服务器上重命名它们。例如,如果我将 005.jpg 拖到第三个位置,它会将其重命名为 002-1608378266.jpg(添加实际的时间戳,使其位于 003.jpg 之前而不删除之前的文件)。

我知道这不是最佳选择(甚至不确定这是否可行)并且我已经在研究数据库解决方案,但我需要一个紧急解决方案来让用户在开发新脚本时冷静下来。

您可以使用 ID 和密码查看测试服务器 Whosebug : https://www.0000.yelofox.fr/page-10-at-vero-eos-et-accusam

感谢那些愿意帮助我的人!

我们能够在聊天中查个水落石出,这里是一个建议的解决方案:

图像的顺序存储在 JSON 文件中。当我们想要获取图库包含的图像列表时,然后会读取该文件,并在添加新图像和用户对这些图像进行排序时进行更新。

为了完成这个,我制作了一个只包含实用函数的文件和一个演示页面:

utils.php

<?php 

/**
 * Returns the path to a gallery's directory
 */
function getClientGalleryDirPath($clientId, $gallery) {
  return 'images/upload/' . $clientId . '/photos/' . $gallery;
}

/**
 * Returns the path to a gallery's data file
 */
function getClientGalleryDataPath($clientId, $gallery) {
  return getClientGalleryDirPath($clientId, $gallery) . '/data.json';
}

/**
 * Makes sure the client's gallery has a directory, and a JSON file
 * containing the list of images
 */
function ensureClientGalleryExists($clientId, $gallery) {
  $dirPath = getClientGalleryDirPath($clientId, $gallery);

  if(!file_exists($dirPath)) {
    mkdir($dirPath, 0755, true);
  }

  $jsonPath = getClientGalleryDataPath($clientId, $gallery);

  if (!file_exists($jsonPath)) {
    // Create an empty Array
    $data = [];

    // If pictures exist, we'll add them
    $pictureFiles = scandir($dirPath);
    foreach($pictureFiles as $pic) {
      if(!empty($pic) && $pic != '.' && $pic != '..') {
          array_push($data, $pic);
      }
    }
    // Make the Array a JSON string, and save it
    $json = json_encode($data);
    file_put_contents($jsonPath, $json);
  }
}

/**
 * Ensures the gallery is created, and returns the data
 */
function getOrCreateClientGallery($clientId, $gallery) {
  // Make sure it exists
  ensureClientGalleryExists($clientId, $gallery);

  $dataPath = getClientGalleryDataPath($clientId, $gallery);
  $json = file_get_contents($dataPath);

  return json_decode($json, true);
}

/**
 * Saves new data in a client's gallery
 */
function saveClientGallery($clientId, $gallery, $data) {
  // Make sure it exists
  ensureClientGalleryExists($clientId, $gallery);

  $dataPath = getClientGalleryDataPath($clientId, $gallery);
  $json = json_encode($data);

  return file_put_contents($dataPath, $json);
}

/**
 * Uploads pictures, and updates the gallery data
 */
function addPicturesToGallery($clientId, $gallery, $files) {
  // Get the existing data
  $data = getOrCreateClientGallery($clientId, $gallery);
  $dirPath = getClientGalleryDirPath($clientId, $gallery);

  foreach($files['tmp_name'] as $index => $tmpName) {
    if (
         !empty($tmpName) &&
         is_uploaded_file($tmpName) &&
         substr($files['type'][$index], 0, 5) == "image"
       ) {
         // Create a unique name, and move the file
         $newName = uniqid() . '.' . pathinfo($files['name'][$index], PATHINFO_EXTENSION);
         move_uploaded_file($tmpName, $dirPath . '/'. $newName);
         // Add the new name to $data 
         array_push($data, $newName);
    }
  }

  // We're done, save the data
  saveClientGallery($clientId, $gallery, $data);
}

/**
 * Compares the new list with the previous one, and updates it
 */
function  reorderClientGallery($clientId, $gallery, $newData) {
  $oldData = getOrCreateClientGallery($clientId, $gallery);

  // Make sure that every element is present in both Arrays
  // (otherwise there's something wrong with the provided data)
  if (
       count(array_diff($oldData, $newData)) == 0 &&
       count(array_diff($newData, $oldData)) == 0
     ) {
       saveClientGallery($clientId, $gallery, $newData);
  }
}

index.php

<?php 

require_once('utils.php');

// Just for the demo, let's say that:
$clientId = 'robert';
$gallery = 'my-first-gallery';

// If pictures were sent, upload them
if (isset($_FILES['images']) && $_FILES['images']['size'] > 0) {
  addPicturesToGallery($clientId, $gallery, $_FILES['images']);
}

// If a picture ordering was sent, apply it
if (isset($_POST['order'])) {
  reorderClientGallery($clientId, $gallery, json_decode($_POST['order']));
}



// To avoid cluttering the HTML below, I declared this here
function displayGalleryItems($clientId, $gallery) {
  $dirPath = getClientGalleryDirPath($clientId, $gallery);
  // Get the gallery and display it
  $data = getOrCreateClientGallery($clientId, $gallery);
  foreach($data as $pic) {
    echo '<div class="pic" data-pic="' . $pic . '" style="background-image: url(\'' . $dirPath . '/' . $pic . '\')"></div>';
  }
}

?><!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My gallery</title>
  <style>
    #saveBtn { display: none; } /* will only be displayed after reordering */
    .pic { display: inline-block; width: 250px; height: 190px; background-size: cover; margin: .5em; }
  </style>
</head>
<body>
  <h1><?=$gallery?></h1>

  <p>Add pictures to your gallery:</p>
  <form method="post" enctype="multipart/form-data">
    <input type="file" name="images[]" multiple>
    <input type="submit">
  </form>

  <div id="sortable">
    <?php displayGalleryItems($clientId, $gallery); ?>
  </div>

  <form method="post">
    <input type="hidden" name="order">
    <input type="submit" value="Enregistrer" id="saveBtn">
  </form>

  <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
  <script>
  $(function() {
    $("#sortable").sortable({
      revert: 200,
      update: function() {
        // Every time the order changes, grab the filenames
        var order = $('.pic').map(function(i, p) { return $(p).attr('data-pic'); }).toArray();
        // Set the form input's value
        $('input[name="order"]').val( JSON.stringify(order) );
        // Show the save button
        $('#saveBtn').show();
      }
    });

    $(".pic").disableSelection();
  });
  </script>
</body>
</html>