Sfatul cu variabilele globale primit de la ceilalți membri este ok, dar poți duce totul un pic mai departe. Ce-ar fi dacă n-ar trebui să ai o variabilă globală $pdo
, $conn
sau cum s-o numi ea, pe care s-o tot pasezi dintr-o parte în alta? Poți realiza asta folosind o singură funcție ce folosește concepte înrudite cu tehnica memoization și pattern-ul singleton.
function db() {
static $connection = NULL;
if (!$connection) {
// inițializezi $dsn, $user, $pass, $opt
$connection = new PDO($dsn, $user, $pass, $opt);
}
return $connection;
}
apoi, în codul tău, oriunde ai nevoie de conexiunea la baza de date, nu mai este necesar să transmiți variabila $pdo
ca parametru:
// Exemplu:
function cotos_setari($setarea) { // a fost eliminat parametrul $pdo
$sql_setari = "SELECT $setarea FROM cotos_setari WHERE id='1'";
$exec_setari = db()->query($sql_setari); // în loc de $pdo, apelezi funcția db()
return $exec_setari->fetch(PDO::FETCH_ASSOC)[$setare];
}
Același procedeu îl poți folosi și pentru configurări sau setări, eliminând astfel orice variabilă globală. Urmând structura lui @PocsanJr, ai putea avea totul structurat cam așa:
[config]
config.php
[functions]
database.php
general.php
[views]
[parts]
footer.html.php
header.html.php
_site-offline.html.php
contact.html.php
home.html.php
_init.php
index.php
contact.php
<?php
// _init.php
define('APP_ROOT', __DIR__);
require_once 'functions/general.php';
require_once 'functions/database.php';
try {
db(config('mysql'));
} catch (PDOException $e) {
echo render('_site-offline');
die();
}
?>
<?php
// config/config.php
return [
'mysql' => [
'hostname' => 'tmp.fail',
'username' => 'root',
'password' => 'root',
'dbname' => 'test',
'charset' => 'utf8',
],
'settingsTable' => 'cotos_setari'
];
?>
<?php
// functions/general.php
function config($key = NULL) {
static $config = [];
if (!$config) {
$config = require_once APP_ROOT . '/config/config.php';
}
if (!$key) {
return $config;
}
if (array_key_exists($key, $config)) {
return $config[$key];
}
return NULL;
}
function settings($key = NULL) {
static $settings = [];
if (!$settings) {
$table = config('settingsTable');
$data = db()->query("SELECT * FROM `{$table}` WHERE `id`=1");
if ($data) {
$settings = $data->fetch(PDO::FETCH_ASSOC);
}
}
if (!$key) {
return $settings;
}
if (array_key_exists($key, $settings)) {
return $settings[$key];
}
return NULL;
}
/**
* Funcție pentru afișarea template-urilor HTML (...sau alte tipuri).
*
* Ex:
* render('page', ['title' => 'My page title']);
* va afișa template-ul `views/page.html.php` în care va fi accesibilă variabila `$title`.
*
* render('latest-news', ['news' => ['news1', 'news2', 'etc']], ['type' => 'xml']);
* va afișa template-ul `views/latest-news.xml.php` în care va fi accesibilă variabila `$news`.
*
* render('sales-report', ['yearly' => [], 'monthly' => []], ['type' => 'csv']);
* va afișa template-ul `views/sales-report.csv.php` în care vor fi accesibile variabilele `$yearly` și `$monthly`.
*
* Pe lângă variabilele trimise ca parametru în `data`, în template-uri mai sunt accesibile funcțiile de ajutor
* `$h($textValue)` - aplică `htmlentities()` la valoarea dată ca parametru
* `$render($viewName)` - afișează un alt `view` în `view`-ul curent, pastrând variabilele
*/
function render($view, $data = [], $params = []) {
$params += [
'type' => 'html'
];
$data += ['page' => $view];
$type = $params['type'];
$path = APP_ROOT . "/views/{$view}.{$type}.php";
$isolate = function($__context__) {
$h = function($str) {
return htmlentities($str, ENT_QUOTES, 'utf-8');
};
$render = function($view) use ($__context__) {
return render($view, $__context__['data'], $__context__['params']);
};
ob_start();
extract($__context__['data']);
include $__context__['path'];
return ob_get_clean();
};
return $isolate(compact('path', 'data', 'params'));
}
?>
<?php
// functions/database.php
function db($config = []) {
static $connection = NULL;
if (!$connection) {
$defaults = [
'hostname' => '127.0.0.1',
'username' => 'root',
'password' => 'root',
'dbname' => '',
'charset' => 'utf8'
];
$config += $defaults;
$dsn = "mysql:host={$config['hostname']};dbname={$config['dbname']};charset={$config['charset']}";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$connection = new PDO($dsn, $config['username'], $config['password'], $opt);
}
return $connection;
}
?>
<?php
// contact.php
require_once __DIR__ . '/_init.php';
echo render('contact', [
'pageTitle' => 'Send me a message!',
'contactOptions' => [
'Twitter' => 'ionut.botizan',
'Github' => 'prafuitu'
]
]);
?>
<!-- views/contact.html.php -->
<?=$render('parts/header')?>
<h1>Contact</h1>
<p>Contact me on:</p>
<ul>
<?php foreach ($contactOptions as $name => $handle) : ?>
<li><strong><?=$h($name)?>:</strong> <?=$h($handle)?></li>
<?php endforeach; ?>
</ul>
<?=$render('parts/footer')?>
Și așa mai departe! Am adăugat o arhivă cu codul complet (și funcțional).
framework.zip (4.0 KB)
Mare atenție la funcția render()
, folosită la afișarea template-urilor!