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

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


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

Четвърти урок » (5440 посещения)

Включване на файлове
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 се намира в директория "/http/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.
Сега да направим разликата между двата варианта за включване на файл. Ето два възможни варианта на 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() е специфична само за 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="public_html/img/icon-small.gif" alt="My Page" align="left" hspace="20">
<h1 style="font:bold 2em sans-serif;color:#3300FF;text-align:center;">
Начални умения в PHP - урок 04
</h1>

След това в menu.php поставяме и навигацията:

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

Вече е време да създадем и завършващата част от интерфейса - footer.php.

<p align="center" style="font:bold .7em sans-serif;color:#000000">
Начални умения в PHP - урок 04<br>
Поредица на <a href="http://www.leofreesoft.com">LeoFreeSoft</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 - урок 04</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("$page.php");
?>
</td></tr></table>
<?php
require("footer.php");
?>
</body>
</html>

Сега вече всичко си е на мястото. Когато повикаме index.php (със съответната стойност на променливата "page"), ще видим съдържанието на съответния файл "$page.php". Какво ще се случи обаче, ако посетителят излезе любопитен и зададе в адреса своеволно стойността на "page" така, че сайтът да се опита да включи несъществуващ файл? В конкретния пример ще се появи грозно съобщение за грешка. Как да избегнем това, а и как да се справим с някои проблеми на сигурността, произтичащи от този начин на "събиране" на сайтове, ще обясним в следващия урок.