[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: PDO и rowCount() - Part 2
VladKamyshanov
Эта тема - полный сборник мыслей которые не вошли в первую тему про rowCount(). Здесь я наиболее точно постараюсь описать свою проблему. Итак...

Познав прелести singleton'a, но не до конца в нём разобравшись, я лепил все свойства как статические. И на тот момент написал обёртку PDO(MySQL) со статическими свойствами в классе($instance,$pdo,$stmt,$row и т.д. - и все статические!!). НО. Всё работало. И даже тот самый rowCount() - но о нём чуть ниже.


Поняв, как всё же реализуется паттерн singleton, принялся за переписание обёртки. Тобишь, раньше к свойствам из методов обращался так:

return self::$stmt->rowCount();


А теперь вот так:

return $this->stmt->rowCount();


Проблема лишь в том, что 2й способ не рабочий. Я уж не знаю в чём ошибка, но остальные методы работают на ура. Поначалу думал что проблемы где-то в области $this->stmt, но, как оказалось, получение строки результата не составило труда:

$database->query("SELECT * FROM users");
// Обработаем первую строку самостоятельно
$database->fetchAssoc();
// Выведем её
echo $database->row['id']. " ".$database->row['fullname'] . "<br />";


Внутри метода fetchAssoc() такая штука:
public function fetchAssoc() {
try {
// Получем следующую строку
$this->row = $this->stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// В случе ошибки бросаем исключение
throw new DatabaseExeption("[Database.php]Error in fetchAssoc(): " . $e->getMessage());
}
}


Не знаю что и думать.. Помогите пожалуйста. Пока я в тупике.

PS
Код обёртки - в студию!
Свернутый текст
class Database {

// Экземпляр класса
private static $instance;
// Дескрипторы
private $pdo = array();
// Prepared Statement обьект
private $stmt;
// Текущее соединение
private $nowConnection;
// Следующая строка результата
public $row;

// Нельзя создать экземпляр класса через конструктор
private function __construct() {

}


// Получение экземпляра только через метод instance()
public static function instance() {
if (empty(self::$instance)) {
self::$instance = new self;
}
return self::$instance;
}

// Добавление нового соединения
public function addConnection($host, $db, $user, $pass, $id, $port = false, $charset = "utf8") {
try {
// Определяем порт
if (!$port)
$port = ini_get("mysql.default_port");
// Драйвер
$dsn = "mysql:";
// Хост
$dsn .= "host={$host};";
// Порт
$dsn .= "port={$port};";
// База данных
$dsn .= "dbname={$db};";
// Кодировка
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES {$charset}",
);

if (!isset($this->pdo[$id])) {
// Если ещё не подключены к базе - подключаемся
$this->pdo[$id] = new PDO($dsn, $user, $pass, $options);
$this->pdo[$id]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// И устанавливаем как текущее соединение
$this->switchConnection($id);
} catch (PDOException $e) {
// В случае ошибки - бросам исключение
throw new DatabaseExeption("[Database.php]Error in switchConnection(): " . $e->getMessage());
}
}


// Переключает активное соединение
public function switchConnection($id) {
if (isset($this->pdo[$id])) {
// Устанавливаем соединение $id как текущее
$this->nowConnection = &$this->pdo[$id];
} else {
// В случае, если нет соединение $id - бросаем исключение
throw new DatabaseExeption("[Database.php]Error in switchConnection(): There is no connections called {$id}");
}
}


// Запрос к базе данных
public function query() {
// Получаем аргументы
$args = func_get_args();
// Первый аргумент - шаблон
$query = array_shift($args);
try {
// Если запрос не требует prepared statement - вызов simplyQuery
if (empty($args))
$this->simplyQuery($query);
// Если аргументы для placeholders переданны как массив - вызываем stmtQuery() с передачей массива
elseif (is_array($args[0]))
$this->stmtQuery($query, $args[0]);
// Иначе собираем аргументы в массив самостоятельно и вызываем stmtQuery()
else
$this->stmtQuery($query, $args);
} catch (PDOException $e) {
// В случае ошибки - бросам исключение
throw new DatabaseExeption("[Database.php]Error in query(): " . $e->getMessage());
}
}


// Запрос, не требующий prepared statement
private function simplyQuery($query) {
// Просто выполняем запрос
$this->stmt = $this->nowConnection->query($query);
}

// Запрос, требующий prepared statement
private function stmtQuery($query, $args) {
// Подготавливаем запрос
$this->stmt = $this->nowConnection->prepare($query);
// Выполняем
$this->stmt->execute($args);
}

// Получение строк, затронутых запросом
public function affectedRows() {
$this->rowCount();
}

// Получение строк в результирующем наборе
public function numRows() {
$this->rowCount();
}

// Возвращает последний вставленный id
public function insertId() {
try {
// Возвращаем lastInsertId() у активного соединения
return $this->nowConnection->lastInsertId();
} catch (PDOException $e) {
// В случе ошибки бросаем исключение
throw new DatabaseExeption("[Database.php]Error in insertId(): " . $e->getMessage());
}
}


// Получение следующей строки результата в виде списка
public function fetchRow() {
try {
// Получем следующую строку
$this->row = $this->stmt->fetch(PDO::FETCH_NUM);
} catch (PDOException $e) {
// В случе ошибки бросаем исключение
throw new DatabaseExeption("[Database.php]Error in fetchRow(): " . $e->getMessage());
}
}


// Получение следующей строки результата в виде ассоциативного массива
public function fetchAssoc() {
try {
// Получем следующую строку
$this->row = $this->stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// В случе ошибки бросаем исключение
throw new DatabaseExeption("[Database.php]Error in fetchAssoc(): " . $e->getMessage());
}
}


// Подсчёт строк после запроса
private function rowCount() {
try {
// Возвращаем rowCount()
return $this->stmt->rowCount();
} catch (PDOException $e) {
// В случе ошибки бросаем исключение
throw new DatabaseExeption("[Database.php]Error in rowCount() " . $e->getMessage());
}
}

}


Клиентский код - в студию!
Свернутый текст
try {
// Получаем экземпляр
$database = Database::instance();
// Соединяемся
$database->addConnection("localhost", "application", "root", "", "application");
// Запрос к базе
$database->query("SELECT * FROM users");
// Вывод строк в результате - НЕ РАБОТАЕТ
echo $database->numRows();
echo "<br />";
// Самостоятельно выводим первую строку
$database->fetchAssoc();
echo $database->row['id']. " ".$database->row['fullname'] . "<br />";
} catch (DatabaseExeption $e) {
echo $e->getMessage();
}





Спустя 43 минуты, 52 секунды (15.08.2012 - 13:50) killer8080 написал(а):
VladKamyshanov
потерял return в методе numRows() wink.gif


PS
Цитата
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.

If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.

Спустя 17 минут, 31 секунда (15.08.2012 - 14:08) VladKamyshanov написал(а):
Спасибо. Действительно. Дебильная ошибка. Пойду посплю))
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.