【问题标题】:upload images through php using unique file names使用唯一文件名通过 php 上传图像
【发布时间】:2013-03-09 06:58:58
【问题描述】:

我目前正在借助 phonegap 编写移动应用程序。我希望这个应用程序具有的少数功能之一是能够捕获图像并将其上传到远程服务器......

我目前的图像捕获和上传/发送电子邮件部分可以使用已编译的 apk 正常工作...但在我的 php 中,我目前将图像命名为“图像 [插入从 10 到 20 的随机数]...问题这里是数字可以重复并且图像可以被覆盖......我已经阅读并考虑过只使用rand()并从0到getrandmax()中选择一个随机数,但我觉得我可能有同样的机会文件覆盖...我需要每次都以唯一的名称将图像上传到服务器,无论如何...所以 php 脚本将检查服务器已有的内容并写入/上传图像具有唯一的名称...

除了“rand()”还有什么想法吗?

我也在考虑可能为每张图片命名...img + 日期 + 时间 + 随机 5 个字符,其中包括字母和数字...所以如果一张图片是在 3 月凌晨 4:37 使用应用程序拍摄的2013 年 2 月 20 日,当上传到服务器时,图像将被命名为“img_03-20-13_4-37am_e4r29.jpg”......我认为这可能有效......(除非有更好的方法)但我相当新到 php 并且不明白如何写这样的东西......

我的php如下...

print_r($_FILES);
$new_image_name = "image".rand(10, 20).".jpg";
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);

感谢任何帮助... 提前致谢! 另外,如果有任何进一步的信息我可能会遗漏,请告诉我......

【问题讨论】:

  • $new_image_name = "image".microtime().".jpg"; 应该足以满足您的需要,如果 2 张图像没有同时处理(秒的几分之一)。

标签: php cordova upload unique filenames


【解决方案1】:

您可能需要考虑 PHP 的 uniqid() 函数。 这样,您建议的代码将如下所示:

$new_image_name = 'image_' . date('Y-m-d-H-i-s') . '_' . uniqid() . '.jpg';
// do some checks to make sure the file you have is an image and if you can trust it
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);

另外请记住,您的服务器的随机函数并不是真正随机的。如果您确实需要随机的东西,请尝试random.org。随机随机随机。

UPD:为了在您的代码中使用 random.org,您必须向他们的服务器发出一些 API 请求。相关文档可在此处获得:www.random.org/clients/http/

调用示例为:random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new。请注意,您可以更改minmax 和其他参数,如documentation 中所述。

在 PHP 中,您可以使用 file_get_contents() 函数、cURL 库甚至套接字向远程服务器发出 GET 请求。如果您使用的是共享主机,您的帐户应该可以使用并启用传出连接。

$random_int = file_get_contents('http://www.random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new');
var_dump($random_int);

【讨论】:

  • 这似乎工作得很好,但我将如何整合 random.org?我绝对对真正的随机性很感兴趣
【解决方案2】:

您应该使用tempnam() 来生成唯一的文件名:

// $baseDirectory   Defines where the uploaded file will go to
// $prefix          The first part of your file name, e.g. "image"
$destinationFileName = tempnam($baseDirectory, $prefix);

您的新文件的扩展名应在移动上传的文件后完成,即:

// Assuming $_FILES['file']['error'] == 0 (no errors)
if (move_uploaded_file($_FILES['file']['tmp_name'], $destinationFileName)) {
    // use extension from uploaded file
    $fileExtension = '.' . pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
    // or fix the extension yourself
    // $fileExtension = ".jpg";
    rename($destinationFileName, $destinationFileName . $fileExtension);
} else {
    // tempnam() created a new file, but moving the uploaded file failed
    unlink($destinationFileName); // remove temporary file
}

【讨论】:

  • 它正在创建 .tmp 文件
  • @user3726268 您可以在之后执行重命名以更改扩展名(或完全删除它)。
  • @user3726268 顺便说一句,tempnam() 是保证新文件名唯一的唯一方法(而不仅仅是随机的)。
  • 仅供参考:这个答案是从stackoverflow.com/questions/24255676/…合并而来的
  • @Shog9 非常感谢 :)
【解决方案3】:

您是否考虑过使用 md5_file ? 这样,您的所有文件都将具有唯一的名称,您不必担心重复名称。但请注意,如果内容相同,这将返回相同的字符串。

这里还有另一种方法:

do {
  $filename = DIR_UPLOAD_PATH . '/' . make_string(10) . '-' . make_string(10) . '-' . make_string(10) . '-' . make_string(10);
} while(is_file($filename));

return $filename;

/**
* Make random string
*
* @param integer $length
* @param string $allowed_chars
* @return string
*/
function make_string($length = 10, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') {
  $allowed_chars_len = strlen($allowed_chars);

  if($allowed_chars_len == 1) {
    return str_pad('', $length, $allowed_chars);
  } else {
    $result = '';

    while(strlen($result) < $length) {
      $result .= substr($allowed_chars, rand(0, $allowed_chars_len), 1);
    } // while

    return $result;
  } // if
} // make_string

【讨论】:

  • 如果它们被称为相同的怎么办? md5_file('image.jpg')===md5_file('image.jpg')
  • 或者我可以一起摆脱“图像”?做类似 print_r($_FILES); $new_image_name = md5().".jpg"; move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);
  • Waygood 你显然不熟悉 md5_file ,因为你给出了这样的评论。它返回内容的哈希值,而不是文件名。文件名与它无关。请测试一下,你会看到两个同名但内容不同的文件会返回不同的哈希值。附言测试成功后请删除反对票:)
  • 让我告诉你 md5_file 的作用:md5(file_get_contents("1.php")) === md5_file("1.php")
  • 天啊!正在考虑md5。无论如何,如果它们是相同的“内容”,一个会覆盖另一个。然后如果你想删除一个,你删除两个!
【解决方案4】:

函数会在上传图片之前创建一个唯一的名称。

// Upload file with unique name
if ( ! function_exists('getUniqueFilename'))
{
    function getUniqueFilename($file)
    {
        if(is_array($file) and $file['name'] != '')
        {
            // getting file extension
            $fnarr          = explode(".", $file['name']);
            $file_extension = strtolower($fnarr[count($fnarr)-1]);

            // getting unique file name
            $file_name = substr(md5($file['name'].time()), 5, 15).".".$file_extension;
            return $file_name;

        } // ends for is_array check
        else
        {
            return '';

        } // else ends

    } // ends
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-03-27
  • 2012-01-23
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多