【问题标题】:Load Random Images from Directory从目录加载随机图像
【发布时间】:2012-02-09 00:04:48
【问题描述】:

我想从一个目录中随机加载图像,并在某处有一个刷新整个页面的按钮。这是我现在拥有的当前代码:

<?php
$a = array();
$dir = '../public/wp-content/uploads/2012/01';
if ($handle = opendir($dir)) {
  while (false !== ($file = readdir($handle))) {
    if (preg_match("/\.png$/", $file)) $a[] = $file;
    elseif (preg_match("/\.jpg$/", $file)) $a[] = $file;
    elseif (preg_match("/\.jpeg$/", $file)) $a[] = $file;
  }
  closedir($handle);
}

foreach ($a as $i) {

  echo "<img src='" . $dir . '/' . $i . "' />";

}

?>  

问题是它一次加载所有 400,000 张图像。我只想加载 30 个。目录中的 30 张随机图像。我尝试查找一些代码,例如将上面的代码修改为:

<?php
$a = array();
$dir = '../public/wp-content/uploads/2012/01';
if ($handle = opendir($dir)) {
  while (false !== ($file = readdir($handle))) {
    if (preg_match("/\.png$/", $file)) $a[] = $file;
    elseif (preg_match("/\.jpg$/", $file)) $a[] = $file;
    elseif (preg_match("/\.jpeg$/", $file)) $a[] = $file;
  }
  closedir($handle);
}

foreach ($a as $i) {

  echo "<img src='" . $dir . '/' . $i . "' />";
  if (++$i == 2) break;

}

?>  

但它似乎什么也没做。所以如果有人可以帮助我从该目录中随机获取 30 张照片以加载并具有某种类型的重新加载按钮,那将是非常有帮助的。

提前谢谢你

【问题讨论】:

  • $i 显然是一个字符串,所以 ++$i 没有意义。随后的相等比较也不起作用。

标签: php jquery ajax random


【解决方案1】:

这是我的缓存解决方案:

<?php

define('CACHE_FILE', 'mycache.tmp');
define('CACHE_TIME', 20); // 20 seconds (for testing!)
define('IMG_COUNT', 30);
define('IMG_DIR', '../public/wp-content/uploads/2012/01');

/**
  * Loads the list (an array) from the cache
  * Returns FALSE if the file couldn't be opened or the cache was expired, otherwise the list (as an array) will be returned.
  */
function LoadListFromCache($cacheFile, $cacheTime)
{
  if ( file_exists($cacheFile) )
  {
    $fileHandle = fopen($cacheFile, 'r');
    if ( !$fileHandle )
      return false;

    // Read timestamp (separated by "\n" from the content)
    $timestamp = intval( fgets($fileHandle) );
    fclose($fileHandle);
    // Expired?
    if ( $timestamp+$cacheTime > time() )
      return false;
    else
    {
      // Unserialize the content!
      $content = file_get_contents($cacheFile);
      $content = substr( $content, strpos($content, "\n") );

      $list = unserialize($content);
      return $list;
    }
  }
  return false;
}

/**
  * Caches the passed array
  * Returns FALSE if the file couldn't be opened, otherwise TRUE.
  */
function SaveListToCache($cacheFile, $list)
{
  $fileHandle = fopen($cacheFile, 'w');
  if ( $fileHandle === FALSE ) return false;

  fwrite($fileHandle, time());
  fwrite($fileHandle, "\n");
  fwrite($fileHandle, serialize($list));

  fclose($fileHandle);
  return true;
}

/**
  * Generates the list of all image files (png, jpg, jpeg) and caches it.
  * Returns the list as an array.
  */
function GenerateList()
{
  $a = array();
  $dir = IMG_DIR;
  if ($handle = opendir($dir))
  {
    while (false !== ($file = readdir($handle)))
    {
      if (preg_match("/\.png$/", $file)) $a[] = $file;
      elseif (preg_match("/\.jpg$/", $file)) $a[] = $file;
      elseif (preg_match("/\.jpeg$/", $file)) $a[] = $file;
    }
    closedir($handle);
  }
  SaveListToCache(CACHE_FILE, $a);
  return $a;
}

function GetRandomImages($list, $count)
{
  $listCount = count($list);
  $randomEntries = array();

  for ($i=0; $i<$count; $i++)
  {
    $randomEntries[] = $list[ rand(0, $listCount) ];
  }
  return $randomEntries;
}

// This code will execute the other functions!

$list = LoadListFromCache(CACHE_FILE, CACHE_TIME);

if ( $list === FALSE )
{
  $list = GenerateList();
}
$images = GetRandomImages($list, IMG_COUNT);

foreach ($images as $image)
{
  echo '<img src="', IMG_DIR.DIRECTORY_SEPARATOR.$image, '" />';
}

【讨论】:

  • 它没有显示我的随机回声 "";任何地方!
  • 我明白了:fopen 需要在线给出的两个参数 1
  • 感谢 ComFreek,您的 php 向导!
【解决方案2】:

如果您有 400,000 张图像,那么我认为每次读取整个目录将是显示随机图像的一种昂贵的方法。我会改用数据库并将文件路径存储在其中。

如果您想使用现有代码,那么请这样想。您有一个长度为 n 的数组,其中包含图像名称。您想在0n-1 之间使用generate thirty random numbers。然后显示与数组中该位置关联的图像。我不是 php 专家,但这里有一些伪代码:

$a = array(); 
$dir = '../public/wp-content/uploads/2012/01';

if (preg_match("/\.png$/", $file)) $a[] = $file;
elseif (preg_match("/\.jpg$/", $file)) $a[] = $file;
elseif (preg_match("/\.jpeg$/", $file)) $a[] = $file;

for ( i=0; i < 30; i++) {
     //generate a random number between 0 and N-1
     random = rand(0, $a.length - 1);
     //display that image in the array
     echo "<img src='" . $dir . '/' . $a[random] . "' />";
}

【讨论】:

    【解决方案3】:

    您需要为计数器创建一个新变量,而不是使用$i

    例如,您可以这样做

    $j = 0;
    foreach ($a as $i) {
      echo "<img src='" . $dir . '/' . $i . "' />";
      $j++;
      if ($j >= 30)
      {
        break;
      }
    
    }
    

    编辑:也许对于随机部分,您可以首先生成一个介于 0 和 n-1 之间的随机数,其中 n 是图像的总数,然后从数组中回显图像索引号。

    我认为您将需要一个 for 循环,而不是使用 foreach

    $totalImgs = count($a);
    $imgUsed = array();
    for ($j = 0; $j < 30; $j++)
    {
        do
        {
            $randIndex = mt_rand(0, $totalImgs);
        }
        while ($imgUsed[$randIndex] === TRUE);
        $imgUsed[$randIndex] = TRUE;
        echo "<img src='" . $dir . '/' . $a[$randIndex] . "' />";
    }
    

    【讨论】:

    • 行得通!现在如何在页面加载或通过按钮随机化图像
    • 把这个放在foreach(...)之前:shuffle($a);
    • @ComFreek - 洗牌 400k 数组元素不会不必要地昂贵吗?
    • 我以为他限制为 30 张图片。 @JD Audi 此代码将始终将相同的图像添加到数组中。您需要使用scandir() 并打乱它返回的数组(但请缓存结果!)。
    • @ComFreek 我将如何将其添加到其中?提交启用缓存的答案!
    【解决方案4】:

    您应该只从您的目录中读取 30 个文件。当 readdir 返回 false 或您的数组长度为 30 时停止查找目录。

    这应该可以工作

        $a = array();
    $dir = '../public/wp-content/uploads/2012/01';
    if ($handle = opendir($dir)) {
      while (false !== ($file = readdir($handle)) && (count($a) <= 30) {
        if (preg_match("/\.png$/", $file)) $a[] = $file;
        elseif (preg_match("/\.jpg$/", $file)) $a[] = $file;
        elseif (preg_match("/\.jpeg$/", $file)) $a[] = $file;
      }
      closedir($handle);
    }
    

    它可能无法执行(我没有尝试)。但想法就在这里

    为了随机化图像: shuffle($a) 应该可以解决问题

    【讨论】:

    • 你能给我一个代码示例吗?整个过程被复制并粘贴并修改了路径以使其正常工作。我真的不明白 readdir 命令。
    • 对不起,我有一段时间没做php了,所以我可能有点生疏了。 readdir 命令从您打开的目录返回下一个文件,直到您到达末尾,所以这里只有当您读取目录上的所有内容时才会停止。我会在一分钟内编辑我的问题作为示例。
    • 感谢您的编辑,但它不起作用 - 我怎样才能在页面加载时随机化?
    【解决方案5】:

    以最简单的方式, 你可以使用

    find , sort , head 
    

    linux中的命令,结合PHP的内置

    exec()
    

    轻松获取30个随机图片链接的功能,下面的sn-p列出了怎么做 (如何在一个数组中随机获取 30 个图片链接。)

    <?php
    $picdir = "directory/containing/pictures"; // directory containing only pictures
    exec("find " . $picdir . " | sort -R | head -30 ",$links);
    while(list($index,$val) = each($links) ) {
        echo "<img src =" .$val . "> <br/>";  // shows image 
    }
    

    ?> 这里 $links 数组包含随机 30 个图像名称(来自文件夹)和完整路径。这与 echo 中的 img 标签一起使用以生成图像

    这里 $picdir 具有包含图像的目录的路径,并且假定该目录只有图像文件。在其他情况下,只需修改 find 命令以排除非图像文件(例如使用 grep 命令排除)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-21
      • 2015-03-13
      • 2012-08-06
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 2016-03-22
      • 1970-01-01
      相关资源
      最近更新 更多