Database.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. /**
  3. * PHPIDS
  4. *
  5. * Requirements: PHP5, SimpleXML
  6. *
  7. * Copyright (c) 2008 PHPIDS group (https://phpids.org)
  8. *
  9. * PHPIDS is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation, version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * PHPIDS is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with PHPIDS. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * PHP version 5.1.6+
  23. *
  24. * @category Security
  25. * @package PHPIDS
  26. * @author Mario Heiderich <mario.heiderich@gmail.com>
  27. * @author Christian Matthies <ch0012@gmail.com>
  28. * @author Lars Strojny <lars@strojny.net>
  29. * @license http://www.gnu.org/licenses/lgpl.html LGPL
  30. * @link http://php-ids.org/
  31. */
  32. require_once 'IDS/Caching/Interface.php';
  33. /**
  34. * Needed SQL:
  35. *
  36. #create the database
  37. CREATE DATABASE IF NOT EXISTS `phpids` DEFAULT CHARACTER
  38. SET utf8 COLLATE utf8_general_ci;
  39. DROP TABLE IF EXISTS `cache`;
  40. #now select the created datbase and create the table
  41. CREATE TABLE `cache` (
  42. `type` VARCHAR( 32 ) NOT null ,
  43. `data` TEXT NOT null ,
  44. `created` DATETIME NOT null ,
  45. `modified` DATETIME NOT null
  46. ) ENGINE = MYISAM ;
  47. */
  48. /**
  49. * Database caching wrapper
  50. *
  51. * This class inhabits functionality to get and set cache via a database.
  52. *
  53. * @category Security
  54. * @package PHPIDS
  55. * @author Christian Matthies <ch0012@gmail.com>
  56. * @author Mario Heiderich <mario.heiderich@gmail.com>
  57. * @author Lars Strojny <lars@strojny.net>
  58. * @copyright 2007-2009 The PHPIDS Groupup
  59. * @license http://www.gnu.org/licenses/lgpl.html LGPL
  60. * @version Release: $Id:Database.php 517 2007-09-15 15:04:13Z mario $
  61. * @link http://php-ids.org/
  62. * @since Version 0.4
  63. */
  64. class IDS_Caching_Database implements IDS_Caching_Interface
  65. {
  66. /**
  67. * Caching type
  68. *
  69. * @var string
  70. */
  71. private $type = null;
  72. /**
  73. * Cache configuration
  74. *
  75. * @var array
  76. */
  77. private $config = null;
  78. /**
  79. * DBH
  80. *
  81. * @var object
  82. */
  83. private $handle = null;
  84. /**
  85. * Holds an instance of this class
  86. *
  87. * @var object
  88. */
  89. private static $cachingInstance = null;
  90. /**
  91. * Constructor
  92. *
  93. * Connects to database.
  94. *
  95. * @param string $type caching type
  96. * @param object $init the IDS_Init object
  97. *
  98. * @return void
  99. */
  100. public function __construct($type, $init)
  101. {
  102. $this->type = $type;
  103. $this->config = $init->config['Caching'];
  104. $this->handle = $this->_connect();
  105. }
  106. /**
  107. * Returns an instance of this class
  108. *
  109. * @static
  110. * @param string $type caching type
  111. * @param object $init the IDS_Init object
  112. *
  113. * @return object $this
  114. */
  115. public static function getInstance($type, $init)
  116. {
  117. if (!self::$cachingInstance) {
  118. self::$cachingInstance = new IDS_Caching_Database($type, $init);
  119. }
  120. return self::$cachingInstance;
  121. }
  122. /**
  123. * Writes cache data into the database
  124. *
  125. * @param array $data the caching data
  126. *
  127. * @throws PDOException if a db error occurred
  128. * @return object $this
  129. */
  130. public function setCache(array $data)
  131. {
  132. $handle = $this->handle;
  133. $rows = $handle->query('SELECT created FROM `' .
  134. $this->config['table'].'`');
  135. if (!$rows || $rows->rowCount() === 0) {
  136. $this->_write($handle, $data);
  137. } else {
  138. foreach ($rows as $row) {
  139. if ((time()-strtotime($row['created'])) >
  140. $this->config['expiration_time']) {
  141. $this->_write($handle, $data);
  142. }
  143. }
  144. }
  145. return $this;
  146. }
  147. /**
  148. * Returns the cached data
  149. *
  150. * Note that this method returns false if either type or file cache is
  151. * not set
  152. *
  153. * @throws PDOException if a db error occurred
  154. * @return mixed cache data or false
  155. */
  156. public function getCache()
  157. {
  158. try{
  159. $handle = $this->handle;
  160. $result = $handle->prepare('SELECT * FROM `' .
  161. $this->config['table'] .
  162. '` where type=?');
  163. $result->execute(array($this->type));
  164. foreach ($result as $row) {
  165. return unserialize($row['data']);
  166. }
  167. } catch (PDOException $e) {
  168. throw new PDOException('PDOException: ' . $e->getMessage());
  169. }
  170. return false;
  171. }
  172. /**
  173. * Connect to database and return a handle
  174. *
  175. * @return object PDO
  176. * @throws Exception if connection parameters are faulty
  177. * @throws PDOException if a db error occurred
  178. */
  179. private function _connect()
  180. {
  181. // validate connection parameters
  182. if (!$this->config['wrapper']
  183. || !$this->config['user']
  184. || !$this->config['password']
  185. || !$this->config['table']) {
  186. throw new Exception('
  187. Insufficient connection parameters'
  188. );
  189. }
  190. // try to connect
  191. try {
  192. $handle = new PDO(
  193. $this->config['wrapper'],
  194. $this->config['user'],
  195. $this->config['password']
  196. );
  197. $handle->setAttribute(
  198. PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true
  199. );
  200. } catch (PDOException $e) {
  201. throw new PDOException('PDOException: ' . $e->getMessage());
  202. }
  203. return $handle;
  204. }
  205. /**
  206. * Write the cache data to the table
  207. *
  208. * @param object $handle the database handle
  209. * @param array $data the caching data
  210. *
  211. * @return object PDO
  212. * @throws PDOException if a db error occurred
  213. */
  214. private function _write($handle, $data)
  215. {
  216. try {
  217. $handle->query('TRUNCATE ' .
  218. $this->config['table'].'');
  219. $statement = $handle->prepare('
  220. INSERT INTO `' .
  221. $this->config['table'].'` (
  222. type,
  223. data,
  224. created,
  225. modified
  226. )
  227. VALUES (
  228. :type,
  229. :data,
  230. now(),
  231. now()
  232. )
  233. ');
  234. $statement->bindParam('type',
  235. $handle->quote($this->type));
  236. $statement->bindParam('data', serialize($data));
  237. if (!$statement->execute()) {
  238. throw new PDOException($statement->errorCode());
  239. }
  240. } catch (PDOException $e) {
  241. throw new PDOException('PDOException: ' . $e->getMessage());
  242. }
  243. }
  244. }
  245. /**
  246. * Local variables:
  247. * tab-width: 4
  248. * c-basic-offset: 4
  249. * End:
  250. * vim600: sw=4 ts=4 expandtab
  251. */