PDO Connection и абстрактный класс

Я использую абстрактный класс с PDO. Я хочу знать, нужно ли каждый раз $conn переменную $conn , или если она делает это сама по себе, когда скрипты заканчиваются?

Можете ли вы также сказать мне, с таким типом структуры, что было бы лучшим способом свести значение $conn ?

 abstract class DB_Connection { protected static $tbl_admin = "prof_admin"; //protected static $tbl_admin = "prof_admin"; protected static function obj_db() { $servername = "localhost"; $username = "root"; $password = ""; $dbname = "salmanshahid"; $conn = null; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $conn; } catch(PDOException $e) { echo $sql . "<br>" . $e->getMessage(); } } protected static function select($query) { try { $conn = self::obj_db(); $stmt = $conn->prepare($query); $stmt->execute(); // set the resulting array to associative $stmt->setFetchMode(PDO::FETCH_ASSOC); return $stmt->fetchAll(); } catch(PDOException $e) { throw new Exception("Error In SELECT STATMENT: " . $e->getMessage()); } } protected static function insert($query) { try { $conn = self::obj_db(); $stmt = $conn->prepare($query); $stmt->execute(); } catch(PDOException $e) { throw new Exception("Error In INSERT STATMENT: " . $e->getMessage()); } } } 

Solutions Collecting From Web of "PDO Connection и абстрактный класс"

или если он делает это сам, когда скрипты заканчиваются?

Да, конечно, PHP автоматически закрывает и очищает все ресурсы, которые были открыты во время выполнения сценария, поэтому не беспокойтесь, чтобы закрыть его вручную.

В любом случае, чтобы аннулировать conn, просто аннулируем его: $this->conn = NULL ;

Но все эти вещи совершенно незначительны по сравнению с другими проблемами вашего класса, которые небезопасны, неэффективны и непригодны для использования.

  • Прежде всего, я понятия не имею, почему вы хотите сделать этот класс абстрактным. Абстрактные классы – это классы прототипов , которые были источником других классов. Но оболочка базы данных скорее готова использовать конечный класс. Я не вижу смысла делать его абстрактным.
  • Сообщение об ошибках также является излишним и непоследовательным. Добавление «Ошибка в SELECT STATMENT» к сообщению об ошибке совершенно бесполезно. Хотя обработка ошибок соединения явно неверна. Вместо этого дайте PDO выбросить исключение и просто отпустите его. Он будет обрабатываться так же, как и любая другая ошибка на вашем сайте.
  • Следующая проблема – безопасность. По какой-то причине функция select() not insert() поддерживает готовые операторы , что делает их совершенно бесполезными: вместо этого вы можете использовать PDO :: query () с точно таким же результатом. Но то, что вам действительно нужно, – это правильно подготовить / выполнить, используя заполнители в запросе при отправке фактических переменных для execute() ;
  • Другой проблемой является дублированный код: обе функции практически одинаковы.
  • И в то же время обе функции довольно ненадежны: функция select() ограничена только одним типом набора результатов, а insert() ничего не возвращает. Вместо этого вы можете использовать только одну функцию для запуска всех ваших запросов и заставить ее вернуть оператор, что будет чрезвычайно полезно. Это позволит вам получить возвращенные данные в десятках различных форматов, поддерживаемых PDO, и даже позволить вам получить количество затронутых строк из запросов DML.

Позвольте мне предложить вам другой подход, простой PDO-обертку, который позволит вам использовать PDO самым простым и безопасным способом:

 <?php define('DB_HOST', 'localhost'); define('DB_NAME', 'test'); define('DB_USER', 'root'); define('DB_PASS', ''); define('DB_CHAR', 'utf8'); class DB { protected static $instance = null; public function __construct() {} public function __clone() {} public static function instance() { if (self::$instance === null) { $opt = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => TRUE, ); $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR; self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt); } return self::$instance; } public static function __callStatic($method, $args) { return call_user_func_array(array(self::instance(), $method), $args); } public static function run($sql, $args = []) { $stmt = self::instance()->prepare($sql); $stmt->execute($args); return $stmt; } } 

Это чрезвычайно мощный, безопасный и простой в использовании.

Вы можете использовать любую функцию PDO, просто добавив ее в вызов после префикса DB:: :::

 $stmt = DB::query("SELECT * FROM table WHERE foo='bar'"); 

Итак, во-первых, это оболочка PDO , которая может запускать любой метод PDO с помощью метода magic __call() . Единственная функция, которую я добавил, – run() .

Вместо ваших собственных ненадежных и ненадежных методов select() и insert() позвольте предложить вам использовать один универсальный метод run() , который является не более чем сокращением этих трех строк:

 $stmt = DB::prepare($query); $stmt->execute($params); $data = $stmt->fetch(); 

Итак, вместо этого вы можете написать его как аккуратный однострочный:

 $data = DB::run($query, $params)->fetch(); 

Обратите внимание, что он может запускать запрос любого типа и возвращать результат в любом формате, поддерживаемом PDO.

Я написал статью об этой простой оболочке, где вы можете найти примеры использования. Весь код примера можно запустить как есть, просто скопируйте и вставьте его в свой скрипт и настройте учетные данные: http://phpdelusions.net/pdo/pdo_wrapper#samples