RFpro.ru: Программирование на PHP

  Все выпуски  

RusFAQ.ru: Программирование на PHP


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / PHP

Выпуск № 384
от 29.06.2006, 17:05

Администратор:Калашников О.А.
В рассылке:Подписчиков: 313, Экспертов: 43
В номере:Вопросов: 3, Ответов: 7


Вопрос № 47152: Здравствуйте уважаемые эксперты! В процессе создания сайта на бесплатном хостинге оказалось что базу данных мне предоставлять не хотят, только php. В связи с чем возникли вопросы: 1)как можно получить массив с именами всех файлов в папке? 2)...
Вопрос № 47156: Доброго времени суток Вам уважаемые. У меня возникла проблема с графической защитой. Думаю вы знаете что это такое - генерация случайной цифирьно-бувенной картинки. Я сам такую зашиту не знаю и поискал в инете. Нашел исходники покопался и соз...
Вопрос № 47193: Здравствуйте товарищи эксперты, У меня к вам пару вопросов: 1) Есть ли какая нибудь функция которая бы из текста с тегами, возвращала бы текст который находится между определёнными тегами, например нужно получить текст между...

Вопрос № 47.152
Здравствуйте уважаемые эксперты! В процессе создания сайта на бесплатном хостинге оказалось что базу данных мне предоставлять не хотят, только php. В связи с чем возникли вопросы:
1)как можно получить массив с именами всех файлов в папке?
2)Насколько безопасно делать админку с веб-интерфейсом в движке, построенном на файлах.
3)Насколько целесообразно прочитывать все файлы через цикл для получения имен статей и их описания для странички оглавления, если значения разделены скажем последовательностью "<!--split-->", или все таки лучше вынести заголовки и описания в отдельный файл, если так то опять таки встает второй вопрос.
Заранее спасибо за ответ.
Отправлен: 23.06.2006, 19:13
Вопрос задал: Bolzamo (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Марк Крейн
Здравствуйте, Bolzamo!
1. Открыть каталог функцией opendir. В цикле while просто вывести имена всех файлов. Примерно так:
while ($d==readdir($dirhandle))
{
echo $dir;
}

2. База данных в любом случае безопаснее чем файлы. Но если встаёт такой вопрос, то Вам нужно в первую очередь позаботиться о блокировках файла. То есть, скажем, писать в файл не так:

$file=fopen("file.txt", "w");
fwrite($file, "строка");
fclose($file);

А так:

$file=fopen("file.txt", "w");
flock($file, LOCK_EX);
fwrite($file, "строка");
flock($file, LOCK_UN);
fclose($file);

Во втором примере показана блокировка файла от других процессов. Т.е. когда Вы пишете в файл что-то, чтобы никто эту информацию не испортил. Но даже с блокировками в конце концов возникнет вопрос когда движком будет пользоваться слишком много людей. Так что ответ однозначный - делать такое точно небезопасно.

3. Мне кажется что лучше вынести их в отдельный файл. В принципе, конечно, и так и так морока. С базой было бы гораздо легче. Но если из двух зол выбирать меньшее, я бы посоветовал вынести имена статей и их описания в отдельный файл.

Надеюсь что хоть немножко прояснил Вам ситуацию. Если что, пишите в мини-форум.
Удачи!
Ответ отправил: Марк Крейн (статус: 6-ой класс)
Ответ отправлен: 23.06.2006, 21:46

Отвечает: Mamont
Здравствуйте, Bolzamo!

Q1) как можно получить массив с именами всех файлов в папке?
A1)
<?
$dir_name=$_SERVER['DOCUMENT_ROOT'].'/';
$d=opendir($dir_name) or die($php_errormsg);
while( false !==($f=readdir($d))){
if (is_file("$dir_name$f")){
$f_arr[]=$f;
}
}
closedir($d);

foreach( $f_arr as $name ){
echo "$name<br> ";
}
?>

Q2)Насколько безопасно делать админку с веб-интерфейсом в движке, построенном на файлах.
A2)Если интересует возможность потери данных (когда используется один и тот же файл), то при одном администраторе таких проблем не возникает (никто больше не пытается получить монопольный доступ к файлу) - просто используем блокировку файла:
$f=fopen('name.txt','a');
flock( $f, LOCK_EX );
fwrite( $f, 'text' );
fflush( $f );
fclose( $f );

Q3)Насколько целесообразно прочитывать все файлы через цикл для получения имен статей и их описания для странички оглавления, если значения разделены скажем последовательностью "<!--split-->", или все таки лучше вынести заголовки и описания в отдельный файл, если так то опять таки встает второй вопрос.
A3) (также касается Q2)
Используя хранение всей информации (заголовок, описание, статья...) в одном файле облегчает реализацию создания/редактирования статьи, но при создании списка необходимо прочитать заголовки всех файлов, что не повышает производительности.
Так же приходиться использовать имя файла как передаваемый параметр, что использовать не безопасно - возможно выполнение произвольного кода и т.д. и т.п., за этим глаз и глаз нужен. Во втором варианте можно ввести поле ID и передавать его и такая проблема отпадает. В принципе этот вариант возможен и в первом случае, но реализуется сложнее (да и работает намного медленней).
P.S. Сам когда-то реализовывал движок со вторым вариантом и использовал подобие формата dBase(.dbf): выравнивал поля по ширине (позволило редактировать описание и т.д. не перезаписывая весь файл, а только нужную строку), записи не удалялись, а помечались "#" в начале строки (тоже весь файл не перезаписываем). И не забудь перед открытием файла со статьей проверять его наличие: if (file_exists('filename.txt'))

Ну в общих чертах это все, удачи!!!

---------
Иногда движение вперед-результат пинка под зад
Ответ отправил: Mamont (статус: 2-ой класс)
Ответ отправлен: 24.06.2006, 10:14

Отвечает: Cybernetic_Creature
Здравствуйте, Bolzamo!
1)
array glob(string $filter) e.g. foreach(glob(*.*) as $nextfile) print $nextfile;
http://php.net/manual/ru/function.glob.php
2)
если нет другого выхода.
хотя можно использовать SQLite
http://php.net/manual/ru/ref.sqlite.php
3)
лучьше конечно хранить каждую статью в отдельном файле.
что бы потом редактировать было проще
Ответ отправил: Cybernetic_Creature (статус: Специалист)
Ответ отправлен: 24.06.2006, 10:27

Отвечает: Цепковский Антон Сергеевич
Здравствуйте, Bolzamo!

Я бы всё-таки заполучил хостинг с БД, избавитесь от многих проблем. Например на hut.ru.

С уважением,
Антон Цепковский
---------
Вся наша жизнь - RPG
Ответ отправил: Цепковский Антон Сергеевич (статус: 1-ый класс)
Ответ отправлен: 25.06.2006, 01:23


Вопрос № 47.156
Доброго времени суток Вам уважаемые.
У меня возникла проблема с графической защитой. Думаю вы знаете что это такое - генерация случайной цифирьно-бувенной картинки.
Я сам такую зашиту не знаю и поискал в инете. Нашел исходники покопался и создал свое. А пока создавал смутно понимал, что мне что-тос ильно непонятно. И я понял что именно. У меня возникло два вопроса. Я не понимаю к чему там функция одна и почему вызываются в трех скриптах сессии. В скрипте формы. В скрипте геренерации картинки и в скрипте обработки формы. Приведу коды всех трех страничек.

Приложение:

Отправлен: 23.06.2006, 21:56
Вопрос задал: Чинга (статус: Посетитель)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Mamont
Здравствуйте, Чинга!

Напрямую на вопросы отвечать не буду, приведу свои комментарии (думаю из них все будет понятно ;) )
Файл page1.php:

session_start(); - начинаем использовать сессии, т.е. создается уникальный идентификатор, который передается от одной странички к другой при помощи куки или внедрения в ссылки/формы. Этим занимается сам PHP.
session_register("secret_number"); - не рекомендуется использовать когда используем массив $_SESSION, удаляем

if (intval($_SESSION["secret_number"])<1000) { - поверяет сгенерирован ли номер для картинки - не нужно (удаляем), каждый с нашим PHPSESSID получит тот же номер. Никакой защиты от многократного использования !!!

srand(doubleval(microtime())); - запускает генератор случайных чисел (типа запускает). Для запуска необходимо указать ЦЕЛОЕ число (тоже случайное, прям замкнутый круг ;) ).
Для этого используем функцию microtime() - которая возвращает текущее время в секундах и микросекундах ( т.е. не 13215456,54645 а 13215456 0,54645 )
Поскольку у srand параметр целое число а передается строка получаем в итоге вызов srand(0) и функция rand() будет выдавать всегда одно и тоже число :(
Используем так:
list($usec, $sec) = explode(' ', microtime());
srand((float) $usec * 100000);

$_SESSION["secret_number"]=rand(1000,9999); получаем случайное число и сохраняем его в массиве (этот массив нам будет доступен и на другой странице если не потеряем PHPSESSID)

header('Content-Type: text/html; charset=windows-1251'); - тоже убираем, сервер сам знает в какой кодировке будет отправка а мы можем все испортить (он может сменить кодировку)

В теле формы:
<img src='code.php?<?=doubleval(microtime()); ?>' width=101 height=26 vspace=5><br><br> - зачем то скрипту с генерацией картинки передается текущее количество микросекунд - я в шоке (оно тем более изменилось уже и не используется к тому же)
заменяем на: <img src='code.php?<? echo SID; ?>' width=101 height=26 vspace=5><br><br> - к сожалению PHP не может догадаться вставить PHPSESSID в ссылку на картинку, жаль делаем это сами (в принципе это нужно только если у пользователя отключены куки)
Файл Code.php:

session_register("secret_number"); - убираем

function mt() {
list($usec, $sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 100000);
}
- нигде не используется, тоже убираем

Ну как генерировать картинку дело вкуса оставим так.

Файл Proverka.php:

даж не знаю что писать....

if(isset($submit)){ - не на всех серверах будет работать
НИ ОДНОЙ ПРОВЕРКИ на существование переменной !! - может вылезти куча ошибок
if ($_POST["secretcode"]!=$_SESSION["secret_number"] - может вызвать ДВЕ ошибки (надо допускать что пользователь подправил форму/PHPSESSID)
должно быть примерно так:
if (isset($_POST["secretcode"]) and isset($_SESSION["secret_number"]) and
($_POST["secretcode"]!=$_SESSION["secret_number"]) ||

это основное, а так крамсать и править еще ;)
Удачи !!!


---------
Иногда движение вперед-результат пинка под зад
Ответ отправил: Mamont (статус: 2-ой класс)
Ответ отправлен: 24.06.2006, 12:15
Оценка за ответ: 5


Вопрос № 47.193
Здравствуйте товарищи эксперты,

У меня к вам пару вопросов:

1) Есть ли какая нибудь функция которая бы из текста с тегами,
возвращала бы текст который находится между определёнными тегами,
например нужно получить текст между тегами <b></b>...

Конечно можно:
Например...

$text - то что нужно получить...

$contents= Весь текст с тегами
$tag= '<b>';
$start= strpos($contents,$tag);
$finish= strpos($contents,'</'.substr($tag,2,strlen($tag)));
$text= substr($contents,$start,$finish-$start);
$text=strip_tags($text);

но это как то не красиво.. может есть что то что работает быстрее
и лучше...

2) Где можно скачать/посмотреть алгоритмы поиска на PHP,
или хотя бы _хорошие_ статьи на эту тему...

Всем спасибо...
Отправлен: 24.06.2006, 09:20
Вопрос задал: Wlp (статус: Посетитель)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Cimus
Здравствуйте, Wlp!
Для поиска текста между тегами можно использовать следующую конструкцию -

$stroka='строка <b>Вашего</b> поиска';
eregi('<b>(.+)</b>', $stroka, $result);
print_r( $result);

Краткая справка по реализации поиска: Обработка строки, вырезание служебных символов, составление запроса к базе, логика, постраничный вывод, релевантность.
http://phpclub.ru/detail/article/mysql_search
---------
Достичь можно любых высот !
Ответ отправил: Cimus (статус: 3-ий класс)
Ответ отправлен: 24.06.2006, 09:42
Оценка за ответ: 5

Отвечает: Mamont
Здравствуйте, Wlp!

Если открывающий и закрывающий теги находятся в одной строке используем регулярные выражения:
<?
$str='Строка в <B>которой</b> производится <b>наш поиск</b>';
echo "Количество совпадений: ".
preg_match_all('#<b>.+?</b>#i', $str, $result)."<br> ";
print_r( $result);
?>

---------
Иногда движение вперед-результат пинка под зад
Ответ отправил: Mamont (статус: 2-ой класс)
Ответ отправлен: 24.06.2006, 11:00
Оценка за ответ: 4


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

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


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2006, Портал RusFAQ.ru, Россия, Москва.
Идея, дизайн, программирование: Калашников О.А.
Email: adm@rusfaq.ru, Тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.34 от 01.06.2006
Яндекс Rambler's Top100

В избранное