Pull to refresh

PHP для самых маленьких, или свой «Index of / » с преферансом и куртизанками

Предыстория

В процессе написания диплома возникла необходимость создать "он-лайн флешку" для хранения материалов.

Пользоваться облачными сервисами не хотелось, хотелось простоты использования, а именно: скопировал с компа на FTP, а затем с любого девайса выходом в интернет получаешь доступ ко всем файлам.


Способ 1. файл «.htaccess» с ключом «Оptions +Indexes»

Что меня не устроило:
1. Кодировка отображения страницы, читай, имён файлов, всегда CP1252
Icon  Name                    Last modified      Size  Description
[DIR] Parent Directory                             -   
[   ] Документ Mic..> 13-May-2014 00:21  314K  Документ Micro>
[   ] Компоновка..> 26-May-2014 23:51   20M  Фрагмент КОÐ>
[TXT] ЛТХ.txt              26-May-2014 23:49  728   
[   ] Раздел 00. ДÐ..> 13-May-2014 00:21   25K  Документ Micro>

Как c этим бороться я так и не понял, ключи AddDefaultCharset и CharsetSourceEnc не работают, а других вариантов управления кодировками я не нашёл.

2. Список файлов выгружается в узкую-узкую таблицу (таблица, она только визуально, а по тегам — это  моноширинным шрифтом)</code>

<code>3. Поле «Description», для меня в данном случае, не имеет смысла, т.к. его значение должно быть прописано вручную для каждого расширения. Файлы в папке могут быть самые разнообразные: документы, таблицы, рисунки, чертежи, —  для каждого типа их может быть больше десяти.</code>

<code>4. Иконки файлов. Отдельный пункт ненависти:</code>
<source lang="HTML">
<img src="/icons/back.gif" alt="[DIR]">
<img src="/icons/unknown.gif" alt="[   ]">
<img src="/icons/text.gif" alt="[TXT]">
</source>
<code>Они просто не отображаются. Почему? А потому что их там нет. Нет такой папки с такими файлами. Можно было бы создать самостоятельно, но зачем? Способов борьбы с ними я тоже не смог найти.</code>

<code>5. Невозможность применять стили. Да что там стили, вообще ничего применять нельзя.</code>
<code> </code>


<h5>Способ 2. index.php</h5>
<code>Самый очевидный: что-то не нравится? Возьми и создай своё с преферансом и куртизанками, чем я и занялся.</code>

<code>Оговорюсь сразу. PHP я видел два раза в жизни:</code>
<code>1. Когда делал именные приглашения на свадьбу (гость получал ссылку вида invite.mydomen.ru/?name=Сергей%20Анатольевич, и видел персональную страницу с приглашением, планом мероприятий и т.п.) </code>
<code>2. Когда помогал сестре в выполнении лабораторных работ по PHP в институте (дают список операторов, которые будут использованы в работе с объяснения и комментариями и простенькое задание)</code>
<code> </code>



<h5>И так, приступим</h5>
<code>По старой доброй традиции, всё сразу делается на продакшн, где и тестируется. Папка уже есть, создаём index.php</code>

<code>Первым делом нам надо получить выгрузить список файлов. Небольшие манипуляции с поисковым сервисом из шести букв, и начало положено.</code>
<source lang="php">
<?php
$dir = '../my_folder';	// определяем рабочую директорию
$f = scandir($dir);	// в массив заносим список файлов
foreach ($f as $file) {echo $file;}	// выводим список файлов (массив)
?>
</source>
<code>
Не с первого раз, но задача выполняется, а это главное. Осталось дело за малым, чуточку усложнить код, чтобы результатом его выполнения был тредуемый результат.
</code>

<code>Добавляем строки и ячейки таблицы, ссылки на файлы, новые поля (размер, расширение, дата изменения), а также заголовок таблицы.</code>

<source lang="php">
<?php
$dir = '../my_folder';
$f = scandir($dir);
echo '<html><head><title></title><style></style></head><body><table>';
echo '<tr> <th>Имя файла</th><th>Размер</th><th>Тип</th><th>Дата и время</th></tr>';
foreach ($f as $file) {
echo '<tr> <td><a href="'.$file.'">'.$file.'</a></td> <td>'.filesize($file).'</td> <td>'.end(explode('.',$file)).'</td> <td>'.date('d.m.Y H:i', filemtime($file)).'</td>';
}
echo '</table></body></html>';
?>
</source>
	
<code>В принципе, уже хорошо, и можно так оставить, но внутренний перфекционист душит хлеще любой жабы.</code>
	
<code>Добавляем стили, сокращаем размер (кБ, МБ, ГБ)... Ого, в выборку попали технические файлы *.php, .htaccess, папки — избавляемся. Попутно всплыло, что если имя файла содержит знак процента, то при попытке загрузить такой файл, сервер показывает ошибку 400. Ничего умнее не придумал, как заменять «%» на «%25».</code>

<source lang="php">
<?php
	$dir = '../my_folder';
	$f = scandir($dir);
	echo '<html><head><title></title><style></style></head><body><table>';
	echo '<tr> <th>Имя файла</th><th>Размер</th><th>Тип</th><th>Дата и время</th></tr>';
	
	foreach ($f as $file){
	    if(preg_match('/\.*/', $file)){
	        $stat = stat($file);
	        $size = filesize($file);
	
	        if ($size < 1024) {
	           $st = $size.' B' ;
	
	        } elseif ($size<1048576) {
	           $st = round(($size/1024),2).' KB' ;
	
	        } elseif ($size<1073741824) {
	           $st =  round(($size/1048576),2).' MB';
	
	        } else {
	           $st =  round(($size/1073741824),2).' G';
	}
	
	        // здесь условие
	        if (basename($file) == '.htaccess' || basename($file) == '.' || basename($file) == '..'|| strtoupper(end(explode('.', $file))) == 'PHP') continue;
	        echo '<tr><td><a href="'.str_replace('%','%25',$file).'">'.$file.'</a></td><td align=right>'.$st.'</td><td>'.strtoupper(end(explode('.', $file))).'</td><td>'.date('d.m.Y H:i', filemtime($file)).'</td></tr>
	';
	    }
	}
	echo '</table></body></html>';
	?>
</source>

<code>Почти хорошо. Добавляем стили, заголовок и фавикон. До сих пор имя папки, для которой мы делаем индексирование статично, и даже если перенести файл в соседнюю папку, отображаться будет текущая. Исправляем и это.</code>
	
<source lang="php">
	<?php
	$dr = end(explode('/', getcwd()));
	$dir = '../'.$dr;
	$f = scandir($dir);
	
	echo '<html>
	<head>
	<link rel="icon" type="image/png" href="data:image/gif;base64,R0lGODlhEAAQAKEBADmQzv///////////yH5BAEKAAIALAAAAAAQABAAAAIrlI+JoM3y2gG0yhSvybp7V4ViGJQlYKJoQLGu+p7wHLP06r53rY6+9TEUAAA7">
	<title>Index of /'.$dr.'</title>
	<style>
	body {background: #fff url(http://mai.megapolis-avto.com/background.gif) repeat-x;}
	fff{font-size:12pt;}
	body  {font-family:  Times New Roman; }
	table {border-collapse:collapse;}
	th {padding-bottom:15px; text-align: left;}
	td {empty-cells:show; margin:0px; border-bottom: 0px solid #efefef; padding: 0 10 ;}
	tr:hover td {background:#daeaf6;}
	td a, a:active {color: #3990ce; text-decoration: none;}
	td a:hover {color:red;}
	td a:visited {color: #5215a7; text-decoration: none;}
	</style>
	</head>
	<body>
	<h1>Index of /'.$dr.'</h1>
	<table>';
	echo '<tr> <th>Имя файла</th><th>Размер</th><th>Тип</th><th>Дата и время</th></tr>';
	
	foreach ($f as $file){
	    if(preg_match('/\.*/', $file)){
	        $stat = stat($file);
	        $size = filesize($file);
	
	        if ($size < 1024) {
	           $st = $size.' B' ;
	
	        } elseif ($size<1048576) {
	           $st = round(($size/1024),2).' KB' ;
	
	        } elseif ($size<1073741824) {
	           $st =  round(($size/1048576),2).' MB';
	
	        } else {
	           $st =  round(($size/1073741824),2).' G';
	}
	
	        // здесь условие
	        if (basename($file) == '.htaccess' || basename($file) == '.' || basename($file) == '..'|| strtoupper(end(explode('.', $file))) == 'PHP') continue;
	        echo '<tr><td><a href="'.str_replace('%','%25',$file).'">'.$file.'</a></td><td align=right>'.$st.'</td><td>'.strtoupper(end(explode('.', $file))).'</td><td>'.date('d.m.Y H:i', filemtime($file)).'</td></tr>
	';
	    }
	}
	echo '</table></body></html>';
	?>
</source>

<code>Есть один большой минус, который способен перечеркнуть все плюсы. Это отсутствие сортировки. Самое распространённое решение — это воспользоваться JS, но это не наш метод. Будем реализовывать сортировку через переменную $_GET</code>

<source lang="php">
...

$sorted =$_GET[sorted]; 
...
<thead><tr>
<th><a href="?sorted=name" title="Сортировать по имени">Имя файла</a></th>
<th><a href="?sorted=size" title="Сортировать по размеру">Размер</a></th>
<th><a href="?sorted=type" title="Сортировать по типу">Тип</a></th>
<th><a href="?sorted=time" title="Сортировать по дате">Дата и время</a></th>
</tr></thead>
...
$files = array(); 

if ($sorted =='time') {
foreach ($f as $file) $files[$file] = filemtime("$file");

} elseif ($sorted =='type') {
foreach ($f as $file) $files[$file] = strtoupper(end(explode('.', $file)));

} elseif ($sorted =='size') {
foreach ($f as $file) $files[$file] = filesize($file);

} else {
foreach ($f as $file) $files[$file] = ($file);
}

asort($files); 
$files = array_keys($files); 
	foreach ($files as $file){
    if(preg_match('/\.*/', $file)){
        $stat = stat($file);
        $size = filesize($file);
	        if ($size < 1024) {
           $st = $size.' B' ;

        } elseif ($size<1048576) {
           $st = round(($size/1024),2).' KB' ;

        } elseif ($size<1073741824) {
           $st = round(($size/1048576),2).' MB';

        } else {
           $st = round(($size/1073741824),2).' G';
}
        // здесь условие
       if (basename($file) == '.htaccess' || basename($file) == '.' || basename($file) == '..'|| strtoupper(end(explode('.', $file))) == 'PHP') continue;
        echo '<tr><td><a href="'.str_replace('%','%25',$file).'">'.$file.'</a></td><td align=right>'.$st.'</td><td>'.strtoupper(end(explode('.', $file))).'</td><td>'.date('d.m.Y H:i', filemtime($file)).'</td></tr>
';
   }
</source>

Ах-да, чуть не забыл экранирование символов в запросе:
	
<source lang="php">
$sorted=htmlspecialchars($_GET[sorted]); 
</source>

В конечном счётё файл выглядит так:

<source lang="php">
<?php
	
	$dr = end(explode('/', getcwd()));
	$dir = '../'.$dr;
	$f = scandir($dir);
	
	$sorted =htmlspecialchars($_GET[sorted]); 
	
	echo '<html>
	<head>
	<link rel="icon" type="image/png" href="data:image/gif;base64,R0lGODlhEAAQAKEBADmQzv///////////yH5BAEKAAIALAAAAAAQABAAAAIrlI+JoM3y2gG0yhSvybp7V4ViGJQlYKJoQLGu+p7wHLP06r53rY6+9TEUAAA7">
	<title>Index of /'.$dr.'</title>
	
	<style>
	body {background: #fff url(http://mai.megapolis-avto.com/background.gif) repeat-x;}
	fff{font-size:12pt;}
	body  {font-family:  Times New Roman; }
	table {border-collapse:collapse;}
	th {padding-bottom:15px; text-align: left;}
	td {empty-cells:show; margin:0px; border-bottom: 0px solid #efefef; padding: 0 10 ;}
	tr:hover td {background:#daeaf6;}
	th a  {color: #3990ce;  text-decoration: none; border-bottom: 1px solid #d6e4f5;}
	th a:active {color: black; text-decoration: none;}
	th a:hover {color:red;}
	td a, a:active {color: #3990ce; text-decoration: none;}
	td a:hover {color:red;}
	td a:visited {color: #5215a7; text-decoration: none;}
	</style>
	</head>
	<body>
	<h1>Index of /'.$dr.'</h1>
	<table>
	<thead><tr>
	<th><a href="?sorted=name" title="Сортировать по имени">Имя файла</a></th>
	<th><a href="?sorted=size" title="Сортировать по размеру">Размер</a></th>
	<th><a href="?sorted=type" title="Сортировать по типу">Тип</a></th>
	<th><a href="?sorted=time" title="Сортировать по дате">Дата и время</a></th>
	</tr></thead>
	 <tbody>
	'; 
	
	$files = array(); 
	
	if ($sorted =='time') {
	foreach ($f as $file) $files[$file] = filemtime("$file");
	
	} elseif ($sorted =='type') {
	foreach ($f as $file) $files[$file] = strtoupper(end(explode('.', $file)));
	
	} elseif ($sorted =='size') {
	foreach ($f as $file) $files[$file] = filesize($file);
	
	} else {
	foreach ($f as $file) $files[$file] = ($file);
	}
	
	asort($files); 
	$files = array_keys($files); 
	
	foreach ($files as $file){
	    if(preg_match('/\.*/', $file)){
	        $stat = stat($file);
	        $size = filesize($file);
	
	        if ($size < 1024) {
	           $st = $size.' B' ;
	
	        } elseif ($size<1048576) {
	           $st = round(($size/1024),2).' KB' ;
	
	        } elseif ($size<1073741824) {
	           $st =  round(($size/1048576),2).' MB';
	
	        } else {
	           $st =  round(($size/1073741824),2).' G';
	}
	
	        // здесь условие
	        if (basename($file) == '.htaccess' || basename($file) == '.' || basename($file) == '..'|| strtoupper(end(explode('.', $file))) == 'PHP') continue;
	        echo '<tr><td><a href="'.str_replace('%','%25',$file).'">'.$file.'</a></td><td align=right>'.$st.'</td><td>'.strtoupper(end(explode('.', $file))).'</td><td>'.date('d.m.Y H:i', filemtime($file)).'</td></tr>
	';
	    }
	}
	
	echo '
	</tbody>
	</table>
	</body>
	</html>
	';
	
	?>
</source>

<h5>Выводы</h5>
<code>И так, мы получаем:</code>
<ul>
	<li>файл, который можно применить в любой папке, просто поместив его в неё</li>
	<li>относительно, гибкая настройка и доработка</li>
	<li>предмет гордости</li>
	<li>бесценный опыт</li>
	<li>данный пост и возможность получить полезные советы в комментариях к посту.</li>
</ul>
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.