Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Вывод случайной картинки из заданого списка


Автор: NaglfarNight 3.9.2008, 11:33
Здравствуйте, друзья.

Мне нужно на странице моего сайта каждый день выводить три случайные картинки из заданного списка (все картинки находятся в одной папке).

Примерно так:
user posted image

Только это я вывожу вручную.

Подскажите, пожалуйста.


Автор: bars80080 3.9.2008, 12:08
если есть список, массив то есть с путями к картинкам, то остаётся сделать три случайных числа, неповторяющихся

Код

$mv = array(); // список путей
$kol = count($mv);
$t = array();

$max = 3;
if($kol > $max) {
$i = 0;
while($i < $max) {
$c = rand(0, $kol - 1);
if(array_search($c, $t) === flase) {
$t[$i] = $c; $i++;
}
}}
else $t = $mv;
дальше просто подставить эти три путя

Автор: HackMan 3.9.2008, 14:16
bars80080, зачем придумывать, то что уже придумано, и придумано намного проще  smile 
Код

  $data = range(1, 3);
  shuffle($data);


NaglfarNight,  всё зависит от того, как устроена структура сайта. Уточни, данные об изображениях хранятся в базе или просто в отдельной папке набор картинок?

a) Если в базе и картинок не так много, тогда делай запрос
Код

SELECT path FROM images ORDER BY RAND() LIMIT 3

Если же в базе записей много, тогда ORDER BY RAND() лучше не использовать - сильно грузит сервер. Надо будет сначала сгенерировать 3 случайных числа, сделать из них индексы а потом сделать выборку простым SELECT

b) Если это просто набор файлов в папке, тогда что-то вроде такого
Код

  $images = glob('*.jpg');
  shuffle($images);
  array_splice($images, 3);

Автор: NaglfarNight 3.9.2008, 14:53
HackMan
Без базы.
Просто набор картинок в папке.

Я тормоз в вопросах php  smile 
Путь до папки с картинками прописывать где? Тут 
Код

$images = glob('*.jpg');
 ? Или я что-то опять не понимаю?  smile 

Автор: Ockonal 3.9.2008, 15:32
Код

$path_to_img = "/images/";    // Дирректория с картинками
$num_of_show = 3;        // Сколько выводить
$imgs = 50;                    // Сколько картинок всего

$temp[$num_of_show-1];    // Хранилище для картинок, которые будем выводить


for( $i=0;$i<=$num_of_show;i++ ) {
    $rand = rand( 0,$num_show );
    $temp[$i] = $path_to_img.$rand.".jpg";
};

// Теперь у вас есть массив $temp, в котором адреса тех 3 рисунков( или сколько нужно )
// Выводить так:
for( $i=0;$i<=$num_of_show;i++ ) {
    echo "<img src=".$temp[$i]." /> <br />";
};

$path_to_img - меняете на свою папку
Все рисунки должны быть такого типа:
1.jpg
2.jpg и т.д.
если вам нужно выводить отдельно все 3 ( или сколько ) рисунков:
Код

echo "<img src=".$temp[ИНДЕКС]." /> <br />";

Вместо "ИНДЕКС" - номер рисунка-1

Автор: NaglfarNight 3.9.2008, 15:57
Ockonal, 
Выдаёт ошибку:

Цитата

Parse error: syntax error, unexpected T_INC, expecting ')' on line 6   
 :(

Автор: s0lman 3.9.2008, 16:00
NaglfarNight, попробуйте этот скриптик - специально для вас изменил;)

Автор: Ockonal 3.9.2008, 16:50
Код

for( $i=0;$i<=$num_of_show;i++ ) {
    $rand = rand( 0,$num_show );
    $temp[$i] = $path_to_img.$rand.".jpg";
};

Ошибся, извините... 
Выше исправьте на:
Код

for( $i=0;$i<=$num_of_show; $i++ ) {
    $rand = rand( 0,$num_show );
    $temp[$i] = $path_to_img.$rand.".jpg";
};


Автор: HackMan 4.9.2008, 02:34
NaglfarNight, да, тут

Ockonal, у меня есть папка images, в ней 866 картинок. Сделаем сравнительный тест моего кода с исправленным твоим

а)
Код

  $start = microtime(true);

  $images = glob('images/*.jpg');
  shuffle($images);
  array_splice($images, 3);

  $end = microtime(true); 

  echo ($end - $start);

В результате получаем 0.000214099884033

б)
Код

  $start = microtime(true);

  $path_to_img = "/images/";    // Дирректория с картинками
  $num_of_show = 3;        // Сколько выводить
  $imgs = 50;                    // Сколько картинок всего
  $temp[$num_of_show-1];    // Хранилище для картинок, которые будем выводить

  for ($i=0; $i<=$num_of_show; $i++)
    {
      $rand = rand(0, $imgs);
      $temp[$i] = $path_to_img.$rand . ".jpg";
    };

  $end = microtime(true);
  
  echo ($end - $start);

В результате получаем 0.000100135803223

Разница во времени составляет 0,00011396408081 сек. Разница в коде - 3 строчки против 9, и мой код в несколько раз прозрачней для понимания, да и ко всему в твоём коде картинки должны иметь пронумерованные имена, подряд, без пропуска, да и очень большой шанс, что сгенерируется несколько одинаковых чисел smile я уже не говорю, про то, что массив $temp у тебя нигде не объявлен как массив и вылетит ошибка. Видимо, код выдранный тупо откуда-то и предназначен для конкретной задачи.

Спасибо за внимание   smile 

Автор: s0lman 4.9.2008, 10:16
HackMan, у меня ваш код выдал 0.031064987182617
тогда как мой -  0.18256306648254  smile 

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


Автор: Ockonal 4.9.2008, 14:33
HackMan
Цитата

я уже не говорю, про то, что массив $temp у тебя нигде не объявлен как массив и вылетит ошибка. Видимо, код выдранный тупо откуда-то и предназначен для конкретной задачи.

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

Добавлено через 2 минуты и 56 секунд
Цитата

и мой код в несколько раз прозрачней для понимания

Извините, конечно, может это зависит от моих знаний, но ваш код мне кажется сложнее. И, как раз, 
мой более прозрачный. Согласитесь smile Я соглашусь, что Ваш более эфективный.

Автор: MoLeX 4.9.2008, 15:44
HackMan, 
Ockonal, может не будем выяснять у кого код круче и понятнее?  smile 

NaglfarNight, вопрос решен? если да то отметь пожалуйста его соответствующим образом.

Автор: NaglfarNight 5.9.2008, 12:08
MoLeX
Неа... вопрос ещё не решён. Прошу простить меня за тупость, я с самыми простейшими задачами в пхп справляюсь за сутки, а то и больше  smile 

HackMan
Ваш код привлекает столь маленьким объёмом.
Так... где прописывать дирректорию с картинками понятно. Путь абсолютный? 
А выводим как? smile 

Автор: HackMan 5.9.2008, 14:31
NaglfarNight, путь можно как относительный, так и абсолютный. Удобнее - относительный.

Выводить примерно так:
Код

<?php
  foreach ($images as $image)
    {
      echo '<img src="' . $image . '">';
    }
?>

Автор: NaglfarNight 5.9.2008, 17:02
HackMan, 
Вставляю на страничку 
Код

 <?php   
  $images = glob('/images/avatars/*.jpg');
  shuffle($images);
  array_splice($images, 3);
  
 foreach ($images as $image)
    {
      echo '<img src="' . $image . '">';
    }
  ?>


Не работает. Может что-то неверно делаю  smile 

Код Ockonal работает, но иногда почему-то вместо заданых 3-х изображений выводит либо 2, либо 4. 
Ockonal, для Вашего кода нужно, чтобы все картинки были названы в духе 001.jpg, 002.jpg? Или не важно?

Автор: Ockonal 5.9.2008, 17:26
Даж не знаю, стоит ли ворошить мой код smile Но раз уж вы взялись:
Название картинок должно быть только таким: 1.jpg, 2.jpg ... 10.jpg ... 100.jpg
И, как я понял, массив нужно объявить массивом, что-то типа такого:
$temp[$num_of_show-1] = Array();
HackMan, 
Поправьте меня, если что.

Автор: NaglfarNight 5.9.2008, 17:34
Как не стоит? Работает же, только не совсем так как нужно, значит стоит.
Так...
Данную строчку вставила, но всё равно, как заколдованый выводит по 4 картинки  smile 
Хотя в коде ясно написано 
Код

  $num_of_show = 3;        // Сколько выводить

 

Автор: Ockonal 5.9.2008, 17:48
Цитата

Как не стоит? Работает же, только не совсем так как нужно, значит стоит.

Ок-ок smile Сейчас я у себя протестю.

Автор: Ockonal 5.9.2008, 18:10
У меня все работает. Вот код:
Код

$path_to_img = "images/";    // Дирректория с картинками
$num_of_show = 5;        // Сколько выводить
$imgs = 10;                    // Сколько картинок всего
$temp[$num_of_show-1];    // Хранилище для картинок, которые будем выводить

for( $i=1;$i<=$num_of_show; $i++ ) {
    $rand = rand( 1, $num_of_show );
    $temp[$i] = $path_to_img.$rand.".jpg";
};

for( $i=1;$i<=$num_of_show; $i++ ) {
    echo "<img src=".$temp[$i]." /> <br />";
};




Автор: NaglfarNight 5.9.2008, 18:25
Ockonal, 
Вот теперь всё работает и у меня.

Вот тут
Код

for( $i=1;$i<=$num_of_show; $i++ ) {

было 
Код

for( $i=0;$i<=$num_of_show; $i++ ) {


Видимо поэтому выводило неправильное количество. 

Только вот тут: 
Код

     $rand = rand( 0,$num_show );

нужно так?
Код

    $rand = rand( 0,$imgs );



Автор: Ockonal 5.9.2008, 18:28
Да-да smile Вы молодец ;)
А то будет выводить только первые 3 картинки.
Извиняюсь за свои ошибки.

Добавлено @ 18:29
Цитата

Вот теперь всё работает и у меня.

Вот тут

for( $i=1;$i<=$num_of_show; $i++ ) {

было 

for( $i=0;$i<=$num_of_show; $i++ ) {

Все правильно. В первом месте будет 4 итерации, а не 3 как нужно smile Т.е. сколько бы вы ни написали, всегда будет на 1 больше.

Добавлено @ 18:30
Код

srand( (double)microtime()*1000000 );

Вставьте это перед первым for

Код

srand( (double)microtime()*1000000 );
for( $i=1;$i<=$num_of_show; $i++ ) {
    $rand = rand( 1, $imgs );
    $temp[$i] = $path_to_img.$rand.".jpg";
};

Будет лучше генерироваться случайное число.

Добавлено через 6 минут и 19 секунд
Да
Код

 $rand = rand( 0,$imgs );

Если у вас будет картинка 0.jpg, то можете использовать код выше, но если у вас все картинки начинаются с 1.jpg:
Код

 $rand = rand( 1,$imgs );


p.s. Если нужно, чтобы не было выведено одинаковых картинок - пишите.

Автор: NaglfarNight 5.9.2008, 18:46
Ockonal,
Спасибо! Наконец-то всё работает. 
По поводу одинаковых картинок, желательно чтобы не было таковых. Можете с этим помочь?

Автор: HackMan 5.9.2008, 19:05
Ockonal,
Цитата(Ockonal @  5.9.2008,  17:26 Найти цитируемый пост)
$temp[$num_of_show-1] = Array();

Этим кодом ты второму элементу несуществующего массива $temp задаёшь тип данных "массив". Надо делать так:
Код

$temp = array()

Но, вообще, этого делать совсем не обязательно, так как если в PHP присвоишь значение элементу массива с несуществующим индексом - он просто напросто создастся и массив расширит свои рамки.
Цитата(Ockonal @  5.9.2008,  18:28 Найти цитируемый пост)
srand( (double)microtime()*1000000 );

А толку? И что вообще значит "будет лучше генерироваться"? Функция rand() вообще не генерирует случайных чисел. Генерируется одно большое псевдослучайное число которое зависит от системного время. Функция srand() изменяет начальное число генератора псевдослучайных чисел.

NaglfarNight,
Цитата(NaglfarNight @  5.9.2008,  17:02 Найти цитируемый пост)
Вставляю на страничку 
Выделить всёкод PHP
Код


 <?php   
  $images = glob('/images/avatars/*.jpg');
  shuffle($images);
  array_splice($images, 3);
  
 foreach ($images as $image)
    {
      echo '<img src="' . $image . '">';
    }
  ?>


Не работает. Может что-то неверно делаю  smile 

Конечно не работает. /images/avatars/*.jpg - это абсолютный путь. Скрипт будет искать в корне папку images, и ничего не найдёт, потому что там такой нет. Слэш в начале надо убрать

Автор: NaglfarNight 5.9.2008, 19:23
HackMan, 
Так пробовала, тоже не работает.
Пыталась по разному - и абсолютным, и относительным, и со слэшем, и без него.

Ockonal
А от расширения файлов тоже зависит? Все должны быть jpg, так?
Если у меня есть несколько gif, они не будут отображаться?

Автор: HackMan 5.9.2008, 19:28
Код

var_dump($images);

что выводит?

Автор: NaglfarNight 5.9.2008, 19:40
HackMan, 
это куда нужно вставлять? smile 
если ставлю в начало кода, выдаёт: NULL
если в конец: array(0) { }

Автор: HackMan 5.9.2008, 19:43
1) В каком каталоге находится скрипт?
2) В каком каталоге находятся картинки?
3) Что выводит следующий код
Код

echo __FILE__;

Автор: NaglfarNight 5.9.2008, 19:54
HackMan

1. /include/sidebar/avatars.php
2. /images/avatars/
3. /home/u18822/naglfarru/www/include/sidebar/avatars.php

Автор: Ockonal 5.9.2008, 20:41
Цитата

А от расширения файлов тоже зависит? Все должны быть jpg, так?
Если у меня есть несколько gif, они не будут отображаться?

Да, в том и недостаток моего скрипта - он только для одной цели. 
HackMan
Спасибо за советы/ответы.

Автор: HackMan 5.9.2008, 20:48
Ockonal, 
всегда пожалуйста  smile 


NaglfarNight, 
Код

$images = glob('../../images/avatars/*.jpg');

или
Код

$images = glob('/home/u18822/naglfarru/www/images/avatars/*.jpg');


Советую ознакомиться со статьёй "http://www.phpfaq.ru/paths"

Если картинки с несколькими расширениям, тогда комбинировать надо так:
Код

  $images = glob('../images/*.{jpg,gif}', GLOB_BRACE);


Да и вообще это всё можно красиво записать в две (ато и в одну  smile ) строчки следующим образом:
Код

  foreach (array_splice(shuffle(glob('../../images/*.{jpg,gif}', GLOB_BRACE)), 3) as $image)
    echo '<img src="' . $image . '">';

но лично я предпочитаю делать так, как написал раньше, расписывать действия.

Автор: NaglfarNight 5.9.2008, 21:53
HackMan
Да, действительно коротко  smile 


Ockonal  smile , HackMan  smile , большое спасибо за помощь. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)