Klasa dostępu do bazy danych

Jest wiele gotowych rozwiązań dostępu do bazy danych ale czasami jest potrzebna prosta przejrzysta klasa. W której można łatwo się rozeznać a jednocześnie jest bardzo elastyczna. A oto moja propozycja.

Oto ogólna klasa zapewniejąca dostęp do bazy danych.

define("PROGRAM_PATH", str_replace($_SERVER["SCRIPT_NAME"], '', $_SERVER["SCRIPT_FILENAME"]));
define("MODEL_PATH", PROGRAM_PATH."/model");

//ustawienia cache
define("CACHE_DB", true);
define("CACHE_DB_PATH", PROGRAM_PATH."/cache/db");
define("DB_PATH", MODEL_PATH."/db");

//konfiguracja bazy danych
define("DB_HOST", 'localhost');
define("DB_PORT", '3306');
define("DB_LOGIN", 'root');
define("DB_PASSWORD", 'rootpass123');
define("DB_DATABASE", 'test');

class Db_Mysql {

    private $con = null;

    public function  __construct() {
        $this->connect();
    }

    public function  __destruct() {
        $this->close();
    }

    private function connect() {

        $this->con = @mysql_pconnect(DB_HOST.':'.DB_PORT, DB_LOGIN, DB_PASSWORD);
        if (!$this->con) {
            throw new Exception('Nie można się połaczyć: ' . mysql_error());
        }

        $dbSelected = @mysql_select_db(DB_DATABASE, $this->con);
        if (!$dbSelected) {
            throw new Exception('Nie można ustawić bazy danych: ' . mysql_error());
        }

    }

    private function close() {
        mysql_close($this->con);
    }

    /**
     *
     * @param string $sql
     * @return resource
     */
    private function query($sql) {
	mysql_query("SET NAMES 'utf8';", $this->con);
        $result = mysql_query($sql, $this->con);

        if(!$result) {
            throw new Exception('Zapytanie "'.$sql.'" jest niepoprawne (' . mysql_error() . ').');
        }

	if(isset ($_SESSION['sqlQuery']) ) {
	    $_SESSION['sqlQuery']++;
	} else {
	    $_SESSION['sqlQuery'] = 1;
	}

        return $result;
    }

    /**
     *
     * @param resource $query
     * @return array
     */
    private function fetch($query) {
	if(is_bool($query)) {
	    return array();
	}
        return mysql_fetch_assoc($query);
    }

    //------------------------------------------------------------------------

    /**
     *
     * @param string $sql
     * @return array
     */
    private function queryFetchOneRow($sql) {
	return $this->fetch($this->query($sql));
    }

    /**
     *
     * @param string $sql
     * @return array
     */
    private function queryFetchAllRow($sql) {
	$query = $this->query($sql);

	$result = array();

	while ($row = $this->fetch($query)) {
	    $result[] = $row;
	}

	return $result;
    }

    private function queryFetch($sql, $row) {
	if($row == 'all') {
	    return $this->queryFetchAllRow($sql);
	} elseif($row == 'one') {
	    return $this->queryFetchOneRow($sql);
	} else {
	    throw new Exception('Nie właściwy argument "row" ('.$row.').');
	}
    }

    /**
     *
     * Wykonuje zapytanie uwzglądniając cache.
     *
     * @param string $sql
     * @param string $row all|one OPTIONAL
     * @param string $cacheName OPTIONAL
     * @param int $cacheLifeTime OPTIONAL Czas życie cache w sekundach
     * @return array
     */
    protected function getFromDb($sql, $row = 'all', $cacheName = null, $cacheLifeTime = 60) {

	if(!CACHE_DB) {
	    $result = $this->queryFetch($sql, $row); //wykonuje zapytanie do bazy
	} elseif(is_string($cacheName)) { //należy skorzystać z cache
	    $dataCache = $this->getCacheData($cacheName); //odczytuje cache
	    if(is_null($dataCache)) { //jeśli nie ma cache lub się przeterminowało
		$result = $this->queryFetch($sql, $row); //wykonuje zapytanie do bazy
		$this->setCacheData($cacheName, $cacheLifeTime, $result); //zapisuje cache
	    } else { //cache jest
		$result = $dataCache; //więc z niego korzystam
	    }
	} else {
	    $result = $this->queryFetch($sql, $row); //wykonuje zapytanie do bazy
	}

	return $result;
    }

    //------------------------------------------------------------------------

    /**
     *
     * Zwraca obiekt obsługujący cache zapytań do bazy.
     *
     * @return Db_Cache
     */
    private function getDbCache() {
	require_once DB_PATH.'/Db_Cache.php';
	return new Db_Cache();
    }

    /**
     *
     * Pobiera dane z cache.
     *
     * Jeśli zwraca null to znaczy, że nie ma cache lub cache wygasł.
     *
     * @param string $cacheName
     * @return mixed|null
     */
    private function getCacheData($cacheName) {
	return $this->getDbCache()->getData($cacheName);
    }

    /**
     *
     * Dodaje dane do cache.
     *
     * @param string $cacheName
     * @param int $lifeTime
     * @param mixed $data
     * @return void
     */
    private function setCacheData($cacheName, $lifeTime, $data) {
	return $this->getDbCache()->setData($cacheName, $lifeTime, $data);
    }

    /**
     *
     * Usuwa cache.
     *
     * @param string $cacheName
     * @return void
     */
    protected function clearCache($cacheName) {
	return $this->getDbCache()->clearCache($cacheName);
    }

    //------------------------------------------------------------------------

    /**
     * Usuwa zabronione znaki z wartości w zapytaniach SQL
     *
     * @param string $value
     * @return string
     */
    protected function cleanValue($value) {
	return str_replace(array("'",'"'), array('’','"'), $value);
    }

}

Potem każda tabelka (można też dokonać innego podziału) ma swoją klasę:

class Db_Mysql_Ksiazki extends Db_Mysql {

    public function  __construct() {
        parent::__construct();
    }

    public function insertKsiazki($id, $desc, $isbn, $language, $title, $types, $author, $publication_date) {
        $title = $this->cleanValue($title);
        $desc = $this->cleanValue($desc);
        $author = $this->cleanValue($author);
        $publisher = $this->cleanValue($publisher);

        $sql = "INSERT INTO `ksiazki` (`id`, `desc`, `isbn`, `language`, `title`, `types`, `author`, `publication_date`) VALUES ('".$id."', '".$desc."', '".$isbn."', '".$language."', '".$title."', '".$types."', '".$author."', '".$publication_date."');";
        $this->getFromDb($sql);
    }

    public function truncateKsiazki() {
        $sql = "TRUNCATE TABLE `ksiazki`;";
        $this->getFromDb($sql);
    }

    public function selectRandomKsiazki($limit = 1) {
        $sql = "SELECT * FROM ksiazki ORDER BY RAND() LIMIT ".$limit.";";
        return $this->getFromDb($sql);
    }

    public function selectKsiazkiById($id) {
        $sql = "SELECT * FROM ksiazki WHERE id = ".$id.";";
        return $this->getFromDb($sql,'one', 'book_'.$id, 43200);
    }

}

Użycie w programie jest już proste:

$dbKsiazki = new Db_Mysql_Ksiazki();
$book = $dbKsiazki->selectRandomKsiazki();

2 thoughts on “Klasa dostępu do bazy danych

Comments are closed.