YokiToki
@YokiToki
PHP-разработчик

Как грамотно закрыть MySQLi?

Приветствую, есть следующий код, если попытаться выполнить его в контроллере, создав экземпляр этого класса и последовательно вызвать get_one, а затем get_two, то get_two вернет ошибку т.к. mysql-соединение уже закрыто.
class Foo extends Bar
{
	function __construct()
	{

		parent::__construct();

		$this->mysqli = new mysqli($this->cfg->db->host, 
		                           $this->cfg->db->user, 
		                           $this->cfg->db->password, 
		                           $this->cfg->db->database);
		$this->mysqli->query('SET NAMES utf8');
		
	}

	public function get_one()
	{

		$table_one = array();

		$result = $this->mysqli->query('SELECT * FROM `table_one`');

		for ($i=0; $row = $result->fetch_assoc(); $i++) { 
			$table_one[] = $row;
		}

		$result->close();
		$this->mysqli->close();

		return $table_one;

	}


	public function get_two()
	{

		$table_two = array();

		$result = $this->mysqli->query('SELECT * FROM `table_two`');

		for ($i=0; $row = $result->fetch_assoc(); $i++) { 
			$table_two[] = $row;
		}

		$result->close();
		$this->mysqli->close();

		return $table_two;

	}

}

В голову приходит только такое
public function get_one($keep = false)
	{
		...
		if(!$keep)
			$this->mysqli->close();

		...
	}

Как можно более-менее универсально его закрывать?
  • Вопрос задан
  • 6304 просмотра
Решения вопроса 1
MegaMufa
@MegaMufa
Соединение закроется автоматически, когда отработает скрипт. В дальнейшем вам возможно еще раз понадобиться обращатся к бд. А установление соединения - довольно дорогостоящая операция.

Если вы пишите на php и это не демон (написание которого на пыхе - сомнительное удовольствие), то об освобождении ресурсов сильно не парьтесь. Скрипт отработал - за вас все подчистят.

Конкретно в этом случае, вынесите закрытие соединения в дестурктор. Или создайте отдельный метод close() и дергайте его.

По поводу подхода. В данном случае действительно будет лучше писать в процедурном стиле (и в этом нет ничего плохого; ООП - не панацея). Здесь вы класс используете не по назначению. Классы нужны для разделения логики: один отвечает за соединение с бд, другой за формирование запросов, третий за формирование результатов.

Я не хочу вас обидеть, но вы действительно не понимаете самого смысла ООП. И просто на голой теории это сложно понять. Я сам два года писал, используя ООП. И только потом понял для чего это на самом деле надо.

Для поднятия навыка попробуйте покопаться в исходниках какого-нибудь фреймворка. Я в свое время перебрал ядро Yii. Он прост для понимания и не перегружен паттернами.

Касательно конкретно этого случая, я уже сказал, вынесите закрытие соединения в деструктор.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
SagePtr
@SagePtr
Еда - это святое
*картинка про троллейбус*
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
Два обязательных правила, которые ты должен соблюдать
1. Не пиши классов.
2. Не закрывай mysqli
Ответ написан
PretorDH
@PretorDH
HTML5, CSS3, PHP, JS - люблю в чистом виде.
Если уж создаёш классы с конструктором, используй и встроеный метод __destruct(). Он запускается при уничтожении объекта созданого конструктором, или по завершению скрипта.

Например вот так:
function __destruct(){   
/* Освобождаем результаты запроса */
		empty($this->dbresult) || $this->dbresult->close();            
/* Иногда результатов запроса несколько освободим их тоже */
		while ( self::$db->more_results() && self::$db->next_result() && self::$db->store_result() );
		if ($this->connected && self::$db) { 
/* Закрываем соединение */
			self::$db->close();
			self::$db=NULL;
			$this->connected=false;
		};
	}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы