Обертка для mysqli VS mysqli_init()

Panchous

Павел
Обертка для mysqli VS mysqli_init()

Сделал обертку для mysqli (взял пример mysqli2 из комметов в мануале)

Возникло несколько вопросов:
  1. Корректно ли в своей обертке в деструкторе вызывать метод close родителя?
    Ведь данный метод вожвращает TRUE или FALSE - а значит, предполагается, что его можно обрабатывать.
    С деструктором так не выйдет...
    Не спроста же, разработчики не сделали вызывают close() в деструкторе mysqli?
    (по крайней мере в мануале подробностей не нашел)
  2. Как правильно пользоваться своей оберткой, если я хочу использовать [m]mysqli_init()[/m], [m]mysqli_options()[/m] и [m]mysqli_real_connect()[/m]?
    Т.е. я хочу сделать одну функцию для подключения к БД (создание объекта, вызов connet...):
    Код:
    [PHP]
    public static function getDbConnection($settings)
    {				
    	$db = (mysqli2) mysqli_init();
    	$db->options(MYSQLI_INIT_COMMAND, "SET NAMES cp1251");
    	$db->real_connect($settings ['host'], $settings ['user'], $settings ['password'], $settings ['db'], $settings ['port']);
    	return $db;
    }
    [/PHP]
    Но выясняется, что такой код неверный:
    PHP:
    $db = (mysqli2) mysqli_init(); // ошибка
    Как правильно поступать в подобных случаях?
    [/list=1]
 

Profic

just Profic (PHP5 BetaTeam)
1. Какая разница вызывать close() в деструкторе или нет? После деструтора (т.е. уничтожения объекта) коннект все равно закрывается.

2. А где ты видел такой синтаксис? Я имею ввиду "(class)"? Не забываем, что это не c/c++. Я делаю примерно так (понял, что код кусками не совсем понятен, потому запостил все три класса, удалил только методы упрощающие жизнь):
PHP:
<?php
class DbException extends Exception {
	private $sqlState = NULL;
	private $sqlQuery = NULL;

	public function __construct($code, $message, $sqlState = NULL, $sqlQuery = NULL) {
		$this->sqlState = $sqlState;
		$this->sqlQuery = $sqlQuery;
		parent::__construct($message, $code);
	}

	public function getSqlState() {
		return $this->sqlState;
	}

	public function __toString() {
		if ($this->sqlState !== NULL) {
			$this->message = sprintf('[SQLSTATE:%s] %s', $this->sqlState, $this->message);
		}
		if ($this->sqlQuery !== NULL) {
			$this->message = sprintf('%s [SQL:%s]', $this->message, $this->sqlQuery);
		}
		return parent::__toString();
	}
}

class DbResult implements Iterator {
	const fetchAssoc = MYSQLI_ASSOC;
	const fetchNum = MYSQLI_NUM;
	const fetchBoth = MYSQLI_BOTH;
	const fetchDefault = NULL;

	private $res = NULL;
	private $fetchDefault = MYSQLI_BOTH;

	public function __construct(mysqli_result $res, $fetchMode = self::fetchBoth) {
		$this->res = $res;
		$this->fetchDefaultSet($fetchMode);
	}

	public function __destruct() {
		$this->free();
		$this->res = NULL;
	}

	public function fetchDefaultSet($fetchDefault) {
		$this->fetchDefault = $fetchDefault !== self::fetchDefault
			? $fetchDefault
			: self::fetchBoth
		;
		return true;
	}

	public function fetchRow() {
		return $this->res->fetch_row();
	}

	public function fetchAssoc() {
		return $this->res->fetch_assoc();
	}

	public function fetchArray($fetchMode = self::fetchDefault) {
		if ($fetchMode === self::fetchDefault) {
			$fetchMode = $this->fetchDefault;
		}
		return $this->res->fetch_array($fetchMode);
	}

	public function free() {
		return $this->res->free();
	}

	// {{{ Iterator implementation
	private $row = NULL;
	private $key = 0;
	private $keyOffset = 0;

	public function setKeyOffset($keyOffset) {
		$this->keyOffset = $keyOffset;
		return true;
	}

	public function rewind() {
		$this->res->data_seek(0);
		$this->row = $this->fetchArray();
		$this->key = 0;
	}

	public function current() {
		return $this->row;
	}

	public function key() {
		return $this->key + $this->keyOffset;
	}

	public function next() {
		$this->row = $this->fetchArray();
		$this->key++;
		return $this->row;
	}

	public function valid() {
		return $this->key < $this->res->num_rows;
	}
	// }}}
}

class DbConnection {
	const optionInitCommand = MYSQLI_INIT_COMMAND;

	private $link = NULL;
	private $queriesCount = 0;

	public function connect($host, $user, $pass, $base, $initCmd = NULL) {
		$this->init();
		if ($initCmd !== NULL) {
			$this->options(self::optionInitCommand, $initCmd);
		}
		$this->connectReal($host, $user, $pass, $base);
		return true;
	}

	public function init() {
		$this->link = mysqli::init();
		return true;
	}

	public function options($option, $value) {
		return $this->link->options($option, $value);
	}

	public function connectReal($host, $user, $pass, $base) {
		$this->link->real_connect($host, $user, $pass, $base);
		if (mysqli_connect_errno()) {
			throw new dbException(mysqli_connect_errno(), mysqli_connect_error());
		}
		return true;
	}

	public function query($sql, $fetchMode = dbResult::fetchBoth) {
		$res = $this->link->query($sql);
		if ($this->link->errno) {
			throw new dbException(
				$this->link->errno,
				$this->link->error,
				$this->link->sqlstate,
				$sql
			);
		}
		++$this->queriesCount;
		if ($res instanceof mysqli_result) {
			return new dbResult($res, $fetchMode);
		}
		if ($res) {
			if ($this->link->insert_id) {
				return $this->link->insert_id;
			}
			return $this->link->affected_rows;
		}
		return $res;
	}

	// методы облегчающие жизнь выкинуты :)

	public function queriesCount() {
		return $this->queriesCount;
	}

	public function affectedRows() {
		return $this->link->affectedRows;
	}

	public function escapeString($str) {
		return $this->link->escape_string($str);
	}
}
ЗЫ. Может таки поглядеть на PDO? Он уже не экперементальный. :)
 
Сверху