【问题标题】:PDOException on Duplicate filename in Drupal 7Drupal 7 中重复文件名的 PDOException
【发布时间】:2012-01-10 19:07:43
【问题描述】:

使用以下代码:

foreach ($form_state['values']['uploads'] as $key => $value) {
if (strlen($value)) {
  $file = file_save_upload($key, array(
    'file_validate_is_image' => array(), // Validates file is really an image. 
    'file_validate_extensions' => array('png gif jpg jpeg'), // Validate extensions.
  ));
  // If the file passed validation:
  if ($file) {
    // Move the file, into the Drupal file system
    if ($file = file_move($file, 'public://')) {
     // Save the file for use in the submit handler.
     $form_state['values']['uploaded_photos'][] = $file;
             $x++;
    } else {
     form_set_error($key, t('Failed to write the uploaded file the site\'s file folder.'));
    }
  }
}

}

我正在尝试使用 CTools 将附加到表单的图像保存到缓存对象中。所有这些都运行良好,直到我尝试再次上传相同的文件,我得到一个白屏,上面写着“错误 - 网站遇到错误”。 (来自看门狗):

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'public://ad-10.jpg'; for key 2: UPDATE {file_managed} SET uid=:db_update_placeholder_0, filename=:db_update_placeholder_1, uri=:db_update_placeholder_2, filemime=:db_update_placeholder_3, filesize=:db_update_placeholder_4, status=:db_update_placeholder_5, timestamp=:db_update_placeholder_6
WHERE  (fid = :db_condition_placeholder_0) ; Array
(
[:db_update_placeholder_0] => 0
[:db_update_placeholder_1] => ad-10.jpg
[:db_update_placeholder_2] => public://ad-10.jpg
[:db_update_placeholder_3] => image/jpeg
[:db_update_placeholder_4] => 4912
[:db_update_placeholder_5] => 0
[:db_update_placeholder_6] => 1326221376
[:db_condition_placeholder_0] => 834
)
";s:9:"%function";s:21:"drupal_write_record()";

由于我没有设置 $replace 参数,它不应该默认为 FILE_EXISTS_RENAME 并因此不会引发此错误吗?我该如何解决这个问题?

【问题讨论】:

    标签: drupal drupal-7


    【解决方案1】:

    试试这个模块。它修复了并发文件对象被写入数据库的问题。 https://drupal.org/project/upload_qc

    【讨论】:

      【解决方案2】:

      我无法评论为什么这不起作用(看起来确实应该),但我可以提供一个更简单的解决方案。

      Drupal 实际上有一个内置的表单小部件来处理文件上传,managed_file 类型。它为您处理所有文件上传/验证,您只需在表单的提交处理程序中将文件标记为永久文件。

      所以在你的表单函数中:

      $form['files'] = array('#tree' => TRUE);
      
      for ($i = 0; $i < $num_file_fields; $i++) {
        $form['files']["file_$i"] = array(
          '#type' => 'managed_file',
          '#title' => 'Select a file',
          '#upload_location' => 'public://',
          '#upload_validators' => array(
            'file_validate_is_image' => array(),
            'file_validate_extensions' => array('png gif jpg jpeg')
          )
        );
      }
      

      然后在您的提交处理程序中:

      $count = count($form_state['values']['files']);
      
      for ($i = 0; $i < $count; $i++) {
        $file = file_load($form_state['values']['files']["file_$i"]);
        $file->status = FILE_STATUS_PERMANENT;
        file_save($file);
      }
      

      希望有帮助

      【讨论】:

      【解决方案3】:

      由于奇怪的未使用临时文件,我遇到了同样的问题。 您可以使用以下方法检查是否有未使用的文件:

      $result = db_select('file_managed', 'f')
          ->fields('f', array('fid'))
          ->condition('f.uri', db_like('temporary://') . '%', 'LIKE')
          ->execute()->fetchCol();
      
      foreach ($result as $fid) {
        if ($file = file_load($fid)) {
          if (!file_usage_list($file)) {
            dpm($file->filename);
          }
        }
      }
      

      如果您未能上传您看到的同名文件,您可以将其删除(请先仔细检查并备份):

      /**
       * Clean unused temporary files.
       */
      function MYMODULE_update_7007() {
        $files = db_select('file_managed', 'f')
          ->fields('f', array('fid'))
          ->condition('f.uri', db_like('temporary://') . '%', 'LIKE')
          ->execute()->fetchCol();
        foreach ($files as $fid) {
          if ($file = file_load($fid)) {
            $references = file_usage_list($file);
            if (empty($references)) {
              if (!file_delete($file)) {
                watchdog('file system', 'Could not delete temporary file "%path" during garbage collection', array('%path' => $file->uri), WATCHDOG_ERROR);
              }
            }
            else {
              watchdog('file system', 'Did not delete temporary file "%path" during garbage collection, because it is in use by the following modules: %modules.', array('%path' => $file->uri, '%modules' => implode(', ', array_keys($references))), WATCHDOG_INFO);
            }
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-11
        • 2011-11-27
        • 2011-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多