ФАЙЛ DO.PHP

Сценарій цього файлу виконує вибрана відвідувачем дія і перенаправляє його назад на основну сторінку файлового менеджера.
На цій сторінці знаходитиметься лише програмний код. Оскільки користувач після виконання дії відразу буде перенаправлений на основну сторінку, який-небудь дизайн даної сторінки зайвий.
Почнемо сценарій. Так само на його початку запишемо в змінну ім'я кореневої теки аккаунта - щоб потім його використовувати в сценаріях:

<?php
$begin="files";

Доцільність перевірки вмісту змінною Sfolder на предмет можливості спроби злому сайту може представитися сумнівною. Ета змінна передається за допомогою заголовка форми і в адресному рядку не відображується, проте ніщо не заважає зловмисникові сохрацить сторінку з формою запиту інформації на свій жорсткий диск, виправити її вміст і, замінивши відносні заслання на абсолютні, перейти із збереженого варіанту на сторінку виконання дії. Отже перевіряти змінну Sfolder на наявність в ній заслання на батьківський каталог (двох крапок підряд), а також упевнитися, що дорога, записана в ній, починається з імені кореневої теки аккаунта, все ж необхідно. Якщо останнє невірно або в Sfolder можна знайти дві крапки підряд, то подальше виконання коди припиняється:

If
((strpos($folder,$begin)!=0)||(strpos($folder,"..")
!=False))
158
exit; }

Примітка:
Команда exi t повністю припиняє виконання коди і виведення тексту на сторінці, на якій вона розташована, - неначебто саме на ній сторінка закінчувалася. Звернете увагу, що ця команда завершує не виконання РНР-программы, а виведення сторінки - тобто HTML-код після завершуючого тега РНР-сценария, якщо такий є, виводитися також не буде.

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

ВИДАЛЕННЯ, ВИКОНАННЯ ДІЇ

Для видалення файлів в РНР існує спеціальна команда - unlink.

Примітка:
Команда unlink (ім'я файлу з повним дорогою до нього) видаляє файл, вказаний в її параметрі. Якщо цього зробити не удасться - виводить на сторінку повідомлення про помилку.
Команда rmdir (ім'я директорії з повним дорогою до неї) видаляє вказану в її параметрі директорію, якщо вона порожня. Якщо тека, що видаляється, не порожня або сценарій не має прав на видалення директорії, то на сторінку виводиться повідомлення про помилку.

Видалити цією командою файли, чиї імена передані із сторінки запиту підтвердження видалення - справа трьох рядків коди. Проте наш сценарій, якщо ви пам'ятаєте, дозволяє видаляти і цілі директорії. Порожню директорію можна видалити командою rmdir, - але як зробити директорію порожньою, як її очистити від вмісту? Адже в директорії можуть бути і вкладені теки, а в них - теж вкладені.
І знову використовуємо рекурсію. От як виглядає рекурсивний алгоритм видалення всього вмісту теки:

function delfiles($fId)
$hdl=opendir($fld); while ($file = readdir($hdl)) {
if (($file!=".")&&($file!="..")) {
if (is_dir($fld."/".$file)==True) {
delfiles ($fId.»/".$file); rmdir ($fld."/".$file); }
else {
unlink ($fld."/".$file); } } }
closedir($hdl);
}

Проаналізуйте його самі. Думаю, ви легко зрозумієте логіку його роботи: вказана в параметрі функції тека сканується сценарієм, розібраним в главі "Папкопотрошилка", і якщо черговий знайдений в ній об'єкт є файлом, то він віддаляється, а якщо об'єкт є текою, то викликається ця ж функція, але як параметр їй цього разу передається ім'я цієї теки. Рано чи пізно функція дійде до тек, що містять одні файли, і рекурсія почне уриватися. Після видалення всіх файлів в теці віддаляється і сама тека, оскільки вона вже порожня.
Сам код виконання видалення вибраних користувачем файлів простий.
Якщо як дія вибрано видалення...

if ($udal!="")

то кожен обьект, ім'я якого передане з форми на сторінці запиту підтвердження на видалення...

foreach ($fl as $i)

перевіримо на те, чи немає він директорією.

if (is_dir($folder."/".$i)==True)
{

Якщо є, то видалимо всі файли в цій директорії - рекурсивною функцією delf iles...

delfiles ($folder."/".$i); а потім і саму, вже спустошену директорію - командою rmdir.
rmdir ($folder."/".$i); } else

А якщо цей об'єкт, що підлягає видаленню, є звичайним файлом...
то для нього припасена вже згадана вище команда unlink: unlink ($folder."/".$i); }
І так поступимо з кожним об'єктом, ім'я якого передане сценарію через масив $fl, а дорога до нього - через змінну Sfolder в адресному рядку.
} Власне, і все (мал. 11.10).

Мал. 11.10. Видалення виконане

КОПІЮВАННЯ, ВИКОНАННЯ ДІЇ

З копіюванням буде поскладніше. Нагадаю, що з сценарію запиту додаткової інформації переданий масив Sfl, що складається з імен копійованих файлів і тек, і змінна $rd, що містить ім'я з повним дорогою до тієї теки, в яку планується здійснити копіювання. Ну і, зрозуміло, дорога до поточної теки, в якій спочатку і знаходяться копійовані файли, - $folder.
Спочатку напишемо функцію копіювання цілої теки зі всіма вкладеними в неї теками на нове місце. Ця функція, як і функції видалення теки і виведення списку всіх тек, на аккаунте буде рекурсивною - тобто з викликом самій себе зі своєї коди. Алгоритм її простий:

  1. 1. Створити в теці призначення теку з тим же ім'ям, що і в копійованої.
  2. 2. Копіювати з копійованої теки в новостворену теку весь її вміст.
  3. 3. Якщо черговий копійований об'єкт - тека, то перейти до пункту 1, прийнявши як теку призначення - новостворену теку, а як копійована тека - цей самий черговий копійований об'єкт, що виявився текою.

Рано чи пізно функція дійде до тек, що містять лише файли, які і стануть переривати рекурсію.
Функція отримуватиме повне ім'я (разом з дорогою) теки, в якій знаходиться копійована тека, ім'я цієї самої копійованої теки, і ім'я (разом з дорогою) теки призначення копіювання (тобто тій, в яку вироблятиметься копіювання).
function copyfold ($fld, $nm, $tgt)
Усередині функції ці дані будуть доступні в змінних $fld, $nm, $tgt відповідно.
Спочатку створимо в теці призначення копіювання теку з таким же ім'ям, що і ім'я копійованої теки. Природно, якщо там такої ще немає:

if (file_exists($tgt."/".$nm)!=True)
mkdir ($tgt."/".$nm, 0666);

Примітка:
Команда mkdir (ім'я нової теки разом з дорогою до неї, параметри доступу) створює нову теку. Якщо створити теку неможливо (наприклад, вже є тека з таким ім'ям), то видається повідомлення про помилку.

Параметри доступу, або атрибути файлу або теки - це вісімкове число, що повідомляє web-серверу про те, що можна робити з файлом, якому ці параметри встановлені. Наприклад дозволити його читати лише іншим сценаріям на тому ж аккаунте, але не відвідувачам з Мережі. Дізнатися про відповідність значень параметрів доступу їх вісімковій виставі можна, наприклад в FTP-клиенте CUTEFTP, скориставшись його вікном виставляння атрибутів файлу (ріс.11.11), доступному через пункт "Chmod" меню правої кнопки миші будь-якого файлу на сайті. "Owner permissions" - це раз рішення для інших програм на тому ж аккаунте, а "Public permissions" - для відвідувачів з Інтернету. Ви можете вирішити або заборонити три види дій: читання, запис і запуск на виконання (останнє має сенс лише для програм).

Мал. 11.11 . "Калькулятор параметрів доступу" з CUTEFTP

Тепер почнемо копіювати файли з вихідної теки в новосоздан-ную (використовуємо старий добрий сценарій "папкопотрошилки"): вихідна тека при цьому - $f Id. " /" . $шп, а новостворена -

$tgt."/".$nm.
$hdl=opendir($fld."/".$nm) ; while ($file= readdir($hdl)) { if (($file!=" . .")&&($file! = "."))

Якщо черговий об'єкт з "потрошимой" теки $f Id. " / " . $nm -діректорія...

if (is_dir($fld."/".$nm."/".$file)==True) {

про застосуємо рекурсію - знов викличемо функцію з кричу fold, лише араметри їй вже передамо дещо інші:

copyfold($fld."/".$nm, $file, tgt."/".$nm);

Іншими словами, як ім'я копійованої теки - вказуємо мя чергового обьекта, знайденого в "потрошимой" теці. Останніми передаваними функціями параметри є відповідно ім'я "батьківської" теки для копійованої (це ім'я "потрошимой" теки), ім'я теки призначення (складено з вихідного імені апки призначення і імені копійованої теки, ця тека, до речі, як ви, напевно, пам'ятаєте, була створена командою mkdir на початку роботи функції).
Якщо ж черговий об'єкт з "потрошимой" теки $f Id." /" . $nm є звичайним файлом...

}
else
{

то просто скопіюємо його з вихідної теки в теку призначення -і справа з кінцем.
сміттю ($fld."/".$nm."/".$file, $tgt."/".$nm."/".$file);

Примітка:
Функція сміттю (вихідний файл, файл на місці призначення) копіює файл, повна дорога до якого вказана в першому параметрі, в той файл, повна дорога до якого вказана в другому параметрі. Якщо копіювання не удається, то функція виводить повідомлення про помилку (можна відключити, помістивши символ @ перед командою) і повертає false.
Якщо файл призначення вже існує, він буде перезаписаний без виведення якого-небудь підтвердження.

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

сміттю ("/files/data/filel.htm", "/files/last/'filel.htm");

Як імена файлів можуть виступати що містять їх строкові змінні.
Робота функції завершена. Закриємо відкриті цикли і умовних операторів...

}
} }

і відкриту "потрошимую" директорію:

closedir($hdl); }

Текст цієї функції слід помістити перед розділом коди, що виконується в тому випадку, якщо як дія над вибраними файлами вибрано копіювання. Код же цей наступний.

if ($copy!="")
{

Переберемо всі об'єкти, що підлягають копіюванню: foreach ($fl as $i)
{ Якщо черговий об'єкт - тека...

if (is_dir($folder."/".$i)==True)

то запустимо функцію копіювання теки, розібрану вище, передавши їй потрібні параметри.

copyfold($folder, $i, $rd);

Коментар:
Як ви пам'ятаєте, на сторінку запиту інформації ми помістили спеціальний код, який складав список тек, що можуть бути пунктом призначення для копіювання. У цьому коді також відстежувалося, чи немає чергова тека з цього списку вкладеною текою який-небудь з копійованих тек, і такі теки із списку віддалялися. Це і зрозуміло, копіювання теки в свою ж вкладену теку приведе або до "підвисання" web-сервера, якщо він не дуже добре конфігурований, або до забивання аккаунта безліччю тек і файлів (це пов'язано з тим, що рекурсивна функція копіювання у такому разі увійде до безконечного циклу).

Проте виключення вкладених тек із списку можливих пунктів призначення на сторінці запиту додаткової інформації не гарантує неможливості початку такого копіювання! Зловмисник може зберегти сторінку файлового менеджера із списком пунктів призначення копіювання на своєму комп'ютері, а потім, виправивши відносні заслання на абсолютні, додати в локальну копію сторінки новий можливий пункт призначення копіювання, тобто ім'я теки, вкладеної в копійовану теку, а потім, помітивши саме цю теку, запустити копіювання, тим самим нашкодивши власникові сайту, на якому розташований файловий менеджер.
Щоб зробити такі дії неможливими, на сторінці виконання дії можна перевіряти, чи не вкладена тека призначення копіювання в копійовану теку. Для цього найпростіше порівняти повні імена цих тек. Якщо повне ім'я копійованої теки можна знайти на початку повного імені теки призначення, то копіювання виконувати не можна. Для порівняння найпростіше скористатися функцією strpos (довідку по ній дивитеся на початку цієї глави):

if (!(strpos ($rd, $?older."/".$i)===0)) { copyfold($folder, $i, $rd);
}

Хоча, безперечно, в даному сценарії такий "захист", швидше, є демонстраційним - якщо відвідувач має можливість завантажувати на аккаунт будь-які файли, то ніхто не перешкодить йому завантажити на нього яку-небудь шкідливу програму на РНР і виконати її.
Якщо ж черговий об'єкт - файл...

}
else {
то його скопіюємо.
сміттю ($folder."/".$i, $rd."/".$i);

Залишилося закрити фігурними дужками запущені цикли і умовні оператори.

} }
}

Процес копіювання завершений (мал. 11.12).

Мал. 11.12. Файли скопійовані

ПЕРЕЙМЕНУВАННЯ, ВИКОНАННЯ ДІЇ

В тому випадку, якщо відвідувач вибрав як необхідну дію перейменування, то на сторінці запиту додаткової інформації йому довелося ввести нові імена для тих файлів і тек, перейменувати які він побажав. Сценарію ж виконання дії передалися два масиви із старими і новими іменами цих обьектов -$afl і $rfl відповідно.

if ($ren!="")
{

Переберемо всі елементи масиву із старими іменами - $af 1. Оскільки для здійснення власне перейменування для кожного елементу масиву із старими іменами нам також буде потрібно елемент масиву $rf 1 з новими іменами під тим же порядковим номером, то перебирати ці елементи будемо підряд, по номерах - за допомогою циклу for:

for ($i = 0; $i < sizeof($afl); $i++)

Якщо нове ім'я не збігається із старим і не є порожнім рядком...

if (($rfl[$i]!="")&($rfl[$i]!=$afl[$i]))

то можна перейменовувати. Проте відвідувач сповна може в новому імені вказати символи, які недопустимі для імен файлів, - від пропусків до слешей. Повертати відвідувача на етап введення імені з виведенням йому повідомлення про недопустимі символи не будемо - просто замінимо всі такі символи на знаки підкреслення: "_". Тим більше що таку заміну можна зробити спеціальною командою PHP - strtr:

(Кількість знаків підкреслення в третьому параметрі функції дорівнює кількості вказаних в другому недопустимих символів.)

Примітка:
Функція strtr("рядок", "замінювані символи", "замінюючі символи") замінює в рядку, вказаному в її першому параметрі, символи, приведені в рядку в її другому параметрі, на символи з рядка в її третьому параметрі, що стоять в цьому рядку на тих же місцях, що і замінювані символи в рядку в її другому параметрі.

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

1. Дивиться, який символ стоїть в рядку в її третьому параметрі на тому ж самому місці від початку рядка, що і зустрінутий символ в рядку в другому параметрі.
2. Замінює в рядку в першому параметрі цей черговий символ на знайдений в третьому рядку. Наприклад результатом виконання функції

strtr ("Оабвапабаво", "ба", "ру")

буде рядок

"Оурвупуруво"

Якщо рядки в другому і третьому параметрах різної довжини, то зайві символи в довшому рядку ігноруються.

Оскільки на всіх місцях в рядку в третьому параметрі цієї функції коштує знак підкреслення, то всі недопустимі символи, вказані в рядку в її другому параметрі, будуть на нього замінені.
І нарешті, само перейменування - командою rename:

rename ($folder."/".$af1[$i], $folder."/".$rfl[$i]) ;

Примітка:
Команда rename (ім'я файлу, що перейменовується, разом з дорогою, його нове ім'я разом з дорогою) перейменовує файл. Якщо файл перейменувати з якої-небудь причини не удалося (скажімо, файл, що перейменовується, не існує або в теці вже є файл з таким же ім'ям, що і нове ім'я), то виводиться повідомлення про помилку.

От і все (мал. 11.13).
} } }

Коментар:
Якщо при перейменуванні файлу як нове ім'я задати ім'я вже існуючого файлу, то команда rename видасть повідомлення про помилку (мал. 11.14). Це і зіпсує зовнішній вигляд сторінки, і утруднить дії користувача. Можна, звичайно, перед командою rename поставити знак @ - тоді повідомлень про помилку не буде (стандартний спосіб заборони на виведення такого повідомлення), але тоді користувач навіть не дізнається про помилку.

Мал. 11.13. Файли перейменовані

Мал. 11.14. Помилка при перейменуванні - повідомлення РНР

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

while (file_exists($folder."/".$rfl[$i])==True)
{
$rfl[$i] = "_".$rfl[$i];
}

Як неважко зрозуміти, він додає в початок нового імені файлу знак "_", якщо файл з таким ім'ям вже існує в тій же теці, куди передбачається копіювати файл. Якщо ж і такий файл - із знаком "_" на початку -уже в теці є, то до нового імені додається ще один такий символ, і так до тих пір, поки нове ім'я не стане унікальним.

СТВОРЕННЯ НОВОЇ ТЕКИ, ВИКОНАННЯ ДІЇ

Створення нової теки виконує найменший фрагмент коди у всьому сценарії. Навіть менше того, що виводив запит імені для цієї нової теки.

if ($md!="") {

Як і в сценарії перейменування файлу, виключимо з імені нової теки недопустимі символи...

$newname=strtr($newname, " []{},/\!@#$%л&*",

і створимо теку - командою mkdir, не забувши вказати в її параметрах повну дорогу до нової теки:

mkdir ($folder."/".$newname, 06 66);

Опис команди mkdir ви вже бачили вище - в підрозділі "Копіювання, виконання дії". Власне, і все (мал. 11.15).

Мал. 11.15. Тека створена

ЗАВЕРШЕННЯ ДІЇ

Ну і після закінчення виконання дій перенаправимо відвідувача на основну сторінку файлового менеджера - в ту ж директорію, в якій він і знаходився, передавши сценарію на основній сторінці дорога до неї через змінну fold в адресному рядку. Для цього скористаємося командою Header, передавальною браузеру заголовки.
Якщо на сторінці запиту додаткової інформації відвідувачем натискувала кнопка "Відміна", то жоден з наведених вище блоків виконання дії виконаний не буде - жодна із змінних Sudal $copy, $ren, $md визначена не буде. А ця команда виконається - тобто після натиснення кнопки "Відміна" на сторінці запиту додаткової інформації відвідувач виявиться на основній сторінці файлового менеджера.

Header ("Location: index.php?fold=$folder");

Примітка:
Заголовок - це дані, передавані браузеру до передачі самої web-страницы, повідомляючі йому деякі параметри передаваного файлу або певні команди. Список всіх можливих заголовків, які зобов'язані підтримувати сучасні браузери, можна знайти в специфікаціях протоколу HTTP - вони є, наприклад, на сайті http://www.w3.org. PHP-команда Header виконує всього одну дію -она просто передає те, що вказане в її параметрі, в браузер, що запитав сторінку, на якій вона знаходиться, як заголовок.
Заголовок "Location" здійснює перенаправлення браузера на сторінку, вказану в його параметрі.

Сценарій можна завершити - відвідувач вже на іншій сторінці...
В результаті після того, як відвідувач на сторінці запиту додаткової інформації натискуватиме кнопку початку дії, після невеликої паузи (що триває рівно стільки часу, скільки треба web-серверу для здійснення цієї дії) він знов виявиться на головній сторінці файлового менеджера, а замовлена ним дія буде виконана.
Проте якщо в процесі виконання сценарію виникне помилка (скажімо, нову теку створити не удасться, оскільки виявиться, що тека з таким же ім'ям вже існує, або виникла проблема при перейменуванні файлу - см.ріс.11.14), то на сторінку буде виведено повідомлення про помилку, а команда Header не спрацює - і теж видасть повідомлення про помилку (оскільки заголовок можна відправляти лише до якого-небудь виводу на сторінку). Якщо вас це не владнує - тому можете або передувати всі команди символом "@" (він забороняє виводити повідомлення про помилки), або забезпечити сторінку з сценаріями виконання дії в самому низу невеликим коментарем (з інформацією начеб "Виникла помилка, даруйте...") і засланням на головну сторінку файлового менеджера.
Ось, власне, і весь сценарій. Якщо бажаєте - можете його використовувати в своїх розробках. Або просто, проглянувши текст з коментарями, скласти собі уявлення про те, як складати програми на РНР.
Зрозуміло, сценарій можна покращувати. Перші дві пропозиції по поліпшенню напрошуються відразу - додати в нього можливість завантаження файлів і блок авторизації доступу. Код програм, що реалізовують ці пропозиції, вже розглядався в попередніх главах, так що навряд чи їх реалізація буде для вас складною. (Не 174
забудьте хіба що вставити код перевірки вмісту авторизаційних змінних на всі сторінки файлового менеджера, а не лише на основну.) Можна також навчити сценарій видавати осмислені повідомлення про помилки, якщо вони виникнуть, змусити його видавати підтвердження, скажімо, в разі існування в теці призначення копіювання файлів і тек, однойменних копійованим, - щоб запобігти випадковому їх переписуванню. Але це все залишається вже на ваш розсуд.

 
На правах реклами: xxx порно торрент трекер. где смотреть порно фильмы онлайн порно видео бесплатно взрослых женщин . acquisto viagra on line . Предложение лета. Возбуждающие эротические порно рассказы. Варианты 1 2 Необходимо выставить права 777 на папку 62014364

:: Меню ::

ГОЛОВНА

Введення

Небагато про Web-программировании

PHP: Історія. Місця. Джерела.

PHP: Основи

PHP: Вибіркове завантаження

PHP: Простий інтернет-магазин

PHP: Папкопотрошилка

PHP: Закачування файлів

PHP: Авторизація доступу

PHP: Гостьова книга

PHP: Система оцінки матеріалів

PHP: Файловий менеджер

PHP: Корисні дрібниці

PHP: Способи передачі даних між окремими сторінками

Висновок

Додаток 1. Перетвори свій сайт на портал

Додаток 2. Використовуй те, що під рукою - і не шукай завжди інше

Додаток 3. На сайті - як в "Вінде"


:: Реклама ::

  Настройка і оптимізація комп'ютера акции, производство ТЭС низкие цены

 

:: Статистика ::

  Індекс цитування

:: Навігація ::

Головна

Гостьова книга

Додати у вишукане  

 

 

 


Copyright © Asentli, 2008