Правильный способ PDO обрабатывать освобождение ресурсов после хранимой процедуры с несколькими запросами?
Я работаю над заменой использования mysqli
с PDO
в файле соединителя базы данных Tera-WURFL, потому что наш сервер имеет PHP 5.2.6 и mysqli не поддерживает постоянные соединения до 5.3.0.
Итак, я заменяю весь код mysqli на код PDO. Закончив с базовым поиском и обработкой данных, я пришел к этой части освобождения ресурсов, где я не уверен, как именно заменить следующее:
protected function cleanConnection(){
while($this->dbcon->more_results()){
$this->dbcon->next_result();
$res = $this->dbcon->use_result();
if ($res instanceof mysqli_result){$res->free();}
}
}
Вышеуказанная функция вызывается каждый раз после вызова хранимой процедуры. Я предполагаю, что эта функция извлекает любые оставшиеся результаты и очищает канал между ведущим и ведомым. Может кто-нибудь ответить, если то, что я думаю, правильно, и объяснить, почему это делается только в этом случае.
Ниже приведен пример хранимого вызова proc из файла коннектора базы данных Tera-WURFL, который впоследствии вызывает вышеуказанную функцию:
$query = sprintf("CALL ".TeraWurflConfig::$TABLE_PREFIX."_RIS(%s,%s,%s)",$this->SQLPrep($userAgent),$tolerance,$this->SQLPrep($matcher->tableSuffix()));
$res = $this->dbcon->query($query); //this calls TeraWurfl_RIS() stored proc
if(!$res){
throw new Exception(sprintf("Error in DB RIS Query: %s. \nQuery: %s\n",$this->dbcon->error,$query));
exit();
}
$data = $res->fetch_assoc();
$this->cleanConnection(); //calling cleanConnection()
Ниже приведена хранимая процедура, вызываемая выше:
CREATE PROCEDURE `TeraWurfl_RIS`(IN ua VARCHAR(255), IN tolerance INT, IN matcher VARCHAR(64))
BEGIN
DECLARE curlen INT;
DECLARE wurflid VARCHAR(64) DEFAULT NULL;
DECLARE curua VARCHAR(255);
SELECT CHAR_LENGTH(ua) INTO curlen;
findua: WHILE ( curlen >= tolerance ) DO
SELECT CONCAT(LEFT(ua, curlen ),'%') INTO curua;
SELECT idx.DeviceID INTO wurflid
FROM TeraWurflIndex idx INNER JOIN TeraWurflMerge mrg ON idx.DeviceID = mrg.DeviceID
WHERE mrg.match = 1 AND idx.matcher = matcher
AND mrg.user_agent LIKE curua
LIMIT 1;
IF wurflid IS NOT NULL THEN
LEAVE findua;
END IF;
SELECT curlen - 1 INTO curlen;
END WHILE;
SELECT wurflid as DeviceID;
END
Что у меня так далеко
protected function cleanConnection($resultObj){
if($resultObj instanceof PDOStatement)
{
while($res = $resultObj->fetch()){
if ($res instanceof PDO){$res = null;}
}
}
}
И вот как я звоню -
$query = sprintf("CALL ".TeraWurflConfig::$TABLE_PREFIX."_RIS(:userAgent,:tolerance,:tableSuffix)");
$queryHandle = $this->dbcon->prepare($query);
$queryHandle->execute(array(':userAgent' => $userAgent,':tolerance' => $tolerance,':tableSuffix' => $matcher->tableSuffix()));
$data = $queryHandle->fetch();
$this->cleanConnection($queryHandle); //calling here
Обновить
Этот фрагмент кода будет размещен на наших серверах доставки рекламы, которые многочисленны и обслуживают большой трафик. Я полагаю, что в таких условиях важно освободить ресурсы, поэтому это было сделано в исходном файле. Кто-нибудь может прокомментировать это? Спасибо...
1 ответ
Вам не нужно беспокоиться об этом, к тому времени, когда скрипт останавливает свое выполнение; PHP обычно выполняет очистку (GC sortof); вычистить все открытые дескрипторы ресурсов и тому подобное.
Это основная причина, по которой при работе с файлами необходимо вызывать close()
метод на file handle
иначе ваши изменения не могут быть сохранены, потому что PHP просто очищает.
В заключение, вы можете оставить эту часть вне своей базы кода.