Море приколов и флешек на CD Море разнообразных приколов! :: KOLBAS2003.NAROD.RU

Главная Статьи Книги Опрос Чат Гостевая книга Форум Ссылки

 Основы PHP

Вы вышли за рамки статических www-страниц? Вам требуется обрабатывать html-формы? Вы хотите сделать интефейс с базой данных через веб? Электронный магазин? Счетчик с подробной статистикой или опрос посетителей вашего сайта (см. «Мир Internet», #11'99)? Есть множество программ, работающих через интерфейс CGI, как правило, написанных на языке Perl, но сегодня существуют и другие возможности.

Почему PHP?

Perl - очень хороший, мощный язык, но слишком высоки системные издержки во время вызова программы на каждый запрос страницы, особенно в Windows. Существуют ли альтернативы? В последние годы быстро набирает популярность язык программирования веб-приложений PHP (Personal Home Page, www.php.net). В 1994 году Расмус Лердорф (Rasmus Lerdorf) начал разработку встроенного в HTML языка программирования, исполняющегося на стороне сервера. Со временем к проекту присоединились и другие разработчики, и сейчас PHP - это бурно развивающееся средство программирования, работающее на очень многих серверах в Интернете. Как средство разработки www-приложений PHP сейчас лидирует - вместе с ASP, FrontPage и mod_perl.

Достаточно полно описать язык программирования и сопутствующие инструментальные библиотеки в одной статье невозможно, однако можно постараться: не описывая синтаксис или библиотечные функции, полезно остановиться на особенностях создания скриптов на PHP. А с подробной документацией по PHP можно ознакомиться на сайте www.php.net/manual.

PHP можно установить в двух вариантах: как отдельный интерпретатор, работающий через интерфейс CGI, или как модуль веб-сервера, встроенный в сам сервер. В последнем случае становятся актуальными все преимущества PHP.

Из аналогичных встроенных в сервер программных средств хорошо известны SSI, mod_perl, ASP. Но SSI обладает довольно ограниченными возможностями, а mod_perl, на мой взгляд, слишком много умеет. Ближайшим аналогом PHP является ASP, но технология ASP не прижилась в мире Unix/Apache, где простой, удобный и быстрый язык PHP постепенно завоевывает первые ряды.

Сейчас распространена версия 3 интерпретатора PHP, версия 4 пока еще находится в стадии бета-тестирования. Принципиальных отличий четвертой версии от третьей нет, есть только несколько изменений синтаксиса (описанных на сайте www.php.net/version4/incompatibilities.php), которые большинство пользователей не заметит: подавляющее большинство скриптов будут работать в обеих версиях языка.

Как и все процедурные языки, PHP можно разделить на собственно язык и библиотеку функций. Существует большое количество инструментальных средств для PHP, интерфейсы ко всем популярным СУБД, почтовым протоколам, к разделяемой памяти, графическим файлам, архивам и множество других инструментов.

Основы языка PHP

Скрипт на PHP представляет собой файл, как правило, с суффиксом .phtml, .php3 или .php, который внутри выглядит как обычная страница на HTML. Отличие проявляется только в виде хитрого тега <?php ?>, делающего из HTML настоящий язык программирования. Часто применяют сокращенную форму <? ?>или, для совместимости с визуальными средствами формирования страниц, <% %> . Будем разумно придерживаться традиции и пользоваться тегом <? ?>. Внутри этого тега располагается код на языке PHP. Вот тривиальный пример страницы:

<? include('header.html' ?>

Это текст страницы


<? include('footer.html') ?>

Посетителю такой страницы будет показан документ с картинками, меню и текстом, красиво упакованным в хитро вложенную таблицу. Отдельные файлы header.html и footer.html будут просто включены в тот документ, что отдается сервером посетителю страницы. Таким образом можно отделить оформление страницы от ее наполнения, сильно облегчая работу по внесению информации на сайт даже неквалифицированным работникам.

Текст скрипта выполняется сверху вниз и справа налево, последовательно. Эта последовательность может быть изменена операторами цикла и условными операторами. Например:

Тебя зовут
<? if ($name=='Вася') : ?>
Вася
<? else : ?>
капитан Немо
<? endif ?>

Здесь мы получим текст «Тебя зовут Вася» или «Тебя зовут капитан Немо» в зависимости от значения переменной $name.

В примере видно, что мы прервали текст тегами PHP. В языке есть несколько функций вывода - echo, printf и др., но приведенный в примере код работает намного быстрее, чем, например, if ($name=='Вася') echo 'Вася'.

Перевод строки, идущий после закрытия тега ?>, интерпретатор пропускает. Сделано это для удобства форматирования исходных текстов скриптов.

Переменные в PHP отличаются наличием символа $ (доллар) перед именем самой переменной. Объявлять их никак не надо, так как они создаются автоматически при присвоении им значения и удаляются при выходе из области действия. Переменные бывают типа строка, число, массив и объект. Некоторые трудности может вызвать нестрогое отличие строк от чисел. Поясню на примере:

<?
$a=5; // Число
$b='6b'; // Строка
$c=$b.$a; // Строка: '6b5'
$d="$a$b"; // Строка: '56b'
$e=$a+$b; // Число: 11
$f=$b+$a; // Число: 11
?>

Интерпретатор очень вольно приводит типы строка и число друг к другу. Хотя чаще всего это даже удобно. Просто надо об этом помнить и не пытаться сравнивать строку с числом:

<?
$a=5;
$b='ой!';
if ($a>$b) echo "1";
if ($b>$a) echo "2";
?>

В первом случае сравниваются числа 5 и 0 и результат, естественно, положительный. А во втором случае что сравнивается? Документация на этот счет молчит, а эксперимент показывает, что сравниваться будут тоже числа. Согласен, что это не строго и не очень красиво, и в условных операторах я рекомендую использовать операторы приведения типа, как в языке Cи:

<? if ((int)$a < (int)$b) : ?>

или

<? if ((string)$a < (string)$b) : ?>

Синтаксис языка PHP вообще очень похож на синтаксис Си, если бы не символы $ в начале имени переменных и некоторые вольности с типами и массивами. Как в «Поднятой целине» председатель колхоза английский учил: «... Английские слова такие же, как русские, только в конце шипение какое-то, революшн, например...»

Для изменения типа переменной, в принципе, особенного ничего делать не надо, достаточно просто присвоить ей значение нового типа:

<?
$a=5; // Целое число
$a='5'; // Строка
$a=5.5; // Вещественное число
$a[0]=5; // Массив
$a['пять']=5; // Хэш-массив
?>

Последняя строка, например, показывает нам очень популярный и удобный тип данных - хэш-массив (hash array). В принципе, это обычный массив, только индексом у него выступает строка, а не целое число, и никакого приведения типов, о котором я говорил ранее, здесь нет. PHP позволяет создавать многомерные сооружения вида массив хэш-массивов, как, например, $name[5]['ой'][6]= 'не может быть';

В принципе, массив - это тоже хэш, только в нем индексами являются строки, соответствующие числам. Почему так хитро? Это еще ничего, а вот, например, фраза $name[5]=0; создает массив $name из 6 элементов (индексы считаются от 0, как в Си), но только 1 элемент реально существует, остальные просто не определены. На практике это не сильно мешает, помните только, что это не Cи и не Паскаль.

Конечно, не очень хорошо, но частенько удобно пользоваться конструкциями

<? if ($test!='') : ?>

вместо правильной

<? if (isset($test) && $test!='') : ?>

просто потому, что первая запись короче. В первом случае, если переменная $test будет не определена, то ее значение будет как бы пустой строкой. Логично считать, что «никакая» строка - это тоже пустая. Подобная фраза может вызвать предупреждение о синтаксической ошибке, если администратор включил параноидальный контроль синтаксиса, но это бывает редко. Если вам не лень, то пользуйтесь правильными конструкциями и проверяйте наличие переменной перед обращением к ней. А если лень, то считайте неопределенную переменную пустой строкой, нулем, логической ложью и т. п.

Как-то специально объявлять массив или хэш тоже не надо. Но в некоторых случаях это бывает полезно, например, если ваша функция возвращает массив, то она должна вернуть именно массив, а не неопределенное значение. Это, кстати, относится и к функциям:

<?
function initArray($num) {
  if ($num>0) return $a[$num]=$num;
  return $a;
}
?>

Эта надуманная функция возвращает массив, если $num больше нуля, и непределенное значение - в противном случае, что затрудняет работу с результатом ее выполнения:

<?
$foo=initArray(0);
...
$bar=$foo[0]; // Ошибка, $foo не массив.
...
?>

Здесь вам поможет функция array(), возвращающая массив, в том числе и пустой. Либо стоит сразу инициализировать переменную $a=array() или вернуть пустой массив как return array(). Первый вариант предпочтительнее.

В PHP есть даже некоторая объектность, то есть вы можете создавать классы, методы и т. д. Как правило, классы хороши в больших приложениях или как средство ограничения области видимости переменных. Я бы не рекомендовал очень уж активно ими пользоваться: помните, что объектный подход нынче очень моден, но не стоит из него делать фетиш. Реализация классов в PHP версии 4 обещает быть намного эффективнее, чем в третьей. Поживем - увидим.

Примеры программирования на PHP

Как и для скриптов на языке Perl, в Интернете есть множество сайтов, содержащих десятки готовых PHP-программ. Такие ресурсы делятся на два вида: наборы функций или классы, - что отражает идеологический подход авторов к программированию.

Программа на языке PHP, как правило, не живет сама по себе, а применяется для обработки запросов через интерфейс CGI. Даже если интерпретатор PHP встроен в сервер как модуль, с точки зрения самой пользовательской программы, она, эта программа, работает через CGI. А для чего творцам чудесных веб-сайтов нужен CGI? Конечно же, для обработки форм. Именно на скрипт указывет параметр action-тега

.

 

В PHP автору не требуется каким-то особым образом извлекать данные формы. В момент начала выполнения скрипта для вас уже существуют и определены переменные, соответствующие одноименным полям. Если форма имеет вид





то при старте скрипта doit.phtml в нем уже определены переменные $f1, $f2 и $do. Можно указать имя поля в форме как

тогда на момент выполнения скрипта, обрабатывающего эту форму, будет определен массив $sel, содержащий выбранные пункты списка select.

По умолчанию и чаще всего форма передается HTTP-методом POST. А статические страницы посетитель обычно получает методом GET. В последнем случае вы тоже можете передавать «параметры» выполняющемуся скрипту через так называемую строку запроса (query string), то есть через URL. Выглядит такой URL как-то так: www.domain.ru/script.phtml?a=5&b=no&c=%2f.

Собственно параметры начинаются после знака «?» и состоят из пар «имя=значение», разделенных знаком «&». Как и в случае с полями формы, программа script.phtml получит переменные $a, $b и $c с соответственным содержимым «5», «no» и «/». Обратите внимание на значение переменной $c. Вообще-то лучше не полениться и, зайдя на сайт www.w3c.org, вдумчиво прочитать документацию о протоколе HTTP/1.0. Это очень поможет вам в профессиональном росте.

Кстати, вам ведь ничто не мешает комбинировать оба эти метода. То есть вы можете создавать формы и указывать обработчику параметры через URL:


...

Передавать данные скрипту можно не только посредством параметров в URL или в полях формы. Практически все современные броузеры понимают cookies. В PHP вы можете пользоваться ими совершенно свободно. Когда броузер отдает cookie вашему скрипту, вы просто получаете переменную с именем cookie и значением, соответствующим значению cookie. Отдать же cookie броузеру вы можете функцией

setcookie('имя','значение' [,необязательные параметры])

Помните, что эта функция должна выполняться до любого вывода текста страницы.

PHP позволяет с помощью cookies хранить в броузере клиента множество информации. Для этого реализован механизм cookies-массива. Например, после однократного выполнения такого фрагмента кода:

<?
$myData['id']=1234;
$myData['name']='Вася';
$myData['email']='qq@xxx.ru';
setcookie('myData[]',$myData);
?>

все ваши скрипты будут иметь в начале выполнения хэш-массив $myData с точно тем же содержимым. Помните, что количество информации в cookies ограничено, так что старайтесь ими не злоупотреблять. Да, и не храните в cookies текст на русском языке или двоичную информацию, лучше предварительно закодируйте ее с помощью функции rawurlencode().

Если же вам очень хочется завести о пользователе целую уйму персональных данных, а использовать для этого cookies неудобно, то вам стоит выбрать одну из схем «ведения пользователя» (user tracking). Их существует множество - это и модули к www-серверу, и отдельные библиотеки к PHP, и множество готовых функций или классов, написанных на самом PHP. Вы легко можете сделать и свою систему ведения. Вот вам простенький примерчик. Включив этот файл в начало любого скрипта, вы можете вести пользователей, сохраняя информацию о пользователе в течение года:

<?
function userTrack() {
 global $mySesID; // Кука.
 $db=dbmopen('/путь/userTrack.db','c');
  //Откроемхэш-базу
 if (! (isset($mySesID) && dbmfetch($mySesID)) ) {
  // Если куки не было или ее нет в базе, то внесем новую
  $mySesID=uniqid(); // новый уникальный ключ
  dbminsert($mySesID,userTrackNew());
   // добавляем его и данные по умолчанию
  setcookie('mySesID',$mySesID,time()+60*60*24*365);
   // устанавливаем куку на год
 }
 dbmclose($db);
 $tmp=split(«\t»,dbmfetch($mySesID));
 $user=array(); // Пустой массив лучше создать
 for ($i=0; $i

Этот файл можно включать в самом начале, не задумываясь о его содержимом, так как значения по умолчанию можно задавать своей функцией:

<?
include('usertrack.inc');
function userTrackNew() {
 return "id=5\tname=Вася\tcolor=white";
}
$userInfo=userTrack(); // получить данные о пользователе
?>

В результате мы получим хэш-массив со всеми заданными нами настройками посетителя. Базы данных dbm* работают очень быстро и не требуют больших ресурсов, и пользоваться ими можно и нужно. Мы могли бы использовать для хранения данных СУБД, но пока не будем. В данном случае применение SQL СУБД оправдано, если большая часть ваших страниц также формируется из базы данных. Сейчас стало очень модно применять SQL-серверы где угодно, там где надо и где не надо (чаще всего, где не надо). Даже www-чаты на SQL-базах делают. При небольших объемах данных стоит подумать о простых средствах: текстовых файлах, хэш-базах (dbm*) и т. п. Прочитать файл в 100 К в память и порыться в ней будет намного быстрее, чем даже 1 запрос к SQL-базе. О пользовании СУБД я расскажу несколько позже.

Работа с файлами в PHP

А пока немного о файлах. Внешний по отношению к скрипту файл можно включить в скрипт функцией include(). Но всегда хочется большего. Например, вы гениальный дизайнер, вы нарисовали шикарный сайт некой фирме, но вам очень не хочется обновлять каждую неделю их прайс-лист. Вы можете за обновление брать деньги, но много денег за это брать стыдно (я надеюсь), а повозиться придется. Как быть? А как готовят прайс-лист в той фирме? Скорее всего, у них есть некая таблица в неком табличном редакторе типа 1-2-3 или Excel. Вот его бы и положить на сайт... Но файл этот хитрого формата, да и размера немалого.

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

<?
 $fp=fopen('файл.tsv','r'); // Откроем этот файл из-под Excel
 if ($fp) :
?>
<?
 for ($i=0; !feof($fp); $i++) : // пока не конец файла
  // читаем строку, отрезаем пробелы в конце и разбиваем ее на поля.
  list($a,$b,$c)=split("\t",chop(fgets($fp,1000)));
?>
»>
<? echo $a ?>
<? echo $b ?>
<? echo $c ?>
<? endfor ?>
<? fclose($fp); endif ?>

PHP имеет достаточное количество встроенных функций для работы с файлами, но частенько хочется этот набор несколько расширить. Например как сделать www-чат? В теории все просто, все посетители пишут в один файл и читают последние N строк этого файла. Конечно, хотелось бы читать этот файл не последовательно с начала. Я предлагаю вашему вниманию функцию tail(), которая работает очень быстро не зависимо от размеров читаемого файла.

<?
if (!$tail_inc) : // Чтобы не включать файл дважды
$tail_inc=1;
function tail($file,$num) {
 // читаем $num последних строк файла $file
 global $tail_start_buf; // предполагаемая длина строки
 if ($tail_start_buf==0) $tail_start_buf=80;
 $appxlen=$tail_start_buf;// примерная длина строки для расчета
 $flen=filesize($file); // длина файла
 $out=array(); // то, что вернется
 $fp=@fopen($file,'r');
 if ($fp) {
 do {
  // вычисляем, откуда читать файл
  if ($num*$appxlen>$flen) $pos=0;
  else $pos=$flen-($num*$appxlen);
  $out=_readfile($fp,$pos,$num); // читаем строчки до конца файла
   // на следующий цикл длиной строки считаем удвоенную среднюю
      прочитанную
  $appxlen=($flen-$pos+1)*$num*2/count($out); // *!*
 } while (count($out)!=$num && $pos!=0);
 fclose($fp);
 }
 return $out;
}
// вспомогательная функция
// читает файл $fp с позиции $pos и максимум $num строк
function _readfile($fp,$pos,$num) {
 fseek($fp,$pos); // позиционируем файл
 $tmp=array(); // временный массив
 while (!feof($fp)) { // читаем файл до конца
  $line=chop(fgetsl($fp)); // *!!*
 $tmp[]=$line;
 }
 $j=count($tmp)-$num; // кол-во лишних строк
 if ($pos!=0 && $j==0) { // если ровно сколько надо строк,
  $j++; // пропустить первую неполную
 }
 if ($j<0) { // если не хватает строк,
  $j=0; // выводить все
  $xnum=$num-1;
 } else $xnum=$num;
  // переписать в выводной массив нужные строки.
  for ($i=0; $i<$xnum && $j

Я не буду утверждать, что это лучший на свете алгоритм, и принимаю все предложения по его улучшению. Есть два замечания сразу.

*!* Здесь вычисляется средняя длина строки для следующего цикла. У меня это отлично работало и при $appxlen*=2, но так, наверно, быстрее будет. *!!* Здесь я применил функцию fgetsl(), но это особый разговор.

Функция чтения строки из файла имеет ограничение на длину считываемой строки. А думать о длинах строк при написании гениальных скриптов не хочется. Как быть? Я предлагаю небольшую функцию, аналогичную fgets(), но без неприятного ограничения:

<?
function fgetsl($fp) {
while (!feof($fp) && strchr($out,"\n")) $out.=fgets($fp,1000);
return $out;
}
?>

Авторизация посетителя сайта на PHP

Если вы решили продавать содержимое сайта или просто ограничить доступ к некоторой его части по паролю, то имеется возможность контролировать этот процесс с помощью PHP. Вопрос авторизации решается в PHP элегантно и просто. Я один раз оформил нужный фрагмент кода как включаемый файл и использую его уже больше года. Здесь я приведу код в несколько сокращенной общей форме:

<?
 if (!$auth_inc) :
 $auth_inc=1;
 // Параметры:
 // $realm область действия авторизации.
 // $sorry имя файла, что будет показан при отказе от авторизации
 // $tmp* необязательные параметры для функции проверки пароля
 function authCheck($realm,$sorry=",$tmp1=",$tmp2=") {
  global $PHP_AUTH_USER;
  global $PHP_AUTH_PW;
  if(!isset($PHP_AUTH_USER)) {
   Header("WWW-Authenticate: Basic realm=\"$realm\"");
   Header("HTTP/1.0 401 Unauthorized");
   if ($sorry == ") echo "Вам отказано в доступе!";
   else {
    include($sorry);
   }
   exit;
  } else {
  if (@authFunction($PHP_AUTH_USER,$PHP_AUTH_PW,$tmp1,$tmp2)) {
   $ok=1;
  } else {
   Header("WWW-Authenticate: Basic realm=\"$realm\"");
   Header("HTTP/1.0 401 Unauthorized");
   if ($sorry == ") echo "Вам отказано в доступе!";
   else {
    include($sorry);
   }
   exit;
  }
 }
 }
 endif;
?>

Функцию authFunction() пишет сам пользователь, она получает аргументами, соответственно, логин и пароль, введенные посетителем, и два необязательных параметра по наследству от authCheck(). Автор скрипта должен просто включить файл auth.inc в свою программу, написать функцию authFunction(), которая, например, будет проверять пользователя по базе данных, и вызвать функцию authCheck() перед каким-либо выводом текста страницы, как было замечено про функцию setcookie(). Написание разных authFunction() позволяет контролировать доступ посетителей из множества различных источников, таких как файлы паролей, СУБД, хэш-файлы, запросы к сетевым сервисам авторизации, и из любых на ваше усмотрение.

Такой тип авторизации самый, так сказать, железный. При посещении закрытой страницы посетителю выдается диалоговое всплывающее окно с полями имени и пароля. В дальнейшем броузер запоминает $realm и при последующем запросе пароля будет автоматически отправлять серверу пару имя/пароль. Однако это не единственный способ авторизации. Пример писать не буду, а просто потеоретизирую немного. Описанная выше система ведения пользователя вполне подойдет с небольшими модификациями. Для регистрации создадим форму с полями login и password. Обработчик формы генерирует случайный уникальный ключ и записывает с ним дату/время регистрации в хэш-файл. Вместо даты и времени годится значение функции time(), возвращающей количество секунд с 01.01.1970. Броузеру клиента выдается cookie, например, xfile со значением только что сгенерированного ключа. Каждая страница, требующая авторизации, должна проверить наличие ключа $xfile в хэш-файле и, если он есть, записать туда время обращения, не затрагивая времени регистрации.

Для отказа от авторизации достаточно удалить ключ из базы. Внешняя программа может раз в полчаса, допустим, удалять ключи, выданные 3 часа назад, и ключи, к которым не было обращения в течение 1 часа. Стойкость такой системы определяется трудностью подбора ключа-cookie за ограниченное время, так как ключи живут относительно недолго и они достаточно длинные. Ключ можно передавать не только через cookie, но и через URL как параметр скрипта.

Конечно, гениальный автор сайта сам должен решить, какой алгоритм авторизации он себе выберет, так как у обоих вариантов есть свои плюсы и минусы. Возможно, есть еще какие-либо варианты. Пишите, обсудим.

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

Работа с базами данных на PHP

А какой же электронный магазин без базы данных? В принципе, можно и без нее, но насколько СУБД облегчает разработку подобных проектов. PHP поддерживает множество СУБД от xBase до дорогих коммерческих SQL-серверов. Особого внимания заслуживают такие базы, как MySQL (www.tcx.se) и PostgreSQL (www.postgresql.org) - по причине их популярности, хороших характеристик и бесплатности. Легкодоступность СУБД и интерфейса к ней побуждает юные умы применять базу данных направо и налево, не особенно задумываясь о необходимости применения и об алгоритмах работы с базой.

Самая распространенная ошибка авторов скриптов - это отношение к СУБД как к чему-то сверхоперативному. А это вовсе не так. Вот пример, как не надо писать скрипты:

<?
1 pg_pconnect("host=localhost dbname=test");
2 $s1=pg_exec("select a from b");
3 for ($i=0; $i 4 $a=pg_result($s1,$i,0);
5 $s2=pg_exec("select c,x,y,z from d where e=$a");
6 for ($j=0; $j 7 $c=pg_result($s2,$j,0);
8 $x=pg_result($s2,$j,1);
9 $y=pg_result($s2,$j,2);
10 $z=pg_result($s2,$j,3);
11 echo "$c $x $y $z
\n";
}
}
?>

1 - надо трижды подумать, прежде чем иcпользовать постоянное соединение с базой. Здесь выбран хост localhost, но работа с локальным сервером через unix socket может быть быстрее.

2 - надо проверить, выполнился ли запрос без ошибок.

3 - нехорошо вызывать функцию в цикле, лучше завести дополнительную переменную $num=pg_numrows($s1).

5 - самая грубая ошибка: запрос в цикле по другому запросу, от такого программирования не спасут ни множество процессоров, ни обилие памяти, ни быстрая дисковая система. Почему бы не решить проблему в один запрос?

$s1=pg_exec("select a,c,x,y,z from b,d where e=a order by a");

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

7-10 - можно не вытаскивать поля по одному, а применить функцию pg_fetch_array() или pg_fetch_object(), которые возвращают хэш и объект соответственно с именами полей, соответствующими именам полей результата запроса.

PHP позволяет поддерживать постоянные соединения с СУБД. То есть при завершении скрипта соединение с сервером базы данных разорвано не будет, а будет возобновлено при повторном запросе. Такой метод работы очень экономит время соединения, но съедает системные ресурсы (память, дескрипторы и т. д.). Если у вас один пользователь базы, одна база и один сайт, который непрерывно обращается к базе, то вам стоит попробовать поэкспериментировать. В конфигурации PHP можно глобально отменить постоянные соединения, чем и пользуются провайдеры, чтобы защитить свои хосты от жадных пользователей.

Раз уж мы начали говорить об электронной торговле, то можно развеять еще одно заблуждение, - что MySQL для нее годится. Это не совсем так. Он годится для макета, но не для серьезного сайта. В MySQL нет транзакций. Для сложной базы, для денежных расчетов, для оформления заказов и многих других важных операций транзакции необходимы. Так что используйте PostgreSQL, который все это умеет.

Допустим, магазин вы организовали, заработали кучу денег, давайте теперь продолжим ознакомление с программированием на PHP. Вкратце коснусь других возможностей.

Работа с электронной почтой на PHP

Чего вожделеет каждый веб-мастер, создав на странице форму? Да, отправить ее содержимое себе по почте. А сделать это на PHP очень просто - есть функция mail($to,$subj,$body, $header). Но есть и тонкость: почта будет уходить от имени www-сервера (как пользователя). Не забывайте, пожалуйста, про четвертый аргумент $header, в котором вы можете указывать любой параметр заголовка письма (см. RFC-822):

mail('user@isp.ru','test message','Выполучили письмо',
"From: bill@gates.ru\nContent-type: text/plain;
charset=windows-1251");

Указывайте хотя бы From: и Content-type: - это предохранит вас от раздраженных получателей писем или, если получаете вы, от получения писем в непонятной кодировке неизвестно от кого.

Одно время у провайдеров были популярны системы чтения/отправки электронной почты с www-сайта. На PHP вы можете сделать то же самое. Достаточно лишь почитать описание протоколов POP и IMAP и открыть сетевое соединение с почтовым сервером. Функция fsockopen(хост, порт) открывает сетевое соединение, а пользоваться им можно при помощи обычных файловых функций. Только не открывайте соединение к своему www-серверу и не запрашивайте свой же скрипт - веб-мастеру это может сильно не понравиться. В целом работа с сетью в PHP оставляет желать лучшего - надеюсь, многие изъяны будут исправлены в четвертой версии. В первую очередь не хватает функции select() или аналога соответствующему вызову POSIX. Сетевое соединение - это не совсем файл, оно может прерваться, другая программа может не закрыть соединение и завершиться/зависнуть и т. п. Функция select() позволяет сделать работу с сетью более надежной. Подождем.

О корректной работе PHP

Не следует забывать еще про одно сетевое соединение - соединение клиента с веб-сервером, во время которого выполняется скрипт. Представьте себе ситуацию, когда ваш скрипт обрабатывает сложный запрос, что-то читает из базы, пишет в файл, изменяет данные в базе и т. д., а во время этого процесса клиент нажал кнопку «Стоп» и разорвал соединение. Процесс работы вашей программы будет прерван в самый неожиданный момент, и обработка не будет завершена. Но частично-то работа проделана. Необходимо как-то откатить назад внесенные изменения. Для этого в PHP встроен механизм контроля за соединением. Вы можете подготовить функцию аварийной остановки с помощью register_shutdown_function(функция). Заданная функция вызывается интерпретатором PHP при завершении работы скрипта. Сетевое соединение в PHP находится в следующих состояниях:

0 - NORMAL;

1 - ABORTED;

2 - TIMEOUT.

Когда PHP работает нормально, статус соединения будет NORMAL. Когда клиент прерывает соединение, устанавливается флаг ABORT. Если для выполнения скрипта не хватило времени, то будет установлен флаг TIMEOUT.

Вы можете указать интерпретатору, будет или нет ваш скрипт прерван при разрыве соединения. Этот вариант можно выбрать функцией ignore_user_abort(). Другой вариант - это создание функции аварийного завершения, как было описано выше. При ее выполнении вы можете задать проверку причины завершения при помощи функций connection_aborted(), connection_timeout() и connection_status(). Если вы использовали ignore_user_abort(), то функция аварийного завершения может обнаружить два статуса, ABORT, если пользователь прервал соединение, и TIMEOUT если при этом скрипт выполнялся слишком долго.

Как известно, для пользователя самый страшный враг - это сам пользователь. А если таких много на одном сервере? И обязательно найдется некто, который назовет себя «куул хацкером» и начнет либо искать спрятанную информацию, либо просто пакостить. В PHP предприняты попытки ограничить возможности пользовательского скрипта, чтобы предотвратить возможность утечки информации и порчи чужих данных. Провайдеры обычно разрешают пользователям выполнять скрипты в «безопасном режиме». Сильно это ограничение не сковывает, но помнить об этом надо.

* * *

Что ж, осталось найти хостинг с поддержкой PHP, почитать документацию и создать отличный динамичный сетевой ресурс, от которого все ахнут. Я надеюсь, что эта статья поможет вам разобраться в дебрях программирования для www-серверов. PHP хороший язык, попробуйте - вам понравится!

 

 
              
   

Комментарии: Пишите мне Rambler's Top100 Copyright ©
Хостинг от uCoz