This version of the page http://phpua.net/FileBrauser/Index3.htm (0.0.0.0) stored by archive.org.ua. It represents a snapshot of the page as of 2011-02-20. The original page over time could change.
ФАЙЛ INDEX.PHP

 

ФАЙЛ INDEX.PHP

Сценарій в цьому файлі відображує список файлів і надає відвідувачеві можливість вибрати файли для здійснення над ними дії і вигляд цієї дії.
Спочатку в сценарії виробляється вивід на сторінку списку файлів і тек в поточній директорії і надається можливість відкрити будь-який файл або перейти в іншу теку.
Просканувати теку і вивести список файлів можна за допомогою сценарію на зразок "Папкопотрошилки", описаного в 6-ій главі. Оскільки планується використовувати одну і ту ж сторінку для відображення вмісту як кореневий, так і будь-якій з вкладених тек, то сценарію на цій сторінці потрібно знати, список файлів в якій конкретно теці йому відображувати, а також як скласти заслання на ці файли, з вказівкою якої дороги -"чтобы з файлового менеджера їх можна було переглядати.
Найпростіше передавати сценарію інформацію про те, список вмісту якої теки підлягає виводу на екран, через змінну в адресному рядку - просто вказавши в ній дорогу від кореневої теки до поточної. Скажімо, якщо коренева тека має назву files, то вона відкриватиметься по засланню index.php?f old=f iles, а вкладена в неї тека folded - по засланню index. php?f old= files /folder 1. (Як видно з тексту заслань, інформація про дорогу до поточної теки буде доступна сценарію на сторінці із значення змінної Sfold, і саме значення цієї змінної і підставлятиметься в сценарії як ім'я теки для сканування.)
Наприклад, на мал. 11.3 файловий менеджер відображує вміст теки f iles/folder2/folder3. Звернете увагу на адресний рядок браузера.

Мал. 11.3. Файловий менеджер в роботі

Коментар:
Неважко відмітити, що подібна конструкція вельми уразлива для злому. Насправді, - якщо підставити замість імені кореневої теки - files - ім'я будь-якої іншої теки, що знаходиться на тому ж рівні, що і тека files, то сценарій "Патопотрошилки" тихо-спокійно виведе і її вміст, - чого, можливо, робити не слід, а воно для цього може бути зовсім не призначене! А якщо вказати в дорозі замість імені каталога символи /../ (двома крапками позначається батьківський каталог, одній - поточний), то відвідувач зможе добратися і до кореневої теки всього сайту, і фактично дістане можливість видаляти, перейменовувати, переглядати всі файли на сайте-аккаунте, оскільки весь сайт буде в його розпорядженні.
Змінити ж адресний рядок - завдання зовсім не складне, просто найлегше. Тому таке положення справ, зрозуміло, не так
і безпечно... Отже, тому в сценарій виведення списку файлів слід додати перевірку вмісту змінною Sfold, в якій дорога до поточної теки і передається. - Напевно, на перших порах вистачить двох умов: щоб дорога до поточної теки починалася з імені кореневої теки, в якій містяться доступні відвідувачеві файли, і щоб в цій дорозі не було символів "..", тобто - двох крапок підряд (у нормальних іменах файлів такого зустрічатися не повинно).
Втім, якщо ви надаєте кому б то не було право розміщувати файли на вашому сайті, то тому, хто їх розміщує, не складе труднощів помістити на сайт файл з програмою на РНР, що виробляє будь-які дії (хоч би власну версію файлового менеджера без згаданих обмежень), і тим самим отримати контроль над всім сайтом, - у тому числі навіть над кореневою директорією. Отже описані в цьому коментарі прийоми - це, швидше, "захист від дурня", від того, хто вже може змінити адресний рядок, але ще не здатний писати програми на РНР.

На сторінці із списком файлів в якій-небудь директорії має бути також заслання на список файлів в тій теці, в яку поточна тека вкладена. Найпростіше отримувати таке заслання на підставі дороги до поточної теки, просто відсікаючи отдюлного дороги її ім'я.
Втім, все це ви побачите в сценарії. Красивому оформленню сторінки із списком файлів часу приділяти не будемо, його ви зможете зробити самостійно. Також в початок сценарію файлового менеджера і на кожну його сторінку ви можете вставити скрипт авторизації, на зразок того, який описаний в гл. 8-ої (лише не забудьте, що поміщати такий скрипт треба до якого-небудь виводу в браузер, будь то команда echo, текст web-страницы або щось інше.).
Отже, починаємо:

<htmlx?php

Вкажемо кореневу теку аккаунта відвідувача - тобто ту, з файлами і теками в якій йому дозволено працювати, і запишемо її ім'я в змінну для подальшого використання в сценарії. Хай ця тека називається files.

$begin="files";

Коментар:
Зрозуміло, можна не записувати ім'я кореневої теки аккаунта в змінну, а просто використовувати це ім'я в сценарії там, де це буде потрібно. Але тоді в тому випадку, якщо вам потрібно буде перейменувати кореневу теку, вам доведеться переглядати всі тексти сценаріїв і замінювати старе ім'я теки на нове скрізь, де воно зустрічається. Якщо ж ім'я записане в змінну, то досить буде змінити лише ту строчку, де цей запис виробляється.

Тепер перевіримо:

  • чи визначена та, що взагалі містить дорогу до теки, що відображується, змінна $fold (тобто чи присутня вона в адресному рядку - її там не буде, якщо до сторінки з файловим менеджером звернулися по зовнішньому засланню, а не з цієї ж сторінки по засланню на яку-небудь теку із списку файлів і тек);
  • чи не містить вона двох крапок підряд - ознаки спроби злому;
  • чи починається наявна в ній дорога з імені кореневої теки аккаунта (поміщеного строчкою вище в змінну Sbegin):
    if ((strpos($fold,$begin)!= 0)|(strpos($fold,"..")!=False)||($fold==""))
    {

Примітка:
Функція strpos (рядок - об'єкт пошуку, шукана комбінація символів) повертає або номер позиції, на якій у вказаному в її першому параметрі рядку знаходиться вказана в другому параметрі комбінація символів, або False - якщо така не знайдена взагалі.
Щоб розрізнити можливі результати роботи функції "комбінація символів знайдена в рядку на позиції 0" і "комбінація символів в рядку не знайдена", можна використовувати при порівнянні поєднання трьох знаків рівності - це означає перевірку на "тотожність ":
if (strpos ("рядок", "символи") ===0) {... буде вірно, якщо "рядок" починається з "символів".
Можна також перевіряти результат на приналежність до цілих чисел:
if (is_integer (strpos ("рядок ", "символи")==false) {...
виконається, лише якщо в "рядку" "символи" не знайдені.

і якщо змінна не визначена або дорога в ній не починається з імені кореневої теки або містить дві крапки підряд, то виведемо вміст кореневої теки - для зручності запишемо її ім'я в змінну $dirct, з якою ми і надалі працюватимемо як з тією, що містить дорогу до поточної теки:

$dirct=$begin;
}
else
{

а якщо змінна Sfold "в порядку", то в змінну Sdirct помістимо саме її значення:

$dirct=$fold;
}

Виведемо заголовок форми менеджера файлів. Заразом і передамо в засланні на файл з сценарієм-обробником цієї форми (а цей сценарій, згідно з нашим планом, розташовується у файлі zapros.php) дорога до поточної теки - насправді, звідки обробник може його ще взнати? При передачі форми змінні, вказані в засланні на сценарій-обробник форми, теж будуть йому передані - разом із змінними з форми.

echo ("<formaction=zapros.php?folder=$dirct method=post>");

В тому випадку, якщо поточна тека не є кореневою, виведемо заслання на батьківську теку - тобто ту, яка містить в собі поточну...

if ($dirct!=$begin) {

для чого виділимо з дороги до поточної теки його частину з початку аж до останнього слеша - роздільника директорій; це і буде дорога до батьківської теки (скажімо, якщо дорога до поточної теки -f iles/folderl/papkal, то дорога до батьківської теки виглядатиме як f iles/f olderl):

$back=substr ($dirct, 0, strrpos($dirct, "/"));

Примітка:
Команда substr (рядок, початок виділення, довжина виділення) призначена для виділення з рядка її частини. Рядок (або змінна, що її містить) має бути вказана в першому параметрі команди. Другий параметр - позиція, з якою починається частина (вірніше, число символів, які необхідно пропустити до початку виділення частині рядка), що виділяється, а третій -колічество символів, що виділяються.
Команда strrpos (рядок, символ) видає номер позиції останньої появи вказаного в її другому параметрі символу в рядку, вказаному в її першому параметрі. У наведеній вище строчці вона використовується для визначення довжини вирізуваного з повної дороги фрагмента - до останнього слеша.

і виведемо заслання на батьківську теку, просто передавши отриману дорогу до неї через змінну $fold:

echo ("<ahref=index.рbр?:?о1с1=$bаськ>корневая папка</а><br>");

Все це робиться, природно, лише в тому випадку, якщо поточна тека - не коренева.
}
Тепер можна і сканувати поточну теку. Отримуємо список файлів в ній (пояснення дивитеся в гл. 6 - в описі сценарію "Папкопотрошилка"):

$hdl=opendir($dirct); while ($file= readdir($hdl)) {
if (($file!="..")&&($file!=".")) { $a[]=$file;
} }
closedir($hdl);

В тому випадку, якщо файли в теці є...

if (sizeof($a) >0) {

відсортуємо масив з їх іменами за абеткою. На жаль, при цьому імена тек виявляться перемішаними з іменами файлів, але робити спеціальну функцію сортування доки не будемо: asort($a);
Тепер треба вивести на сторінку імена файлів і тек, причому кожне ім'я має бути засланням на відповідний файл або теку, а перед ім'ям повинен стояти checkbox для можливості вибору відповідних файлів і тек для здійснення над ними дій.
З кожним ім'ям файлу або теки...
foreach ($a as $k) { поступимо таким чином.

Примітка:
Оператор foreach прочитує вказану в його параметрах змінну, в даному випадку $к, всі елементи масиву, в даному випадку $а, по черзі виконуючи кожного разу вказаний після нього у фігурних дужках код, в якому може використовуватися вказана змінна. Foreach працюватиме лише в РНР 4.0 і вище. Якщо ви можете використовувати лише РНРЗ, то замість нього можна використовувати цикл for, вказавши в його параметрах величину масиву $1.

Спочатку запишемо в змінну дорогу до даного файлу або теки -относительний від тієї директорії, де знаходяться файли самого файлового менеджера. Для цього просто додамо ім'я даного файлу або теки до дороги до поточної директорії:
$full=$dirct."/". $k; Тепер виведемо checkbox:

echo ("<input name=fl[] value=$k type=checkbox>");

При передачі форми сторінці-обробникові буде переданий масив $fl, що складається із значень атрибутів value відмічених checkbox'oe (лише відмічених - невідмічені ігноруються). А як значення атрибутів value ми вказуємо імена файлів. Отже сценарію-обробникові буде повністю ясно, з якими файлами йому працювати - дорога до поточної теки буде передана в змінній в засланні на обробник, вказаної в заголовку форми, а імена файлів передадуться в масиві $fl.
Якщо черговий елемент масиву з іменами файлів в поточній директорії є текою...

if (is__dir ($full)==True)

Примітка:
Функція is_dir повертає True, якщо вказаний в її параметрі об'єкт існує і є текою.

то виведемо заслання на неї. Вірніше, не на неї, а на цей же файл нашого файлового менеджера - index.php, передавши йому як дорога до поточної теки - в значенні змінної Sfold - записаний нами раніше в змінну Sfull повна дорога до даної теки:

echo ("<ahref=index.php?fold=$full><b>nariKa $k</bx/a>") ;

Ну і вкажемо як текст заслання назву теки, пояснивши, що це заслання веде саме на теку (див. мал. 11.4).
В результаті переходу по такому засланню файлу index.php буде передана нова дорога - дорога до теки, що "відкривається", - і відвідувач зможе побачити список файлів в ній.
Якщо ж черговий елемент масиву з імен