Увод в PHP

Увод в PHP

Увод в PHP

Най-популярният език за създаване на интерактивни и динамични web сайтове е PHP.
Това е не просто твърдение, а реален факт според изследователските фирми. Причините са много - гъвкав, компактен, лесен за изучаване и използване, предлагащ всички възможности за създаване на динамичен, съвременен сайт, задоволяващ и най-големите капризи...
Създаден като личен проект, той бива преработен от група разработчици и бързо намира приложението си в Интернет. За да улесни грижите си за собствения си личен сайт, през 1994 година Размус Лердорф създава скриптов език, наричайки го Personal Home Page Tools. От това наименование по-късно излиза и съкращението PHP.
Нововъведението бързо събужда интереса на множество разработчици и скоро след това първата версия на езикът е вече факт. Съкращението PHP вече се разбира като PHP: Hypertext Preprocessor, но основната идея - простотата на използване, е запазена. PHP и до днес остава силен скриптов език с много възможности за web програмиране. И може би най-лесния за изучаване и прилагане.

Факт е, че PHP позволява да постигнете определен резултат само с няколко реда код, докато ако използвате други програмни езици за целта може да се наложи да изпишете десетки редове. Това е основната причина, поради която езикът получи толкова бърза и голяма популярност сред web разработчиците.Използването на PHP спестява време, а и позволява създаването на интерактивни сайтове дори от начинаещи. Малко по малко почти всички хостващи компнии започват да предлагат поддръжка за езика.

Програмни езици

Езиците, които програмистите използват, за да накарат компютъра да направи това, което искат, се наричат програмни езици. Но едва ли можем да очакваме че машината ще прочете сложните комбинации от букви и цифри, и ще разбере какво очакваме от нея. За компютъра такива редове са безсмислени :

<?

echo "Здравейте";

?>

За да може машината да изпълни желанието ни, което в случая беше да изпише на екрана "Здравейте", тази инструкция трябва да се преведе на нейния език. Това може да стане чрез така наречените интерпретатори, които "смилат" инструкциите в кода и ги подават на компютъра в разбираем за него вид или чрез предварително превеждане на кода в такъв вид - компилация. От тази гледна точка програмните езици се делят на скриптови и компилируеми.
Кодът, написан на скриптов език, се обработва от междинна програма - интерпретатор, в момента на изпълнението си. А кодът, написан на компилируем език трябва да се приведе предварително във вид, разбираем за машината. Затова във втория случай имаме два вида код - изходен (source code) и изпълним (executable).
За пример можем да посочим Java и Java Script, които в съзнанието на повечето хора са почти едно и също. Разбира се, това не е вярно. Въпреки че имат сходен синтаксис, двата езика са доста различни по начина си за използване. Java е компиулируем език. Файловете, съдържащи изходния код на Java, имат разширения .java. Ако ги отворим, в тях ще видим всички инструкции, които програмистът е написал, във вид, разбираем за човека. Но тези файлове не могат да бъдат изпълнени в този си вид. Те трябва да бъдат компилирани - приведени в двоичен вид. Изпълнимите файлове на Java имат разширение .class и ако ги отворим с текстов редадактор ще видим поредица от символи, която няма да означава нищо за нас.
От друга страна Java Script е език, който се интерпретира в момента на изпълнението си. Когато отворите web страница, съдържаща в себе си Java Script код, той се обработва в реално време от интерпретатор, вграден в браузъра, и след това се подава за изпълнение. По - старите браузъри, които нямат вграден такъв интерпретатор, няма да се справят със задачата.
PHP е скриптов език. Когато потърсите с браузъра си PHP страница в Интернет, кодът се обработва в момента, в който сървърът изпълнява заявката ви, от програма, намираща се на него. От тази гледна точка, разликата между двата скриптови езика - Java Script и PHP е в това, че кодът на първия се интерпретира от браузъра ви(web клиента), а на втория - от програма на сървъра. Затова се казва, че JS е клиентски език (client side), а PHP - сървърен (server side).

 

Основата

Голямата популярност на PHP се дължи главно на гъвкавостта му при включване в HTML документи. Възприето е мнението, че концепцията на езика е смесица от Perl, Java и C, но най-голяма е близостта с C. Така PHP предлага лесни възможности за изпълняване на сложни математически изчисления, изпълняване на мрежови функции, възможностти за обработка на електронна поща, работа с обикновени изрази и множество други. Но безспорно най-голямата сила на езика е във взъможностите му за работа с бази данни. Осигурена е поддръжка на най-разпостранените бд, като MySQL, PostgreSQL, Oracle, Sybase, mSQL и други. Връзката с базата данни и работата с нея са облекчени и позволяват лесното създаване на ефективни динамични сайтове.

От начало

След толкова уводни думи вече е крайно време да направим първия си PHP скрипт. Макар и банално, ще накараме компютъра да изпише "Здравей свят!"
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<TITLE>Здравей, свят!</TITLE>
</HEAD>
<BODY>
Първият ми PHP скрипт<br>
<?
echo ("<b>Здравей, свят!</b>");
?>
</BODY>
</HTML>

Когато запишете този файл и го сложите на сървър, поддържащ PHP, след като го извикате в браузъра си ще видите изписано там поздравлението. Разбира се, полза от такъв скрипт няма, но той ще ни помогне да посочим основните положения.
За разлика от cgi файловете, не е необходимо да променяте разрешенията на файла с PHP код. Необходимо е просто да го сложите на сървъра. Няма значение и дали ще използвате бинарен трансфер или ascii, въпреки че е препоръчително да използвате втория метод.
PHP кодът се поставя между <? и ?>. Така сървърът разбира, че трябва да подаде това съдържание на интерпретатора за PHP. Може да се използва и друг вариант - <?PHP ...?>. Изборът е ваш.
Всяка инструкция трябва да завършва с точка и запетая. За да изпишете текст на екрана можете да използвате вградените функции echo или print. В горния пример можехме да постигнем идентичен резултат използвайки инструкцията print ("Здравей, свят!"); Изразите в PHP се ограждат с единични или двойни кавички.
Примерът демонстрира как може да се вгради скриптовия код в HTML. Нека сега направим обратното, имайки предвид, че всичко, което подадем като аргумент на echo ще бъде изведено на екрана.

<?
echo "<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<TITLE>Здравей, свят!</TITLE>
</HEAD>
<BODY>
Първият ми PHP скрипт<br>
<b>Здравей, свят!</b>
</BODY>
</HTML>";
?>

Резултатът от този код ще бъде абсолютно същия. Но може би забелязахте обратната наклонена черта, поставена преди кавичките в реда, където се указва енкодинга на страницата. По този начин указваме на интерпретатора, че трябва да изобрази кавички на екрана, а не че низът завършва. Много грешки в PHP скриптовете се дължат на неправилно боравене с тях.

Кавичките

Както вече стана дума, един израз може да се огради с единични или с двойни кавички. Двата начина на запис

echo ("<b>Здравей, свят!</b>");

и

echo ('<b>Здравей, свят!</b>');

ще доведат до един и същ резултат. Но това важи само за изразите. Разлика между двата записа има, когато използвате променливи, но за това ще стане дума по-късно.
Нека сега включим кавички в самия израз. Примерно за да изпишем "Този скрипт се казва "Здравей, свят!".
Ако използваме единични кавички, за да укажем на интерпретатора, че това изречение е един низ, то проблеми няма.

echo ('<b>Този скрипт се казва "Здравей, свят!"</b>');

В случая интерпретаторът е отчел отварящите единични кавички и очаква затварящите, за да отчете края на низа. Но ако използваме двойни кавички, ще се получи объркване:

echo ("<b>Този скрипт се казва "Здравей, свят!"</b>");

След като запишем и видим скрипта така, ще получим съобщение за грешка - "Parse error".
Причината е, че интерпретаторът очаква да види затварящ двойни кавички, за да отбележи край на низа. Тоест в случая това е "<b>Този скрипт се казва ". Останалият текст, обаче, не може да се впише по никакъв начин в синатаксиса на PHP и интерпретаторът не може да го разбере. Затова и дава грешка при обработването (парсването).
За да решим проблема, трябва да използваме обратно наклонената черта. Така ще укажем, че става дума за символ, който трябва да се изобрази, а не да се интерпретира :

echo ("<b>Този скрипт се казва \"Здравей, свят!\"</b>");

Сега вече всичко ще бъде наред.
Обратно наклонената черта може да ни послужи и за вкарване на нов ред (\n ), на табулация (\t) и така нататък.

Коментари

Поставянето на коментари в кода е полезно, не само когато работите с големи файлове. Понякога, когато се връщате към скрипт, който сте писали преди по-дълго време, може да се окаже, че коментарите са полезни и на самите вас. Друга полезно приложение е, когато имате нужда временно да отстраните известно количество код. Вместо да го изтривате и слeд това възстановявате, можете просто да го коментирате.
В PHP имате възможност да коментирате съдържанието на 1 ред или на цял блок редове.
За да поставите коментар на 1 ред можете да използвате символа # или две наклонени черти (//). А за да коментирате блок от редове, оградете го с /* и */.
Ето и един пример:

<?
/* Този скрипт ще изпише на екрана коя е датата днес.
Затова ще използваме функцията date(), за да я разберем.*/
$today = date("Y-m-d");
//А сега ще изпишем датата.
echo "<CENTER>Днес е: $today.</CENTER>";
//И това е всичко.
?>"

Усложняване на примера

Нека сега добавим няколко неща към скрипта си. Ще приветстваме посетителя на страницата си, ще му кажем датата и часа и ще го "стреснем", като му покажем с какъв браузър е дошъл и от коя страница. Така примерът ще добие повече смисъл.

Примерен резултат от този скрипт виждате на изображението. Използвахме функцията date() за да разберем колко е часът и коя е датата според сървъра, а така наречените "променливи на срадата" за да изясним от къде е дошъл посетителя и с какъв браузър (в случая IE 5.5).
Променливите

Една от най-големите сили на PHP е възможността му да работи с променливи. Няма да се впускаме в теоретични подробности за същността и концепцията им, а ще демонстрираме основните правила при използването им.
Най-общо, променливата се състои от две "части" - име и стойност. Обръщайки се към името на променливата можем да й присвоим нова стойност или да получим достъп до текущата.
Има две основни неща, които трябва да имате предвид, работейки с променливи в PHP. За разлика от повечето програмни езици, тук те не се декларират предварително. Създаването на променливата става в момента, в който и присвоявате стойност. В PHP името на променливата винаги е предшествано от знак за долар - $. Без значение дали и присвоявате стойност или използвайте стойността и по някакъв начин.

<?
$ime="Иван Петров";
echo $ime;
?>

Тези редове код ще изпишат на екрана съдържаниет на променливата $ime, което сме дефинирали по-рано. Ако бяхме пропуснали да й присвоим стойност, на екрана нямаше да се изпише нищо. Проверката за това дали на определена променлива е присвоена стойност е много полезна и често използвана възможност за проверка на това дали определено събитие се е случило или не. Как става това ще демонстрираме по-късно.

Видове променливи

PHP предлага големи облекчения при работат с променливите, което в началото би ви се сторило странно ако сте се занимавали с други програмни езици. Стана вече дума, че не е необходимо да декларирате променивата преди да й присвоите стойност. Друга важна особеност е, че не е необходимо да указвате какъв тип информация се съдържа в нея - дали е низ (string), цяло число (int), число с плаваща запетая (float) и т.н. PHP сам определя типа на променливата в зависимост от съдържанието й. Според някои напреднали програмисти това е по-скоро вредно, но както скоро ще се убедите, освен улеснението, гъвкавостта на PHP в това отношение има и множество други плюсове.
Съществуват няколко вградени функции с чиято помощ можете да разберете какъв тип е дадена променлива. Това са
is_bool() - връща истина ако променливата е булева (истина/лъжа);
is_float() - връща истина ако променливата съдържа число с плаваща запетая;
is_integer() - връща истина ако променливата е цяло число;
is_string() - връща истина ако променливата е низ от символи;
is_array() - връща истина ако променливата е масив;
is_object() - връща истина ако променливата е обект;
Enviroment variables

Съществува един особен вид променливи, наричани "променливи на обкръжението". Най-общо казано, това са променливи, поддържани от сървъра и PHP интерпретатора, описващи текущото състояние на връзката и характеристиките на двете страни в нея - клиент и сървър.
В предната част на този материал използвахме две от тези промливи - $HTTP_USER_AGENT и $HTTP_REFERER, с чиято помощ открихме с какъв браузър посетителят разглежда страницата и от къде е дошъл на нея.
Събирането и анализирането на подобни данни е безкрайно полезно за всеки web разработчик. Така можете да научите кой сайт ви праща най-много посетители и да организирате рекламната си стратегия, наблягайки на него. Полезно е също и да следите кои от страниците в сайта ви се посещават повече и предизвикват по-голям интерес, така че да наблегнете на тях и на подобен вид съдържание в по-нататъчното изграждане на сайта.
Пълен преглед на променливите на средадата може да видите, използвайки вградената в PHP функция - phpinfo(). Напишете в текстов файл следните редове :

<?
phpinfo();
?>

Запишете го на сървъра с име info.php, примерно, и го отворете в браузъра си. Ще видите най-важната информация за PHP инсталацията, както и всички създадени в текущата връзка променливи на средата на PHP и сървъра. Изписаното в левите полета на таблицата представляват имената на променливите, а в дясната част - стойностите им.
Нека сега разширим примера и добавим още малко информация в него.

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<TITLE>Здравей свят!</TITLE>
</HEAD>
<BODY>
<?
$data=date("d-m-Y");
$chas=date("H:i:s");
$browser=$HTTP_USER_AGENT;
$ref=$HTTP_REFERER;
$user_ip=$REMOTE_ADDR;
$forw=$HTTP_X_FORWARDED_FOR;
$serv=$SERVER_SOFTWARE;
$rem_host=gethostbyaddr($user_ip);
echo ("<b>Здравейте,<br><br>Добре дошли в сайта!</b><br>");
echo ("Сега е $chas часа, по моя часовник, на $data, а Вие дойдохте тук от $ref с $browser<br>");
echo ("Вашето IP е $user_ip($forw) - $rem_host. <br><p>Поздрави: <br>$serv");
?>

</BODY>
</HTML>

Нека сега обясним отделните редове в него. Нямаше нужда да използвам променливите $browser, $ref, $user_ip, $forw, $serv и $rem_host, но ги включих за по-голяма прегледност. Всяка от тях получи за стойност стойността на някоя от променливите на средата.
На променливата с име "browser" бе присвоена стойността на $HTTP_USER_AGENT, която винаги съдържа идентификационната информация на браузъра. В случая "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)". Браузърът Opera позволява на потребителите си да променят идентификацията й, така че тя може да се представя като IE или Netscape. Причината е в рестрикциите, които някои сайтове налагат на използващите браузър, различен от Internet Expolorer. Обикновено това също става с помощтта на $HTTP_USER_AGENT. Имайки предвид особеностите на различните браузъри, можете да покажете на посетителя на сайта си страница, оптимизирана за неговата програма, съдейки по съдържанието на тази променлива на средата. В скоби казано, възможността на Opera да се представя по различен начин може да ви изправи пред куриозната информация, че посетителят използва IE под операционна система Linux.
На променливата с име "ref" бе присвоена стойността на $HTTP_REFERER, съдържаща URL на мястото, от което идва посетителят. Вече обяснихме по-подрбоно тази променлива, но трябва да имате предвид, че тя не винаги дава полезна информация. В конкретния случай едва ли мога да очаквам, че Yahoo са поставили на началната си страница линк към моя тестов файл.
Променливата, наименувана "user_ip" получи стойността на променливата на средата $REMOTE_ADDR. Тя винаги съдържа в себе си IP адреса на посетителя. Тук много рядко може да се получи разминаване на стойността с истинската. Защото сървърът използва стойността й за да определи на кого да изпрати поискания файл.
Много често се случва множество потребители да се намират зад едно или повече прокси сървъри. Няма да коментираме сега защо и как се получва това. В случая трябва да имаме предвид, че ако посетителят е зад прокси, то $REMOTE_ADDR ще покаже IP адреса на проксито. За адреса на клиентската машина се създава нова променлива - $HTTP_X_FORWARDED_FOR. Повечето прокси сървъри осигуряват тази информация, особено ако администраторите им не желаят да изкарат живота си по съдебните зали.
Използването на последните две описани променливи на средата е полезно, когато давате достъп до чувствителна информация или по една или друга причина е важно да знаете кой точно е отсреща. Така можете да ограничите достъпа до сайта си на хора, които нарушават добрия тон в него или да подсигурите сигурността му при e-commerce приложения.
Тук използвахме и още една променлива на средата - $SERVER_SOFTWARE, която съдържа в себе си информация за сървърния софтуер - версия на сървъра и операционна система. В горния пример използвахме това, като "подпис" на съобщението.

Видове променливи

PHP предлага големи облекчения при работата с променливите, което в началото би ви се сторило странно ако сте се занимавали с други програмни езици. Стана вече дума, че не е необходимо да декларирате променивата преди да й присвоите стойност. Друга важна особеност е, че не е необходимо да указвате такъв тип информация се съдържа в нея - дали е низ (string), цяло число (int), число с плаваща запетая (float) и т.н. PHP сам определя типа на променливата в зависимост от съдържанието й. Според някои напреднали програмисти това е по-скоро вредно, но както скоро ще се убедите, освен улеснението, гъвкавостта на PHP в това отношение има и множество други плюсове.
Съществуват няколко вградени функции с чиято помощ можете да разберете какъв тип е дадена променлива. Това са
is_bool() - връща истина ако променливата е булева (истина/лъжа);
is_float() - връща истина ако променливата съдържа число с плаваща запетая;
is_integer() - връща истина ако променливата е цяло число;
is_string() - връща истина ако променливата е низ от символи;
is_array() - връща истина ако променливата е масив;
is_object() - връща истина ако променливата е обект;
Изпращане на променлива

Съществуват три начина по които можете да изпратите стойността на променлива към един PHP скрипт. Това са методите POST, GET и чрез cookies. Нека ги илюстрираме чрез прост пример. Ще създадем две страници - първата ще съдържа форма, в която потребителите ще напишат името и възрастта си, а втората ще изпише тези данни на екрана. Ще наречем първия файл index.html, а втория - show.php.
Нека напишем HTML формата, в която посетителите ще попълнят данните си :

<!-- index.html -->
<p>Здравейте! Моля попълнете следната информация : <br>
<form action="show.php" method="post">
Вашето име : <input type="text" name="ime"><br>
Възраст : <input type="text" name="godini"><br>
<input type="submit" value="Изпрати!">
</form></p>

Когато посетителят въведе даните и натисне бутона "Изпрати!", тези данни ще достигнат до файла show.php във вид на променливи. Можете да ги използвате веднага. Тук е мястото да уточним, че за разлика от други езици, PHP не ви кара да проверявате дали информацията е изпратена чрез GET или POST. Не е необходимо и да правите нищо, за да получите достъп до съхраняваната в променливите данни. PHP се грижи за това и сам създава променливите. Затова можем направо да ги използваме, например - да ги изпишем:
<?
//show.php
echo "<p>Здравейте, $ime, вие сте на $godini години! ";
?>

Очевидно това не е най-смисления ред код, който можете да напишете, но по-късно ще разгледаме възможностите, които ни дава информацията за възрастта на посетителя, за да го пренасочим към съответното място в сайта.
Най-често няма значение кой от двата метода - POST или GET използвате, с изключение на случаите когато трябва да изпратите файл или по-дълга информация.
Най-просто казано, GET използва така нареченото URL кодиране, тоест така данните се дописват след името на файла в неговия URL. Ако промените значението на "action" във формата в index.html от POST на GET и изпратите информация, ще видите в адресното поле на браузъра си нещо като show.php?ime=Ivan&godini=25. При изпращане на данните чрез POST, те се предават в тялото на заявката.
Много често информацията се задава на скрипта не чрез HTML форми, а пряко чрез URL. Това е така, защото в съвременните динамични сайтове един PHP файл би могъл да генерира множество web страници в зависимост параметрите, които му се подадат.

URL кодиране

За да постигнете това, трябва да зададете необходимите параметри в адреса, с който викате файла. Данните се поставят след името му, като за разделяне се използва въпросителния знак (?). Той указва края на URL и началото на допълнителните данни, известни още като "query string". Там данните се описват по двойки (име=стойност), като всяка двойка се разделя със знака "&" (амперсанд):

файл.php?име1=стойност1&име2=стойност2&име3=стойност3

При отварянето на файл по този начин, в него можем свободно да боравим с променливите "имеX", които PHP създава и на които присвоява стойностите "стойностX".
Както можете да си представите, в този начин за предаване на информацията се крият и някои опасности. Нека си преставим, че потребителят въведе двете си имена, разделени с интервал. Тогава бихме получили нещо като

show.php?ime=Иван Петров&godini=25.

Очевидно е, че в този случай няма да получим желания резултат, тъй като интервалът след името ще се възприеме като край на URL и всичко последващо ще се игнорира. Неточни резулати биха се получили и при използване на занака амперсанд (&), %, + и някоии други. Затова информацията трябва да се пригоди преди да бъде изпратена чрез така нареченото URL кодиране. В най-общи линии интервалите се заместват със знак плюс (+), а някои от символите с "%xx", където xx са ascii кодовете на съответните символи в шестнадесетичен вид.
Така ако посетителят (в примера - Иван Петров) напише като възраст 26&7 (за 26 години и 7 месеца), то това ще се предаде така :

show.php?ime=Иван+Петров&godini=26%267
(& се представя чрез %26)

Не е необходимо да мислите за тези усложнения, по простата причина че PHP се грижи сам за правилното кодиране и декодиране на данните в адреса. Но понякога ще се налага да използвате функцията urlencode, за да си осигурите правилна обработка.

низ urlencode (низ)

Така можехме да извикаме спокойно show.php без да се притесняваме за интервалите и специалните символи. Например

echo '<a href="show.php?'.urlencode (ime=Иван Петров&godini=25);

Всички двойки от име и стойност се съхраняват в служебната променлива $QUERY_STRING, а ако в конфигурационния файл на PHP е включена опцията track_vars, то данните, изпратени към скрипта могат да се открият и в масивите $HTTP_POST_VARS и $HTTP_GET_VARS, в зависимост от метода, използван за изпращането им. Така че, ако потребителят попълни формата, която включихме в index.html, можем да открием името му в $HTTP_POST_VARS['ime'].

Масиви във формите

PHP предоставя допълнително облекчение, когато трябва да обработвате по-големи и сложни форми. Можете да зададете стойностите в масиви. Например така :

<p>Здравейте! Моля попълнете следната информация : <br>
<form action="show.php" method="get">
Вашето име : <input type="text" name="ime"><br>
Възраст : <input type="text" name="godini"><br>
Интереси : <select multiple name="interesi[]">
<option value="1">Интернет
<option value="2">Музика
<option value="3">Кино
<option value="4">Филателия
</select>
<input type="submit" value="Изпрати!">
</form></p>

Сега всички избрани от посетителя възможности ще се съхраняват като елементи в масива "interesi[]". Как се обработват масивите в PHP ше изясним по-късно.

Cookies

Невъзможно е да си представим добър и полезен сайт, който не използва "бисквитки" напоследък. Въпреки опитите на някои политически организаци да ограничат използването им в Европа, очевидно е, че ако това, стане световната мрежа би загубила поне половината от потенциала си, а защо не и много повече. Факт е, че положителните страни от използването на cookie файловете са много повече от лошите. При това същите щети могат да се нанесат лесно и чрез други технологии. Затова мога да ви посъветвам да използвате "бисквитки" винаги, когато смятате, че ще имате полза от тях, без да се притеснявате от странични аргументи.
Има две много важни неща, които трябва да знаете, преди да започнете да включвате cookie в сайтовете си. Първото е, че достъп до информацията във всеки такъва файл има само собствения ви домейн. Това, което вие запишете на машината на посетителя не може да бъде прочетено от други, съответно и вие не можете да прочетете записаното от други. Но тук идва и едно предупреждение. Бисквитките са прости текстови файлове, които се предават по Интернет и ако не използвате подсигурена връзка са също толкова незащитени от зложелателна намеса, колкото и цялата информация по мрежата. Затова никога не слагайте в тях пароли, адреси, номера на кредитни карти или друга подобна информация, освен ако тя не е по някакъв начин кодирана. Най-добрата тактика е да записвате някакъв идентификатор, по който можете да разпознавате посетителя, а информацията му да държите в някаква собствена база данни.
Още трябва да знаете, че големината на един такъв файл не може да е повече от 4k. Не можете да запишете на твърдия диск повече от 20 "бисквитки" от един домейн. От своя страна браузърът не може да поддържа повече от 300 файла от всички посещавани сайтове общо. Последното е важно, защото би могло да причини изтриване на вашия файл преди указаната в него дата.
Твърди се, че някои потребители забраняват приемането на cookie чрез съответните опции на браузъра си. Казвам твърди се, защото това звучи невероятно и едва ли някога ще срещнете такъв посетител. Технологията е толкова масово разпостранена в Интернет и без нейна помощ огромно количество услуги няма да действат, така че вероятността такива потребители наистина да съществуват е доста малка. Можете да направите малък експеримент и да инструктирате браузъра си да иска потвърждение за всяко cookie, което приема. Най-вероятно няам да издържите още след първите два часа.
Сега няма да се впускаме в история и теория на cookie файловете, а ще демоснтрираме начина, по който можете да ги използвате в своите PHP скриптове. За повече информация можете да прочетете официалната спецификация на Netscape, която се намира на адресhttp://www.netscape.com/newsref/std/cookie_spec.html.
За или против ползването на cookie?

"Бисквитките" са малки текстови файлове, които уеб сайтовете записват на твърдите дискове на посетителите си. За разлика от рапозстранените напоследък предразсъдъци, те не са програми, а просто парчета текст. Много се изговори за потенциалната опасност от тях и за начина, по който те застрашавали правото на неприкосновеност на потребителя и неговата лична информация. Всъщност cookie файловете са необходим елемент в дейността на всеки полезен сайт и свързването им само с рекламни или следящи технологии е едностранчиво.
В тези файлове обикновено сайтовете записват важна за обслужването на посетителя информация. Без тях, например, би било невъзможно да се извърши идентификацията на потребителя за множество уеб базирани услуги. Представете си, че се налага постоянно да въвеждате името и паролата си при всяко отваряне на ново писмо, когато проверявате електронната си поща. Това би било безкрайно отегчително, бавно и неефективно. Затова когато се идентифицирате веднъж, уеб интерфейсът на e-mail услугата ще запише на cookie на твърдия ви диск информация, по която ще ви разпознава от тук нататък.
Важно е да се знае, че браузърът изпраща "бисквитката" само на този адрес от който я е получил. Така че няма начин друг сайт да прочете информация, която не е поставена от него, като по този начин открадне важна лична информация (като парола, например).
Идентификацията съвсем не е единственото приложение на cookie файловете. С тяхна помощ сайтът би могъл да ви позволи да променяте външния му вид или да изберете информацията, която да ви предлага. Използването им е особено важно в областта на онлайн търговията и рекламата. И до сега тази технология остава най-доброто решение за идентификация и персонализация на съдържаниео и услугите в Интернет.

Как да използваме cookie?

Има шест неща, които трябва да укажете при работа с една "бисквитка". Това са нейното име, съдържание, продължителност на живота, домейн, път и подсигуреност.
Името на cookie е този низ, с който по-късно ще се обръщате към нея за да получите стойността й. Продължителността на живота указва колко време желаете "бисквитката" да е валидна. Ако не сте задали време или сте го указали като 0, то файлът ще бъде изтирт от браузъра веднага след неговото затваряне. Такива cookie файлове са валидни само за текущото посечение на потребителя. Може би най-рядко ще се налага да задавате домейн за който да е валиден файла. Така или иначе не може да напишете yahoo.com и да чакате да получите файловтете, записани на твърдия диск на посетителя от портала. Браузърът така или иначе ще ви изпрати само вашите. Полза от тази възможност за настройка на cookie може да имате, ако използвате няколко субдомейна на един и същ домейн. По принцип ако "бисквитката" е зададена от уеб страница, намираща се на адрес http://www.domain.com, то тя ще се изпраща само до другите страници в този домейн, но не и до http://www.domain.com или другите негови поддомейни. как да преодолеем това ограничение ще разберем след малко. Пътят на валидност на cookie файла дава възможност да ограничите или разширите страниците, до които той ще се предава в рамките на текущия домейн. Това е полезно, ако имате няколко различни сайта като поддиректории на домейна. Сега ще обясним това с практически примери.
За разлика от други програмни езици, PHP предлага изключително лесен начин за записване, променяне и изтриване на "бисквитки". Тук това става става само с един ред код, съдържащ функцията setcookie(). Синтаксисът е следният:

число setcookie (низ име [, низ стойност [, число продължителност [, низ път [, низ домейн [, число подсигурена]]]]])

Функцията ще върне 1, ако се е изпълнила успешно и 0 - ако не е успяла.
Запомнете, че "бисквитките" се получават и изпращат в HTPP хедърите - тоест преди каквото и да било същинско съдържание на Уеб страницата. Това е най-често срещаната причина за появата на грешки при работа с тях. Ако искате да изпратите, промените или изтриете cookie това трябва да стане преди да изпратите на браузъра каквото и да било друго. Например :

<?
echo "<html><head>";
setcookie ("user", "ivan");
?>

Този код ще върне грешка, зашото се опитвате да изпратите "бисквитка" след като вече сте пуснали някакво съдържание. HTTP хедърите нямат нищо общо с хедърите на HTML сттраниците, ограниавани между таговете <head> и </head>. Цялото съдържание на уеб страницата влиза в тялото на HTTP пакета.
Когато се опитате да изпълните този код, PHP ще ви съобщи, че хедърите вече са изпратени, като ще ви каже на кой ред в скрипта е завършило изпращането и на кой ред вие се опитвате да пуснете cookie. Това е наистина полезно, но бих искал да обърна внимание на един случай, когато е много трудно да откриете от къде идва грешката.

<?
setcookie ("user", "ivan");
echo "<html><head>";
?>

На пръв поглед проблемът би трябвало да е решен и горния код трябва да се изпълни правилно. Но поради една или друга причина в него има интервал пред отварящата скоба на PHP. Този интервал сам по себе си е изход, така че слага край на заглавните части. Затова бъдете сигурни, че "<?" е винаги в самото начало на файла. Макар и на пръв поглед дребен, този пробелм може да прични няколко часа търсене на причната си, особено ако има някоко включени един в друг файлове, затова е добре да го имате предвид.
Както забелязахте от начина на представяне на синтаксиса на функцията setcookie(), единствения задължителен елемент в нея е името й. Това обаче не означава, че можете да прескачате аргументите както искате. Това е друга често срещана грешка, която води до грешно записани "бисквитки" или до невъзможността да се изтрие вече съществуваща. Ако желаете да използвате опцията път на действие, но не желаете да указвате продължителност, нямате право да напишете

setcookie ("user", "ivan", "/mojat_sajt");

Функцията си търси елементите по реда, който те бяха показани по-горе и когато ползвате някой от тях, другите в ляво от него стават задължителни. Така че верният вариант на горния ред е:

setcookie ("user", "ivan", 0, "/mojat_sajt");

Можете да "прескочите" елеметите, които не искате да задавате с 0 - когато трябва да са числа или с "" - когато трябва да са низове. Ето как ще изглежда една "бисквитка", която искаме да използваме по подигурена връзка (HTTPS), но всички останали аргументи са по подразбиране:

setcookie ("user", "ivan", 0, "", "", 1);

Така записахме "бисквитка" с име "user", стойност "ivan", валидна за всички страници в текущата поддиректория на текущия домейн при използването на подсигурена връзка.
Изтриването на cookie става, като на съществуващ файл се зададе празно съдържание. Но това трябва да стане по същия начин, по който е бил създаден. Така за да изтирем току що създаденото cookie, трябва да напишем:

setcookie ("user", "", 0, "", "", 1);

Нека сега илюстрираме всичко това с пример. Ще създадем малка система за проследяване на посетителя на адрес http://www.domain.com/site
В началния файл, примерно index.php, включваме форма, в която очакваме да получим името/прякора на потребителя:

<form action=user.php method=post>
<input type="text" name="username">
<input type="submit" value="изпрати">
</form>

Когато потребителят въведе името си и кликне бутона за изпращане, той ше попадне на файла user.php, в който е записано:

<?
setcookie ("user", $username);
?>
По този начин всички страници, намиращи се на http://www.domain.com/site ще имат достъп до съдържанието на cookie файла user - тоест до името, посочено от посетителя. Важно е да запомните, че това не може да стане в момента на изпращането. С други думи - user.php няма достъп до "бисквитката" в момента. Тя ще достъпна при следващото зареждане на страница. В конкретния случай това не е проблем, защото ние все пак разполагаме с името на потребителя в променливата, използвана във формата от index.php. Така че можем да напишем :

<?
setcookie ("user", $username);
echo "Здравейте, $username!<br>Кликнете <a href="index.php">тук</a>, за да смените името, което посочихте или <a href="content.php">тук</a> за да продължите!"
?>

За да променим съдържанието на cookie в PHP е необходимо просто да изпратим ново със същото име и същите други атрибути, ако сме посочили такива, но с различно съдържание. Затова ако посетителят иска да смени въведеното от него име, го изпратихме отново в index.php, където ще може да повтори процедурата.
В PHP прочитането на cookie е безкрайно упростено. Тя е винаги достъпна за използване, без да е необходимо да пишете какъвто и да било предварителен код. При зареждането на PHP скрипта се създават автоматично променливи за всички "бисквитки", които сървърът получи. Името на променливата взема името на съответното cookie, а в стойността й ще открием съдържанието му. И ако основното съдържание на сайта се намира във файл content.php, в него можем да запишем :

<?
echo "Потребител: $user";
........
?>

След това, знаейки името, можем да направим проверка в база данни за някакви настройки, записани по-рано от посетителя или да извършим други действия с информацията в $user.
Нека сега добавим още един аргумент за "бисквитката" си, например да укажем, че тя ще е валидна в следващия един час. За целта можем да използваме вградената в PHP функция time(), от която ще вземем текущото време, след което ще прибавим 3 600 секунди:

setcookie ("user", $username, time() + 3600);

При това положение, за да изтрием "бисквитката" можем да напишем:

setcookie ("user", "", time() - 3600);

Нека сега разширим обхвата на дейност, например до Уеб страници, намиращи се в рамките на която и да е директория на www.mydomain.com/ Тъй като cookie файла бе записан от директория "site" в рамките на домейна, при досегашния начин на боравене с нея тя ще е достъпна само до PHP скриптовете в тази поддиректория. Но може да се наложи да го ползваме например в http://www.domain.com/more. За целта трябва да укажем, че съответното cookie е валидно за всички поддиректории на главната директория на домейна, която се обозначава с наклонена черта - "/". Тогава записът би изглеждал така:

setcookie ("user", $username, time() + 3600, "/");

По този начин във всеки PHP скрипт, намиращ се в която и да е поддиректория на http://www.domain.com ще можем да прочетем стойността на променливата $user, която ще ни дава въведеното потребителско име. Но какво ще стане ако посетителят отиде на http://domain.com/site/content.php? За момента бисквитката ни е валидна само за www субдомейна, но не и за останалите. За да решим проблема трябва да използваме атрибута domain и да я изпратим така:

setcookie ("user", $username, time() + 3600, "/", ".domain.com");

Обърнете внимание на точката преди името на домейна. По този начин указваме, че желаем да получаваме "user" в който и да е негов субдомейн. За да изтрием това cookie трябва да напишем :

setcookie ("user", "", time() - 3600, "/", ".domain.com");

Това са основните неща, които трябва да знаете, за да използвате "бисквитки" в сайтовете си.

-php-

Включване на файлове

PHP предоставя няколко лесни възможности да изграждате интерактивни уеб страници в зависимост от нуждите ви. Една от тях е включването на множество файлове един в друг. Освен че по този начин можете да поднасяте на посетителите си динамично съдържание, включването на файлове позволява и многократното използване на един и същи код. По този начин можете да държите конторла върху интерфейса, основните настройки или функции на доста големи сайтове.

include

Един от начините за включване на файл в текущия е чрез функцията include(). Тя приема като параметър пътят (абсолютен или относителен) до файла, който искаме да включим. Ако той не съществува, ще получим съобщение за грешка.
Можете да разглеждате включеният чрез include() файл като код, който се намира на реда, в който се намира функцията. Той всъщност се "вгражда" в тялото на декущия документ. Така всички променливи, които са дефинирани до появата на функцията ще са достъпни и за кода на включени файл. По принцип няма ограничение какъв тип ще е той - дали ще е текстов, php или някакъв друг. Различните типове файлове имат свои особености, които трябва да имате предвид.
Така например, ако във включения файл има PHP код, който очаквате да бъде изпълнен, трябва да го заградите с . Ако извикате PHP файл от отдалечен сървър, трябва да сте сигурен, че скриптът може да бъде изпълнен там. В такава ситуация имате възможност и да предадете променливите, които ще ви трябват чрез URL, което е неприложемо за локалните включвани файлове. Ще илюстрираме казаното с прост пример. Създаваме два файла - index.php и content.php :

 

<? // Това е index.php

$name="Иван";

$ip=$REMOTE_ADDR;

include ("content.php");

?>

<? // Това е content.php

echo "Здравейте, $name!<br>Вашият IP адрес е $ip";
?>

Както забелязвате, в index.php зададохме стойности на две променливи, които след това изписахме. Двата файла трябва да са в една и съща директория, тъй като не сме задали друг път, когато извикахме функцията - include ("content.php");

Тук би било добре да припомним набързо, че пътищата до даден файл могат да абсолютни и относителни. Абсолютен е пътят от коренната директория на системата, а относителен - от единия файл до другия. Нека си представим, че index.php се намира в директория "/httpd/www/pcworld/", а content.php в "/home/www/files". В този случай бихме могли да изпишем функцията по следните два начина :

include ("../files/content.php");

или

include ("/home/www/files/content.php");

Ако content.php се намира на друг сървър, можем да го извикаме така :

include ("http://www.server.com/content.php");

В този случай можем да зададем променливите и като част от използваното URL, като index.php би могъл да изглежда :

<? // Това е index.php
include ("content.php?name=Ivan&ip=$REMOTE_ADDR");
?>

require ()

Същите правила важат и за друга вградена функция на PHP - require(). Всъщност, според официалната документация на PHP, това не е функция, а езикова конструкция. Една от последиците от този факт е, че не връща стойност. Т.е. не можете да проверите дали включването на допълнителния файл е било успешно или не.
За да разберем една от другите разлики между require() и include() трябва да обясним как става обработката на PHP кода от страна на интерпретатора. Когато сървърът получи заявка за файл, асоцииран с PHP, той подава целия код, затворен между на PHP интерпретатора (парсера). Тук кодът първо се обработва (парсва) и чак след това изпълнява. Важно е да забележите следната особеност - ако имате грешка на последния ред от кода си, той може да не се изпълни изобщо, нито ред от него, защото може да се появи грешка при обработването - Parse error. Всичко, което трябва да знаете за грешките ще откриете в следващия брой на PC World. Сега само ще направим разликата между двата варианта за включване на файл. Ето два възможни варианта на index.php :
<?
// Това е вариант 1 на index.php
echo "Поздрав : <br>";
$name="Иван";
$ip=$REMOTE_ADDR;
include ("content.php");
echo "Добре дошъл в сайта! <br>";
?>

Или :

<?
// Това е вариант 2 на index.php
echo "Поздрав : <br>";
$name="Иван";
$ip=$REMOTE_ADDR;
require ("content.php");
echo "Добре дошъл в сайта!<br>";
?>

Какво ще се случи при изпълнението на двата варианта на кода, ако content.php всъщност не съществува? В първия случй на екрана ще се изпише "Поздрав : ", а на долния ред ще се появи съобщение за грешка. Въпреки това, изпълнението на кода ще продължи и ще видим изписано и приветствието за добре дошъл.

Във втория случай, обаче, изпълнението на кода спира веднага, след липсващия файл и тук поздравът отсъства.

На пръв поглед разликата е дребна, но всъщностт е много важна, както ще се убедим след малко. Тя се подсилва и от факта, че парсерът взема съдържанието на require-натия файл още по време на предварителната обработка, а на include-натия - едва по време на изпълнението. Тоест, дори и редът в който имаме require() никога да не се изпълни, кодът на файла, който е там се използва при предварителната обработка.
Това е особено важно, когато искаме да правим определени проверки, в резултат на които да решим кой файл да включим. Това ще бъде демонстрирано след малко. Друга особеност на двете функции е начинът по който те се изпълняват в цикъл. Най- общо казано, require() е неподходяща за целта.

Избягване на повторенията

Понякога, при по-сложни включвания на файлове един в друг, може да се получи неколкократно повтаряне на кода на един и същи файл.

Това най- често води до грешки - или в обработката или в логиката на изпълнението. За да се предодвратят подобни нежелани явления може да се използват вариации на двете функции, указващи изрично, че включването трябва да стане еднократно. Конструкциите са include_once() и require_once(). В този случай, ако PHP интерпретаторът попадне на повторна инструкция да включи посочения външен файл, той ще я пренебрегне. По този начин се избягва предефиниране на функции или подмяна на стойностите на различни променливи.

Изпълними файлове

Особено място трябва да отделим на разликата между включване на файл от отдалечен сървър и на файл от локалната машина. Особено когато става дума за изпълними файлове, каквито са PHP, CGI, PL и други. Нека си представим, че искаме да включим в текущата страница perl скрипт за банерна ротация - banner.cgi. И нека този скрипт приема като променлива page адресът, където ще се покаже банера - т.е. текущата страница.
Ако той се намира на друг сървър, можем да направим включването така:

<?
// Включване на банер
include ("http://www.server.php/banner.cgi?page=$PHP_SELF");
echo "<br>Добре дошъл в сайта!<br>"; ?>

Така скриптът ще се изпълни на отдалечения сървър, а в нашия файл ще се включи резултатът от това изпълнение - в случая изображение на банер и линк към съответен сайт.
Но ако се опитаме по този начин да извикаме локален файл, резултатът ще бъде друг.

<?
// Включване на банер
include ("banner.cgi?page=$PHP_SELF");
echo "<br>Добре дошъл в сайта!<br>";
?>

При изпълнението на тези редове на екрана ще се изпише изходния код на CGI скрипта, а не резултатът от неговото изпълнение. За да предодвратите това можете да използвате virtual().

virtual ()

Функцията virtual () е специфична само за Apache и казва на сървъра, че трябва да изпълни съответния файл и да върне резултата от това изпълнение. По този начин можете да изпълнявате различни видове файлове в PHP скриптовете си, но трябва да запомните, че не можете да използвате virtual () за PHP файлове. С други думи, следният код е коректен:

<?
// Включване на банер
$page=$PHP_SELF;
virtual ("banner.cgi");
echo "<br>Добре дошъл в сайта!<br>";
?>

Но ако банерната система е написана на PHP, то използването на virtual () ще върне грешка. При всички случаи трябва да използвате include () или require () за да включите PHP код в PHP файл.

Примерен сайт

За да илюстрираме на практика използването на функците, нека съставим малък сайт, съдържащ основните части на този текст. Сайтът ще се състои от няколко страници с еднакъв външен вид - т.е. еднакви горна и долна част, както и еднакво навигационно меню. Сайтовете, правени по тази схема могат да се управляват лесно и са приятелски към потребителите, защото не им поднасят "изненади" на всяка страница - като променено местоположение на менюто или различна цветова схема.
Страниците в примерния сайт ще се състоят от 4 части - header.html, footer.php, menu.php и съответното съдържание за всяка от тях.

В header.html поставяме кода, който ще се вижда в заглавната част на всички страници.

<img src="http://www.idg.bg/public_html/bg/iconpcw-small.gif" alt="PC World - Bulgaria" align="left" hspace="20">
<h1 style="font:bold 2em sans-serif;color:#3300FF;text-align:center;">
Увод в PHP - 5
</h1> <br>
След това поставяме и навигацията - в menu.php:

<p align="center" style="font:bold 1em sans-serif;color:#000099">
<a href="index.php?p=main">Начало</a><br>
<a href="index.php?p=include">include ()</a><br>
<a href="index.php?p=require">require ()</a><br>
<a href="index.php?p=once">Избягване на повторенията</a><br>
<a href="index.php?p=executables">Изпълними файлове</a><br>
<a href="index.php?p=virtual">virtual ()</a><br>
</p>

Както забелязвате, всички линкове тук водят до един и същи файл, но с различна стойност, зададена за променливата "p" (от page). Разбира се името на променливата няма никакво значене, със същия успех можеше да е "a" или "bBbbb". Вече е време да създаден и завършващата част от интерфейса - във footer.php. В него показваме авторските права, както и датата и часа, в които е била заредена текущата страница :

<p align="center" style="font:bold .7em sans-serif;color:#000000">
Самоучител по PHP - част 5
<br>
Поредица на <a href="http://www.pcworld.bg">PC World - Bulgaria</a><br>
<? echo date ("d.m.Y, H:i:s"); ?>
</p>
Вече е време за съдържанието на отделните страници. Нека вземем за пример съдържанието на частта "Избягване на повторенията":

<h2 style="font:1.5em serif;color:#cc0000;">
Избягване на повторенията
</h2>
<p style="font:.9em sans-serif;color:#000000">
Понякога, при по-сложни включвания на файлове един в друг, може да се получи неколкократно повтаряне на кода на един и същи файл.
</p>
<p style="font:.9em sans-serif;color:#000000">
Това най- често води до грешки - или в обработката или в логиката на изпълнението..................
</p>
Записваме този код във файл с име once.php. Остава да съберем парчетата от пъзела в обща картина. Нека съставим примерен index.php, в който да подредим цялостната картина:

<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<title>Увод в PHP - 5</title>
</head>
<body>
<?php
require("header.html");
?>
<table width="95%" cellspacing="15" cellpadding="5" border="0">
<tr><td valign="top" width="120">
<?php
require("menu.php")
?>
</td><td valign="top">
<?php
include("$p.php");
?>
</td></tr></table>
<?php
require("footer.php");
?>
</body>
</html>
Сега вече всичко си е на мястото. Когато повикаме index.php със съответната стойност на променливата "p", ще видим съдържанието на съответния файл "$p.php". Какво ще се случи обаче, ако посетителят излезе любопитен и промени своеволно стойността на "p", така че сайтът да се опита да включи несъществуващ файл. В конкретния пример ще се появи грозно съобщение за грешка. Как да избегнем това, а и как да се справим с някои проблеми на сигурността, произтичащи от този начин на "събиране" на сайтове, ще обясним в следващия брой. Тогава ще стане дума за условните конструкции и грешките в PHP.

Условни конструкции

В предния брой създадохме малък сайт, като страниците в него се изграждаха "в движение", като вземаха съдържанието си от няколко различни файла. Името на файла със съдържанието се предаваше като част от URL, например http://www.server.com/index.php?p=once.
Това означаваше, че index.php трябва да включи в себе си съдържанието на файла once.php. Тогава зададохме въпроса, какво би се получило, ако по някаква причина на index.php му се зададе да включи файл, който не съществува? Например при опит за извикване на /index.php?p=onced, ще получим съобщение за грешка :
Warning: Failed opening 'onced.php' for inclusion (include_path='.; \apache\includes;\apache\htdocs\;') in C:\apache\htdocs\pcworld\index.php on line 17

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

Тук трябва да посочим и друга възможна уязвимост на този начин за съставяне на сайтове. Не използвате в кода си ред като:

include ("$p");

Тук се очаква да бъде включен файлът, чието име се съдържа в променливата $p, например once.php. Ситуацията представлява огромен риск за сигурността на сайта и сървъра, защото дава възможност за извеждане на който и да е файл, за който съръвърът има право на четене. Поразиите, които могат да се направят са големи, така че е необходимо да вземете мерки, за да ги предодвратите.
Можете да направите поне две неща - да определеите точен път до файловете, които да се включват и да определите точния им тип (например .txt, .html, .inc и други). Този вариант на същия ред е доста по-сигурен :

include ("/httpd/www/site/files/$p.html");

В примера се предполага, че файловете, които ще включвате се намират в директория files в Уеб директорията на сайта - /httpd/www/site/. Този път до нея е примерен, тук трябва да проверите как изглежда той в системата, която използвате.
Ползвайте абсолютни, а не относителни пътища, защото относителните са лесно манипулируеми. Те биха могли да бъдат преодоляни чрез повикване като :

http://www.server.com/index.php?p=../file.html

If - else

Изобобщо доста често при създаването на динамични файлове ще се налага да правите проверка дали е изпълнено едно или друго условие. Най-често използваната за целта конструкция е if - else. Ще я демонстрираме с пример, като включим към нашия index.php проверка дали търсеният файл наистина съществува. За да направим това ще използваме и функцията, проверяваща за наличието на файл в локалната система file_exists ()

<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<title>Увод в PHP - 5</title>
</head>
<body>
<?php
require("header.html");
?>
<table width="95%" cellspacing="15" cellpadding="5" border="0">
<tr><td valign="top" width="120">
<?php
require("menu.php")
?>
</td><td valign="top">
<?php
if (file_exists ("$p.php")) {
include("$p.php");
}
else {
echo "<center><b>Не съществува такава глава от самоучителя!</b><br><br>Моля изберете от менюто вляво!</center>";
}
?>
</td></tr></table>
<?php
require("footer.php");
?>
</body>
</html>
За да изчистим нещата, ето как изглежда синтаксиса на конструкцията:

if (условие) {
действие
}
else {
друго действие
}

Възможно е да се добавят множество алтернативни проверки с помощтта на elseif :

if (условие) {
действие
}
elseif {
второ действие
}
else {
друго действие
}

Преди да покажем друг пример, трябва да обърнем внимание на операторите за сравнение в PHP - равно, различно, по-голямо, по-малко, логическо и, логическо или и други. Следният пример сравнява две подадени числа :

<?
//Това е test.php
if ($a > $b) {
echo "$a е по-голямо от $b";
}
elseif ($a == $b) {
echo "Двете числа са равни";
} else {
echo "$b е по-голямо от $a";
}
?>

Забележете, че при проверката дали числата са равни използвахме два знака "равно" един след друг. Ако бяхме сложили само един, то интерпретаторът щеше да изравни стойностите на двете променливи. И така, ето как се правят проверките в PHP:

== - проверява за равенство;
!= - проверява за неравенство;
> - проверява дали първият параметър е по-голям от втория;
< - проверява дали първият параметър е по-малък от втория;
>= - проверява дали първият параметър е по-голям или равен от втория;
<= - проверява дали първият параметър е по-малък или равен от втория;
&& - логически "и" - проверява дали всички условия отговарят на истината;
|| - логически "или" - проверява дали поне едно от условията отговаря на истината;

Много грешки можете да допуснете в началото поради объркване на операторите за сравнение, особено в ситуацията с равно. Нека видим два примера:

if ($a == $b) {
echo "Двете неща са равни";
//още действия тук
}

и

if ($a = $b) {
echo "Двете неща са равни";
//още действия тук
}

Ако извикаме тези две конструкции със стойности за променливите, например 2 и 5, в първия случай няма да видим изписано твърдението за равенство, защото проверката ще бъде направена според очакванията и тъй като двете числа не са равни, действието няма да бъде изпълнено.
Във втория случай, обаче, на екрана ще се изпише твърдението за равенство, както и ще се изпълнят всички действия, които сме задали. Това е така, защото един знак за равенство се възприема от PHP интерпретатора като инструкция за изравняване на стойността на единия параметър със стойността на другия, а не като оператор за сравнение. Важно е да забележите, че проверките, които се правят в PHP касаят не само числа и низове. В случая конструкцията ще върне положителен резултат от проверката, защото извършването на операцията изравняване е извършена успешно.
Можете да проверявате стойността на булеви променливи или настъпването на някакво събитие, по същите начини, по който можете да разберете дали една променлива съществува или не. Примери:

if ($a) {
echo "Променливата \$a има стойност - $a"
}
else {
echo "Няма променлива $a";
}

Тази конструкция проверява дали съществува променлива $a и изписва стойността й. Но можехме да напишем също :

if (!$a) {
echo "Няма променлива $a";
}
else {
echo "Променливата \$a има стойност - $a"
}

Както забелязвате, възможностите за проверки са доста гъвкави. Всяка вградена функция на PHP връща стойност (най-често 1), ако бъде изпълнена, и не връща нищо (или 0) ако бъде. В примера за index.php направихме проверка за съществуването на файла, който искаме да включим. Но по една или друга причина е възможно файлът да съществува, но да не може да бъде включен. Затова можем да използваме друг вариант на проверка :

if (!include("$p.php")) {
echo "<center><b>Не съществува такава глава от самоучителя!</b><br><br>Моля изберете от менюто вляво!</center>";
}

Забележете, че извикването на функция в конструкцията води до нейното изпълнение. Така ако функцията include се изпълни, то условието няма да бъде вярно и предупредителния текст няма да се изпише. Но ако по някаква причина не се изпълни, то тогава условието ще е вярно и текстът ще се появи на екрана. Тук трябва да припомним особеността на конструкцията require (), която, както стана дума в предишната част, не връща стойност при изпълнението си.
Съществуват няколко вариации на изписване на тази контролна структура, но е за препоръчване да следвате основния синтаксис и да не смесвате стиловете. Ако действието, което трябва да се изпълни при удовлетворено условие на проверката е едно, то можем да запишем

if ($name) echo "Моля, въведете потребителско име!";

С подобна конструкция можете например да проверите дали потребителят е попълнил името си в поле във форма. Съществуват и други варианти за алтернативно записване, но те се използват много рядко и сега няма да се спираме на тях.

while

While представлява най-простия начин за изграждане на цикъл в PHP. Чисто и просто той следи за това дали дадено условие отговаря на истината и докато това е така се поддържа изпълнението на определени действия:

while (условие) действие

Конструкцията е доста гъвкава и позволява свобода на използването си за различен вид условия. Най-простият вариант е създаваане на цикъл, който да се повтаря определен брой пъти :

$i=1;
while ($i <= 100) {
echo "Това е ред ".$i."<br>";
$i++;
}

В този пример дадохме на променливата $i начална стойност 1, което е по-малко от 100, следователно води до изпълнение на действията, указани в конструкцията. При всяко изпълнение на цикъла се проверява истинността на условието и когато то спре да е истина, спира и изпълнението на цикъла.
Ето този код в действие

Най-често while конструкциите се използват в по-сложни ситуации, като например обхождане на масиви :

while (list ($key, $val) = each ($masiv) ) echo $key - $val;

С масиви ще се занимаваме по-късно и тогава ще обясним подробно какво прави горния ред. Сега е важно да запомните, че проверката за истинността на условието се прави в началото на всяка итерация от цикъла. Така че е възможно той да не се изпълни нито веднъж, ако условието е невярно още при първата проверка.
Съществува конструкция, при която проверката се прави в края на итерациите. Тоест действията в цикъла задължително ще се изпълнят поне веднъж. Това е конструкцията do..while :

$i = 1;
do {
echo $i;
} while ($i < 100);

for

Най-популярният начин за създаване на цикли в PHP остава конструкцията for :

for (действие1, условие, действие2) {
действия
}

Първото действие се осъществява само веднъж, в самото начало на цикъла, а второто - при всяка негова итерация. Условието се оценява при всяка итерация, а цикълът продължава докато то е вярно. На пръв поглед изглежда сложно, но сега ще демонстрираме практическото приложение с пример:

for ($i = 1; $i <= 100; $i++) {
echo "Това е ред ".$i."<br>";
}

В първото действие присвояваме на променливата $i стойност 1. Това става само веднъж, преди същинското начало на цикъла. След това проверяваме дали стойността на $i е по-малка от 100. Ако това е вярно изпълняваме и второто действие - добавяме едно към стойността на $i. (Записът $i++ е съкратен вариант на $i=$i+1.) След това изпълняваме и действията, поставени в блока, заграден в големите скоби.
Практическия резулат от изпълнението на горните редове код ще е същия като от изпълнението на примерните while конструкции - изписване на изречението 100 пъти, като всяко ще бъде на нов ред.

Управление на цикъла

PHP предоставя допълнителни възможности за управление на цикъла, чрез break и continue. Те могат да се използват във for, foreach while, do..while или switch (ще я разгледаме след малко) конструкциите и дават по-голяма гъвкавост за реакция при определени условия. С тяхна помощ можем да определяме и други условия, влияещи на хода на циклите, които използваме. Вижте този пример :

for ($i = 1; $i <= 100; $i++) {
if ($i==3) continue;
if ($i==$a) break;
echo "Това е ред ".$i."<br>";
}

При изпълнението на този код на екрана ще се изпише изречението не 100 пъти, а толкова, колкото сме указали в променливата $a. Използвайки break можем да прекъснем изпълнението на определен цикъл при възникване на условие, различно от основното. В случая основното условие е стойността на променливата $i да е по-малка от сто. Но тук добавихме по-голяма гъвкавост, като посочихме допълнително условие, което може да прекъсне цикъла.
Друга особеност в горния код е, че в изхода му няма да има ред "Това е ред 3". Използвахме continue за да укажем, че не желаем действията в цикъла да се изпълнят, ако е вярно условието, че стойността на $i е 3. В този случай изпълнението на цикъла продължава нормално, като текущата итерация се прекратява преждевременно.
Практическото изпълнение на кода е тук. Променете стойността на $a за да промените изпълнението на цикъла.

Трябва да имате предвид, че continue и break действат считано от реда на който се намират. Нека погледнем този пример :

for ($i = 1; $i <= 100; $i++) {
//някакво действие тук
if ($i==3) continue;
if ($i==$a) break;
echo "Това е ред ".$i."<br>";
}
В този случай някаквото действие, определено в цикъла ще бъде изпълнено дори ако стойността на $i е три или е равна на стойността на $a.

switch

Това е друг вариант за управление на изпълнението на скрипта, при който имаме по-голяма възможност да разчитаме на една променлива. От стойността на тази променлива зависи кое точно действие ще бъде изпълнено. Най-удобно ще е да илюстрираме синтаксиса на конструкцията с пример :

switch ($i) {
case "edit":
echo "Редактиране на информацията...";
break;
case "view":
print "Преглед на информацията ";
break;
case "delete":
print "Изтриване на информацията ";
break;
}

В зависимост от съдържанието на променливата, парсерът ще изпълни съответните действия.

Съобщаване на грешки в PHP

Едно от големите предимства на PHP пред другите скриптови езици са съобщенията за грешка. Те са доста дружелюбни и ясни, и често казват какво точно трябва да се направи, за да се премахне грешката. Ако вземем за сравнение писането на CGI скриптове, при появата на грешка това което виждате е простото "Error 550 - Internal Server Error". За да се ориентирате къде точно е проблема в сгрешения скрипт, трябва да отоврите лога на сървъра, където ще намерите сравнително по-ясно обяснение за грешката. Но често дори и тази информация е по-обща и неясна от необходимото ви.

При PHP положението е по-различно. Тук често ще срещнете съобщения за грешка, които кзват какво точнотрябва да направите, за да премахнете проблема и на кой ред се намира некоректния код. Можем да разделим грешките в PHP на три категории - синтактични, семантични и логически.

Нека отново напомним как става изпълнението на един PHP скрипт от страна на сървъра. Когато се получи заявка за определен скрипт, сървърът го подава на PHP парсера, който първо го "парсва", иначе казано "смила" и едва след това изпълнява. Важно е да се подчертае, че парсерът обработва целия скрипт преди да започне да го изпълнява. На това ниво на предварителна обработка могат да се появят синтактичните грешки. Ако тук всичко е наред, то следва изпълнението на кода, процес при който биха могли да се появят семантичните грешки. Най-сложни и за откриване, и поправяне са логическите грешки, които не водят до преки съобщения за проблеми, но могат да доведат до некоректно изпълнение на скрипта.

Parse error

Синтактичните грешки се наричат още грешки при обработването (parse error). Нека погледнем следния пример :

<?
$ime=Иван";
echo $ime;
?>

При изпълението на този код ще получим следното съобщение :

Parse error: parse error, unexpected '\"' in /www/idg-web.001/pcworld/php/parse_error_primer.php on line 2

Виждаме, че на втория ред от кода има синтактична грешка. Ако се вгледаме ще открием, че са пропуснати отварящите кавички на низа, задаващ стойност на променливата "ime". Понякога обаче съобщението за грешка може да ни подведе. Нека погледнем друг пример:

<?
if ($name=="Иван")
echo "Здравейте, Иван!";
}
else {
echo "Вие не сте Иван!";
}
?>

При изпълнение на този код ще получим съобщение, че съществува грешка на ред 4. Всъщност, обаче, истинският проблем е скрит във втория ред, където сме пропуснали отварящата голяма скоба.
Още един подобен пример :

<?
if ($name=="Иван") {
echo "Здравейте, Иван!";
}
else {
echo "Вие не сте Иван!";
?>

В този случай ще се сблъскаме с една от най-влудяващите ситуации, когато парсерът отчита грешка на последния ред от кода, където се намира единствено затварящата комбинация от въпросителна и средна скоба. Най-често този феномен се дължи на пропусната затваряща или отваряща скоба. В конкретния случай сме изтървали скобата, затваряща условието else.
Запомнете, че когато се получи съобщение за грешка при парсването, скриптът озобщо няма да се изпълни. По този начин парсерът се защитава от евентуалните усложнения, които биха могли да настъпят при изпълнение на грешно написания код.

Fatal error

Фаталните грешки са една от разновидностите на семантичните. Те се появяват в процеса на изпълнение на скрипта и най-често се причиняват от извикване на несъществуващи и недефинирани функции или файлове.
Нека погледнем следния пример:

<?
require "config.php";
if (!$user) {
not_auth();
}
?>

Тук бихме могли да получим фатална грешка по някоя от следните причини - ако не съществува файлът "config.php" или ако в него не е дефинирана функцията not_auth().
Фаталните грешки се изписват на екрана в момента в който се появят в процеса на изпълнение на скрипта. В този момент изпълнението се прекратява.

Warning

Предупрежденията са друга разновидност на семантичните грешки. Те също се появяват в процеса на изпълнение, но той продължава и след тях. Предизвикват се от грешки, които не са фатални за цялостния ефект, макар че най - често водят до грешно изпълнение на кода. Нека вземем горния пример, но ще сменим функцията за включване на файл от "require" на "include".

<?
include "config.php";
if (!$user) {
header ("location: login.php");
}
...
?>

В този пример проверяваме дали на променливата $user е присвоена някаква стойност или не. Ако не, тогава препращаме потребителя към форма за идентификация, ако да - продължаваме с изпълнението на скрипта. Нека сега приемем, че файлът config.php не съществува. Понеже сме използвали "include", ще получим предупреждение за невъзможността да се включи указания файл, но изпълнението на скрипта ще продължи.
Фаталните грешки и предупрежденията са съобщения, които трябва да възприемате сериозно, ако искате кода, който пишете наистина да изпълнява предназначението си.

Забележки

Забележките са този вид съобщения, с чиято помощ можете да се преборите с логическите грешки в скриптовете си. Под логически грешки се разбират неточности в кода, които де факто не възпрепятстват изпълнението му, но водят до грешни резултати. Те могат да са резултат от грешка на изписването или на недобре съставен алгоритъм. По подразбиране, настройките на PHP за показване на грешки са така направени, че забележките не се изписват на екрана. Това е напълно логично, защото в противен случай не бихме могли да използваме конструкции като тези, показани в горния пример. Ако го изпълните на сървър с PHP, настроено да показва всичкии грешки, ще получите дълго съобщение за грешка, което твърди, че се опитвате да използвате неинициализирана променлива. Както вече стана дума, променливите в PHP не е необходимо да бъдат обявявани преди да се използват. Тяхното инициализиране става автоматично, в момента в който на променливата се присвоява някаква стойност. В случая ние разчитаме на променливата $user за да проверим дали посетителят вече се е идентифицирал или не. Ако обаче показването на забележки е включено, тогава ще видим изписаното на екрана съобщение, че се опитваме да използваме недефинираната променлива в случаите, когато потребителят все още не се е идентифицирал.
Използването на забележки е особено полезно в стадиите на тестване на сайта, когато реузлтатите не са такива, каквито очакваме. Например напълно възможно е да допуснем грешка в името на някоя променлива при писането на кода. Разбира се това ще причини множество проблеми и няма да ни доведе до желания резултат. Използвайки забележките, можем да открем подобни грешки.

 

Евтини почивки в
България, Гърция, Турция, Италия и Хърватия


Bookmark and Share

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *