Řízené vkládání zdrojových kódů
Čím větší projekt, tím je implementace složitější. Je potřeba komunikovat s databázovým serverem, FTP, IMAP, zpracovávat XML a jiné vstupy. V tomto článku se budu zabývat otázkou, jak správně a přehledně řídit zařazování kódu v rozsáhlém PHP skriptu. Využiji přitom metodu objektového programování, kdy vývojář píše jednotlivé komponenty a udržuje si pořádek stylem „co objekt, to samostatný soubor“.
Máme-li určen cíl, pojďme si hned ukázat techniku, jak řídit řazení PHP kódu v programu. Já osobně v PHP programuji objektově. Každý objekt píši do vlastního souboru, udržuji ho pak v určeném adresáři. Uvažujme o hlavním skriptu index.php. Chci-li vytvořit objekt A (instanci třídy A), musí interpret PHP znát jeho definici třídy. Pak bych mohl psát:
<?php
$A = new class_a();
?>
Definici třídy class_a() uloženou v souboru class_a.php, musím načíst jedním z příkazů:
<?php
include ‚class_a.php‘;
require ‚class_a.php‘;
include_once ‚class_a.php‘;
require_once ‚class_a.php‘;
?>
Rozdíl mezi těmito příklady je dostatečně popsán v manuálu PHP. Nyní se pojďme podívat, jak by vypadal kód programu, pokud bychom používali více objektů:
<?php
// index.php
require_once ‚class_a.php‘;
require_once ‚class_b.php‘;
$a = new class_a();
$b = new class_b();
?>
<?php
// class_a.php
require_once ‚class_c.php‘;
class a {
…
}
?>
V tomto jednoduchém příkladu potřebujeme pracovat s objekty A a B. Objekt A ještě pro svou práci využívá objekt C. Říkáme tedy, že funkčnost objektu A je závislá na objektu C. Tento příklad je přehledný, v adresáři existují vedle souboru index.php i class_a.php, class_b.php a class_c.php. Soubor index.php může být v tomto případě výchozím dokumentem webu, ovšem proč v tomto adresáři vedle něj existují class_a.php, class_b.php a další? Tyto soubory by měly patřit mimo část _public_ našeho webu. Přesuňme je tedy mimo tuto oblast a podívejme se na kód příkladu nyní:
<?php
// index.php
require_once ‚../../../htprivate/code/class_a.php‘;
require_once ‚../../../htprivate/code/class_b.php‘;
$a = new class_a();
$b = new class_b();
?>
<?php
// class_a.php
require_once ‚../../../htprivate/code/class_c.php‘;
class a {
…
}
?>
Jak dlouho by nám asi trvalo vyznat se po týdnu v tomto kódu a jak dlouho by to mohlo trvat u rozsáhlého skriptu? Vyvíjíme přece webovou aplikaci, každou chvíli se něco mění a ačkoli máme připravenu analýzu, musíme občas přepisovat kód, který jsme napsali již před dvěma měsíci… Pak se v takových odkazech na soubory těžko orientujeme a odvádíme pozornost jinam. U většího projektu určitě stojí za to situaci řešit. Princip mého řešení je blízký pointrům z C. Nebudu při každé potřebě určitého kódu psát:
<?php
include ‚cesta/jmenosouboru.php‘
?>
Raději se vždy odkáži na funkci, která to zařídí:
<?php
// index.php
require_once ‚../../../htprivate/project/code/setup.php‘;
load_a();
load_b();
$a = new class_a();
$b = new class_b();
?>
<?php
// class_a.php
load_c();
class a {
…
}
?>
Nevolám už require_once() (na začátku skriptu ručně načtu jen setup.php), ale volám „načti třídu A!“, „načti třídu B!“. V programu potřebuji načíst deklaraci tříd a je mi na tomto místě přece jedno, odkud (z jakého souboru) se třída A (respektive třída B) načte. Obě funkce využívají objekt CODE MANAGERA:
<?php
class code_manager {
var $DIRECTORY_ROOT = “;
function code_manager($root = NULL) {
if (isset($root)):
$this->set_dirroot($root);
endif;
}
function set_dirroot($root) {
$this->DIRECTORY_ROOT = $root;
}
function prequire($path, $relative = NULL) {
if (empty($relative)):
require $this->DIRECTORY_ROOT.$path;
else:
require $path;
endif;
}
function prequire_once($path, $relative = NULL) {
if (empty($relative)):
require_once $this->DIRECTORY_ROOT.$path;
else:
require_once $path;
endif;
}
function test() {
echo ‚<pre>‘;
print_r(get_required_files());
echo ‚</pre>‘;
}
}
?>
Metodou test() si potom můžeme ověřit, jaké soubory byly načteny a odladit chyby.
<?php
// setup.php
$code_mng_str = ‚/Program Files/Apache Group/Apache/htprivate/general/‘;
$mycode_mng_str = ‚/Program Files/Apache Group/Apache/htprivate/project/‘;
require_once ($code_mng_str.’code/class.codemanagement.php‘);
$code_manager = new code_manager($code_mng_str);
$mycode_manager = new code_manager($mycode_mng_str);
$mycode_manager->prequire_once(‚code/general.php‘);
load_template();
?>
Právě na tomto jediném místě se určí cesty do adresářů, kde udržujeme kód PHP programů, knihovny funkcí, deklarace tříd. Objekty CODE MANAGERA lze inicializovat i relativně položenou cestou. Musíme přitom pamatovat, že vždy relativně k veřejně uloženému programu. V souboru, který jsem pojmenoval setup.php rovnou includuji soubor general.php a nástroj pro práci se šablonami. Pokud vím, že tento nástroj používám ve všech programech, nebudu se bát načíst kód již zde:
<?php
// general.php
function load_a() {
global $mycode_manager;
load_c();
$mycode_manager->prequire_once(‚code/class_a.php‘);
}
function load_b() {
global $code_manager;
$code_manager->prequire_once(‚code/class_b.php‘);
}
function load_c() {
global $code_manager;
$code_manager->prequire_once(‚code/class_c.php‘);
}
function load_template() {
global $code_manager;
$code_manager->prequire_once(‚code/class.template.php‘);
}
?>
Nyní si to zopakujme. V index.php nejprve načítám setup.php. Zde je uložena absolutní cesta k adresáři general ($code_manager) a project ($mycode_manager). Pro oba adresáře vytvářím instanci objektu CODE MANAGERA. Do adresáře general ukládám všeobecně často užívané deklarace tříd, do adresáře project ukládám takové deklarace, které souvisí jen s daným projektem (může to být například chat, weblog, ankety atd.).
Práci a orientaci dále ulehčí funkce jako load_a(), load_b(), load_c() či load_template(). V případech, kdy jeden objekt využívá druhý a tento je dále závislý na nějakém dalším, se tímto dosáhne elegantního kódu.
Vložení kódu je možné několika způsoby (include, include_once, require, require_once) – v tomto případě se volil require_once(). Analogicky si můžeme definovat metody pinclude() i pinclude_once().
Jelikož se vložení (require_once) kódu provádí v objektu code_manager (přesněji metodou prequire_once), plyne z toho jedno omezení. Nemůžeme totiž například v souboru class_a pracovat s globální proměnnou (objektem, polem apod.) při absenci odkazu na $GLOBALS[]. Z mého pohledu z toho plyne cesta k důslednějšímu OOP. Podívejte se například na soubor db_connect.php (tento kód při načtení CODE MANAGEREM absolutně ztratí smysl):
<?php
$server_name = „localhost“;
$db_user = „root“;
$db_pass = „sa“;
$db_name = „jmeno_databaze“;
?>
A nyní tentýž soubor db_connect.php (nyní při použití CODE MANAGERA.. poté pracujeme s objektem $db_connect_info):
<?php
class db_connect_info {
var $server_name = „localhost“;
var $db_user = „“;
var $db_pass = „“;
var $db_name = „sipky_vyvoj“;
}
global $db_connect_info;
$db_connect_info = new db_connect_info();
?>
Tak to je řízení vkládání kódu v PHP podle mého. Zdá se vám tato technika naprosto zbytečná či složitá? Nebo používáte zaběhnutou techniku z příruček pro začátečníky, případně máte svou vlastní? Podělte se o své zkušenosti v diskusi.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
Umělá inteligence v IT
27. září 2023 -
Souboj na trhu s CPU pro servery: AMD vs. Intel
8. prosince 2023
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024