Categories
Лично творчество Статии

Singleton, static и други подобни PHP щуротии

Какво точно е Singleton и какво са статичните данни? На този въпрос се опитват да си отговорят колегите от BGDev. Тук ще се опитам да хвърля малко светлина по въпроса.

Първо що е то статична данна?

Статични данни са такива, които са “живи” през целият период на изпълнение на приложението. Най-добре ще ме разберете с пример.

function static_test() {

static $a = null;

if( $a == null ) {
$a = 1;
echo ‘Първо извикване на функцията’;
} else {
echo ‘Всяко следващо’;
}
}

static_test();
static_test();

Ха сега, познайте какво ще се покаже при първото и после и при второто извикване?

След като очевидно схванахте как се използват статични данни нека да спомена, че за да може да имате достъп до статични данни в клас ( PHP, Java, а предполагам и други езици ) трябва да дефинирате метода си като статичен. Готиното на статичните методи, е че можете да ги извиквате без да се нуждаете от  създаване на обект. Пак пример?

class StaticTest {

private static $test = “test”;

public function getTestNonStatic() {
echo $this->test;
}

public static function getTest() {
echo self::$test . ‘<br />’;
}
}

$StaticTest = new StaticTest();
$StaticTest->getTestNonStatic();

StaticTest::getTest();

Въпросният код дава следният изход:

Notice: Undefined property: StaticTest::$test in …
test

T.e. имате достъп до статични данни само от статични методи.

Сега малко за Singleton. Няма да обеснявам какво е Singleton, а направо ще ви покажа пример за Database клас, който използва такъв шаблон.

class Database {

private static $instance = null;

public static function getInstance() {
if( !self::$instance instanceof self ) {
self::$instance = new self;
}
return self::$instance;
}

private function __construct() {
global $host, $user, $pass, $dbname;

$this->connect( $host, $user, $pass, $dbname );
}

private function connect( $host, $user, $pass, $dbname ) {

$this->host = $host;
$this->user = $user;

echo ‘Host: ‘ . $host . ‘<br />’;
echo ‘User:’ . $user . ‘<br />’;
echo ‘Pass:’ . $pass . ‘<br />’;
echo ‘Name:’ . $dbname . ‘<br /><br />’;
}

public function query( $sql ) {

echo ‘Host: ‘ . $this->host . ‘<br />’;
echo $sql . ‘<br /><br />’;
}
}

$host = $user = $pass = $dbname = “Testing”;

$DBI = Database::getInstance();
$DBI->query( “SELECT .. “);

$DBI2 = Database::getInstance();
$DBI2->query( “INSERT INTO ..” );

Тук ще се наложат малко пояснения явно. ОК. Singleton шаблона е перфектен за извикване на инстанция на клас за връзка с база от данни. Защо? Защото хем е глобален т.е. можем от всяко кътче на PHP кода да си го да извикаме, хем прави само един път връзка към базата … а не 100, ако създавахме обект всеки път. Когато създаваме $DBI обекта, чрез статичният метод getInstance() всъщност се прави проверка дали вече е създаден въпросният обект. Ако не .. тогава правим нов, ако е – връщаме инстанция към него и го използваме. Катко забелязвате ( всъщност може да забележите тук 🙂 ) Данните за host, user, pass и т.н.т. се показват само един път от connect метода т.е. тук симулирам достъп до базата де .. но виждате резултатът. Та това е “сложният” Singleton шаблон.

Ако имате въпроси използвайте формата за коментари по надолу 🙂