Reklama

zonerbooks.cz | zoner.cz | czechia.com | regzone.cz | inshop.cz | inmail.cz | zonerpress.cz | zonerantivirus.com | zonerama.cz

interval.cz

Řízené vkládání zdrojových kódů

07. 03. 2003 | Ondřej Jureček | PHP | Komentáře: 0

Čí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.


Reklama


Další aktuální články na interval.cz

Tematicky související články

Dejte vědět i ostatním o článku

Diskuse (počet komentářů: 0)

Buďte prvním návštěvníkem, který přidá nový komentář.

Přidat nový komentář

Jméno a e-mail jsou nepovinné. Příspěvky obsahující odkaz jsou moderovány.

Zoner AntiVirus Free pro Android
zabezpečte si svůj smartphone, zdarma
Profesionální eshop Zoner inShop od 990 Kč.
Reklama
Reklama

Syndikace

hledáme nové autory | redakce interval.cz | reklama na interval.cz

© ZONER software, a.s., všechna práva vyhrazena, interval.cz dodržuje právní předpisy o ochraně osobních údajů. Powered by WordPress.