class.mubcache.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. defined( 'IN_WEB') or die( 'Include Error!');
  3. /**
  4. *
  5. * bcache封装类
  6. * @author 张奎
  7. * 注意事项:
  8. * $aKeyWhere key条件,二维数组,即可以指定多个条件 单键多值型
  9. * 如:array(array('id' => 1001),array('id' => 1002),array('id' => 1003)))
  10. * $aWhere 附加条件,二维数组(内层数组:0字段名,1条件符,2是值),条件符(=,<>,!=,>,>=,<,<=)
  11. * 如:array(array('desc','=','4515'));
  12. *
  13. */
  14. class mubcache {
  15. /**
  16. *
  17. * 表配置
  18. * @var unknown_type
  19. */
  20. private $_config;
  21. private $_compositeKey; //是否组合主键
  22. private $_keyField; //主键字段
  23. private $_aKeyWhere; //主键条件
  24. private $_keyWhereCount; //条件值的数量
  25. /**
  26. * @var BcServer
  27. */
  28. private $_bcServer; //BcServer对象
  29. /**
  30. *
  31. * 构造函数
  32. * @param unknown_type $config
  33. * server bcache地址
  34. * port bcache端口
  35. * key_field 键字段名
  36. * key_type 键字段类型
  37. */
  38. public function __construct(array $config) {
  39. $this->_config = $config;
  40. $this->_keyField = $config['keyField'];
  41. $this->_compositeKey = $config['compositeKey'];
  42. $this->_keys = $config['keys'];
  43. }
  44. /**
  45. *
  46. * 设置bcache服务器
  47. */
  48. public function createBcServer() {
  49. $this->_bcServer = new BcServer(); //创建BcServer对象
  50. $code = $this->_bcServer->setAddress( $this->_config['server'], $this->_config['port'] );
  51. if ($code != 0) { //错误码
  52. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  53. }
  54. //设置表名
  55. $code = $this->_bcServer->setTablename( $this->_config['tablename'] );
  56. if ($code != 0) { //错误码
  57. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  58. }
  59. //设置键
  60. //组合主键
  61. if ($this->_compositeKey) {
  62. } else {
  63. $keyType = intval( $this->_config['keyType'] );
  64. if ($this->_keyWhereCount > 1) { //单键多值
  65. if ( $this->_keyWhereCount > 31){
  66. bc_set_key_value_max( 20000);
  67. }
  68. $code = $this->_bcServer->addKey( $this->_keyField, $keyType );
  69. if ($code != 0) {
  70. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  71. }
  72. } else { //单键单值
  73. if ($keyType == BC_INT_KEY) {
  74. $code = $this->_bcServer->intKey();
  75. if ($code != 0) {
  76. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  77. }
  78. } elseif ($keyType == BC_STRING_KEY) {
  79. $code = $this->_bcServer->stringKey();
  80. if ($code != 0) {
  81. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  82. }
  83. }
  84. }
  85. }
  86. }
  87. private function reset() {
  88. $this->_aKeyWhere = null;
  89. $this->_bcServer = null;
  90. }
  91. /**
  92. *
  93. * 新添加数据 键-值对
  94. * @param unknown_type $aFieldVal array('key'=>value, 'key'=>value)
  95. * @return int
  96. */
  97. public function insert(array $aFieldVal) {
  98. if (! is_array( $aFieldVal )) {
  99. return 0;
  100. }
  101. $this->createBcServer();
  102. $req = new BcRequest( $this->_bcServer, BC_INSERT ); //创建BcRequest对象
  103. foreach ( $aFieldVal as $field => $value ) {
  104. if ($field == $this->_keyField) { //主键
  105. $code = $req->setKey( $value );
  106. if ($code != 0) {
  107. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  108. }
  109. } else {
  110. $code = $req->set( $field, $value ); //其他字段值
  111. if ($code != 0) {
  112. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  113. }
  114. }
  115. }
  116. $res = new BcResult();
  117. $code = $req->execute( $res );
  118. if ($code != 0) {
  119. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  120. }
  121. $affected = $res->affectedRows();
  122. $insertId = $res->insertId();
  123. $this->reset();
  124. return ($affected && $insertId ? $insertId : $affected);
  125. }
  126. /**
  127. *
  128. * 更新记录
  129. * @param unknown_type $aSet 需要修改的键值对
  130. * @param unknown_type $aKeyWhere 主键条件键值对
  131. * @param unknown_type $aWhere 附加条件
  132. * @param unknown_type $aLimit 限制记录数 array(array(1))
  133. * @return int(true/false)
  134. */
  135. public function update(array $aSet, array $aKeyWhere, array $aWhere = array(), array $aLimit = array()) {
  136. $this->_aKeyWhere = $aKeyWhere;
  137. $this->_keyWhereCount = count( $aKeyWhere );
  138. $this->createBcServer();
  139. $req = new BcRequest( $this->_bcServer, BC_UPDATE ); //创建BcRequest对象
  140. $this->makeKeyWhere( $req, $aKeyWhere );
  141. $this->makeWhereAndLimit( $req, $aWhere, $aLimit );
  142. foreach ( $aSet as $field => $value ) {
  143. $code = $req->set( $field, $value );
  144. }
  145. $res = new BcResult();
  146. $code = $req->execute( $res );
  147. if ($code != 0) {
  148. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  149. }
  150. return $res->affectedRows();
  151. }
  152. /**
  153. * 删除记录(一次只能删除一条记录)
  154. * @param unknown_type $aKeyWhere 主键条件键值对
  155. * @param unknown_type $aWhere 附加条件
  156. * @param unknown_type $aLimit 限制记录数
  157. * @return int(0失败/1成功)
  158. */
  159. public function delete(array $aKeyWhere, array $aWhere = array(), array $aLimit = array()) {
  160. $this->_aKeyWhere = $aKeyWhere;
  161. $this->_keyWhereCount = count( $aKeyWhere );
  162. $this->createBcServer();
  163. $req = new BcRequest( $this->_bcServer, BC_DELETE ); //创建BcRequest对象
  164. $this->makeKeyWhere( $req, $aKeyWhere );
  165. $this->makeWhereAndLimit( $req, $aWhere, $aLimit );
  166. $res = new BcResult();
  167. $code = $req->execute( $res );
  168. if ($code != 0) {
  169. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  170. }
  171. return $res->affectedRows();
  172. }
  173. /**
  174. * 查询一条记录
  175. * @param array $fields 需要的字段 array( key=>value, key=>value)
  176. * @param array $aKeyWhere 主键条件键值对 array( array(key=>value)))
  177. * @param array $aWhere 附加条件 array
  178. * @return array()
  179. */
  180. public function getOne(array $fields, array $aKeyWhere, array $aWhere = array()) {
  181. $this->_aKeyWhere = $aKeyWhere;
  182. $this->_keyWhereCount = count( $aKeyWhere );
  183. $this->createBcServer();
  184. $req = new BcRequest( $this->_bcServer, BC_SELECT ); //创建BcRequest对象
  185. $this->makeKeyWhere( $req, $aKeyWhere );
  186. $this->makeWhereAndLimit( $req, $aWhere, array(0, 1 ) );
  187. foreach ( $fields as $field ) {
  188. $code = $req->need( $field );
  189. if ($code != 0) {
  190. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  191. }
  192. }
  193. $res = new BcResult();
  194. $code = $req->execute( $res );
  195. if ($code != 0) {
  196. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  197. }
  198. return $res->fetchRow( BC_FETCH_ASSOC );
  199. }
  200. /**
  201. *
  202. * 查询多条记录
  203. * @param array $fields 需要的字段
  204. * @param array $aKeyWhere 主键条件键值对
  205. * @param array $aWhere 附加条件
  206. * @param array $aLimit 限制记录数
  207. */
  208. public function getMulti(array $fields, array $aKeyWhere, array $aWhere = array(), array $aLimit = array()) {
  209. $this->_aKeyWhere = $aKeyWhere;
  210. $this->_keyWhereCount = count( $aKeyWhere );
  211. $this->createBcServer();
  212. $req = new BcRequest( $this->_bcServer, BC_SELECT ); //创建BcRequest对象
  213. $this->makeKeyWhere( $req, $aKeyWhere );
  214. $this->makeWhereAndLimit( $req, $aWhere, $aLimit );
  215. foreach ( $fields as $field ) {
  216. $code = $req->need( $field );
  217. if ($code != 0) {
  218. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  219. }
  220. }
  221. $res = new BcResult();
  222. $code = $req->execute( $res );
  223. if ($code != 0) {
  224. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  225. }
  226. $result = array();
  227. while ( $row = $res->fetchRow( BC_FETCH_ASSOC ) ) {
  228. $result[] = $row;
  229. }
  230. return $result;
  231. }
  232. /**
  233. * 统计记录数
  234. * @param unknown_type $aKeyWhere
  235. * @param unknown_type $aWhere
  236. */
  237. public function count(array $aKeyWhere, array $aWhere = array()){
  238. $this->_aKeyWhere = $aKeyWhere;
  239. $this->_keyWhereCount = count( $aKeyWhere );
  240. $this->createBcServer();
  241. $req = new BcRequest( $this->_bcServer, BC_SELECT ); //创建BcRequest对象
  242. $this->makeKeyWhere( $req, $aKeyWhere );
  243. $this->makeWhereAndLimit( $req, $aWhere, array() );
  244. $res = new BcResult();
  245. $code = $req->execute( $res );
  246. if ($code != 0) {
  247. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  248. }
  249. return $res->totalRows();
  250. }
  251. /**
  252. * 自增操作(int++)
  253. * @param unknown_type $field 自增字段
  254. * @param unknown_type $step 步长
  255. * @param unknown_type $aKeyWhere 主键条件
  256. * @param unknown_type $aWhere 附加条件
  257. */
  258. public function inc($field, array $aKeyWhere, array $aWhere = array(), $step = 1){
  259. $this->_aKeyWhere = $aKeyWhere;
  260. $this->_keyWhereCount = count( $aKeyWhere );
  261. $this->createBcServer();
  262. $req = new BcRequest( $this->_bcServer, BC_UPDATE ); //创建BcRequest对象
  263. $this->makeKeyWhere( $req, $aKeyWhere );
  264. $this->makeWhereAndLimit( $req, $aWhere, array() );
  265. $req->add($field, $step);
  266. $res = new BcResult();
  267. $code = $req->execute( $res );
  268. if ($code != 0) {
  269. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  270. }
  271. return $res->affectedRows();
  272. }
  273. /**
  274. * 自减操作(int--)
  275. * @param unknown_type $field 自增字段
  276. * @param unknown_type $step 步长
  277. * @param unknown_type $aKeyWhere 主键条件
  278. * @param unknown_type $aWhere 附加条件
  279. */
  280. public function dec($field, array $aKeyWhere, array $aWhere = array(), $step = 1){
  281. $this->_aKeyWhere = $aKeyWhere;
  282. $this->_keyWhereCount = count( $aKeyWhere );
  283. $this->createBcServer();
  284. $req = new BcRequest( $this->_bcServer, BC_UPDATE ); //创建BcRequest对象
  285. $this->makeKeyWhere( $req, $aKeyWhere );
  286. $this->makeWhereAndLimit( $req, $aWhere, array() );
  287. $req->sub($field, $step);
  288. $res = new BcResult();
  289. $code = $req->execute( $res );
  290. if ($code != 0) {
  291. $this->error( $code, $res->errorMessage() . 'DB:' . $res->errorFrom(), __LINE__ );
  292. }
  293. return $res->affectedRows();
  294. }
  295. /**
  296. *
  297. * 生成主键条件
  298. * @param unknown_type $req
  299. */
  300. public function makeKeyWhere(&$req, array $aKeyWhere) {
  301. foreach ( $aKeyWhere as $row ) {
  302. foreach ( $row as $field => $value ) {
  303. if ($this->_keyWhereCount > 1) { //单键多值
  304. $code = $req->addKeyValue( $field, $value );
  305. //var_dump( $code, 'xxxxxxxxxxx', $field, '------',$value,'<br><br>');
  306. } else {
  307. $code = $req->setKey( $value );
  308. }
  309. if ($code != 0) {
  310. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  311. }
  312. }
  313. }
  314. }
  315. /**
  316. *
  317. * 生成附加条件和限制记录
  318. * @param unknown_type $aWhere
  319. * @param unknown_type $aLimit
  320. */
  321. public function makeWhereAndLimit(&$req, array $aWhere, array $aLimit = array()) {
  322. foreach ( $aWhere as $row ) {
  323. $field = $row[0];
  324. $op = strtolower( $row[1] );
  325. $value = $row[2];
  326. $op = strtolower( $op );
  327. switch ($op) {
  328. case '!=' :
  329. case '<>' :
  330. $op = 'ne';
  331. break;
  332. case '<' :
  333. $op = 'lt';
  334. break;
  335. case '>' :
  336. $op = 'gt';
  337. break;
  338. case '<=' :
  339. $op = 'le';
  340. break;
  341. case '>=' :
  342. $op = 'ge';
  343. break;
  344. default :
  345. $op = 'eq';
  346. break;
  347. }
  348. $code = $req->$op( $field, $value );
  349. if ($code != 0) {
  350. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  351. }
  352. }
  353. if (intval( $aLimit[1] ) > 0) {
  354. $code = $req->limit( intval( $aLimit[0] ), intval( $aLimit[1] ) );
  355. if ($code != 0) {
  356. $this->error( $code, $this->_bcServer->errorMessage(), __LINE__ );
  357. }
  358. }
  359. return true;
  360. }
  361. public function error($code, $msg, $line) {
  362. $str = 'line:' . $line . '--code:' . $code . '---msg:' . $msg;
  363. die( $str );
  364. }
  365. }