Самообучение PHP училище

Кратко ръководство по PHP за начинаещи


Източник: PC World » Последна редакция: LeoS

Пети урок » (5531 посещения)

Условни конструкции
В предния урок създадохме малък сайт, като страниците в него се изграждаха "в движение" и вземаха съдържанието си от няколко различни файла. Тогава зададохме въпроса, какво би се получило, ако по някаква причина на index.php му се зададе да включи файл, който не съществува? Например при опит за извикване на /index.php?page=other, ще получим съобщение за грешка :
Warning: Failed opening 'other.php' for inclusion (include_path='...') in 'index.php' on line ...

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

include ("$p");

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

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

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

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

<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<title>Начални умения в PHP - урок 05</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 "$a е по-малко от $b";
}
?>

Забележете, че при проверката дали числата са равни използвахме два знака "равно" един след друг. Ако бяхме сложили само един, то интерпретаторът щеше да изравни стойностите на двете променливи. И така, ето как се правят проверките в 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 представлява най-простия начин за изграждане на цикъл в PHP. Чисто и просто той следи за това, дали дадено условие отговаря на истината и докато това е така се поддържа изпълнението на определени действия:
» while (условие) действие «
Конструкцията е доста гъвкава и позволява свобода на използването си за различен вид условия. Най-простият вариант е създаване на цикъл, който да се повтаря определен брой пъти :

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

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

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

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

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

Най-популярният начин за създаване на цикли в 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 пъти, като всяко ще бъде на нов ред.