Рубрика «PHP»

Фотогалерея: просмотр файлов в каталоге с постраничной навигацией

Пусть у нас есть каталог (директория), содержащий файлы изображений и мы хотим создать удобный интерфейс для их просмотра. Было бы неудобно выводить все файлы изображений в каталоге - ведь их может быть очень много. Следовательно, необходимо сделать постраничный вывод: по 10 (20, 30) изображений на страницу, а внизу - ссылки на остальные страницы.


Для этого мы должны прочитать все содержимое каталога (исключив директории и файлы, не являющиеся картинками), записать в массив, отсортировать, а потом просто вывести не все содержимое массива, а только нужные элементы (например, с 0 до 9 или с 10 по 19).

<?php
// количество изображений на странице
define( 'PERPAGE', 10 );
$directory = 'small';
$dir = new DirectoryItems($directory);
// Отфильтровываем все файлы, которые не являются изображениями
$dir->filter();
// Сортируем картинки
$dir->indexOrder();
// Общее количество изображений в директории
$totalCount = $dir->getCount();
// Текущая страница
if ( isset( $_GET['page'] ) )
  $page = $_GET['page'];
else
  $page = 1;
$numPages = ceil($totalCount/PERPAGE);
if ( $page < 1 ) $page = 1;
if ( $page > $numPages ) $page = $numPages;
// Получаем часть массива
$filearray = $dir->getFileArraySlice( ($page-1)*PERPAGE, PERPAGE);

foreach( $filearray as $value) {
  $path = $dir->getDirectoryName().'/'.$value;
  echo '<img src="'.$path.'" alt="" />'."\n";
}

// Создавать постраничную навигацию есть смысл, только если
// есть больше одной страницы
if($numPages > 1) {
  // Создаем навигатор
  $nav = new PageNavigator($totalCount, PERPAGE, $page);
  echo $nav->getNavigator();
}

class DirectoryItems {
  private $filearray = array();
  private $directory;

  public function __construct($directory) {
    $this->directory = $directory;
    if ( is_dir($directory) ) {
      $d = opendir( $directory ) or die("Failed to open directory.");
      while ( false !== ($f = readdir($d)) ) {
        if( is_file($directory.'/'.$f) ) {
          $this->filearray[] = $f;
        }
      }
      closedir($d);
    } else {
      die("Must pass in a directory.");
    }
  }

  public function __destruct(){
    unset($this->filearray);
  }

  public function getDirectoryName(){
    return $this->directory;
  }
   
  public function indexOrder(){
    sort($this->filearray);
  }

  public function getCount() {
    return count($this->filearray);
  }

  public function getFileArray() {
    return $this->filearray;
  }
   
  public function getFileArraySlice($start, $numberitems) {
    return array_slice($this->filearray, $start, $numberitems);
  }

  // исключить из массива все элементы с недопустимым расширением
  public function filter(){
    $extensions = array("jpg", "jpeg", "gif", "png");
    foreach ($this->filearray as $key => $value) {
      $ext = substr($value,(strpos($value, ".")+1));
      $extstrtolower($ext);
      if(!in_array($ext, $extensions)){
        unset($this->filearray[$key]);
      }
    }
  }   
}

class PageNavigator {
  // общее число страниц, необходимых для вывода всего списка изображений
  private $totalpages;
  // число изображений на одной странице
  private $recordsperpage;
  // текущая страница
  private $currentpage
  // текст для навигации
  private $strfirst = 'Первая';
  private $strlast = 'Последняя';
 
  public function __construct($totalrecords, $recordsperpage = 10, $currentpage = 1){
    $this->totalrecords = $totalrecords;
    $this->recordsperpage = $recordsperpage;
    $this->currentpage = $currentpage;   
    $this->setTotalPages($totalrecords, $recordsperpage);
  }
  // Возвращает HTML код навигатора
  public function getNavigator(){
    $strnavigator = '<div>'."\n";
    // Ссылка "Первая страница"   
    if($this->currentpage != 1) {
      $strnavigator .= $this->createLink(1, $this->strfirst);
      $strnavigator .= ' ... ';
    }
    // Две страницы назад + текущая страница + две страницы вперед
    for($i = $this->currentpage - 2; $i <= $this->currentpage + 2; $i++) {
      if($i < 1 or $i > $this->totalpages) continue;
      if($i == $this->currentpage) {
        $strnavigator .= '<b>';
        $strnavigator .= $i;
        $strnavigator .= '</b>'."\n";
      } else {
        $strnavigator .= $this->createLink($i, $i);
      }
      if ($i != $this->totalpages) $strnavigator .= ' | ';
    }
    // Ссылка "Последняя страница"   
    if($this->currentpage != $this->totalpages){
      $strnavigator .= ' ... ';
      $strnavigator .= $this->createLink($this->totalpages, $this->strlast);
    }
    $strnavigator .= '</div>'."\n";
    return $strnavigator;
  }
 
  private function createLink($offset, $strdisplay ){
    $strtemp = '<a href="'.$_SERVER['PHP_SELF'].'?page='.$offset.'">'.$strdisplay.'</a>'."\n";
    return $strtemp;
  }
  // всего страниц
  private function setTotalPages($totalrecords, $recordsperpage){
    $this->totalpages = ceil($totalrecords/$recordsperpage);
  }
}
?>

Чтение Excel-файлов средствами PHP

Если вам необходимо читать файлы Excel (.xls) средствами PHP, то библиотека PHP-ExcelReader создана специально для вас. Для работы необходима поддержка iconv или mbstring. Вот пример того, как можно оформить вывод xls-документа в HTML-таблицу с использованием этой библиотеки:

<?php
require_once ('Excel/reader.php');

$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('CP1251');
$data->read('filename.xls');     

echo '<table>';
for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
  echo '<tr>';
  for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++) {
    echo '<td>'.$data->sheets[0]['cells'][$i][$j].'</td>';
  }
  echo '</tr>';
}
echo '</table>';
?>

Альтернативный вариант - PHP Excel PARSER. Вот что написано в файле Help_rus.txt:

Вам нужен скрипт, который может читать MS файлы Excel и сохранять данные в базе данных, HTML страницах и и т.д.? Вы хотите делать это используя PHP под Unix и Linux, но без того, чтобы использовать инструментальные средства Windows напоподобии COM? Тогда PHP Excel PARSER - для вас. Все, в чем вы будете нуждаться - это только наш excel.php и PHP сервер без установки дополнительных инструментальных средств.

В файле документации Help_rus.txt довольно подробно описано, как использовать PHP Excel PARSER. Кроме того, дистрибутив содержит примеры работы с Excel-файлом:

  • PHP Excel Parser/Setup/SAMPLE/XLS2HTML/SAMPLE.PHP - вывод Excel-файла в браузер
  • PHP Excel Parser/Setup/SAMPLE/xls2mysql/INDEX.PHP - запись Excel-файла в базу данных

Пример вывода Excel-файла в браузер в формате HTML:

<?php
include ("excel.php");

$exc = new ExcelFileParser ("log.txt", ABC_NO_LOG);
$res = $exc->ParseFromFile("test.xls");

switch ($res) {
    case 0: break;
    case 1: die ("Невозможно открыть файл");
    case 2: die ("Файл, слишком маленький чтобы быть файлом Excel");
    case 3: die ("Ошибка чтения заголовка файла");
    case 4: die ("Ошибка чтения файла");
    case 5: die ("Это - не файл Excel или файл, сохраненный в Excel < 5.0");
    case 6: die ("Битый файл");
    case 7: die ("В файле не найдены данные  Excel");
    case 8: die ("Неподдерживаемая версия файла");
    default: die ("Неизвестная ошибка");
}

// цикл по рабочим листам
for( $ws_num=0; $ws_num<count($exc->worksheet['name']); $ws_num++ )
{                 
    echo "<h3>Рабочий лист: ";
    if( $exc->worksheet['unicode'][$ws_num] )
        echo uc2cp1251($exc->worksheet['name'][$ws_num]);
    else
        echo $exc->worksheet['name'][$ws_num];

    echo "</h3>\n";
    $ws = $exc->worksheet['data'][$ws_num];

    // если рабочий лист не пустой
    if ( is_array($ws) && isset($ws['max_row']) && isset($ws['max_col']) ) {
        echo "<table border=1 cellspacing=0 cellpadding=2>\n";

        echo "<tr><td>&nbsp;</td>";
        for( $j=0; $j<=$ws['max_col']; $j++ ) {
            echo "<td class=index>&nbsp;";
            if( $j>25 ) echo chr((int)($j/26)+64);
            echo chr(($j % 26) + 65)."&nbsp;</td>";
        }
        echo "</tr>\n";
        // начало цикла по строкам
        for( $i=0; $i<=$ws['max_row']; $i++ ) {
            echo "<tr><td class=index>".($i+1)."</td>\n";
            // начало цикла по столбцам
            if( isset($ws['cell'][$i]) && is_array($ws['cell'][$i]) ) {
                for( $j=0; $j<=$ws['max_col']; $j++ )
                {
                    if( isset($ws['cell'][$i][$j]) ) {

                        // Печать данных ячейки
                        echo "<td>";
                        $data = $ws['cell'][$i][$j];
                       
                        switch ($data['type'])
                        {
                            // строка
                            case 0:
                                $ind = $data['data'];
                                if( $exc->sst['unicode'][$ind] )
                                    $s = uc2cp1251($exc->sst['data'][$ind]);
                                else
                                    $s = $exc->sst['data'][$ind];
                                if( strlen(trim($s))==0 )
                                    echo "&nbsp;";
                                else
                                    echo $s;
                                break;
                            //целое число
                            case 1:
                                echo (int)($data['data']);
                                break;
                            //вещественное число
                            case 2:
                                echo (float)($data['data']);
                                break;
                            // дата
                            case 3:
                                $ret = $exc->getDateArray($data['data']);
                                printf ("%s-%s-%s",$ret['day'], $ret['month'], $ret['year']);
                                break;
                            default:
                                echo "&nbsp;";
                                break;
                        }
                        echo "</td>\n";
                           
                    } else {
                        echo "<td>&nbsp;</td>\n";
                    }
                }
            } else {
                // все ячейки стрки пустые
                for( $j=0; $j<=$ws['max_col']; $j++ ) {
                    echo "<td>&nbsp;</td>\n";
                }
            }
            echo "</tr>\n";
           
        }

        echo "</table>\n";
    } else {
        // пустой рабочий лист
        echo "<p>Пустой рабочий лист</p>\n";
    }
} 

// конвертим в нужную кодировку
function uc2cp1251($str) {
    return iconv('UNICODELITTLE','cp1251',$str);
}
?>

Ссылки по теме:

Работа с архивами средствами PHP

На http://www.phpclasses.org можно скачать класс Create ZIP File, предназначенный для создания zip-файлов с иерархией папок. Пример использования:

<?php
// Подключаем класс для работы с zip-архивами
include_once("createZip.inc.php");
$createZip = new createZip; 

// Добавляем директорию
$createZip -> addDirectory("dir/");

// Добавляем файл
$fileContents = file_get_contents("img.jpg")
$createZip -> addFile($fileContents, "dir/img.jpg")

// Создаем архив
$fileName = "archive.zip";
$fd = fopen ($fileName, "wb");
$out = fwrite ($fd, $createZip -> getZippedfile());
fclose ($fd);

// Отдаем архив браузеру
$createZip -> forceDownload($fileName);
@unlink($fileName);
?>

Функция для извлечения файлов из архива:

<?php
/**
 * Распаковывает zip-архив в указанный каталог.
 * $dir  - полный путь к каталогу.
 * $file - полный путь к zip-архиву.
 * $log  - флаг вывода диагностики.
 */

function unpackZip($dir, $file, $log=0) {
    if ($log) echo "Start unpack [$file] into [$dir] directory... <br/>";
 
    if ($zip = zip_open($file)) {
        if ($zip) {
            // создать каталог, если он не существует
            if (! file_exists($dir)) mkdir($dir);
 
            while ($zip_entry = zip_read($zip)) {
                $name = zip_entry_name($zip_entry);
                if ($log) echo "   <b>unpack </b>: $name <br/>";
 
                // последний символ имени
                $last = substr($name, strlen($name)-1);
 
                // если это каталог
                if ($last == "/" || $last == "\\") {
                    $subdir = $dir."/".$name;
                    // создать каталог, если он не существует
                    if (! file_exists($subdir)) mkdir ($subdir);
                } else {
                    // распаковать файл
                    if (zip_entry_open($zip, $zip_entry, "r")) {
                        $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                        $fp = fopen($dir."/".zip_entry_name($zip_entry), "w");
                        fwrite($fp, $buf);
                        zip_entry_close($zip_entry);
                    } else {
                         return false;
                    }
                }
            }
            zip_close($zip);
        }
    } else {
        return false;
    }
 
    return true;
}
?>

Ссылки по теме: