На этот раз хочу поделиться с ёвижн сообществом со своей реализацией паттерна Singleton.
Пример взят с разрабатываемого проекта.
Чтобы не надоедать текстом сразу приведу код
- // Накрываем свой класс неймспейсом во избежание не поняток )
- namespace yvision;
- // Обратный слэш нужен для понимания интерпретатора грузить класс из глобального окружения
- class mysqli extends \mysqli{
- // Была идея пулла но я вовремя остановился массивчик для инстанции
- static private $_instance = array();
- static private $_host = "localhost";
- // Сам тока заметил что у нас все коннекты через рута ойбай побежал менять
- static private $_user = "root";
- // Мой пароль знало пол офиса )(
- static private $_password = "sodnaj";
- // Ваша база
- static private $_db = "db";
- static private $_port = 3306;
- static private $_socket = "/var/run/mysqld/mysqld.sock";
- /**
- *
- * @access public
- * @return mysqli basic mysqli class instance
- * Выбираем статичный метод как и обычно это происходит
- */
- static public function getInstance(){
- // На случай нескольких инстанций все дело храним в массивчик
- if(empty(self::$_instance[$scope='default']))
- {
- // Вот в этой строчке весь смысл синглетона те создаем инстанцию родительского класса и сохраняем ее во внутреннюю переменную
- self::$_instance[$scope] = new parent(self::$_host, self::$_user, self::$_password, self::$_db, self::$_port, self::$_socket);
- // При ошибке соединения показываем непонятный для клиента текст
- if(self::$_instance[$scope]->connect_errno>0){
- ob_clean();
- echo self::$_instance[$scope]->connect_errno;
- exit;
- }// end if
- // Хоть и по дефолту у меня везде утф-8 но дурная привычка дает о себе знать
- // Тут важно не ошибиться потому что мускул при всей его великолепии не понимает utf-8 а именно utf8 те без тире
- self::$_instance[$scope]->query("SET NAMES utf8;");
- // Хере некоторые отрывки из проекта прошу не обращать внимания
- self::$_instance[$scope]->query("SET @current_user_id=".CurrentUser::getUserID());
- // Как говориться на пожарный случай проверяем никаких ошибок не возникло при последних обращениях
- if(self::$_instance[$scope]->errno){
- ob_get_clean();
- echo self::$_instance[$scope]->error;
- exit;
- }// end if
- // И возвращаем долгожданный единственный экземпляр ура!
- return self::$_instance[$scope];
- }else{// При последующих обращениях
- // При больших таймаутах или обычно после больших инсертов почему то установки летели
- self::$_instance[$scope]->query("SET NAMES utf8;");
- self::$_instance[$scope]->query("SET @current_user_id=".CurrentUser::getUserID());
- if(self::$_instance[$scope]->errno){
- ob_get_clean();
- echo self::$_instance[$scope]->error;
- exit;
- }// end if
- return self::$_instance[$scope];
- }// end if
- }// end function
- // Супер мега метод
- // хочу но еще не реализовал в XPath стиле получить значение по полю
- static public function get($xpath=''){
- $conn = self::getInstance();
- $sql = 'SELECT ';
- $conn->query();
- }// end get
- // Метод класса реализующий разделение на страницы пагинатор кароче к топику сильного отношения не имеет
- static public function queryndivide($tablename, $fields = array(), $fromPage=self::FROMITEM, $howmany=self::PPAGE, $whereclause=''){
- $fsql = "SELECT SQL_CALC_FOUND_ROWS";
- // Вычисление начального элемента страницы
- $fromPage = ($fromPage<1?1:$fromPage);
- $from = ($fromPage-1)*$howmany;
- $limit = "LIMIT {$from}, {$howmany}";
- // Массив списка колонок
- $sql = array();
- // Создание списка колонок
- foreach($fields as $alias=>$field){
- $sql[] = "`".$tablename."`.`".$field."` AS ".$alias;
- }// end foreach
- $sql = implode(", ", $sql);
- /**
- * @var Созданный SQL запрос
- */
- $fsql = implode(' ', array($fsql, $sql, 'FROM', $tablename, $whereclause, $limit));
- $conn = self::getInstance();
- // ResultSet of elements on page
- $resultSet = $conn->query($fsql);
- // Количество всех строк в выборке
- $getAllRows = "SELECT FOUND_ROWS() AS fr";
- $allRows = $conn->query($getAllRows);
- /**
- * @var Количество выбранных строк
- */
- $rows = 0;
- if($allRows->num_rows>0){
- $row = $allRows->fetch_object();
- $rows = $row->fr;
- }// end if
- $tmp = new \stdClass;
- $tmp->rows = $rows;
- $tmp->allRows = $resultSet;
- return $tmp;
- }
- /**
- * @return nothing
- * Закрываем конструктор
- */
- final private function __construct(){}
- }
В чем прелесть синглетона для наших обычных задач
- Меньше соеднинений
- Можно вести сессионные переменные мускула
- Меньше кода то есть после подключения можно
- При смене паролья изменить лишь в одном месте
Следующий этап хочу датабейз коннекшн пулинг сделать правда уже на йава тк для похапе смысла не вижу