kk
Default banner
Разное
426 297 постов48 подписчиков
Всяко-разно
0

Singleton-PHP-mysqli

На этот раз хочу поделиться с ёвижн сообществом со своей реализацией паттерна Singleton.

Пример взят с разрабатываемого проекта.

Чтобы не надоедать текстом сразу приведу код

  1. // Накрываем свой класс неймспейсом во избежание не поняток )
  2. namespace yvision;
  3. // Обратный слэш нужен для понимания интерпретатора грузить класс из глобального окружения
  4. class mysqli extends \mysqli{
  5. // Была идея пулла но я вовремя остановился массивчик для инстанции
  6. static private $_instance = array();
  7. static private $_host = "localhost";
  8. // Сам тока заметил что у нас все коннекты через рута ойбай побежал менять
  9. static private $_user = "root";
  10. // Мой пароль знало пол офиса )(
  11. static private $_password = "sodnaj";
  12. // Ваша база
  13. static private $_db = "db";
  14. static private $_port = 3306;
  15. static private $_socket = "/var/run/mysqld/mysqld.sock";
  16. /**
  17. *
  18. * @access public
  19. * @return mysqli basic mysqli class instance
  20. * Выбираем статичный метод как и обычно это происходит
  21. */
  22. static public function getInstance(){
  23. // На случай нескольких инстанций все дело храним в массивчик
  24. if(empty(self::$_instance[$scope='default']))
  25. {
  26. // Вот в этой строчке весь смысл синглетона те создаем инстанцию родительского класса и сохраняем ее во внутреннюю переменную
  27. self::$_instance[$scope] = new parent(self::$_host, self::$_user, self::$_password, self::$_db, self::$_port, self::$_socket);
  28. // При ошибке соединения показываем непонятный для клиента текст
  29. if(self::$_instance[$scope]->connect_errno>0){
  30. ob_clean();
  31. echo self::$_instance[$scope]->connect_errno;
  32. exit;
  33. }// end if
  34. // Хоть и по дефолту у меня везде утф-8 но дурная привычка дает о себе знать
  35. // Тут важно не ошибиться потому что мускул при всей его великолепии не понимает utf-8 а именно utf8 те без тире
  36. self::$_instance[$scope]->query("SET NAMES utf8;");
  37. // Хере некоторые отрывки из проекта прошу не обращать внимания
  38. self::$_instance[$scope]->query("SET @current_user_id=".CurrentUser::getUserID());
  39. // Как говориться на пожарный случай проверяем никаких ошибок не возникло при последних обращениях
  40. if(self::$_instance[$scope]->errno){
  41. ob_get_clean();
  42. echo self::$_instance[$scope]->error;
  43. exit;
  44. }// end if
  45. // И возвращаем долгожданный единственный экземпляр ура!
  46. return self::$_instance[$scope];
  47. }else{// При последующих обращениях
  48. // При больших таймаутах или обычно после больших инсертов почему то установки летели
  49. self::$_instance[$scope]->query("SET NAMES utf8;");
  50. self::$_instance[$scope]->query("SET @current_user_id=".CurrentUser::getUserID());
  51. if(self::$_instance[$scope]->errno){
  52. ob_get_clean();
  53. echo self::$_instance[$scope]->error;
  54. exit;
  55. }// end if
  56. return self::$_instance[$scope];
  57. }// end if
  58. }// end function
  59. // Супер мега метод
  60. // хочу но еще не реализовал в XPath стиле получить значение по полю
  61. static public function get($xpath=''){
  62. $conn = self::getInstance();
  63. $sql = 'SELECT ';
  64. $conn->query();
  65. }// end get
  66. // Метод класса реализующий разделение на страницы пагинатор кароче к топику сильного отношения не имеет
  67. static public function queryndivide($tablename, $fields = array(), $fromPage=self::FROMITEM, $howmany=self::PPAGE, $whereclause=''){
  68. $fsql = "SELECT SQL_CALC_FOUND_ROWS";
  69. // Вычисление начального элемента страницы
  70. $fromPage = ($fromPage<1?1:$fromPage);
  71. $from = ($fromPage-1)*$howmany;
  72. $limit = "LIMIT {$from}, {$howmany}";
  73. // Массив списка колонок
  74. $sql = array();
  75. // Создание списка колонок
  76. foreach($fields as $alias=>$field){
  77. $sql[] = "`".$tablename."`.`".$field."` AS ".$alias;
  78. }// end foreach
  79. $sql = implode(", ", $sql);
  80. /**
  81. * @var Созданный SQL запрос
  82. */
  83. $fsql = implode(' ', array($fsql, $sql, 'FROM', $tablename, $whereclause, $limit));
  84. $conn = self::getInstance();
  85. // ResultSet of elements on page
  86. $resultSet = $conn->query($fsql);
  87. // Количество всех строк в выборке
  88. $getAllRows = "SELECT FOUND_ROWS() AS fr";
  89. $allRows = $conn->query($getAllRows);
  90. /**
  91. * @var Количество выбранных строк
  92. */
  93. $rows = 0;
  94. if($allRows->num_rows>0){
  95. $row = $allRows->fetch_object();
  96. $rows = $row->fr;
  97. }// end if
  98. $tmp = new \stdClass;
  99. $tmp->rows = $rows;
  100. $tmp->allRows = $resultSet;
  101. return $tmp;
  102. }
  103. /**
  104. * @return nothing
  105. * Закрываем конструктор
  106. */
  107. final private function __construct(){}
  108. }

В чем прелесть синглетона для наших обычных задач

  1. Меньше соеднинений
  2. Можно вести сессионные переменные мускула
  3. Меньше кода то есть после подключения можно
  4. При смене паролья изменить лишь в одном месте

Следующий этап хочу датабейз коннекшн пулинг сделать правда уже на йава тк для похапе смысла не вижу