 |
 |
Форум сетевых администраторов » Программирование » PHP » "Сказка про PHP скрипт" или "как оно работает".
| Автор |
| Тема |
 |
|
 |
|
|
|
STFW
|
"Сказка про PHP скрипт" или "как оно работает". |
[сооб. #17578]
27-07-2002 21:01 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
quote: Предисловие:
сижу вобщем, рисую блок схемы работы web-приложений и тут мне приходит в голову что все можно описать гораздо проще...
..и без всяких трудных терминов. Об этом и сказка. :)
Жил был скрипт, никого не трогал, лежал себе спокойненько на винте у прова и не было у него ни забот ни хлопот.
И вот однажды, слышит он громкий голос Апача, - "скрипт! ПААДЪЕМ!!!"
- "А! Чо!..."
- "Вставай, работа есть."
...скрипт, пошел умылся, снял пижаму и оделся в спецовку.
- "Слышь, Апач? А где я вообще?"
...Апач что то пробурчал насчет склероза в раннем возрасте, но массив с переменными окружения все же показал.
- "Ясненько, щас определимся..."
... клиент скромно стоял за прилавком на которым жирными буквами по трафарету было написано CGI/1.1 и переминался с ноги на ногу, Апач о чем то его распрашивал
- "э... Апач... эт кто?", шепотом спросил скрипт.
- "Клиент это. Вот IP, порт, понимает по русски, английски, (просил на русском) ест text/html, image/gif и все что съедобное (но лучше только то, что указал), пользуется Mozilla/4.0..."
...скрипт изучал карточку клиента и думал что делать дальше.
- "а чо надо то ему?", снова задал вопрос Апачу скрипт.
- "Да просил вот передать куки и строку запроса", ответил Апач.
...теперь скрипт с пыхтением разбирался с передачкой от клиента и разобравшись пошел на склад за данными.
Ð_адостный, он вприпрыжку помчался к прилавку у которого его ждал Апач, но по дороге споткнулся о глиняную табличку на которой, клинописью, были начертаны предпочтения клиента. Собрав все что рассыпалось по полу, он разложил данные в коробке, в соответствивии с надписями на табличке и уже не спеша пошел к цели. (Админ разрешил Апачу, чтоб скрипт сам выдавал ответ клиенту).
- "Вот. Получите пожалуйста.", сказал скрипт и смотря как клиент довольно шарит в коробке, перебирая данные, записал в свой небольшой блокнотик, который назавался "log.today" все что с ним произошло на этот раз...
__________________
FAQ OFF
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
27-07-2002 21:01 |
|
|
Guest+
|
| SCHIZO прикольно очень но помоему луще такие... |
[сооб. #17598]
27-07-2002 23:34 |
|
|
STFW
|
| неее во флейм не надо... я скоро схему с примером... |
[сооб. #17600]
27-07-2002 23:42 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
неее во флейм не надо... я скоро схему с примером накалякаю, сюда же постить буду...
накалякал немного..
вот к примеру возьмем самый первый эпизод когда он встает до момента когда определяется
т.е.
при вызове, происходит инициализация параметров выполнения(конфиг, настройки и др.), затем смотрим, что имеем и где находимся.
теперь принимаем решение:
можем ли продолжать выполнение в таких условиях или нет, если не можем пытаемся исправить и снова смотрим можем или нет...
это упрощенная схема, есть ньюансы...
казалось бы просто, а это в среднем от 50 и более строк кода только на обеспечение корректной инициализации средненького web-приложения на PHP....
P.S.
рабочий пример еще не доделал, что-то уже спать охота....
продолжение следует...
__________________
FAQ OFF
Сообщение было отредактировано SCHIZO 28-07-2002 в 01:25
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
27-07-2002 23:42 |
|
|
STFW
|
| вот так по моему мнению может выглядет этап... |
[сооб. #17621]
28-07-2002 07:17 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
вот так по моему мнению может выглядет этап инициализации...
PHP:
<?php
// устанавливаем максимальный уровень сообщений об ошибках для отладки
error_reporting(E_ALL);
# все что ниже прототип кода который можно использовать
# при инициализации скрипта
/**
* константы для индексов массива параметров
* (мне так удобнее, чем обращение по числовому индексу)
*/
define('ASIS', 1);
define('NEED', 2);
define('FIXIT',3);
define('EMSG', 4);
define('ETYPE',5);
/**
* определение настроек из переданного массива параметров
* возвращает TRUE при успешной установке или соответствии всех параметров
* возвращает FALSE при количестве ошибок более нуля
*/
function setConfig($conf)
{
// инициализируем количество ошибок
$errors = 0;
// вычисляем сколько всего параметров
$items = sizeof($conf);
// проходим в цикле по списку параметров
for ($i = 0; $i < $items; $i++) {
// если действительное и желаемое не совпадают
if (eval($conf[$i][ASIS]) != $conf[$i][NEED]) {
// попробовать исправить
eval($conf[$i][FIXIT]);
// если действительное и желаемое не совпадают после попытки исправления
if (eval($conf[$i][ASIS]) != $conf[$i][NEED]) {
// вызвать ошибку с определенным типом и сообщением
user_error($conf[$i][EMSG],$conf[$i][ETYPE]);
// увеличить счетчик ошибок на единицу
$errors++;
}
}
}
// если ошибок нет
if (!$errors) {
// возвращаем TRUE
return TRUE;
}
// в любом другом случае
else {
// возвращаем FALSE
return FALSE;
}
}
/* конфигурация одной опции (для примера) */
// как узнать текущее значение параметра?
$conf[0][ASIS] = "return file_exists('php_data_file.txt');";
// каким должен быть параметр?
$conf[0][NEED] = TRUE;
// как это следует исправлять? -> если действительное и желаемое не совпадают
$conf[0][FIXIT] = "touch('php_data_file.txt');";
// сообщение об ошибке -> если не удалось исправить
$conf[0][EMSG] = 'File php_data_file.txt is not exists!';
// тип ошибки -> если не удалось исправить
$conf[0][ETYPE] = E_USER_WARNING;
/* тестируем... (как работает команда touch() в виндах, я не пробовал!) */
if (setConfig($conf)) {
echo 'Успешно';
}
else {
echo 'Неудачно';
}
?>
__________________
FAQ OFF
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
28-07-2002 07:17 |
|
|
STFW
|
....блин, а все оказывается гораздо проще =)
вместо... |
[сооб. #17711]
29-07-2002 03:13 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
....блин, а все оказывается гораздо проще =)
вместо того чтобы проверять что либо по ходу скрипта, можно собрать в один массив и затем сравнить требуемое и какое есть.
Содержимое массива проще контролировать чем лазить по скрипту в полторы тысячи строк и искать момент проверки =)
функции должен передаваться двухмерный массив в подмассиве всего два элемента результат проверки и то каким он должен быть
если написать что то типа:
PHP:
$arr[0][CHECK] = is_string($val);
то при инициализации этого элемента он получит значение которое вернет функция is_string потом останется только проверить на НЕÐ_АВЕНСТВО примерно таким образом
PHP:
function is_valid($params)
{
// вычисляем сколько всего параметров
$items = sizeof($params);
// проходим в цикле по списку параметров
for ($i = 0; $i < $items; $i++) {
// если действительное и требуемое не совпадают сказать НЕТ
if ($params[$i][CHECK] != $params[$i][NEED]) return FALSE;
}
// если цикл успешно завершился можем сказать ДА
return TRUE;
}
имея всего две такие функции (эта + из предыдущего сообщения, ее кстати можно обозвать как set_valid) можно делать все что угодно дописывая по необходимости пользовательские функции которые возвращают логические значения, потому что нам со скриптом по большей части по барабану какой там у клиента IP адрес, важнее то забанен он или нет, к примеру...
P.S.
далее в программе: идентификация и авторизация...
__________________
FAQ OFF
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
29-07-2002 03:13 |
|
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
Итак, идентификация. По русски - "мы узнали кто к нам обратился".
Есть три традиционных подхода:
- что из себя представляет объект;
- чем объект владеет;
- что объект знает.
Самый простой способ идентифицировать - по IP адресу(что из себя представляет). Наиболе часто применяется в возможности бана по определенному IP. Как же определить забанен IP или нет?
Первое что приходит на ум, хранить забаненые айпишники в одномерном массиве, а при обращении проверять есть ли в массиве забаненых адресов адрес клиента. Ð_то достаточно просто сделать с помощью функции in_array() Передается массив(банлист) и искомое значение, если оно есть в массиве, функция вернет TRUE. Ð_тот метод работает отлично до определенной критической точки. Его можно использовать если у вас мало обращений и народ не очень буйный. А что делать если завтра война? =) флуд, DoS атаки и им подобные вещи?
Для этого случая есть немного другой подход: проверять по номерам сетей вплоть до адреса хоста. Для того, что бы это сделать требуется четырехмерный массив древовидной структуры типа такого:
PHP:
$banlist[32][40][37][23];
$banlist[32][40][37][28];
$banlist[19][78][23][45];
$banlist[16][64][29][67];
...это наш банлист
IP адрес клиента тоже надо поместить в такую структуру, только повернутую на 90 градусов..
PHP:
// к примеру - первая запись банлиста
$ip[0] = 32;
$ip[1] = 40;
$ip[2] = 37;
$ip[3] = 23;
теперь сердце проверки - функция которой все это передается:
PHP:
function is_banned($ip,$banlist)
{
if (!empty($banlist[$ip[0]])) // n.*.*.*
{
if (!empty($banlist[$ip[0]][$ip[1]])) // n.n.*.*
{
if (!empty($banlist[$ip[0]][$ip[1]][$ip[2]])) // n.n.n.*
{
if (!empty($banlist[$ip[0]][$ip[1]][$ip[2]][$ip[3]])) // n.n.n.n
{
return TRUE;
}
}
}
}
return FALSE;
}
Чтобы целиком забанить сеть надо просто прописать ее адрес, а передавая клиентский ИП обнулить соответсвующие значения...
А что же с in_array? С ним все очень грустно когда банлист разрастается до определенных пределов, тем более "1.1.1.1" это строка, а просто "1" число. Второе требует намного меньше ресурсов. Как известно возможное(но нереальное) количество IP`ов в версии IP V4 = ((253*253)*253)*253 =))) туева хуча короче говоря, а ресурсов у нас мало-мало... Я решил объективно посмотреть на вопрос и провести бенчмарки. Требовалось создать банлист который бы содержал в себе все возможные IP адреса =)
Для пользовательской функции подготовительные действия выглядели таким образом:
PHP:
$ip_1 = array();
$ip_2 = array();
$ip_3 = array();
$ip_4 = array();
for($i=1; $i<=254; $i++) $ip_1[$i] = $i;
for($i=1; $i<=254; $i++) $ip_2[$i] = $ip_1;
for($i=1; $i<=254; $i++) $ip_3[$i] = $ip_2;
for($i=1; $i<=254; $i++) $ip_4[$i] = $ip_3;
// теперь массив $ip_4 содержит все варианты IP адресов
$banned[0] = array_rand($ip_1);
$banned[1] = array_rand($ip_1);
$banned[2] = array_rand($ip_1);
$banned[3] = array_rand($ip_1);
// а чейчас у нас есть случайно сгенерированный IP
// котрый ессесно забанен =)
все готово, можно начать...(по математике у меня одни тройки, так что сильно не пинайте...)
(FreeBSD 4.5/Apache 1.3.26/PHP 4.2.1[скомпилирован как модуль], AMD Athlon Thunderburd 1,2 GHz/RAM 512 DDR)
PHP:
//--------------------
$s = gettimeofday();
//--------------------
for($i=1; $i<=100000; $i++) is_banned($ip,$banlist);
//--------------------
$e = gettimeofday();
//--------------------
$a = $s['sec'].'.'.$s['usec'];
$b = $e['sec'].'.'.$e['usec'];
$a = (double) $a;
$b = (double) $b;
$f = $b - $a;
echo 'Время поиска: '.number_format($f,8).' секунд<br>';
echo 'Количество забаненых IP адресов: '. ((253*253)*253)*253;
У меня в среднем 100000 циклов выполнялись за 1,4 секунды...
Теперь тестируем вариант с is_array(). Так как довольно затруднительно создать массив строк такой величины решено было поступить проще:
PHP:
$all_ip = ((253*253)*253)*253;
// создаем массив из диапазона чисел...
$ipls = range(1,$all_ip);
// соответственно как будто IP...
$banned = array_rand($ipls);
в принципе на этом все тестирование способа с is_array() и закончилось, PHP мне просто сказал:
Fatal error: Allowed memory size of 4194304 bytes exhausted (tried to allocate 262144 bytes) in /usr/home/..бла..бла..бла../bench.php on line 15
Вот такие дела =)))
P.S.
У кого есть какие мнения?
__________________
FAQ OFF
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
29-07-2002 23:25 |
|
|
STFW
|
| Benjamin - не пугайся, есть в тыщу раз круче,... |
[сооб. #18058]
31-07-2002 16:51 |
|
|
|
Формат времени GMT. Текущее время 03:04.
|
Правила форума:
Вы не можете создавать новые темы.
Вы не можете отвечать на существующие темы.
Вы не можете прикреплять файлы.
Вы не можете редактировать свои сообщения. |
HTML теги выкл.
Спец. код вкл.
Смайлики вкл.
[IMG] тег выкл.
|
|
|
|
| |
Page generated in 1.80335402 seconds (99.70% PHP - 0.30% MySQL) with 26 queries.
|
 |