RkBlog

Hardware, programming and astronomy tutorials and reviews.

Rozszerzenie MySQLi

Obiektowa obsługa bazy danych MySQL poprzez rozszerzenie MySQLi wprowadzone w PHP5 jako zastępstwo przestarzałych funkcji mysql_*

MySQLi to zaktualizowany interfejs do bazy MySQL. Jest wydajniejszy oraz wykorzystuje kilka ciekawych nowości PHP5 takie jak wyjątki (obsługa błędów) czy też iteratory. Prosta klasa ułatwiająca obsługująca MySQL poprzez MySQLi wygląda następująco:
<?php
class mysqli_db
	{
	public function __construct($host, $user, $password, $dbname)
		{
		// łączymy się z bazą danych
		IF(!$this->mysqli = new mysqli($host, $user, $password))
			{
			$this->error = true;
			// W przypadku niepowodzenia połączenia wygeneruj wyjątek
			throw new Exception('Błąd Połączenia z Bazą Danych - '.$this->mysqli->error, $this->mysqli->errno);
			}
		// wybieramy bazę danych
		IF(!$this->mysqli->select_db($dbname))
			{
			$this->error = true;
			// W przypadku niepowodzenia wybrania bazy wygeneruj wyjątek
			throw new Exception('Nie można wybrać bazy danych - '.$this->mysqli->error, $this->mysqli->errno);
			}
		// ustawiamy "tryb" transakcji dla tabel InnoDB
		$this->mysqli->autocommit(false);
		$this->mysqli->query('SET AUTOCOMMIT = 0');
		$this->mysqli->query('BEGIN');
		}
	// Wykonywanie zapytań nie zwracających wartości (nie-Select)
	public function query($query)
		{
		IF(!ereg('SELECT', $query) and !$this->error)
			{
			IF(!$result = $this->mysqli->query($query))
				{
				$this->error = true;
				throw new Exception('Błąd wykonania zapytania - ('.$query.') - '.$this->mysqli->error, $this->mysqli->errno);
				}
			else
				{
				return true;
				}
			}
		}
	// Zapytania z SELECT zwrócą nam od razu tablicę asocjacyjną z wynikami
	public function query_select($query)
		{
		IF(!$this->error)
			{
			IF(!$result = $this->mysqli->query($query))
				{
				$this->error = true;
				throw new Exception('Błąd wykonania zapytania - ('.$query.') - '.$this->mysqli->error, $this->mysqli->errno);
				}
			while($row = $result->fetch_assoc())
				{
				$return[] = $row;
				}
			unset($result);
			unset($row);
			return $return;
			}
		}
	// ID pola autoincrement użyte w ostatnim zapytaniu INSERT
	public function insert_id()
		{
		return $this->mysqli->insert_id;
		}
	public function escape($string)
		{
		return  $this->mysqli->real_escape_string($string);
		}
	// Destruktor, w przypadku błędów wszystkie zmiany będą cofnięte
	public function __destruct()
		{
		IF(!$this->error)
			{
			$this->mysqli->query('COMMIT');
			}
		else
			{
			$this->mysqli->query('ROLLBACK');
			}
		unset($this->mysqli);
		unset($this->error);
		}
	}
Klasa ta wykorzystuje kilka rozwiązań:
- w przypadku błędów generowane są wyjątki
- jeżeli korzystamy z tabel typu InnoDB to połączenie będzie obsługiwało transakcje

Transakcja jest bardzo przydatnym rozwiązaniem. Skrypt zazwyczaj składa się z kilku zapytań i w przypadku gdy jedno z nich zakończy się niepowodzeniem - wszystkie zmiany wprowadzone przez wcześniejsze zapytania zostaną cofnięte do stanu wyjściowego. Kolejna sprawa to wyjątki, które dość łatwo mogą dać nam gotowy debuger skryptu.
Zwykłe wykorzystanie klasy:
<?php

$ms = new mysqli_db('localhost', 'root', '', 'biblioteka2');
echo '<pre>';
print_r($ms->query_select("SELECT * FROM cms_rk_users"));
Z wyłapaniem wyjątków:
<?php

try
	{
	$ms = new mysqli_db('localhost', 'root', '', 'biblioteka2');
	echo '<pre>';
	print_r($ms->query_select("SELECT * FROM cms_rk_users"));
	}
catch (Exception $error)
	{
	echo '<b>Komunikat</b>: '.$error->getMessage().'<br /><b>Plik</b>: '.$error->getFile().'<br /><b>Wiersz</b>: '.$error->getLine().'<br /><b>IP</b>: '.$_SERVER['REMOTE_ADDR'].' | <b>LINK</b>: '.$_SERVER['REQUEST_URI'].'<br /><br />'.$error->getTraceAsString();
	}
Kod, który ma być "sprawdzany" na obecność wyjątków umieszczamy w bloku "try" następnie umieszczamy blok "catch" obsługujący wygenerowany wyjątek. Wyjątki obsługiwane są przez klasę PHP5 - Exceptions, która podaje takie dane jak treść wyjątku, nazwa pliku, numer wiersza w który wygenerowano wyjątek i inne. Jeżeli cms_rk_users nie istnieje to zobaczymy wynik:
Komunikat: Błąd wykonania zapytania - (SELECT * FROM cms_rk_users) - Table 'biblioteka2.cms_rk_users' doesn't exist
Plik: /var/www/localhost/htdocs/html/1.php
Wiersz: 49
IP: ::1 | LINK: /html/1.php

#0 /var/www/localhost/htdocs/html/1.php(89): mysqli_db->query_select('SELECT * FROM c...')
#1 {main}
RkBlog

14 July 2008;

Comment article