Merge remote-tracking branch 'origin/master' into beta
Showing
34 changed files
with
4696 additions
and
8 deletions
Too many changes to show.
To preserve performance only 34 of 34+ files are displayed.
1 | +<?php return function ($in, $debugopt = 1) { | ||
2 | + $cx = array( | ||
3 | + 'flags' => array( | ||
4 | + 'jstrue' => false, | ||
5 | + 'jsobj' => false, | ||
6 | + 'spvar' => true, | ||
7 | + 'prop' => false, | ||
8 | + 'method' => false, | ||
9 | + 'mustlok' => true, | ||
10 | + 'echo' => false, | ||
11 | + 'debug' => $debugopt, | ||
12 | + ), | ||
13 | + 'constants' => array(), | ||
14 | + 'helpers' => array(), | ||
15 | + 'blockhelpers' => array(), | ||
16 | + 'hbhelpers' => array(), | ||
17 | + 'partials' => array(), | ||
18 | + 'scopes' => array(), | ||
19 | + 'sp_vars' => array('root' => $in), | ||
20 | + 'lcrun' => 'Plugin\LCRun3', | ||
21 | + | ||
22 | + ); | ||
23 | + | ||
24 | + return '<!DOCTYPE html> | ||
25 | +<html> | ||
26 | +<head> | ||
27 | + <meta charset="UTF-8"> | ||
28 | + <title>'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('staticTitle')), ENT_QUOTES, 'UTF-8').'</title> | ||
29 | + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> | ||
30 | + <style> | ||
31 | + *{margin: 0;padding: 0;} | ||
32 | + #coupon-container {width: 100%;} | ||
33 | + #coupon-container img {width: 100%; height: auto; display: block;overflow: hidden;} | ||
34 | + .img-box {width: 100%;position: relative;} | ||
35 | + .img-box .href {width: 50%; height: 100%;position: absolute;top: 0;} | ||
36 | + .img-box .href-left {left: 0} | ||
37 | + .img-box .href-right {right: 0} | ||
38 | + .img-box .href-center {width: 90%;height: 100%;position: absolute;top: 0;left: 5%;} | ||
39 | + .show-more {height: 100%;width: 25%;position: absolute;top: 0;right: 10%;} | ||
40 | + .yoho-tip {position: fixed;display: none;text-align: center;width: 70%;padding: 34px 0;top: 50%;left: 50%;margin-left: -35%;margin-top: -45px;background-color: #000;opacity: 0.9;color: #fff;font-size: 18px;border: none;border-radius: 10px;} | ||
41 | + </style> | ||
42 | + <link rel="dns-prefetch" href="//cdn.yoho.cn"> | ||
43 | + <link rel="dns-prefetch" href="//static.yohobuy.com"> | ||
44 | +</head> | ||
45 | +<body> | ||
46 | + <div id="coupon-container" param="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('activityId')), ENT_QUOTES, 'UTF-8').'" isLogged="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('isLogged')), ENT_QUOTES, 'UTF-8').'"> | ||
47 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/01.jpg"> | ||
48 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/02.jpg"> | ||
49 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/03-a.jpg"> | ||
50 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
51 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/04-a.jpg"> | ||
52 | + <div class="img-box"> | ||
53 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/05-a.jpg"> | ||
54 | + <a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_yohope')), ENT_QUOTES, 'UTF-8').'"></a> | ||
55 | + </div> | ||
56 | + <div class="img-box"> | ||
57 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/06.jpg"> | ||
58 | + <a class="href href-center" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_mycoupon')), ENT_QUOTES, 'UTF-8').'"></a> | ||
59 | + </div> | ||
60 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-2.jpg"> | ||
61 | + | ||
62 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/07.jpg"> | ||
63 | + <div class="img-box"> | ||
64 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/08.jpg"> | ||
65 | + <a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a> | ||
66 | + <a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a> | ||
67 | + </div> | ||
68 | + <div class="img-box"> | ||
69 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/09.jpg"> | ||
70 | + <span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17443"></span> | ||
71 | + <span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17445"></span> | ||
72 | + </div> | ||
73 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
74 | + <div class="img-box"> | ||
75 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/10.jpg"> | ||
76 | + <a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a> | ||
77 | + <a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_1')), ENT_QUOTES, 'UTF-8').'"></a> | ||
78 | + </div> | ||
79 | + <div class="img-box"> | ||
80 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/11.jpg"> | ||
81 | + <span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17463"></span> | ||
82 | + <span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17451"></span> | ||
83 | + </div> | ||
84 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
85 | + <div class="img-box"> | ||
86 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/12.jpg"> | ||
87 | + <a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_2')), ENT_QUOTES, 'UTF-8').'"></a> | ||
88 | + <a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_3')), ENT_QUOTES, 'UTF-8').'"></a> | ||
89 | + </div> | ||
90 | + <div class="img-box"> | ||
91 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/13.jpg"> | ||
92 | + <span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17461"></span> | ||
93 | + <span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17459"></span> | ||
94 | + </div> | ||
95 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
96 | + <div class="img-box"> | ||
97 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/14.jpg"> | ||
98 | + <a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_4')), ENT_QUOTES, 'UTF-8').'"></a> | ||
99 | + <a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_5')), ENT_QUOTES, 'UTF-8').'"></a> | ||
100 | + </div> | ||
101 | + <div class="img-box"> | ||
102 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/15.jpg"> | ||
103 | + <span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17453"></span> | ||
104 | + <span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17455"></span> | ||
105 | + </div> | ||
106 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
107 | + <div class="img-box"> | ||
108 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/16.jpg"> | ||
109 | + <a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_6')), ENT_QUOTES, 'UTF-8').'"></a> | ||
110 | + </div> | ||
111 | + <div class="img-box"> | ||
112 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/17.jpg"> | ||
113 | + <span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17449"></span> | ||
114 | + </div> | ||
115 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg"> | ||
116 | + | ||
117 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-1.jpg"> | ||
118 | + <div class="img-box"> | ||
119 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-2.jpg"> | ||
120 | + <a class="show-more" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_help')), ENT_QUOTES, 'UTF-8').'"></a> | ||
121 | + </div> | ||
122 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-3.jpg"> | ||
123 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-2.jpg"> | ||
124 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-1-a.jpg"> | ||
125 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-2-a.jpg"> | ||
126 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-3-a.jpg"> | ||
127 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/26-a.jpg"> | ||
128 | + <img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/27-a.jpg"> | ||
129 | + </div> | ||
130 | + <script type="text/javascript" src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/js/jquery.min.js"></script> | ||
131 | + <script type="text/javascript" src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/js/newuser/coupon2.js"></script> | ||
132 | +</body> | ||
133 | +</html>'; | ||
134 | +} | ||
135 | +?> |

36.4 KB

35.3 KB

8.16 KB

34.9 KB

42.4 KB

52.9 KB

77.4 KB

47.7 KB
@@ -23,11 +23,11 @@ | @@ -23,11 +23,11 @@ | ||
23 | <div id="coupon-container" param="{{activityId}}" isLogged="{{isLogged}}"> | 23 | <div id="coupon-container" param="{{activityId}}" isLogged="{{isLogged}}"> |
24 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/01.jpg"> | 24 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/01.jpg"> |
25 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/02.jpg"> | 25 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/02.jpg"> |
26 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/03.jpg"> | 26 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/03-a.jpg"> |
27 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-1.jpg"> | 27 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-1.jpg"> |
28 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/04.jpg"> | 28 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/04-a.jpg"> |
29 | <div class="img-box"> | 29 | <div class="img-box"> |
30 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/05.jpg"> | 30 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/05-a.jpg"> |
31 | <a class="href href-right" href="{{url_yohope}}"></a> | 31 | <a class="href href-right" href="{{url_yohope}}"></a> |
32 | </div> | 32 | </div> |
33 | <div class="img-box"> | 33 | <div class="img-box"> |
@@ -98,11 +98,11 @@ | @@ -98,11 +98,11 @@ | ||
98 | </div> | 98 | </div> |
99 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/24-3.jpg"> | 99 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/24-3.jpg"> |
100 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-2.jpg"> | 100 | <img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-2.jpg"> |
101 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-1.jpg"> | ||
102 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-2.jpg"> | ||
103 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-3.jpg"> | ||
104 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/26.jpg"> | ||
105 | - <img src="{{jsUrl}}/cuxiao/img/newuser/160107/27.jpg"> | 101 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-1-a.jpg"> |
102 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-2-a.jpg"> | ||
103 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-3-a.jpg"> | ||
104 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/26-a.jpg"> | ||
105 | + <img src="{{jsUrl}}/cuxiao/img/newuser/160107/27-a.jpg"> | ||
106 | </div> | 106 | </div> |
107 | <script type="text/javascript" src="{{jsUrl}}/cuxiao/js/jquery.min.js"></script> | 107 | <script type="text/javascript" src="{{jsUrl}}/cuxiao/js/jquery.min.js"></script> |
108 | <script type="text/javascript" src="{{jsUrl}}/cuxiao/js/newuser/coupon2.js"></script> | 108 | <script type="text/javascript" src="{{jsUrl}}/cuxiao/js/newuser/coupon2.js"></script> |
yaf/Hood/Action.php
0 → 100644
1 | +<?php | ||
2 | +namespace Hood; | ||
3 | + | ||
4 | +use Yaf\Controller_Abstract; | ||
5 | +use Hood\Helper\View as hoodView; | ||
6 | +use Yaf; | ||
7 | +use Hood\Validator as hoodValidator; | ||
8 | + | ||
9 | +class Action extends Controller_Abstract | ||
10 | +{ | ||
11 | + private $_viewLink = array(); | ||
12 | + | ||
13 | + private $_viewScript = array(); | ||
14 | + | ||
15 | + private $_headTitle; | ||
16 | + | ||
17 | + private $_headmeta; | ||
18 | + | ||
19 | + /** | ||
20 | + * Meta | ||
21 | + * @return \Hood\Helper\View\Meta | ||
22 | + */ | ||
23 | + public function _headMeta() | ||
24 | + { | ||
25 | + if (empty($this->_headmeta)) { | ||
26 | + $this->_headmeta = new hoodView\Meta(); | ||
27 | + $this->getView()->assign("_headmeta", $this->_headmeta); | ||
28 | + } | ||
29 | + return $this->_headmeta; | ||
30 | + } | ||
31 | + | ||
32 | + | ||
33 | + /** | ||
34 | + * Script | ||
35 | + * @return \Hood\Helper\View\Script | ||
36 | + */ | ||
37 | + public function _viewScript($scriptName = '_headScript') | ||
38 | + { | ||
39 | + if (!isset($this->_viewScript[$scriptName])) { | ||
40 | + $this->_viewScript[$scriptName] = new hoodView\Script(); | ||
41 | + $this->getView()->assign($scriptName, $this->_viewScript[$scriptName]); | ||
42 | + } | ||
43 | + return $this->_viewScript[$scriptName]; | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * | ||
48 | + * @return \Hood\Helper\View\Link | ||
49 | + */ | ||
50 | + public function _viewLink($linkName = '_headLink') | ||
51 | + { | ||
52 | + if (!isset($this->_viewLink[$linkName])) { | ||
53 | + $this->_viewLink[$linkName] = new hoodView\Link(); | ||
54 | + $this->getView()->assign($linkName, $this->_viewLink[$linkName]); | ||
55 | + } | ||
56 | + return $this->_viewLink[$linkName]; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Title | ||
61 | + * @return \Hood\Helper\View\Title | ||
62 | + */ | ||
63 | + public function _headTitle($title) | ||
64 | + { | ||
65 | + if (empty($this->_headTitle)) { | ||
66 | + $this->_headTitle = new hoodView\Title(); | ||
67 | + $this->getView()->assign("_headTitle", $this->_headTitle); | ||
68 | + } | ||
69 | + return $this->_headTitle->headTitle($title); | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * js 跳转 并 提示 | ||
74 | + * | ||
75 | + * @param String $url | ||
76 | + * @param String $expression | ||
77 | + */ | ||
78 | + protected function helpJsRedirect($message = '', $script = "history.back();") | ||
79 | + { | ||
80 | + $html = ''; | ||
81 | + if (!empty($message)) { | ||
82 | + header("content-type: text/html; charset=utf-8"); | ||
83 | + $message = str_replace("\n", "\\n", $message); | ||
84 | + $html .= "<script language=\"javascript\">"; | ||
85 | + $html .= "alert(\"{$message}\");"; | ||
86 | + $html .= "</script>"; | ||
87 | + } | ||
88 | + $html .= "<script language=\"javascript\">"; | ||
89 | + $html .= $script; | ||
90 | + $html .= "</script>"; | ||
91 | + die($html); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * 跳转 | ||
96 | + * @param String $url | ||
97 | + */ | ||
98 | + protected function helpLocation($url) | ||
99 | + { | ||
100 | + header('Location: ' . $url); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * refresh跳转 | ||
105 | + * @param $url | ||
106 | + * @param string $message | ||
107 | + */ | ||
108 | + protected function helpRefresh($url, $message = '') | ||
109 | + { | ||
110 | + $html = ''; | ||
111 | + if (!empty($message)) { | ||
112 | + header("content-type: text/html; charset=utf-8"); | ||
113 | + $message = str_replace("\n", "\\n", $message); | ||
114 | + $html .= "<script language=\"javascript\">"; | ||
115 | + $html .= "alert(\"{$message}\");"; | ||
116 | + $html .= "</script>"; | ||
117 | + } | ||
118 | + $html .= "<script language=\"javascript\">"; | ||
119 | + $html .= "window.location.href='{$url}';"; | ||
120 | + $html .= "</script>"; | ||
121 | + echo $html; | ||
122 | + } | ||
123 | + | ||
124 | + /** | ||
125 | + * JSON输出 | ||
126 | + * @param $code | ||
127 | + * @param null $message | ||
128 | + * @param null $data | ||
129 | + */ | ||
130 | + protected function helpJsonResult($code, $message = null, $data = null) | ||
131 | + { | ||
132 | + header('Content-type: application/json'); | ||
133 | + echo json_encode(array('code' => $code, 'message' => $message, 'data' => $data)); | ||
134 | + exit(); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * JSON输出 | ||
139 | + * @param array $data | ||
140 | + */ | ||
141 | + protected function helpJson(array $data) | ||
142 | + { | ||
143 | + header('Content-type: application/json'); | ||
144 | + echo json_encode($data); | ||
145 | + exit(); | ||
146 | + } | ||
147 | + | ||
148 | + /** | ||
149 | + * JSONP Callback输出,用于远程调用 | ||
150 | + * @param $callbackString | ||
151 | + * @param $code | ||
152 | + * @param null $message | ||
153 | + * @param null $data | ||
154 | + */ | ||
155 | + protected function helpJsonCallbackResult($callbackString, $code, $message = null, $data = null) | ||
156 | + { | ||
157 | + header('Content-type: application/json'); | ||
158 | + echo $callbackString . "("; | ||
159 | + echo json_encode(array('code' => $code, 'message' => $message, 'data' => $data)); | ||
160 | + echo ")"; | ||
161 | + exit(); | ||
162 | + } | ||
163 | + | ||
164 | + | ||
165 | + /** | ||
166 | + * @param string $namespace | ||
167 | + * @return \Hood\Core\Session\SessionNamespace | ||
168 | + */ | ||
169 | + public function session($namespace = 'session_default', $sessionName = null) | ||
170 | + { | ||
171 | + return Session::start($namespace, $sessionName); | ||
172 | + } | ||
173 | + | ||
174 | + /** | ||
175 | + * 数据校验 | ||
176 | + * @param array $data | ||
177 | + * @param array $rules | ||
178 | + * @param array $messagesAttribute | ||
179 | + * @return Helper\Validation\Validator | ||
180 | + */ | ||
181 | + public function validator(array $data, array $rules, array $messagesAttribute = array()) | ||
182 | + { | ||
183 | + return hoodValidator::make($data, $rules, $messagesAttribute); | ||
184 | + } | ||
185 | +} |
yaf/Hood/Cache.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/9 | ||
6 | + * Time: 下午7:40 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood; | ||
10 | + | ||
11 | +use Hood\Cache\Memcached as Mcd; | ||
12 | +use Hood\Cache\Memcache as Mc; | ||
13 | +use Hood\Cache\CacheRedis; | ||
14 | +use Hood\Cache\FileCache; | ||
15 | + | ||
16 | +class Cache | ||
17 | +{ | ||
18 | + /** | ||
19 | + * | ||
20 | + * @param null $node | ||
21 | + * @return Mcd | ||
22 | + */ | ||
23 | + static public function Memcached($node = null, $childNode = 'hosts') | ||
24 | + { | ||
25 | + $mc = new Mcd(); | ||
26 | + $mc->setNode($node)->setChildNodes($childNode); | ||
27 | + return $mc; | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * @param null $node | ||
32 | + * @param string $childNode | ||
33 | + * @return Mc | ||
34 | + */ | ||
35 | + static public function Memcache($node = null, $childNode = 'hosts') | ||
36 | + { | ||
37 | + $mc = new Mc(); | ||
38 | + $mc->setNode($node)->setChildNodes($childNode); | ||
39 | + return $mc; | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * @return CacheRedis | ||
44 | + */ | ||
45 | + static public function Redis() | ||
46 | + { | ||
47 | + $servers = array(); | ||
48 | + $persistentID = ''; | ||
49 | + return new CacheRedis($servers, $persistentID); | ||
50 | + } | ||
51 | + | ||
52 | + | ||
53 | + /** | ||
54 | + * | ||
55 | + * @param null $childNode | ||
56 | + * @param string $node | ||
57 | + * @param null $cachePath | ||
58 | + * @return FileCache | ||
59 | + */ | ||
60 | + static public function File($childNode = null, $node = 'cache', $cachePath = null) | ||
61 | + { | ||
62 | + return new FileCache($childNode, $node, $cachePath); | ||
63 | + } | ||
64 | +} |
yaf/Hood/Cache/CacheInterface.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/9 | ||
6 | + * Time: 下午10:35 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache; | ||
10 | + | ||
11 | +interface CacheInterface | ||
12 | +{ | ||
13 | + /** | ||
14 | + * @param $key | ||
15 | + * @return mixed | ||
16 | + */ | ||
17 | + public function get($key); | ||
18 | + | ||
19 | + /** | ||
20 | + * @param $key | ||
21 | + * @param $value | ||
22 | + * @param $minutes | ||
23 | + * @return mixed | ||
24 | + */ | ||
25 | + public function add($key, $value, $minutes); | ||
26 | + | ||
27 | + /** | ||
28 | + * @param $key | ||
29 | + * @param $value | ||
30 | + * @param $minutes | ||
31 | + * @return mixed | ||
32 | + */ | ||
33 | + public function set($key, $value, $minutes); | ||
34 | + | ||
35 | + /** | ||
36 | + * @param $key | ||
37 | + * @param int $value | ||
38 | + * @return mixed | ||
39 | + */ | ||
40 | + public function increment($key, $value = 1); | ||
41 | + | ||
42 | + /** | ||
43 | + * @param $key | ||
44 | + * @param int $value | ||
45 | + * @return mixed | ||
46 | + */ | ||
47 | + public function decrement($key, $value = 1); | ||
48 | + | ||
49 | + /** | ||
50 | + * @param $key | ||
51 | + * @return mixed | ||
52 | + */ | ||
53 | + public function delete($key); | ||
54 | + | ||
55 | + /** | ||
56 | + * @param $tagName | ||
57 | + * @return $this | ||
58 | + */ | ||
59 | + public function tag($tagName); | ||
60 | +} |
yaf/Hood/Cache/CacheRedis.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/11/23 | ||
6 | + * Time: 上午1:39 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache; | ||
10 | + | ||
11 | +use \Redis; | ||
12 | + | ||
13 | +class CacheRedis | ||
14 | +{ | ||
15 | + | ||
16 | + /** | ||
17 | + * | ||
18 | + * Enter description here ... | ||
19 | + * @var Redis | ||
20 | + */ | ||
21 | + private $redis; | ||
22 | + | ||
23 | + private $timeout = 2.5; | ||
24 | + | ||
25 | + public function __construct(array $servers, $persistentID = '') | ||
26 | + { | ||
27 | + if (empty($servers)) { | ||
28 | + throw new Q_Cache_Exception('redis server is null.'); | ||
29 | + } | ||
30 | + $this->redis = new Redis(); | ||
31 | + $this->redis->connect($servers['host'], $servers['port'], $this->timeout); | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * | ||
36 | + * 返回key所关联的字符串值,如果key不存在则返回特殊值nil。 | ||
37 | + * @param String $key | ||
38 | + * @return Mixed or nil | ||
39 | + */ | ||
40 | + public function get($key) | ||
41 | + { | ||
42 | + assert(is_string($key)); | ||
43 | + return $this->redis->get($key); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * | ||
48 | + * 将字符串值value关联到key | ||
49 | + * @param String $key | ||
50 | + * @param Mixed $val | ||
51 | + * @return bool | ||
52 | + */ | ||
53 | + public function set($key, $val) | ||
54 | + { | ||
55 | + assert(is_string($key)); | ||
56 | + return $this->redis->set($key, $val); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * | ||
61 | + * 同时设置一个或多个key-value对。 | ||
62 | + * @param array $keys | ||
63 | + * @return bool | ||
64 | + */ | ||
65 | + public function mset(array $keys) | ||
66 | + { | ||
67 | + return $this->redis->mset($keys); | ||
68 | + } | ||
69 | + | ||
70 | + /** | ||
71 | + * | ||
72 | + * 返回所有(一个或多个)给定key的值.如果某个指定key不存在,那么返回特殊值nil。因此,该命令永不失败。 | ||
73 | + * @param array $keys | ||
74 | + * @return Mixed | ||
75 | + */ | ||
76 | + public function mget(array $keys) | ||
77 | + { | ||
78 | + return $this->redis->mget($keys); | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * | ||
83 | + * 返回key中字符串值的子字符串,字符串的截取范围由start和end两个偏移量决定(包括start和end在内)。 | ||
84 | + * 负数偏移量表示从字符串最后开始计数,-1表示最后一个字符,-2表示倒数第二个,以此类推 | ||
85 | + * @param String $key | ||
86 | + * @param Integer $start | ||
87 | + * @param Integer $end | ||
88 | + * @return String | ||
89 | + */ | ||
90 | + public function getRange($key, $start, $end) | ||
91 | + { | ||
92 | + assert(is_string($key)); | ||
93 | + return $this->redis->getRange($key, $start, $end); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * | ||
98 | + * 删除数据 ( 返回删除个数 ) | ||
99 | + * @param String $key | ||
100 | + * @return bool | ||
101 | + */ | ||
102 | + public function del($key) | ||
103 | + { | ||
104 | + assert(is_string($key)); | ||
105 | + return $this->redis->del($key); | ||
106 | + } | ||
107 | + | ||
108 | + /** | ||
109 | + * 查找符合给定模式的key。 | ||
110 | + * | ||
111 | + * 可以使用正则 | ||
112 | + * ========================================= | ||
113 | + * *命中数据库中所有key | ||
114 | + * h?llo命中hello, hallo and hxllo等 | ||
115 | + * h*llo命中hllo和heeeeello等 | ||
116 | + * h[ae]llo命中hello和hallo,但不命中hillo | ||
117 | + * ========================================= | ||
118 | + * KEYS的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(set)结构。 | ||
119 | + * @param String $keys | ||
120 | + * @return Mixed | ||
121 | + */ | ||
122 | + public function keys($keys) | ||
123 | + { | ||
124 | + return $this->redis->keys($keys); | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * | ||
129 | + * 选择数据库 | ||
130 | + * @param String $db | ||
131 | + * @return bool | ||
132 | + */ | ||
133 | + public function select($db = 9) | ||
134 | + { | ||
135 | + return $this->redis->select($db); | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * | ||
140 | + * 获取 hash 集合中的键值 | ||
141 | + * @param String $hashName | ||
142 | + * @param String $key | ||
143 | + * @param Mixed $val | ||
144 | + * @return Mixed | ||
145 | + */ | ||
146 | + public function hget($hashName, $key, $val) | ||
147 | + { | ||
148 | + assert(is_string($hashName)) && assert(is_string($key)); | ||
149 | + return $this->redis->hget($hashName, $key, $val); | ||
150 | + } | ||
151 | + | ||
152 | + /** | ||
153 | + * | ||
154 | + * 将哈希表key中的域field的值设为value。 | ||
155 | + * @param String $hashName | ||
156 | + * @param String $key | ||
157 | + * @param Mixed $val | ||
158 | + * @return bool | ||
159 | + */ | ||
160 | + public function hset($hashName, $key, $val) | ||
161 | + { | ||
162 | + assert(is_string($hashName)) && assert(is_string($key)); | ||
163 | + return $this->redis->hset($hashName, $key, $val); | ||
164 | + } | ||
165 | + | ||
166 | + /** | ||
167 | + * | ||
168 | + * 排序 | ||
169 | + * | ||
170 | + * @param String $key | ||
171 | + * @param array $options | ||
172 | + * 'by' => 'some_pattern_*', | ||
173 | + * 'limit' => array(0, 1), | ||
174 | + * 'get' => 'some_other_pattern_*' or an array of patterns, | ||
175 | + * 'sort' => 'asc' or 'desc', | ||
176 | + * 'alpha' => TRUE, | ||
177 | + * 'store' => 'external-key' | ||
178 | + * @return array | ||
179 | + */ | ||
180 | + public function sort($key, array $options = array()) | ||
181 | + { | ||
182 | + assert(is_string($key)); | ||
183 | + return $this->redis->sort($key, $options); | ||
184 | + } | ||
185 | + | ||
186 | + /** | ||
187 | + * | ||
188 | + * 从当前数据库中随机返回(不删除)一个key。 | ||
189 | + * @return String or Mixed | ||
190 | + */ | ||
191 | + public function randomkey() | ||
192 | + { | ||
193 | + return $this->redis->randomKey(); | ||
194 | + } | ||
195 | + | ||
196 | + /** | ||
197 | + * | ||
198 | + * 返回给定key的剩余生存时间(time to live)(以秒为单位)。 | ||
199 | + * @param String $key | ||
200 | + * @return Integer | ||
201 | + */ | ||
202 | + public function ttl($key) | ||
203 | + { | ||
204 | + assert(is_string($key)); | ||
205 | + return $this->redis->ttl($key); | ||
206 | + } | ||
207 | + | ||
208 | + /** | ||
209 | + * | ||
210 | + * 检查给定key是否存在 | ||
211 | + * @param String $key | ||
212 | + * @return bool | ||
213 | + */ | ||
214 | + public function exists($key) | ||
215 | + { | ||
216 | + assert(is_string($key)); | ||
217 | + return $this->redis->exists($key); | ||
218 | + } | ||
219 | + | ||
220 | + /** | ||
221 | + * | ||
222 | + * 移动key 到另外一个数据库 | ||
223 | + * @param String $key | ||
224 | + * @param Integer $dbName | ||
225 | + * @return bool | ||
226 | + */ | ||
227 | + public function move($key, $dbName) | ||
228 | + { | ||
229 | + assert(is_string($key)); | ||
230 | + return $this->redis->move($key, $dbName); | ||
231 | + } | ||
232 | + | ||
233 | + /** | ||
234 | + * | ||
235 | + * 将key改名为newkey | ||
236 | + * @param String $key | ||
237 | + * @param String $newKey | ||
238 | + * @return bool | ||
239 | + */ | ||
240 | + public function rename($key, $newKey) | ||
241 | + { | ||
242 | + assert(is_string($key)) && assert(is_string($newKey)); | ||
243 | + return $this->redis->rename($key, $newKey); | ||
244 | + } | ||
245 | + | ||
246 | + /** | ||
247 | + * | ||
248 | + * 返回key所储存的值的类型 | ||
249 | + * @param String $key | ||
250 | + * @return Mixed | ||
251 | + * ================================ | ||
252 | + * none(key不存在) string(字符串) list(列表) set(集合) zset(有序集) hash(哈希表) | ||
253 | + * ================================ | ||
254 | + */ | ||
255 | + public function type($key) | ||
256 | + { | ||
257 | + return $this->redis->type($key); | ||
258 | + } | ||
259 | + | ||
260 | + /** | ||
261 | + * | ||
262 | + * 为给定key设置生存时间 | ||
263 | + * @param String $key | ||
264 | + * @param Integer $expire | ||
265 | + * @return bool | ||
266 | + */ | ||
267 | + public function setTimeout($key, $expire) | ||
268 | + { | ||
269 | + assert(is_string($key)) && assert(is_int($expire)); | ||
270 | + return $this->redis->setTimeout($key, $expire); | ||
271 | + } | ||
272 | + | ||
273 | + /** | ||
274 | + * | ||
275 | + * 不同在于EXPIREAT命令接受的时间参数是UNIX时间戳(unix timestamp)。 | ||
276 | + * @param String $key | ||
277 | + * @param Integer $expire | ||
278 | + * @return bool | ||
279 | + */ | ||
280 | + public function expireAt($key, $expire) | ||
281 | + { | ||
282 | + assert(is_string($key)) && assert(is_int($expire)); | ||
283 | + return $this->redis->expireAt($key, $expire); | ||
284 | + } | ||
285 | + | ||
286 | + /** | ||
287 | + * | ||
288 | + * 移除给定key的生存时间 | ||
289 | + * @param String $key | ||
290 | + * @return bool | ||
291 | + */ | ||
292 | + public function persist($key) | ||
293 | + { | ||
294 | + assert(is_string($key)); | ||
295 | + return $this->redis->persist($key); | ||
296 | + } | ||
297 | + | ||
298 | + /** | ||
299 | + * | ||
300 | + * 将值value关联到key,并将key的生存时间设为seconds(以秒为单位) | ||
301 | + * @param String $key | ||
302 | + * @param Mixed $val | ||
303 | + * @param Integer $expire | ||
304 | + * @return bool | ||
305 | + */ | ||
306 | + public function setex($key, $val, $expire) | ||
307 | + { | ||
308 | + assert(is_string($key)) && assert(is_int($expire)); | ||
309 | + return $this->redis->setex($key, $expire, $val); | ||
310 | + } | ||
311 | + | ||
312 | + /** | ||
313 | + * | ||
314 | + * 如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后 | ||
315 | + * @param String $key | ||
316 | + * @param Mixed $val | ||
317 | + * @return bool | ||
318 | + */ | ||
319 | + public function append($key, $val) | ||
320 | + { | ||
321 | + assert(is_string($key)); | ||
322 | + return $this->redis->append($key, $val); | ||
323 | + } | ||
324 | + | ||
325 | + /** | ||
326 | + * | ||
327 | + * 将给定key的值设为value,并返回key的旧值 | ||
328 | + * @param String $key | ||
329 | + * @param Mixed $val | ||
330 | + * @return Mixed | ||
331 | + */ | ||
332 | + public function getSet($key, $val) | ||
333 | + { | ||
334 | + assert(is_string($key)); | ||
335 | + return $this->redis->getSet($key, $val); | ||
336 | + } | ||
337 | + | ||
338 | + /** | ||
339 | + * | ||
340 | + * 返回key所储存的字符串值的长度 | ||
341 | + * @param String $key | ||
342 | + * @return integer | ||
343 | + */ | ||
344 | + public function strlen($key) | ||
345 | + { | ||
346 | + return $this->redis->strlen($key); | ||
347 | + } | ||
348 | + | ||
349 | + /** | ||
350 | + * | ||
351 | + * 将key中储存的数字值减一 | ||
352 | + * @param String $key | ||
353 | + * @return Integer | ||
354 | + */ | ||
355 | + public function decr($key) | ||
356 | + { | ||
357 | + assert(is_string($key)); | ||
358 | + return $this->redis->decr($key); | ||
359 | + } | ||
360 | + | ||
361 | + /** | ||
362 | + * | ||
363 | + * 将key所储存的值减去减量decrement。 | ||
364 | + * @param String $key | ||
365 | + * @param Integer $value | ||
366 | + * @return intger | ||
367 | + */ | ||
368 | + public function decrBy($key, $value = 1) | ||
369 | + { | ||
370 | + assert(is_string($key)) && assert(is_int($value)); | ||
371 | + return $this->redis->decrBy($key, $value); | ||
372 | + } | ||
373 | + | ||
374 | + /** | ||
375 | + * | ||
376 | + * 将key中储存的数字值增一 | ||
377 | + * @param String $key | ||
378 | + * @param Integer $val | ||
379 | + * @return Integer | ||
380 | + */ | ||
381 | + public function incrBy($key, $val = 1) | ||
382 | + { | ||
383 | + return $this->redis->incrBy($key, $val); | ||
384 | + } | ||
385 | + | ||
386 | + /** | ||
387 | + * | ||
388 | + * 同时将多个field - value(域-值)对设置到哈希表key中 | ||
389 | + * @param String $key | ||
390 | + * @param array $vals | ||
391 | + * @return bool | ||
392 | + */ | ||
393 | + public function hMset($hashKey, array $keys) | ||
394 | + { | ||
395 | + assert(is_string($hashKey)); | ||
396 | + return $this->redis->hMset($hashKey, $keys); | ||
397 | + } | ||
398 | + | ||
399 | + /** | ||
400 | + * | ||
401 | + * 返回哈希表key中,一个或多个给定域的值 | ||
402 | + * @param String $hashKey | ||
403 | + * @param array $keys | ||
404 | + * @return Mixed | ||
405 | + */ | ||
406 | + public function hmGet($hashKey, array $keys) | ||
407 | + { | ||
408 | + assert(is_string($hashKey)); | ||
409 | + return $this->redis->hmGet($hashKey, $keys); | ||
410 | + } | ||
411 | + | ||
412 | + /** | ||
413 | + * | ||
414 | + * 返回哈希表key中,所有的域和值 | ||
415 | + * @param String $hashKey | ||
416 | + * @return Mixed | ||
417 | + */ | ||
418 | + public function hGetAll($hashKey) | ||
419 | + { | ||
420 | + assert(is_string($hashKey)); | ||
421 | + return $this->redis->hGetAll($hashKey); | ||
422 | + } | ||
423 | + | ||
424 | + /** | ||
425 | + * | ||
426 | + * 删除哈希表key中的一个或多个指定域 | ||
427 | + * @param String $hashKey | ||
428 | + * @return bool | ||
429 | + */ | ||
430 | + public function hDel($hashKey, $hashKey2 = null, $hashKeyN = null) | ||
431 | + { | ||
432 | + $this->redis->hDel($hashKey, $hashKey2, $hashKeyN); | ||
433 | + } | ||
434 | + | ||
435 | + /** | ||
436 | + * | ||
437 | + * 返回哈希表key中域的数量 | ||
438 | + * @param String $hashKey | ||
439 | + * @return Integer | ||
440 | + */ | ||
441 | + public function hLen($hashKey) | ||
442 | + { | ||
443 | + return $this->redis->hLen($hashKey); | ||
444 | + } | ||
445 | + | ||
446 | + /** | ||
447 | + * | ||
448 | + * 查看哈希表key中,给定域field是否存在 | ||
449 | + * @param String $hashKey | ||
450 | + * @return bool | ||
451 | + */ | ||
452 | + public function hExists($key, $hashKey) | ||
453 | + { | ||
454 | + return $this->redis->hExists($key, $hashKey); | ||
455 | + } | ||
456 | + | ||
457 | + /** | ||
458 | + * | ||
459 | + * 为哈希表key中的域field的值加上增量increment。 | ||
460 | + * @param String $hashKey | ||
461 | + * @param String $key | ||
462 | + * @param Integer $member | ||
463 | + * @return Integer | ||
464 | + */ | ||
465 | + public function hincrby($hashKey, $key, $member) | ||
466 | + { | ||
467 | + return $this->redis->hIncrBy($hashKey, $key, $member); | ||
468 | + } | ||
469 | + | ||
470 | + /** | ||
471 | + * | ||
472 | + * 返回哈希表key中的所有域 | ||
473 | + * @param String $hashKey | ||
474 | + * @return array | ||
475 | + */ | ||
476 | + public function hKeys($hashKey) | ||
477 | + { | ||
478 | + return $this->redis->hKeys($hashKey); | ||
479 | + } | ||
480 | + | ||
481 | + /** | ||
482 | + * | ||
483 | + * 返回哈希表key中的所有值 | ||
484 | + * @param String $hashKey | ||
485 | + * @return Array | ||
486 | + */ | ||
487 | + public function hVals($hashKey) | ||
488 | + { | ||
489 | + return $this->redis->hVals($hashKey); | ||
490 | + } | ||
491 | + ########################### | ||
492 | + # 表 List | ||
493 | + ########################### | ||
494 | + /** | ||
495 | + * | ||
496 | + * 将值value插入到列表key的表头 | ||
497 | + * @param String $key | ||
498 | + * @param Mixed $value | ||
499 | + * @return bool | ||
500 | + */ | ||
501 | + public function lPush($key, $value) | ||
502 | + { | ||
503 | + assert(is_string($key)); | ||
504 | + return $this->redis->lPush($key, $value); | ||
505 | + } | ||
506 | + | ||
507 | + /** | ||
508 | + * | ||
509 | + * 将值value插入到列表key的表头,当且仅当key存在并且是一个列表 | ||
510 | + * @param String $key | ||
511 | + * @param Mixed $value | ||
512 | + * @return bool | ||
513 | + */ | ||
514 | + public function lPushx($key, $value) | ||
515 | + { | ||
516 | + assert(is_string($key)); | ||
517 | + return $this->redis->lPushx($key, $value); | ||
518 | + } | ||
519 | + | ||
520 | + /** | ||
521 | + * | ||
522 | + * 将值value插入到列表key的表尾 | ||
523 | + * @param String $key | ||
524 | + * @param Mixed $value | ||
525 | + * @return bool | ||
526 | + */ | ||
527 | + public function rPush($key, $value) | ||
528 | + { | ||
529 | + assert(is_string($key)); | ||
530 | + return $this->redis->rPush($key, $value); | ||
531 | + } | ||
532 | + | ||
533 | + /** | ||
534 | + * | ||
535 | + * 将值value插入到列表key的表尾,当且仅当key存在并且是一个列表 | ||
536 | + * @param String $key | ||
537 | + * @param Mixed $value | ||
538 | + * @return bool | ||
539 | + */ | ||
540 | + public function rPushx($key, $value) | ||
541 | + { | ||
542 | + assert(is_string($key)); | ||
543 | + return $this->redis->rPushx($key, $value); | ||
544 | + } | ||
545 | + | ||
546 | + /** | ||
547 | + * | ||
548 | + * 移除并返回列表key的头元素 | ||
549 | + * @param String $key | ||
550 | + * @return bool or nil | ||
551 | + */ | ||
552 | + public function lPop($key) | ||
553 | + { | ||
554 | + return $this->redis->lPop($key); | ||
555 | + } | ||
556 | + | ||
557 | + /** | ||
558 | + * | ||
559 | + * 移除并返回列表key的尾元素 | ||
560 | + * @param String $key | ||
561 | + * @return bool or nil | ||
562 | + */ | ||
563 | + public function rPop($key) | ||
564 | + { | ||
565 | + return $this->redis->rPop($key); | ||
566 | + } | ||
567 | + | ||
568 | + /** | ||
569 | + * | ||
570 | + * BLPOP是列表的阻塞式(blocking)弹出原语 | ||
571 | + * =================================== | ||
572 | + * 类似 Gearman 等待移除 | ||
573 | + * =================================== | ||
574 | + * @param array $keys | ||
575 | + * @param Integer $timeout | ||
576 | + * @return array | ||
577 | + */ | ||
578 | + public function blPop(array $keys, $timeout = 2) | ||
579 | + { | ||
580 | + return $this->redis->blPop($keys, (int)$timeout); | ||
581 | + } | ||
582 | + | ||
583 | + /** | ||
584 | + * | ||
585 | + * BRPOP是列表的阻塞式(blocking)弹出原语。 | ||
586 | + * =================================== | ||
587 | + * 类似 Gearman 等待移除 | ||
588 | + * =================================== | ||
589 | + * @param array $keys | ||
590 | + * @param Integer $timeout | ||
591 | + * | ||
592 | + */ | ||
593 | + public function brPop(array $keys, $timeout = 2) | ||
594 | + { | ||
595 | + return $this->redis->brPop($keys, (int)$timeout); | ||
596 | + } | ||
597 | + | ||
598 | + /** | ||
599 | + * TODO | ||
600 | + * 返回列表key的长度。 | ||
601 | + */ | ||
602 | + public function llen() | ||
603 | + { | ||
604 | + | ||
605 | + } | ||
606 | + | ||
607 | + /** | ||
608 | + * | ||
609 | + * 返回列表key中指定区间内的元素,区间以偏移量start和stop指定。 | ||
610 | + * @param String $key | ||
611 | + * @param Integer $start | ||
612 | + * @param Integer $end | ||
613 | + * @return array | ||
614 | + */ | ||
615 | + public function lRange($key, $start = 0, $end = 0) | ||
616 | + { | ||
617 | + return $this->redis->lRange($key, (int)$start, (int)$end); | ||
618 | + } | ||
619 | + | ||
620 | + /** | ||
621 | + * | ||
622 | + * 根据参数count的值,移除列表中与参数value相等的元素 | ||
623 | + * ============================================ | ||
624 | + * count的值可以是以下几种: | ||
625 | + * count > 0: 从表头开始向表尾搜索,移除与value相等的元素,数量为count | ||
626 | + * count < 0: 从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值 | ||
627 | + * count = 0: 移除表中所有与value相等的值 | ||
628 | + * ============================================ | ||
629 | + * @param String $key | ||
630 | + * @param String $value | ||
631 | + * @param Integer $count | ||
632 | + * @return Integer | ||
633 | + */ | ||
634 | + public function lRem($key, $value, $count) | ||
635 | + { | ||
636 | + $this->redis->lRem((string)$key, (string)$value, (int)$count); | ||
637 | + } | ||
638 | + | ||
639 | + /** | ||
640 | + * | ||
641 | + * 将列表key下标为index的元素的值甚至为value | ||
642 | + * (当index参数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误) | ||
643 | + * @param String $key | ||
644 | + * @param Integer $index | ||
645 | + * @param String $value | ||
646 | + * @return bool | ||
647 | + */ | ||
648 | + public function lSet($key, $index, $value) | ||
649 | + { | ||
650 | + return $this->redis->lSet((string)$key, (int)$index, (string)$value); | ||
651 | + } | ||
652 | + | ||
653 | + /** | ||
654 | + * | ||
655 | + * 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除 | ||
656 | + * @param String $key | ||
657 | + * @param Integer $start | ||
658 | + * @param Integer $stop | ||
659 | + * @return bool | ||
660 | + */ | ||
661 | + public function lTrim($key, $start, $stop) | ||
662 | + { | ||
663 | + return $this->redis->lTrim((string)$key, (int)$start, (int)$stop); | ||
664 | + } | ||
665 | + | ||
666 | + /** | ||
667 | + * | ||
668 | + * 返回列表key中,下标为index的元素 | ||
669 | + * @param String $key | ||
670 | + * @param Integer $index | ||
671 | + * @return bool or nil | ||
672 | + */ | ||
673 | + public function lGet($key, $index) | ||
674 | + { | ||
675 | + return $this->redis->lGet((string)$key, (int)$index); | ||
676 | + } | ||
677 | + | ||
678 | + ################################################################## | ||
679 | + # SET | ||
680 | + ################################################################## | ||
681 | + /** | ||
682 | + * | ||
683 | + * 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略 | ||
684 | + * @param String $key | ||
685 | + * @param Mixed $value | ||
686 | + * @return bool | ||
687 | + */ | ||
688 | + public function sAdd($skey, $value) | ||
689 | + { | ||
690 | + return $this->redis->sAdd($skey, $value); | ||
691 | + } | ||
692 | + | ||
693 | + /** | ||
694 | + * | ||
695 | + * ( 扩展 ) 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略 | ||
696 | + * @param String $key | ||
697 | + * @param Mixed $value | ||
698 | + * @param Integer $expiration | ||
699 | + * @return bool | ||
700 | + */ | ||
701 | + public function sAdd2($skey, $value, $expiration = 0) | ||
702 | + { | ||
703 | + $result = $this->redis->sAdd($skey, $value); | ||
704 | + $this->redis->setTimeout($skey, $expiration); | ||
705 | + return $result; | ||
706 | + } | ||
707 | + | ||
708 | + /** | ||
709 | + * | ||
710 | + * 移除集合key中的一个或多个member元素,不存在的member元素会被忽略 | ||
711 | + * @param String $key | ||
712 | + * @param String $member | ||
713 | + * @return bool | ||
714 | + */ | ||
715 | + public function sRem($skey, $member) | ||
716 | + { | ||
717 | + return $this->redis->sRem((string)$skey, (string)$member); | ||
718 | + } | ||
719 | + | ||
720 | + /** | ||
721 | + * | ||
722 | + * 返回集合key中的所有成员 | ||
723 | + * @param String $key | ||
724 | + * @return array | ||
725 | + */ | ||
726 | + public function sMembers($skey) | ||
727 | + { | ||
728 | + return $this->redis->sMembers((string)$skey); | ||
729 | + } | ||
730 | + | ||
731 | + /** | ||
732 | + * | ||
733 | + * 判断member元素是否是集合key的成员 | ||
734 | + * @param String $key | ||
735 | + * @param String $value | ||
736 | + */ | ||
737 | + public function sIsMember($skey, $value) | ||
738 | + { | ||
739 | + return $this->redis->sIsMember((string)$skey, (string)$value); | ||
740 | + } | ||
741 | + | ||
742 | + /** | ||
743 | + * | ||
744 | + * 返回集合key的基数(集合中元素的数量) | ||
745 | + * @param String $skey | ||
746 | + * @return Integer | ||
747 | + */ | ||
748 | + public function sCard($skey) | ||
749 | + { | ||
750 | + return $this->redis->sCard((string)$skey); | ||
751 | + } | ||
752 | + | ||
753 | + /** | ||
754 | + * | ||
755 | + * 将member元素从source集合移动到destination集合 | ||
756 | + * @param String $srcKey | ||
757 | + * @param String $dstKey | ||
758 | + * @param String $member | ||
759 | + * @return bool | ||
760 | + */ | ||
761 | + public function sMove($srcKey, $dstKey, $member) | ||
762 | + { | ||
763 | + return $this->redis->sMove((string)$srcKey, (string)$dstKey, (string)$member); | ||
764 | + } | ||
765 | + | ||
766 | + /** | ||
767 | + * | ||
768 | + * 移除并返回集合中的一个随机元素 | ||
769 | + * @param String $skey | ||
770 | + * @return string or bool | ||
771 | + */ | ||
772 | + public function sPop($skey) | ||
773 | + { | ||
774 | + return $this->redis->sPop((string)$skey); | ||
775 | + } | ||
776 | + | ||
777 | + /** | ||
778 | + * | ||
779 | + * 返回集合中的一个随机元素。 | ||
780 | + * @param String $skey | ||
781 | + * @return array or nil | ||
782 | + */ | ||
783 | + public function sRandMember($skey) | ||
784 | + { | ||
785 | + return $this->redis->sRandMember((string)$skey); | ||
786 | + } | ||
787 | + | ||
788 | + ######################################################## | ||
789 | + # 有序集(Sorted Set) | ||
790 | + ######################################################## | ||
791 | + /** | ||
792 | + * | ||
793 | + * 将一个或多个member元素及其score值加入到有序集key当中 | ||
794 | + * @param String $zKey | ||
795 | + * @param Integer $score | ||
796 | + * @param String $value | ||
797 | + * @return Integer | ||
798 | + */ | ||
799 | + public function zAdd($zKey, $score, $value) | ||
800 | + { | ||
801 | + assert(is_string($zKey)) && assert(is_int($score)) && assert(is_string($value)); | ||
802 | + return $this->redis->zAdd($zKey, $score, $value); | ||
803 | + } | ||
804 | + | ||
805 | + /** | ||
806 | + * | ||
807 | + * 移除有序集key中的一个或多个成员,不存在的成员将被忽略 | ||
808 | + * @param String $zKey | ||
809 | + * @param String $member | ||
810 | + * @return Integer | ||
811 | + */ | ||
812 | + public function zRem($zKey, $member) | ||
813 | + { | ||
814 | + return $this->redis->zRem((string)$zKey, (string)$member); | ||
815 | + } | ||
816 | + | ||
817 | + /** | ||
818 | + * | ||
819 | + * 返回有序集key的基数 | ||
820 | + * @param String $zKey | ||
821 | + * @return Integer | ||
822 | + */ | ||
823 | + public function zSize($zKey) | ||
824 | + { | ||
825 | + return $this->redis->zSize((string)$zKey); | ||
826 | + } | ||
827 | + | ||
828 | + /** | ||
829 | + * | ||
830 | + * 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员 | ||
831 | + * @param String $zKey | ||
832 | + * @param Integer $start | ||
833 | + * @param Integer $end | ||
834 | + * @return array | ||
835 | + */ | ||
836 | + public function zCount($zKey, $start, $end) | ||
837 | + { | ||
838 | + return $this->redis->zCount($zKey, $start, $end); | ||
839 | + } | ||
840 | + | ||
841 | + /** | ||
842 | + * | ||
843 | + * 返回有序集key中,成员member的score值 | ||
844 | + * @param String $zKey | ||
845 | + * @param String $member | ||
846 | + * @return String | ||
847 | + */ | ||
848 | + public function zScore($zKey, $member) | ||
849 | + { | ||
850 | + return $this->redis->zScore($zKey, $member); | ||
851 | + } | ||
852 | + | ||
853 | + /** | ||
854 | + * | ||
855 | + * 为有序集key的成员member的score值加上增量increment | ||
856 | + * @param String $zKey | ||
857 | + * @param Integer $value | ||
858 | + * @param String $member | ||
859 | + * @return Integer | ||
860 | + */ | ||
861 | + public function zIncrBy($zKey, $value, $member) | ||
862 | + { | ||
863 | + return $this->redis->zIncrBy($zKey, $value, $member); | ||
864 | + } | ||
865 | + | ||
866 | + /** | ||
867 | + * | ||
868 | + * 返回有序集key中,指定区间内的成员 | ||
869 | + * @param String $zKey | ||
870 | + * @param Integer $start | ||
871 | + * @param Integer $end | ||
872 | + * @param bool $withscores | ||
873 | + * @return bool ( 默认False无键值/True有键值 ) | ||
874 | + */ | ||
875 | + public function zRange($zKey, $start, $end, $withscores = false) | ||
876 | + { | ||
877 | + return $this->redis->zRange($zKey, $start, $end, $withscores); | ||
878 | + } | ||
879 | + | ||
880 | + /** | ||
881 | + * | ||
882 | + * 返回有序集key中,指定区间内的成员 | ||
883 | + * 其中成员的位置按score值递减(从大到小)来排列 | ||
884 | + * @param String $zKey | ||
885 | + * @param Integer $start | ||
886 | + * @param Integer $end | ||
887 | + * @param bool $withscores | ||
888 | + * @return bool ( 默认False无键值/True有键值 ) | ||
889 | + */ | ||
890 | + public function zRevRange($zKey, $start, $end, $withscores = false) | ||
891 | + { | ||
892 | + return $this->redis->zRevRange($zKey, $start, $end, $withscores); | ||
893 | + } | ||
894 | + | ||
895 | + /** | ||
896 | + * | ||
897 | + * 返回有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。有序集成员按score值递增(从小到大 or 从大到小)次序排列 | ||
898 | + * @param String $zKey | ||
899 | + * @param Integer $start | ||
900 | + * @param Integer $end | ||
901 | + * @param array $options | ||
902 | + * @return array | ||
903 | + * ========================================================= | ||
904 | + * $redis->zRangeByScore('key', 0, 3); | ||
905 | + * array('val0', 'val2') | ||
906 | + * $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE); | ||
907 | + * array('val0' => 0, 'val2' => 2) | ||
908 | + * $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1)); | ||
909 | + * array('val2' => 2) | ||
910 | + * $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1)); | ||
911 | + * array('val2') | ||
912 | + * $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE, 'limit' => array(1, 1)); | ||
913 | + * array('val2' => 2) | ||
914 | + * ========================================================= | ||
915 | + * | ||
916 | + */ | ||
917 | + public function zRangeByScore($zKey, $start, $end, array $options) | ||
918 | + { | ||
919 | + return $this->redis->zRangeByScore($zKey, $start, $end, $options); | ||
920 | + } | ||
921 | + | ||
922 | + /** | ||
923 | + * | ||
924 | + * 返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大 or 从大到小)顺序排列 | ||
925 | + * @param String $zKey | ||
926 | + * @param String $member | ||
927 | + * @param String $order ( desc or asc ) | ||
928 | + * @return array | ||
929 | + */ | ||
930 | + public function zRank($zKey, $member, $order = 'desc') | ||
931 | + { | ||
932 | + return $order == 'desc' ? $this->redis->zRank($zKey, $member) : $this->redis->zRevRank($zKey, $member); | ||
933 | + } | ||
934 | + | ||
935 | + /** | ||
936 | + * 移除有序集key中,指定排名(rank)区间内的所有成员 | ||
937 | + * 区间分别以下标参数start和stop指出,包含start和stop在内 | ||
938 | + * @param String $zKey | ||
939 | + * @param Integer $start | ||
940 | + * @param Integer $end | ||
941 | + * @return Integer | ||
942 | + */ | ||
943 | + public function zRemRangeByRank($zKey, $start, $end) | ||
944 | + { | ||
945 | + return $this->redis->zRemRangeByRank($zKey, $start, $end); | ||
946 | + } | ||
947 | + | ||
948 | + public function tag($tagName) | ||
949 | + { | ||
950 | + } | ||
951 | + | ||
952 | + /** | ||
953 | + * 移除有序集key中,指定(socre)区间内的所有成员 | ||
954 | + * 区间分别以下标参数start和stop指出,包含start和stop在内 | ||
955 | + * @param String $zKey | ||
956 | + * @param Integer $start | ||
957 | + * @param Integer $end | ||
958 | + * @return Integer | ||
959 | + */ | ||
960 | + public function zRemRangeByScore($zKey, $start, $end) | ||
961 | + { | ||
962 | + return $this->redis->zRemRangeByScore($zKey, $start, $end); | ||
963 | + } | ||
964 | + | ||
965 | + public function zRevRangeByScore($zkey, $start, $end, array $options) | ||
966 | + { | ||
967 | + return $this->redis->zRevRangeByScore($zkey, $start, $end, $options); | ||
968 | + } | ||
969 | + | ||
970 | + /** | ||
971 | + * 发布消息 | ||
972 | + * | ||
973 | + * @param String $channel | ||
974 | + * @param String $message | ||
975 | + * @return Integer | ||
976 | + */ | ||
977 | + public function publish($channel, $message) | ||
978 | + { | ||
979 | + return $this->redis->publish($channel, $message); | ||
980 | + } | ||
981 | + | ||
982 | + /** | ||
983 | + * 订阅消息 | ||
984 | + * @param String $channel | ||
985 | + * @return String | ||
986 | + */ | ||
987 | + public function subscribe(array $channel, $callback) | ||
988 | + { | ||
989 | + return $this->redis->subscribe($channel, $callback); | ||
990 | + } | ||
991 | + | ||
992 | + /** | ||
993 | + * 退订 | ||
994 | + * @param String $channel | ||
995 | + */ | ||
996 | + public function unsubscribe($channel) | ||
997 | + { | ||
998 | + return $this->redis->unsubscribe($channel); | ||
999 | + } | ||
1000 | + | ||
1001 | + /** | ||
1002 | + * 按照模式匹配订阅多个频道 | ||
1003 | + * | ||
1004 | + * @param String $pattern (如:news.* 可订阅news.开头的所有频道) | ||
1005 | + */ | ||
1006 | + public function psubscribe($pattern, $callback) | ||
1007 | + { | ||
1008 | + return $this->redis->psubscribe($pattern, $callback); | ||
1009 | + } | ||
1010 | + | ||
1011 | + /** | ||
1012 | + * 退订给定模式的所有渠道 | ||
1013 | + * | ||
1014 | + * @param String $pattern | ||
1015 | + */ | ||
1016 | + public function punsubscribe($pattern) | ||
1017 | + { | ||
1018 | + return $this->redis->punsubscribe($pattern); | ||
1019 | + } | ||
1020 | + | ||
1021 | + public function pubsub($pattern) | ||
1022 | + { | ||
1023 | + return $this->redis->pubsub($pattern); | ||
1024 | + } | ||
1025 | +} |
yaf/Hood/Cache/FileCache.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace Hood\Cache; | ||
4 | + | ||
5 | +use Hood\Core\Root; | ||
6 | +use Yaf\Exception; | ||
7 | + | ||
8 | +/** | ||
9 | + * Description of cache | ||
10 | + * | ||
11 | + * @author 13011908 | ||
12 | + */ | ||
13 | +class FileCache extends Root implements CacheInterface | ||
14 | +{ | ||
15 | + | ||
16 | + const DEFAULT_EXPIRE = 3600; | ||
17 | + | ||
18 | + protected static $default = 'file'; | ||
19 | + protected static $instances = array(); | ||
20 | + protected $_cache_dir; | ||
21 | + protected $_tag = null; | ||
22 | + | ||
23 | + private $section = 'file'; | ||
24 | + private $node = 'cache'; | ||
25 | + | ||
26 | + public function __construct($childNode = null, $node = 'cache', $cachePath = null) | ||
27 | + { | ||
28 | + if ($cachePath == null) { | ||
29 | + $server = $this->getServerHost('cache'); | ||
30 | + $this->node = ($node == null ? 'cache' : $node); | ||
31 | + $_pathList = $cachePath = $server->getServerConfig($this->section, $this->node); | ||
32 | + if ($childNode == null && is_array($cachePath)) { | ||
33 | + $cachePath = (sys_get_temp_dir() . 'cached' . DIRECTORY_SEPARATOR); | ||
34 | + } else { | ||
35 | + $cachePath = $_pathList[$childNode]; | ||
36 | + } | ||
37 | + } | ||
38 | + $this->initFileInfo($cachePath); | ||
39 | + } | ||
40 | + | ||
41 | + private function initFileInfo($directory) | ||
42 | + { | ||
43 | + try { | ||
44 | + $this->_cache_dir = new \SplFileInfo($directory); | ||
45 | + } // PHP < 5.3 exception handle | ||
46 | + catch (ErrorException $e) { | ||
47 | + $this->_cache_dir = $this->_make_directory($directory, 0777, TRUE); | ||
48 | + } // PHP >= 5.3 exception handle | ||
49 | + catch (UnexpectedValueException $e) { | ||
50 | + $this->_cache_dir = $this->_make_directory($directory, 0777, TRUE); | ||
51 | + } | ||
52 | + | ||
53 | + // If the defined directory is a file, get outta here | ||
54 | + if ($this->_cache_dir->isFile()) { | ||
55 | + throw new Exception('Unable to create cache directory as a file already exists : ' . $this->_cache_dir->getRealPath()); | ||
56 | + } | ||
57 | + | ||
58 | + if (!$this->_cache_dir->isDir()) { | ||
59 | + $this->_cache_dir = $this->_make_directory($directory, 0777, TRUE); | ||
60 | + } | ||
61 | + | ||
62 | + // Check the read status of the directory | ||
63 | + if (!$this->_cache_dir->isReadable()) { | ||
64 | + throw new Exception('Unable to read from the cache directory ' . $this->_cache_dir->getRealPath()); | ||
65 | + } | ||
66 | + | ||
67 | + // Check the write status of the directory | ||
68 | + if (!$this->_cache_dir->isWritable()) { | ||
69 | + throw new Exception('Unable to write to the cache directory ' . $this->_cache_dir->getRealPath()); | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + public function add($key, $value, $minutes) | ||
74 | + { | ||
75 | + } | ||
76 | + | ||
77 | + public function increment($key, $value = 1) | ||
78 | + { | ||
79 | + $tag = $this->_tag; | ||
80 | + if ($get = $this->get($key)) { | ||
81 | + if (preg_match('/^\d+$/', $get)) { | ||
82 | + $value = intval($get) + $value; | ||
83 | + } else { | ||
84 | + return false; | ||
85 | + } | ||
86 | + } | ||
87 | + if ($tag) { | ||
88 | + $this->tag($tag); | ||
89 | + } | ||
90 | + return $this->set($key, $value); | ||
91 | + } | ||
92 | + | ||
93 | + public function decrement($key, $value = 1) | ||
94 | + { | ||
95 | + $tag = $this->_tag; | ||
96 | + if ($get = $this->get($key)) { | ||
97 | + if (preg_match('/^\d+$/', $get)) { | ||
98 | + $value = intval($get) - $value; | ||
99 | + } else { | ||
100 | + return false; | ||
101 | + } | ||
102 | + } | ||
103 | + if ($tag) { | ||
104 | + $this->tag($tag); | ||
105 | + } | ||
106 | + return $this->set($key, $value); | ||
107 | + } | ||
108 | + | ||
109 | + public function tag($tagName = null) | ||
110 | + { | ||
111 | + if ($tagName) { | ||
112 | + $this->_tag = md5($tagName); | ||
113 | + return $this; | ||
114 | + } elseif (!empty($this->_tag)) { | ||
115 | + $tag = $this->_tag; | ||
116 | + unset($this->_tag); | ||
117 | + return $tag . DIRECTORY_SEPARATOR; | ||
118 | + } else { | ||
119 | + return ''; | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + public static function instance($group = NULL) | ||
124 | + { | ||
125 | + // If there is no group supplied | ||
126 | + if ($group === NULL) { | ||
127 | + // Use the default setting | ||
128 | + $group = self::$default; | ||
129 | + } | ||
130 | + | ||
131 | + if (isset(self::$instances[$group])) { | ||
132 | + // Return the current group if initiated already | ||
133 | + return self::$instances[$group]; | ||
134 | + } | ||
135 | + // Create a new cache type instance | ||
136 | + self::$instances[$group] = new self(); | ||
137 | + // Return the instance | ||
138 | + return self::$instances[$group]; | ||
139 | + } | ||
140 | + | ||
141 | + /** | ||
142 | + * Retrieve a cached value entry by id. | ||
143 | + * | ||
144 | + * // Retrieve cache entry from file group | ||
145 | + * $data = self::instance('file')->get('foo'); | ||
146 | + * | ||
147 | + * // Retrieve cache entry from file group and return 'bar' if miss | ||
148 | + * $data = self::instance('file')->get('foo', 'bar'); | ||
149 | + * | ||
150 | + * @param string id of cache to entry | ||
151 | + * @param string default value to return if cache miss | ||
152 | + * @return mixed | ||
153 | + * @throws Cache_Exception | ||
154 | + */ | ||
155 | + public function get($id, $default = NULL) | ||
156 | + { | ||
157 | + $filename = self::filename($this->_sanitize_id($id)); | ||
158 | + $directory = $this->_resolve_directory($filename); | ||
159 | + | ||
160 | + // Wrap operations in try/catch to handle notices | ||
161 | + try { | ||
162 | + // Open file | ||
163 | + $file = new \SplFileInfo($directory . $filename); | ||
164 | + | ||
165 | + // If file does not exist | ||
166 | + if (!$file->isFile()) { | ||
167 | + // Return default value | ||
168 | + return $default; | ||
169 | + } else { | ||
170 | + // Open the file and parse data | ||
171 | + $created = $file->getMTime(); | ||
172 | + $data = $file->openFile(); | ||
173 | + $lifetime = $data->fgets(); | ||
174 | + | ||
175 | + // If we're at the EOF at this point, corrupted! | ||
176 | + if ($data->eof()) { | ||
177 | + return false; | ||
178 | + throw new Exception(__METHOD__ . ' corrupted cache file!'); | ||
179 | + } | ||
180 | + | ||
181 | + $cache = ''; | ||
182 | + | ||
183 | + while ($data->eof() === FALSE) { | ||
184 | + $cache .= $data->fgets(); | ||
185 | + } | ||
186 | + | ||
187 | + // Test the expiry | ||
188 | + if (($created + (int)$lifetime) < time()) { | ||
189 | + // Delete the file | ||
190 | + $this->_delete_file($file, NULL, TRUE); | ||
191 | + return $default; | ||
192 | + } else { | ||
193 | + return unserialize($cache); | ||
194 | + } | ||
195 | + } | ||
196 | + } catch (ErrorException $e) { | ||
197 | + // Handle ErrorException caused by failed unserialization | ||
198 | + if ($e->getCode() === E_NOTICE) { | ||
199 | + throw new Exception(__METHOD__ . ' failed to unserialize cached object with message : ' . $e->getMessage()); | ||
200 | + } | ||
201 | + | ||
202 | + // Otherwise throw the exception | ||
203 | + throw $e; | ||
204 | + } | ||
205 | + } | ||
206 | + | ||
207 | + /** | ||
208 | + * Set a value to cache with id and lifetime | ||
209 | + * | ||
210 | + * $data = 'bar'; | ||
211 | + * | ||
212 | + * // Set 'bar' to 'foo' in file group, using default expiry | ||
213 | + * self::instance('file')->set('foo', $data); | ||
214 | + * | ||
215 | + * // Set 'bar' to 'foo' in file group for 30 seconds | ||
216 | + * self::instance('file')->set('foo', $data, 30); | ||
217 | + * | ||
218 | + * @param string id of cache entry | ||
219 | + * @param string data to set to cache | ||
220 | + * @param integer lifetime in seconds | ||
221 | + * @return boolean | ||
222 | + */ | ||
223 | + public function set($id, $data, $lifetime = NULL) | ||
224 | + { | ||
225 | + $filename = self::filename($this->_sanitize_id($id)); | ||
226 | + $directory = $this->_resolve_directory($filename); | ||
227 | + // If lifetime is NULL | ||
228 | + if ($lifetime === NULL) { | ||
229 | + // Set to the default expiry | ||
230 | + $lifetime = self::DEFAULT_EXPIRE; | ||
231 | + } | ||
232 | + | ||
233 | + // Open directory | ||
234 | + $dir = new \SplFileInfo($directory); | ||
235 | + | ||
236 | + // If the directory path is not a directory | ||
237 | + if (!$dir->isDir()) { | ||
238 | + // Create the directory | ||
239 | + if (!mkdir($directory, 0777, TRUE)) { | ||
240 | + throw new Exception(__METHOD__ . ' unable to create directory : ' . $directory); | ||
241 | + } | ||
242 | + | ||
243 | + // chmod to solve potential umask issues | ||
244 | + chmod($directory, 0777); | ||
245 | + } | ||
246 | + | ||
247 | + // Open file to inspect | ||
248 | + $resouce = new \SplFileInfo($directory . $filename); | ||
249 | + $file = $resouce->openFile('w'); | ||
250 | + | ||
251 | + try { | ||
252 | + $data = $lifetime . "\n" . serialize($data); | ||
253 | + $file->fwrite($data, strlen($data)); | ||
254 | + return (bool)$file->fflush(); | ||
255 | + } catch (ErrorException $e) { | ||
256 | + // If serialize through an error exception | ||
257 | + if ($e->getCode() === E_NOTICE) { | ||
258 | + // Throw a caching error | ||
259 | + throw new Exception(__METHOD__ . ' failed to serialize data for caching with message : ' . $e->getMessage()); | ||
260 | + } | ||
261 | + | ||
262 | + // Else rethrow the error exception | ||
263 | + throw $e; | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
267 | + protected static function filename($string) | ||
268 | + { | ||
269 | + return sha1($string) . '.cache'; | ||
270 | + } | ||
271 | + | ||
272 | + /** | ||
273 | + * Delete a cache entry based on id | ||
274 | + * | ||
275 | + * // Delete 'foo' entry from the file group | ||
276 | + * self::instance('file')->delete('foo'); | ||
277 | + * | ||
278 | + * @param string id to remove from cache | ||
279 | + * @return boolean | ||
280 | + */ | ||
281 | + public function delete($id) | ||
282 | + { | ||
283 | + $filename = self::filename($this->_sanitize_id($id)); | ||
284 | + $directory = $this->_resolve_directory($filename); | ||
285 | + | ||
286 | + return $this->_delete_file(new \SplFileInfo($directory . $filename), NULL, TRUE); | ||
287 | + } | ||
288 | + | ||
289 | + /** | ||
290 | + * Delete all cache entries. | ||
291 | + * | ||
292 | + * Beware of using this method when | ||
293 | + * using shared memory cache systems, as it will wipe every | ||
294 | + * entry within the system for all clients. | ||
295 | + * | ||
296 | + * // Delete all cache entries in the file group | ||
297 | + * self::instance('file')->delete_all(); | ||
298 | + * | ||
299 | + * @return boolean | ||
300 | + */ | ||
301 | + public function delete_all() | ||
302 | + { | ||
303 | + return $this->_delete_file($this->_cache_dir, TRUE); | ||
304 | + } | ||
305 | + | ||
306 | + protected function _delete_file(\SplFileInfo $file, $retain_parent_directory = FALSE, $ignore_errors = FALSE, $only_expired = FALSE) | ||
307 | + { | ||
308 | + // Allow graceful error handling | ||
309 | + try { | ||
310 | + // If is file | ||
311 | + if ($file->isFile()) { | ||
312 | + try { | ||
313 | + if ($only_expired === FALSE) { | ||
314 | + // We want to delete the file | ||
315 | + $delete = TRUE; | ||
316 | + } // Otherwise... | ||
317 | + else { | ||
318 | + // Assess the file expiry to flag it for deletion | ||
319 | + $json = $file->openFile('r')->current(); | ||
320 | + $data = json_decode($json); | ||
321 | + $delete = $data->expiry < time(); | ||
322 | + } | ||
323 | + | ||
324 | + // If the delete flag is set delete file | ||
325 | + if ($delete === TRUE) | ||
326 | + return @unlink($file->getRealPath()); | ||
327 | + else | ||
328 | + return FALSE; | ||
329 | + } catch (ErrorException $e) { | ||
330 | + // Catch any delete file warnings | ||
331 | + if ($e->getCode() === E_WARNING) { | ||
332 | + throw new Exception(__METHOD__ . ' failed to delete file : ' . $file->getRealPath()); | ||
333 | + } | ||
334 | + } | ||
335 | + } // Else, is directory | ||
336 | + elseif ($file->isDir()) { | ||
337 | + // Create new DirectoryIterator | ||
338 | + $files = new DirectoryIterator($file->getPathname()); | ||
339 | + | ||
340 | + // Iterate over each entry | ||
341 | + while ($files->valid()) { | ||
342 | + // Extract the entry name | ||
343 | + $name = $files->getFilename(); | ||
344 | + | ||
345 | + // If the name is not a dot | ||
346 | + if ($name != '.' AND $name != '..') { | ||
347 | + // Create new file resource | ||
348 | + $fp = new \SplFileInfo($files->getRealPath()); | ||
349 | + // Delete the file | ||
350 | + $this->_delete_file($fp); | ||
351 | + } | ||
352 | + | ||
353 | + // Move the file pointer on | ||
354 | + $files->next(); | ||
355 | + } | ||
356 | + | ||
357 | + // If set to retain parent directory, return now | ||
358 | + if ($retain_parent_directory) { | ||
359 | + return TRUE; | ||
360 | + } | ||
361 | + | ||
362 | + try { | ||
363 | + // Remove the files iterator | ||
364 | + // (fixes Windows PHP which has permission issues with open iterators) | ||
365 | + unset($files); | ||
366 | + | ||
367 | + // Try to remove the parent directory | ||
368 | + return rmdir($file->getRealPath()); | ||
369 | + } catch (ErrorException $e) { | ||
370 | + // Catch any delete directory warnings | ||
371 | + if ($e->getCode() === E_WARNING) { | ||
372 | + throw new Exception(__METHOD__ . ' failed to delete directory : ' . $file->getRealPath()); | ||
373 | + } | ||
374 | + throw $e; | ||
375 | + } | ||
376 | + } else { | ||
377 | + // We get here if a file has already been deleted | ||
378 | + return FALSE; | ||
379 | + } | ||
380 | + } // Catch all exceptions | ||
381 | + catch (Exception $e) { | ||
382 | + // If ignore_errors is on | ||
383 | + if ($ignore_errors === TRUE) { | ||
384 | + // Return | ||
385 | + return FALSE; | ||
386 | + } | ||
387 | + // Throw exception | ||
388 | + throw $e; | ||
389 | + } | ||
390 | + } | ||
391 | + | ||
392 | + protected function _resolve_directory($filename) | ||
393 | + { | ||
394 | + return $this->_cache_dir->getRealPath() . DIRECTORY_SEPARATOR . $this->tag() . $filename[0] . $filename[1] . DIRECTORY_SEPARATOR; | ||
395 | + } | ||
396 | + | ||
397 | + protected function _sanitize_id($id) | ||
398 | + { | ||
399 | + // Change slashes and spaces to underscores | ||
400 | + return str_replace(array('/', '\\', ' '), '_', $id); | ||
401 | + } | ||
402 | + | ||
403 | + /** | ||
404 | + * Makes the cache directory if it doesn't exist. Simply a wrapper for | ||
405 | + * `mkdir` to ensure DRY principles | ||
406 | + * | ||
407 | + * @see http://php.net/manual/en/function.mkdir.php | ||
408 | + * @param string directory | ||
409 | + * @param string mode | ||
410 | + * @param string recursive | ||
411 | + * @param string context | ||
412 | + * @return \SplFileInfo | ||
413 | + * @throws Cache_Exception | ||
414 | + */ | ||
415 | + protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL) | ||
416 | + { | ||
417 | + if (!mkdir($directory, $mode, $recursive)) { | ||
418 | + throw new Exception('Failed to create the defined cache directory : ' . $directory); | ||
419 | + } | ||
420 | + chmod($directory, $mode); | ||
421 | + | ||
422 | + return new \SplFileInfo($directory);; | ||
423 | + } | ||
424 | + | ||
425 | + /** | ||
426 | + * Garbage collection method that cleans any expired | ||
427 | + * cache entries from the cache. | ||
428 | + * | ||
429 | + * @return void | ||
430 | + */ | ||
431 | + public function garbage_collect() | ||
432 | + { | ||
433 | + $this->_delete_file($this->_cache_dir, TRUE, FALSE, TRUE); | ||
434 | + return; | ||
435 | + } | ||
436 | + | ||
437 | +} |
yaf/Hood/Cache/Memcache.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 15/4/28 | ||
6 | + * Time: 下午3:16 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache; | ||
10 | + | ||
11 | +use Hood\Core\Root; | ||
12 | + | ||
13 | +class Memcache extends Root implements CacheInterface | ||
14 | +{ | ||
15 | + private $mcInstances = array(); | ||
16 | + | ||
17 | + private $persistentIDs = array(); | ||
18 | + | ||
19 | + private $section = 'memcached'; | ||
20 | + | ||
21 | + private $node = 'servers'; | ||
22 | + | ||
23 | + private $tagName = ''; | ||
24 | + | ||
25 | + private $prefix = ''; | ||
26 | + | ||
27 | + private $persistentID = 'hood.cache'; | ||
28 | + | ||
29 | + private $childNodes = 'hosts'; | ||
30 | + | ||
31 | + public function __construct($prefix = '', $persistentID = 'hood.cache') | ||
32 | + { | ||
33 | + parent::__construct(); | ||
34 | + $this->prefix = $prefix; | ||
35 | + $this->persistentIDs[] = $this->persistentID = $persistentID; | ||
36 | + } | ||
37 | + | ||
38 | + public function init() | ||
39 | + { | ||
40 | + if (isset($this->mcInstances[$this->persistentID])) { | ||
41 | + $mc = $this->mcInstances[$this->persistentID]; | ||
42 | + } else { | ||
43 | + $instance = new \Memcache(); | ||
44 | + $server = $this->getServerHost('cache'); | ||
45 | + $_serverHosts = $server->getServerConfig($this->section, $this->node); | ||
46 | + $mcServers = $this->_makeHosts($server->getServer($_serverHosts[$this->childNodes], 2)); | ||
47 | + foreach ($mcServers as $key => $val) { | ||
48 | + $weight = 100; | ||
49 | + if (count($val) == 3) { | ||
50 | + list($host, $port, $weight) = $val; | ||
51 | + } else { | ||
52 | + list($host, $port) = $val; | ||
53 | + } | ||
54 | + $instance->addServer($host, $port, $this->persistentID, $weight); | ||
55 | + } | ||
56 | + $this->mcInstances[$this->persistentID] = $mc = $instance; | ||
57 | + } | ||
58 | + return $mc; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * 组织host | ||
63 | + * @param array $hosts | ||
64 | + * @return array | ||
65 | + */ | ||
66 | + private function _makeHosts(array $hosts) | ||
67 | + { | ||
68 | + $_server = array(); | ||
69 | + foreach ($hosts as $key => $val) { | ||
70 | + $_server[] = explode(':', $val); | ||
71 | + } | ||
72 | + return $_server; | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * 设置mc配置的块节点 | ||
77 | + * @param $node | ||
78 | + * @return $this | ||
79 | + */ | ||
80 | + public function setNode($node = null) | ||
81 | + { | ||
82 | + if ($node != null) $this->node = $node; | ||
83 | + return $this; | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * 设置子节点 | ||
88 | + * @param $childNode | ||
89 | + * @return $this | ||
90 | + */ | ||
91 | + public function setChildNodes($childNode) | ||
92 | + { | ||
93 | + $this->childNodes = $childNode; | ||
94 | + return $this; | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
98 | + * 构建tag | ||
99 | + * @param bool $mode | ||
100 | + * @return string | ||
101 | + */ | ||
102 | + private function _makeTag($mode = false) | ||
103 | + { | ||
104 | + if (empty($this->tagName)) return ''; | ||
105 | + $_tagVal = $this->init()->get($this->tagName); | ||
106 | + if (empty($_tagVal) && $mode == true) { | ||
107 | + $_tagVal = md5(microtime() . mt_rand() . uniqid()); | ||
108 | + $this->init()->set($this->tagName, $_tagVal, 0); | ||
109 | + } | ||
110 | + unset($this->tagName); | ||
111 | + return empty($_tagVal) ? '' : $_tagVal . '.'; | ||
112 | + } | ||
113 | + | ||
114 | + /** | ||
115 | + * 检索一个元素 | ||
116 | + * @param $key | ||
117 | + * @param callable $flags | ||
118 | + * @return mixed | ||
119 | + */ | ||
120 | + public function get($key, &$flags = \MEMCACHE_COMPRESSED) | ||
121 | + { | ||
122 | + return $this->init()->get($this->_makeTag() . $key, $flags); | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + * 向一个新的key下面增加一个元素 | ||
127 | + * @param $key | ||
128 | + * @param $value | ||
129 | + * @param $expiration | ||
130 | + * @return bool | ||
131 | + */ | ||
132 | + public function add($key, $value, $expiration = 0) | ||
133 | + { | ||
134 | + return $this->init()->add($this->_makeTag(true) . $key, $value, $expiration); | ||
135 | + } | ||
136 | + | ||
137 | + | ||
138 | + /** | ||
139 | + * 减小数值元素的值 | ||
140 | + * @param $key | ||
141 | + * @param int $offset | ||
142 | + * @return int | ||
143 | + */ | ||
144 | + public function decrement($key, $offset = 1) | ||
145 | + { | ||
146 | + return $this->init()->decrement($this->_makeTag() . $key, $offset); | ||
147 | + } | ||
148 | + | ||
149 | + /** | ||
150 | + * @param $key | ||
151 | + * @param int $time | ||
152 | + * @return bool | ||
153 | + */ | ||
154 | + public function delete($key, $time = 0) | ||
155 | + { | ||
156 | + return $this->init()->delete($this->_makeTag() . $key, $time); | ||
157 | + } | ||
158 | + | ||
159 | + | ||
160 | + /** | ||
161 | + * 增加数值元素的值 | ||
162 | + * @param $key | ||
163 | + * @param int $offset | ||
164 | + * @param int $initialValue | ||
165 | + * @param int $expiry | ||
166 | + * @return int | ||
167 | + */ | ||
168 | + public function increment($key, $offset = 1, $initialValue = 0, $expiry = 0) | ||
169 | + { | ||
170 | + return $this->init()->increment($this->_makeTag() . $key, $offset, $initialValue, $expiry); | ||
171 | + } | ||
172 | + | ||
173 | + | ||
174 | + /** | ||
175 | + * 设置 | ||
176 | + * @param $key | ||
177 | + * @param $value | ||
178 | + * @param int $expiration | ||
179 | + * @return bool | ||
180 | + */ | ||
181 | + public function set($key, $var, $expire = 0, $flag = \MEMCACHE_COMPRESSED) | ||
182 | + { | ||
183 | + return $this->init()->set($this->_makeTag(true) . $key, $var, $flag, $expire); | ||
184 | + } | ||
185 | + | ||
186 | + /** | ||
187 | + * 设置tag | ||
188 | + * @param $tagName | ||
189 | + * @return $this | ||
190 | + */ | ||
191 | + public function tag($tagName) | ||
192 | + { | ||
193 | + $this->tagName = $tagName; | ||
194 | + return $this; | ||
195 | + } | ||
196 | +} |
yaf/Hood/Cache/Memcached.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/11/23 | ||
6 | + * Time: 上午1:39 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache; | ||
10 | + | ||
11 | +use Hood\Core\Root; | ||
12 | +use Hood\Debug\DebugException; | ||
13 | + | ||
14 | +class Memcached extends Root implements CacheInterface | ||
15 | +{ | ||
16 | + private $mcInstances = array(); | ||
17 | + | ||
18 | + private $persistentIDs = array(); | ||
19 | + | ||
20 | + private $timeout = 150; | ||
21 | + | ||
22 | + private $section = 'memcached'; | ||
23 | + | ||
24 | + private $node = 'servers'; | ||
25 | + | ||
26 | + private $tagName = ''; | ||
27 | + | ||
28 | + private $prefix = ''; | ||
29 | + | ||
30 | + private $persistentID = 'hood.cache'; | ||
31 | + | ||
32 | + private $childNodes = 'hosts'; | ||
33 | + | ||
34 | + public function __construct($prefix = '', $persistentID = 'hood.cache') | ||
35 | + { | ||
36 | + parent::__construct(); | ||
37 | + $this->prefix = $prefix; | ||
38 | + $this->persistentIDs[] = $this->persistentID = $persistentID; | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * 设置子节点 | ||
43 | + * @param $childNode | ||
44 | + * @return $this | ||
45 | + */ | ||
46 | + public function setChildNodes($childNode) | ||
47 | + { | ||
48 | + $this->childNodes = $childNode; | ||
49 | + return $this; | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * 设置前缀 | ||
54 | + * @param $prefix | ||
55 | + * @return $this | ||
56 | + */ | ||
57 | + public function setPrefix($prefix) | ||
58 | + { | ||
59 | + $this->prefix = $prefix; | ||
60 | + return $this; | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * 设置共享连接ID | ||
65 | + * @param $persistentID | ||
66 | + * @return $this | ||
67 | + */ | ||
68 | + public function setPersistentID($persistentID) | ||
69 | + { | ||
70 | + $this->persistentID = $persistentID; | ||
71 | + return $this; | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * @param $persistentID | ||
76 | + * @return \Memcached | ||
77 | + * @throws \Hood\Debug\DebugException | ||
78 | + */ | ||
79 | + private function init() | ||
80 | + { | ||
81 | + if (isset($this->mcInstances[$this->persistentID])) { | ||
82 | + $mc = $this->mcInstances[$this->persistentID]; | ||
83 | + } else { | ||
84 | + $instance = new \Memcached(); | ||
85 | + $instance->setOption(\Memcached::OPT_PREFIX_KEY, $this->prefix); | ||
86 | + $instance->setOption(\Memcached::OPT_DISTRIBUTION, \Memcached::DISTRIBUTION_CONSISTENT); // 开启一致性哈希 取模(默认)/ 一致性 | ||
87 | + $instance->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);//ketama算法兼容 设置为md5并且分布算法将会 采用带有权重的一致性hash分布 | ||
88 | + $instance->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->timeout); | ||
89 | + if (count($instance->getServerList()) < 1) { | ||
90 | + $server = $this->getServerHost('cache'); | ||
91 | + $_serverHosts = $server->getServerConfig($this->section, $this->node); | ||
92 | + if (empty($_serverHosts[$this->childNodes])) { | ||
93 | + throw new DebugException('Memcache Host Config is Null.'); | ||
94 | + } | ||
95 | + $mcServers = $this->_makeHosts($server->getServer($_serverHosts[$this->childNodes], 2)); | ||
96 | + $instance->addServers($mcServers); | ||
97 | + unset($mcServers); | ||
98 | + } | ||
99 | + $this->mcInstances[$this->persistentID] = $mc = $instance; | ||
100 | + } | ||
101 | + return $mc; | ||
102 | + } | ||
103 | + | ||
104 | + | ||
105 | + /** | ||
106 | + * 设置mc配置的块 | ||
107 | + * @param $section | ||
108 | + * @return $this | ||
109 | + */ | ||
110 | + public function setSection($section) | ||
111 | + { | ||
112 | + $this->section = $section; | ||
113 | + return $this; | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * 设置mc配置的块节点 | ||
118 | + * @param $node | ||
119 | + * @return $this | ||
120 | + */ | ||
121 | + public function setNode($node = null) | ||
122 | + { | ||
123 | + if ($node != null) $this->node = $node; | ||
124 | + return $this; | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * 组织host | ||
129 | + * @param array $hosts | ||
130 | + * @return array | ||
131 | + */ | ||
132 | + private function _makeHosts(array $hosts) | ||
133 | + { | ||
134 | + $_server = array(); | ||
135 | + foreach ($hosts as $key => $val) { | ||
136 | + $_server[] = explode(':', $val); | ||
137 | + } | ||
138 | + return $_server; | ||
139 | + } | ||
140 | + | ||
141 | + /** | ||
142 | + * 构建tag | ||
143 | + * @param bool $mode | ||
144 | + * @return string | ||
145 | + */ | ||
146 | + private function _makeTag($mode = false) | ||
147 | + { | ||
148 | + if (empty($this->tagName)) return ''; | ||
149 | + $_tagVal = $this->init()->get($this->tagName); | ||
150 | + if (empty($_tagVal) && $mode == true) { | ||
151 | + $_tagVal = md5(microtime() . mt_rand() . uniqid()); | ||
152 | + $this->init()->set($this->tagName, $_tagVal, 0); | ||
153 | + } | ||
154 | + unset($this->tagName); | ||
155 | + return empty($_tagVal) ? '' : $_tagVal . '.'; | ||
156 | + } | ||
157 | + | ||
158 | + /** | ||
159 | + * 检索一个元素 | ||
160 | + * @param $key | ||
161 | + * @param callable $cache_cb | ||
162 | + * @param float $cas_token | ||
163 | + * @return mixed | ||
164 | + */ | ||
165 | + public function get($key, $cacheCb = null, &$casToken = null) | ||
166 | + { | ||
167 | + return $this->init()->get($this->_makeTag() . $key, $cacheCb, $casToken); | ||
168 | + } | ||
169 | + | ||
170 | + /** | ||
171 | + * 向一个新的key下面增加一个元素 | ||
172 | + * @param $key | ||
173 | + * @param $value | ||
174 | + * @param $expiration | ||
175 | + * @return bool | ||
176 | + */ | ||
177 | + public function add($key, $value, $expiration = 0) | ||
178 | + { | ||
179 | + return $this->init()->add($this->_makeTag(true) . $key, $value, $expiration); | ||
180 | + } | ||
181 | + | ||
182 | + /** | ||
183 | + * 向已存在元素后追加数据 | ||
184 | + * @param $key | ||
185 | + * @param $value | ||
186 | + * @return bool | ||
187 | + */ | ||
188 | + public function append($key, $value) | ||
189 | + { | ||
190 | + return $this->init()->append($this->_makeTag(true) . $key, $value); | ||
191 | + } | ||
192 | + | ||
193 | + /** | ||
194 | + * 比较并交换值 | ||
195 | + * @param $casToken | ||
196 | + * @param $key | ||
197 | + * @param $value | ||
198 | + * @param int $expiration | ||
199 | + * @return bool | ||
200 | + */ | ||
201 | + public function cas($casToken, $key, $value, $expiration = 0) | ||
202 | + { | ||
203 | + return $this->init()->cas($casToken, $this->_makeTag(true) . $key, $value, $expiration); | ||
204 | + } | ||
205 | + | ||
206 | + /** | ||
207 | + * 减小数值元素的值 | ||
208 | + * @param $key | ||
209 | + * @param int $offset | ||
210 | + * @return int | ||
211 | + */ | ||
212 | + public function decrement($key, $offset = 1) | ||
213 | + { | ||
214 | + return $this->init()->decrement($this->_makeTag() . $key, $offset); | ||
215 | + } | ||
216 | + | ||
217 | + /** | ||
218 | + * @param $key | ||
219 | + * @param int $time | ||
220 | + * @return bool | ||
221 | + */ | ||
222 | + public function delete($key, $time = 0) | ||
223 | + { | ||
224 | + return $this->init()->delete($this->_makeTag() . $key, $time); | ||
225 | + } | ||
226 | + | ||
227 | + /** | ||
228 | + * 删除多个数据 | ||
229 | + * @param array $keys | ||
230 | + * @param int $time | ||
231 | + * @return bool | ||
232 | + */ | ||
233 | + public function deleteMulti(array $keys, $time = 0) | ||
234 | + { | ||
235 | + return $this->init()->deleteMulti($this->_makeMultiKey($keys), $time); | ||
236 | + } | ||
237 | + | ||
238 | + /** | ||
239 | + * 组合多key 数据 | ||
240 | + * @param $keys | ||
241 | + * @return array | ||
242 | + */ | ||
243 | + private function _makeMultiKey($keys, $mode = false) | ||
244 | + { | ||
245 | + $_keys = array(); | ||
246 | + $tag = $this->_makeTag($mode); | ||
247 | + foreach ($keys as $key) { | ||
248 | + $_keys[] = $tag . $key; | ||
249 | + } | ||
250 | + return $_keys; | ||
251 | + } | ||
252 | + | ||
253 | + /** | ||
254 | + * 请求多个元素 | ||
255 | + * @param array $keys | ||
256 | + * @param null $withCas | ||
257 | + * @param callable $valueCb | ||
258 | + * @return bool | ||
259 | + */ | ||
260 | + public function getDelayed(array $keys, $withCas = null, callable $valueCb = null) | ||
261 | + { | ||
262 | + return $this->init()->getDelayed($this->_makeMultiKey($keys), $withCas, $valueCb); | ||
263 | + } | ||
264 | + | ||
265 | + /** | ||
266 | + * 抓取所有剩余的结果 | ||
267 | + * @return array | ||
268 | + */ | ||
269 | + public function fetchAll() | ||
270 | + { | ||
271 | + return $this->init()->fetchAll(); | ||
272 | + } | ||
273 | + | ||
274 | + /** | ||
275 | + * 检索多个元素 | ||
276 | + * @param array $keys | ||
277 | + * @param array $cas_tokens | ||
278 | + * @param null $flags | ||
279 | + * @return mixed | ||
280 | + */ | ||
281 | + public function getMulti(array $keys, array &$casTokens = null, $flags = null) | ||
282 | + { | ||
283 | + return $this->init()->getMulti($this->_makeMultiKey($keys), $casTokens, $flags); | ||
284 | + } | ||
285 | + | ||
286 | + /** | ||
287 | + * 增加数值元素的值 | ||
288 | + * @param $key | ||
289 | + * @param int $offset | ||
290 | + * @param int $initialValue | ||
291 | + * @param int $expiry | ||
292 | + * @return int | ||
293 | + */ | ||
294 | + public function increment($key, $offset = 1, $initialValue = 0, $expiry = 0) | ||
295 | + { | ||
296 | + return $this->init()->increment($this->_makeTag() . $key, $offset, $initialValue, $expiry); | ||
297 | + } | ||
298 | + | ||
299 | + /** | ||
300 | + * 检查memcache是否长连接 | ||
301 | + * @return bool | ||
302 | + */ | ||
303 | + public function isPersistent() | ||
304 | + { | ||
305 | + return $this->init()->isPersistent(); | ||
306 | + } | ||
307 | + | ||
308 | + /** | ||
309 | + * 设置 | ||
310 | + * @param $key | ||
311 | + * @param $value | ||
312 | + * @param int $expiration | ||
313 | + * @return bool | ||
314 | + */ | ||
315 | + public function set($key, $value, $expiration = 0) | ||
316 | + { | ||
317 | + return $this->init()->set($this->_makeTag(true) . $key, $value, $expiration); | ||
318 | + } | ||
319 | + | ||
320 | + /** | ||
321 | + * 设置多个数据 | ||
322 | + * @param array $items | ||
323 | + * @param int $expiration | ||
324 | + * @return bool | ||
325 | + */ | ||
326 | + public function setMulti(array $items, $expiration = 0) | ||
327 | + { | ||
328 | + $_items = array(); | ||
329 | + $tag = $this->_makeTag(true); | ||
330 | + foreach ($items as $key => $val) { | ||
331 | + $_items[$tag . $key] = $val; | ||
332 | + } | ||
333 | + return $this->init()->setMulti($_items, $expiration); | ||
334 | + } | ||
335 | + | ||
336 | + /** | ||
337 | + * 设置tag | ||
338 | + * @param $tagName | ||
339 | + * @return $this | ||
340 | + */ | ||
341 | + public function tag($tagName) | ||
342 | + { | ||
343 | + $this->tagName = $tagName; | ||
344 | + return $this; | ||
345 | + } | ||
346 | + | ||
347 | + /** | ||
348 | + * 清除服务列表 | ||
349 | + * @return $this | ||
350 | + */ | ||
351 | + public function resetServerList() | ||
352 | + { | ||
353 | + $this->init()->resetServerList(); | ||
354 | + return $this; | ||
355 | + } | ||
356 | +} |
yaf/Hood/Cache/README.md
0 → 100644
1 | +#File | ||
2 | + 缓存路径配置在cache.config.ini里面,如果config里面不设置路径的话使用系统默认的临时文件路径 | ||
3 | + [file] | ||
4 | + cache=/tmp/yoho | ||
5 | + $file = Cache::File(); | ||
6 | + | ||
7 | + [file] | ||
8 | + cache.path = /tmp/yoho | ||
9 | + $file = Cache::File('path'); | ||
10 | + | ||
11 | + [file] | ||
12 | + fileCache.path = /tmp/yoho | ||
13 | + $file = Cache::File('path','fileCache'); | ||
14 | + | ||
15 | + 实现了get、set、del 等方法 | ||
16 | + $file = Cache::File('path','cache'); | ||
17 | + $file->set('a', '00'); | ||
18 | + $file->get('a'); |
yaf/Hood/Cache/Ssdb/Client.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 1/27/15 | ||
6 | + * Time: 10:50 PM | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache\Ssdb; | ||
10 | + | ||
11 | +class Client | ||
12 | +{ | ||
13 | + private $debug = false; | ||
14 | + public $sock = null; | ||
15 | + private $_closed = false; | ||
16 | + private $recv_buf = ''; | ||
17 | + private $_easy = false; | ||
18 | + public $last_resp = null; | ||
19 | + | ||
20 | + function __construct($host, $port, $timeout_ms = 2000) | ||
21 | + { | ||
22 | + $timeout_f = (float)$timeout_ms / 1000; | ||
23 | + $this->sock = @stream_socket_client("$host:$port", $errno, $errstr, $timeout_f); | ||
24 | + if (!$this->sock) { | ||
25 | + throw new SSDBException("$errno: $errstr"); | ||
26 | + } | ||
27 | + $timeout_sec = intval($timeout_ms / 1000); | ||
28 | + $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000; | ||
29 | + @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec); | ||
30 | + if (function_exists('stream_set_chunk_size')) { | ||
31 | + @stream_set_chunk_size($this->sock, 1024 * 1024); | ||
32 | + } | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * After this method invoked with yesno=true, all requesting methods | ||
37 | + * will not return a Response object. | ||
38 | + * And some certain methods like get/zget will return false | ||
39 | + * when response is not ok(not_found, etc) | ||
40 | + */ | ||
41 | + function easy() | ||
42 | + { | ||
43 | + $this->_easy = true; | ||
44 | + } | ||
45 | + | ||
46 | + function close() | ||
47 | + { | ||
48 | + if (!$this->_closed) { | ||
49 | + @fclose($this->sock); | ||
50 | + $this->_closed = true; | ||
51 | + $this->sock = null; | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | + function closed() | ||
56 | + { | ||
57 | + return $this->_closed; | ||
58 | + } | ||
59 | + | ||
60 | + private $batch_mode = false; | ||
61 | + private $batch_cmds = array(); | ||
62 | + | ||
63 | + function batch() | ||
64 | + { | ||
65 | + $this->batch_mode = true; | ||
66 | + $this->batch_cmds = array(); | ||
67 | + return $this; | ||
68 | + } | ||
69 | + | ||
70 | + function multi() | ||
71 | + { | ||
72 | + return $this->batch(); | ||
73 | + } | ||
74 | + | ||
75 | + function exec() | ||
76 | + { | ||
77 | + $ret = array(); | ||
78 | + foreach ($this->batch_cmds as $op) { | ||
79 | + list($cmd, $params) = $op; | ||
80 | + $this->send_req($cmd, $params); | ||
81 | + } | ||
82 | + foreach ($this->batch_cmds as $op) { | ||
83 | + list($cmd, $params) = $op; | ||
84 | + $resp = $this->recv_resp($cmd, $params); | ||
85 | + $resp = $this->check_easy_resp($cmd, $resp); | ||
86 | + $ret[] = $resp; | ||
87 | + } | ||
88 | + $this->batch_mode = false; | ||
89 | + $this->batch_cmds = array(); | ||
90 | + return $ret; | ||
91 | + } | ||
92 | + | ||
93 | + function request() | ||
94 | + { | ||
95 | + $args = func_get_args(); | ||
96 | + $cmd = array_shift($args); | ||
97 | + return $this->__call($cmd, $args); | ||
98 | + } | ||
99 | + | ||
100 | + private $async_auth_password = null; | ||
101 | + | ||
102 | + function auth($password) | ||
103 | + { | ||
104 | + $this->async_auth_password = $password; | ||
105 | + return null; | ||
106 | + } | ||
107 | + | ||
108 | + function __call($cmd, $params = array()) | ||
109 | + { | ||
110 | + $cmd = strtolower($cmd); | ||
111 | + if ($this->async_auth_password !== null) { | ||
112 | + $pass = $this->async_auth_password; | ||
113 | + $this->async_auth_password = null; | ||
114 | + $auth = $this->__call('auth', array($pass)); | ||
115 | + if ($auth !== true) { | ||
116 | + throw new Exception("Authentication failed"); | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + if ($this->batch_mode) { | ||
121 | + $this->batch_cmds[] = array($cmd, $params); | ||
122 | + return $this; | ||
123 | + } | ||
124 | + | ||
125 | + try { | ||
126 | + if ($this->send_req($cmd, $params) === false) { | ||
127 | + $resp = new Response('error', 'send error'); | ||
128 | + } else { | ||
129 | + $resp = $this->recv_resp($cmd, $params); | ||
130 | + } | ||
131 | + } catch (SSDBException $e) { | ||
132 | + if ($this->_easy) { | ||
133 | + throw $e; | ||
134 | + } else { | ||
135 | + $resp = new Response('error', $e->getMessage()); | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + if ($resp->code == 'noauth') { | ||
140 | + $msg = $resp->message; | ||
141 | + throw new Exception($msg); | ||
142 | + } | ||
143 | + | ||
144 | + $resp = $this->check_easy_resp($cmd, $resp); | ||
145 | + return $resp; | ||
146 | + } | ||
147 | + | ||
148 | + private function check_easy_resp($cmd, $resp) | ||
149 | + { | ||
150 | + $this->last_resp = $resp; | ||
151 | + if ($this->_easy) { | ||
152 | + if ($resp->not_found()) { | ||
153 | + return NULL; | ||
154 | + } else if (!$resp->ok() && !is_array($resp->data)) { | ||
155 | + return false; | ||
156 | + } else { | ||
157 | + return $resp->data; | ||
158 | + } | ||
159 | + } else { | ||
160 | + $resp->cmd = $cmd; | ||
161 | + return $resp; | ||
162 | + } | ||
163 | + } | ||
164 | + | ||
165 | + function multi_set($kvs = array()) | ||
166 | + { | ||
167 | + $args = array(); | ||
168 | + foreach ($kvs as $k => $v) { | ||
169 | + $args[] = $k; | ||
170 | + $args[] = $v; | ||
171 | + } | ||
172 | + return $this->__call(__FUNCTION__, $args); | ||
173 | + } | ||
174 | + | ||
175 | + function multi_hset($name, $kvs = array()) | ||
176 | + { | ||
177 | + $args = array($name); | ||
178 | + foreach ($kvs as $k => $v) { | ||
179 | + $args[] = $k; | ||
180 | + $args[] = $v; | ||
181 | + } | ||
182 | + return $this->__call(__FUNCTION__, $args); | ||
183 | + } | ||
184 | + | ||
185 | + function multi_zset($name, $kvs = array()) | ||
186 | + { | ||
187 | + $args = array($name); | ||
188 | + foreach ($kvs as $k => $v) { | ||
189 | + $args[] = $k; | ||
190 | + $args[] = $v; | ||
191 | + } | ||
192 | + return $this->__call(__FUNCTION__, $args); | ||
193 | + } | ||
194 | + | ||
195 | + function incr($key, $val = 1) | ||
196 | + { | ||
197 | + $args = func_get_args(); | ||
198 | + return $this->__call(__FUNCTION__, $args); | ||
199 | + } | ||
200 | + | ||
201 | + function decr($key, $val = 1) | ||
202 | + { | ||
203 | + $args = func_get_args(); | ||
204 | + return $this->__call(__FUNCTION__, $args); | ||
205 | + } | ||
206 | + | ||
207 | + function zincr($name, $key, $score = 1) | ||
208 | + { | ||
209 | + $args = func_get_args(); | ||
210 | + return $this->__call(__FUNCTION__, $args); | ||
211 | + } | ||
212 | + | ||
213 | + function zdecr($name, $key, $score = 1) | ||
214 | + { | ||
215 | + $args = func_get_args(); | ||
216 | + return $this->__call(__FUNCTION__, $args); | ||
217 | + } | ||
218 | + | ||
219 | + function zadd($key, $score, $value) | ||
220 | + { | ||
221 | + $args = array($key, $value, $score); | ||
222 | + return $this->__call('zset', $args); | ||
223 | + } | ||
224 | + | ||
225 | + function zRevRank($name, $key) | ||
226 | + { | ||
227 | + $args = func_get_args(); | ||
228 | + return $this->__call("zrrank", $args); | ||
229 | + } | ||
230 | + | ||
231 | + function zRevRange($name, $offset, $limit) | ||
232 | + { | ||
233 | + $args = func_get_args(); | ||
234 | + return $this->__call("zrrange", $args); | ||
235 | + } | ||
236 | + | ||
237 | + function hincr($name, $key, $val = 1) | ||
238 | + { | ||
239 | + $args = func_get_args(); | ||
240 | + return $this->__call(__FUNCTION__, $args); | ||
241 | + } | ||
242 | + | ||
243 | + function hdecr($name, $key, $val = 1) | ||
244 | + { | ||
245 | + $args = func_get_args(); | ||
246 | + return $this->__call(__FUNCTION__, $args); | ||
247 | + } | ||
248 | + | ||
249 | + private function send_req($cmd, $params) | ||
250 | + { | ||
251 | + $req = array($cmd); | ||
252 | + foreach ($params as $p) { | ||
253 | + if (is_array($p)) { | ||
254 | + $req = array_merge($req, $p); | ||
255 | + } else { | ||
256 | + $req[] = $p; | ||
257 | + } | ||
258 | + } | ||
259 | + return $this->send($req); | ||
260 | + } | ||
261 | + | ||
262 | + private function recv_resp($cmd, $params) | ||
263 | + { | ||
264 | + $resp = $this->recv(); | ||
265 | + if ($resp === false) { | ||
266 | + return new Response('error', 'Unknown error'); | ||
267 | + } else if (!$resp) { | ||
268 | + return new Response('disconnected', 'Connection closed'); | ||
269 | + } | ||
270 | + if ($resp[0] == 'noauth') { | ||
271 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
272 | + return new Response($resp[0], $errmsg); | ||
273 | + } | ||
274 | + switch ($cmd) { | ||
275 | + case 'dbsize': | ||
276 | + case 'ping': | ||
277 | + case 'qset': | ||
278 | + case 'getbit': | ||
279 | + case 'setbit': | ||
280 | + case 'countbit': | ||
281 | + case 'strlen': | ||
282 | + case 'set': | ||
283 | + case 'setx': | ||
284 | + case 'setnx': | ||
285 | + case 'zset': | ||
286 | + case 'hset': | ||
287 | + case 'qpush': | ||
288 | + case 'qpush_front': | ||
289 | + case 'qpush_back': | ||
290 | + case 'qtrim_front': | ||
291 | + case 'qtrim_back': | ||
292 | + case 'del': | ||
293 | + case 'zdel': | ||
294 | + case 'hdel': | ||
295 | + case 'hsize': | ||
296 | + case 'zsize': | ||
297 | + case 'qsize': | ||
298 | + case 'hclear': | ||
299 | + case 'zclear': | ||
300 | + case 'qclear': | ||
301 | + case 'multi_set': | ||
302 | + case 'multi_del': | ||
303 | + case 'multi_hset': | ||
304 | + case 'multi_hdel': | ||
305 | + case 'multi_zset': | ||
306 | + case 'multi_zdel': | ||
307 | + case 'incr': | ||
308 | + case 'decr': | ||
309 | + case 'zincr': | ||
310 | + case 'zdecr': | ||
311 | + case 'hincr': | ||
312 | + case 'hdecr': | ||
313 | + case 'zget': | ||
314 | + case 'zrank': | ||
315 | + case 'zrrank': | ||
316 | + case 'zcount': | ||
317 | + case 'zsum': | ||
318 | + case 'zremrangebyrank': | ||
319 | + case 'zremrangebyscore': | ||
320 | + if ($resp[0] == 'ok') { | ||
321 | + $val = isset($resp[1]) ? intval($resp[1]) : 0; | ||
322 | + return new Response($resp[0], $val); | ||
323 | + } else { | ||
324 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
325 | + return new Response($resp[0], $errmsg); | ||
326 | + } | ||
327 | + case 'zavg': | ||
328 | + if ($resp[0] == 'ok') { | ||
329 | + $val = isset($resp[1]) ? floatval($resp[1]) : (float)0; | ||
330 | + return new Response($resp[0], $val); | ||
331 | + } else { | ||
332 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
333 | + return new Response($resp[0], $errmsg); | ||
334 | + } | ||
335 | + case 'get': | ||
336 | + case 'substr': | ||
337 | + case 'getset': | ||
338 | + case 'hget': | ||
339 | + case 'qget': | ||
340 | + case 'qfront': | ||
341 | + case 'qback': | ||
342 | + if ($resp[0] == 'ok') { | ||
343 | + if (count($resp) == 2) { | ||
344 | + return new Response('ok', $resp[1]); | ||
345 | + } else { | ||
346 | + return new Response('server_error', 'Invalid response'); | ||
347 | + } | ||
348 | + } else { | ||
349 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
350 | + return new Response($resp[0], $errmsg); | ||
351 | + } | ||
352 | + break; | ||
353 | + case 'qpop': | ||
354 | + case 'qpop_front': | ||
355 | + case 'qpop_back': | ||
356 | + if ($resp[0] == 'ok') { | ||
357 | + $size = 1; | ||
358 | + if (isset($params[1])) { | ||
359 | + $size = intval($params[1]); | ||
360 | + } | ||
361 | + if ($size <= 1) { | ||
362 | + if (count($resp) == 2) { | ||
363 | + return new Response('ok', $resp[1]); | ||
364 | + } else { | ||
365 | + return new Response('server_error', 'Invalid response'); | ||
366 | + } | ||
367 | + } else { | ||
368 | + $data = array_slice($resp, 1); | ||
369 | + return new Response('ok', $data); | ||
370 | + } | ||
371 | + } else { | ||
372 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
373 | + return new Response($resp[0], $errmsg); | ||
374 | + } | ||
375 | + break; | ||
376 | + case 'keys': | ||
377 | + case 'zkeys': | ||
378 | + case 'hkeys': | ||
379 | + case 'hlist': | ||
380 | + case 'zlist': | ||
381 | + case 'qslice': | ||
382 | + if ($resp[0] == 'ok') { | ||
383 | + $data = array(); | ||
384 | + if ($resp[0] == 'ok') { | ||
385 | + $data = array_slice($resp, 1); | ||
386 | + } | ||
387 | + return new Response($resp[0], $data); | ||
388 | + } else { | ||
389 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
390 | + return new Response($resp[0], $errmsg); | ||
391 | + } | ||
392 | + case 'auth': | ||
393 | + case 'exists': | ||
394 | + case 'hexists': | ||
395 | + case 'zexists': | ||
396 | + if ($resp[0] == 'ok') { | ||
397 | + if (count($resp) == 2) { | ||
398 | + return new Response('ok', (bool)$resp[1]); | ||
399 | + } else { | ||
400 | + return new Response('server_error', 'Invalid response'); | ||
401 | + } | ||
402 | + } else { | ||
403 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
404 | + return new Response($resp[0], $errmsg); | ||
405 | + } | ||
406 | + break; | ||
407 | + case 'multi_exists': | ||
408 | + case 'multi_hexists': | ||
409 | + case 'multi_zexists': | ||
410 | + if ($resp[0] == 'ok') { | ||
411 | + if (count($resp) % 2 == 1) { | ||
412 | + $data = array(); | ||
413 | + for ($i = 1; $i < count($resp); $i += 2) { | ||
414 | + $data[$resp[$i]] = (bool)$resp[$i + 1]; | ||
415 | + } | ||
416 | + return new Response('ok', $data); | ||
417 | + } else { | ||
418 | + return new Response('server_error', 'Invalid response'); | ||
419 | + } | ||
420 | + } else { | ||
421 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
422 | + return new Response($resp[0], $errmsg); | ||
423 | + } | ||
424 | + break; | ||
425 | + case 'scan': | ||
426 | + case 'rscan': | ||
427 | + case 'zscan': | ||
428 | + case 'zrscan': | ||
429 | + case 'zrange': | ||
430 | + case 'zrrange': | ||
431 | + case 'hscan': | ||
432 | + case 'hrscan': | ||
433 | + case 'hgetall': | ||
434 | + case 'multi_hsize': | ||
435 | + case 'multi_zsize': | ||
436 | + case 'multi_get': | ||
437 | + case 'multi_hget': | ||
438 | + case 'multi_zget': | ||
439 | + if ($resp[0] == 'ok') { | ||
440 | + if (count($resp) % 2 == 1) { | ||
441 | + $data = array(); | ||
442 | + for ($i = 1; $i < count($resp); $i += 2) { | ||
443 | + if ($cmd[0] == 'z') { | ||
444 | + $data[$resp[$i]] = intval($resp[$i + 1]); | ||
445 | + } else { | ||
446 | + $data[$resp[$i]] = $resp[$i + 1]; | ||
447 | + } | ||
448 | + } | ||
449 | + return new Response('ok', $data); | ||
450 | + } else { | ||
451 | + return new Response('server_error', 'Invalid response'); | ||
452 | + } | ||
453 | + } else { | ||
454 | + $errmsg = isset($resp[1]) ? $resp[1] : ''; | ||
455 | + return new Response($resp[0], $errmsg); | ||
456 | + } | ||
457 | + break; | ||
458 | + default: | ||
459 | + return new Response($resp[0], array_slice($resp, 1)); | ||
460 | + } | ||
461 | + return new Response('error', 'Unknown command: $cmd'); | ||
462 | + } | ||
463 | + | ||
464 | + private function send($data) | ||
465 | + { | ||
466 | + $ps = array(); | ||
467 | + foreach ($data as $p) { | ||
468 | + $ps[] = strlen($p); | ||
469 | + $ps[] = $p; | ||
470 | + } | ||
471 | + $s = join("\n", $ps) . "\n\n"; | ||
472 | + if ($this->debug) { | ||
473 | + echo '> ' . str_replace(array("\r", "\n"), array('\r', '\n'), $s) . "\n"; | ||
474 | + } | ||
475 | + try { | ||
476 | + while (true) { | ||
477 | + $ret = @fwrite($this->sock, $s); | ||
478 | + if ($ret === false) { | ||
479 | + $this->close(); | ||
480 | + throw new SSDBException('Connection lost'); | ||
481 | + } | ||
482 | + $s = substr($s, $ret); | ||
483 | + if (strlen($s) == 0) { | ||
484 | + break; | ||
485 | + } | ||
486 | + @fflush($this->sock); | ||
487 | + } | ||
488 | + } catch (Exception $e) { | ||
489 | + $this->close(); | ||
490 | + throw new SSDBException($e->getMessage()); | ||
491 | + } | ||
492 | + return $ret; | ||
493 | + } | ||
494 | + | ||
495 | + private function recv() | ||
496 | + { | ||
497 | + $this->step = self::STEP_SIZE; | ||
498 | + while (true) { | ||
499 | + $ret = $this->parse(); | ||
500 | + if ($ret === null) { | ||
501 | + try { | ||
502 | + $data = @fread($this->sock, 1024 * 1024); | ||
503 | + if ($this->debug) { | ||
504 | + echo '< ' . str_replace(array("\r", "\n"), array('\r', '\n'), $data) . "\n"; | ||
505 | + } | ||
506 | + } catch (Exception $e) { | ||
507 | + $data = ''; | ||
508 | + } | ||
509 | + if ($data === false || $data === '') { | ||
510 | + if (feof($this->sock)) { | ||
511 | + $this->close(); | ||
512 | + throw new SSDBException('Connection lost'); | ||
513 | + } else { | ||
514 | + throw new SSDBTimeoutException('Connection timeout'); | ||
515 | + } | ||
516 | + } | ||
517 | + $this->recv_buf .= $data; | ||
518 | +# echo "read " . strlen($data) . " total: " . strlen($this->recv_buf) . "\n"; | ||
519 | + } else { | ||
520 | + return $ret; | ||
521 | + } | ||
522 | + } | ||
523 | + } | ||
524 | + | ||
525 | + const STEP_SIZE = 0; | ||
526 | + const STEP_DATA = 1; | ||
527 | + public $resp = array(); | ||
528 | + public $step; | ||
529 | + public $block_size; | ||
530 | + | ||
531 | + private function parse() | ||
532 | + { | ||
533 | + $spos = 0; | ||
534 | + $epos = 0; | ||
535 | + $buf_size = strlen($this->recv_buf); | ||
536 | + // performance issue for large reponse | ||
537 | + //$this->recv_buf = ltrim($this->recv_buf); | ||
538 | + while (true) { | ||
539 | + $spos = $epos; | ||
540 | + if ($this->step === self::STEP_SIZE) { | ||
541 | + $epos = strpos($this->recv_buf, "\n", $spos); | ||
542 | + if ($epos === false) { | ||
543 | + break; | ||
544 | + } | ||
545 | + $epos += 1; | ||
546 | + $line = substr($this->recv_buf, $spos, $epos - $spos); | ||
547 | + $spos = $epos; | ||
548 | + | ||
549 | + $line = trim($line); | ||
550 | + if (strlen($line) == 0) { // head end | ||
551 | + $this->recv_buf = substr($this->recv_buf, $spos); | ||
552 | + $ret = $this->resp; | ||
553 | + $this->resp = array(); | ||
554 | + return $ret; | ||
555 | + } | ||
556 | + $this->block_size = intval($line); | ||
557 | + $this->step = self::STEP_DATA; | ||
558 | + } | ||
559 | + if ($this->step === self::STEP_DATA) { | ||
560 | + $epos = $spos + $this->block_size; | ||
561 | + if ($epos <= $buf_size) { | ||
562 | + $n = strpos($this->recv_buf, "\n", $epos); | ||
563 | + if ($n !== false) { | ||
564 | + $data = substr($this->recv_buf, $spos, $epos - $spos); | ||
565 | + $this->resp[] = $data; | ||
566 | + $epos = $n + 1; | ||
567 | + $this->step = self::STEP_SIZE; | ||
568 | + continue; | ||
569 | + } | ||
570 | + } | ||
571 | + break; | ||
572 | + } | ||
573 | + } | ||
574 | + | ||
575 | + // packet not ready | ||
576 | + if ($spos > 0) { | ||
577 | + $this->recv_buf = substr($this->recv_buf, $spos); | ||
578 | + } | ||
579 | + return null; | ||
580 | + } | ||
581 | +} |
yaf/Hood/Cache/Ssdb/Response.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 1/27/15 | ||
6 | + * Time: 10:30 PM | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache\Ssdb; | ||
10 | + | ||
11 | + | ||
12 | +class Response | ||
13 | +{ | ||
14 | + public $cmd; | ||
15 | + public $code; | ||
16 | + public $data = null; | ||
17 | + public $message; | ||
18 | + | ||
19 | + function __construct($code = 'ok', $data_or_message = null) | ||
20 | + { | ||
21 | + $this->code = $code; | ||
22 | + if ($code == 'ok') { | ||
23 | + $this->data = $data_or_message; | ||
24 | + } else { | ||
25 | + $this->message = $data_or_message; | ||
26 | + } | ||
27 | + } | ||
28 | + | ||
29 | + function __toString() | ||
30 | + { | ||
31 | + if ($this->code == 'ok') { | ||
32 | + $s = $this->data === null ? '' : json_encode($this->data); | ||
33 | + } else { | ||
34 | + $s = $this->message; | ||
35 | + } | ||
36 | + return sprintf('%-13s %12s %s', $this->cmd, $this->code, $s); | ||
37 | + } | ||
38 | + | ||
39 | + function ok() | ||
40 | + { | ||
41 | + return $this->code == 'ok'; | ||
42 | + } | ||
43 | + | ||
44 | + function not_found() | ||
45 | + { | ||
46 | + return $this->code == 'not_found'; | ||
47 | + } | ||
48 | +} |
yaf/Hood/Cache/Ssdb/SSDBException.php
0 → 100644
yaf/Hood/Cache/Ssdb/SSDBTimeoutException.php
0 → 100644
yaf/Hood/Cache/Ssdb/SimpleSSDB.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 1/27/15 | ||
6 | + * Time: 11:25 PM | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Cache\Ssdb; | ||
10 | + | ||
11 | + | ||
12 | +class SimpleSSDB extends Client | ||
13 | +{ | ||
14 | + | ||
15 | + private $node; | ||
16 | + | ||
17 | + private $childNode; | ||
18 | + | ||
19 | + function __construct($host, $port, $timeout_ms = 2000) | ||
20 | + { | ||
21 | + parent::__construct($host, $port, $timeout_ms); | ||
22 | + $this->easy(); | ||
23 | + } | ||
24 | + | ||
25 | + public function setNode($node) | ||
26 | + { | ||
27 | + | ||
28 | + } | ||
29 | + | ||
30 | + public function setChildNodes($childNode) | ||
31 | + { | ||
32 | + | ||
33 | + } | ||
34 | + | ||
35 | +} |
yaf/Hood/Concurrent.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/16 | ||
6 | + * Time: 下午5:05 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood; | ||
10 | + | ||
11 | +use Hood\Concurrent\Yar; | ||
12 | +use Hood\Concurrent\Http; | ||
13 | + | ||
14 | +class Concurrent | ||
15 | +{ | ||
16 | + /** | ||
17 | + * @param $url | ||
18 | + * @return Yar\Client | ||
19 | + */ | ||
20 | + static public function yarClient($url) | ||
21 | + { | ||
22 | + return new Yar\Client($url); | ||
23 | + } | ||
24 | + | ||
25 | + /** | ||
26 | + * @param $uri | ||
27 | + * @return Yar\Concurrent | ||
28 | + */ | ||
29 | + static public function yarConcurrent($uri) | ||
30 | + { | ||
31 | + return new Yar\Concurrent($uri); | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * | ||
36 | + * @return Http\CurlMulti | ||
37 | + */ | ||
38 | + static public function curlMulti() | ||
39 | + { | ||
40 | + return new Http\CurlMulti(); | ||
41 | + } | ||
42 | +} |
yaf/Hood/Concurrent/ConcurrentInterface.php
0 → 100644
yaf/Hood/Concurrent/Http/Curl.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/22 | ||
6 | + * Time: 下午12:23 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Concurrent\Http; | ||
10 | + | ||
11 | + | ||
12 | +class Curl extends CurlAbstract | ||
13 | +{ | ||
14 | + | ||
15 | + /** | ||
16 | + * GET方式网络请求 | ||
17 | + * @param $url | ||
18 | + * @param array $data | ||
19 | + * @param int $timeout | ||
20 | + * @return mixed | ||
21 | + */ | ||
22 | + public static function get($url, array $data = array(), $timeout = 20) | ||
23 | + { | ||
24 | + $ch = curl_init(self::makeUrl($url, $data)); | ||
25 | + curl_setopt($ch, CURLOPT_HEADER, 0); | ||
26 | + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
27 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
28 | + $result = curl_exec($ch); | ||
29 | + curl_close($ch); | ||
30 | + return $result; | ||
31 | + } | ||
32 | + | ||
33 | + | ||
34 | + /** | ||
35 | + * post提交数据 | ||
36 | + * @param $url | ||
37 | + * @param $data | ||
38 | + * @param int $timeout | ||
39 | + * @param array $header | ||
40 | + * @param array $cookie | ||
41 | + * @return mixed | ||
42 | + */ | ||
43 | + public static function post($url, $data, $timeout = 20, array $header = array(), array $cookie = array()) | ||
44 | + { | ||
45 | + $ch = curl_init($url); | ||
46 | + curl_setopt($ch, CURLOPT_HEADER, 0); | ||
47 | + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
48 | + if (!empty($header)) { | ||
49 | + curl_setopt($ch, CURLOPT_HTTPHEADER, $header);// array('Content-Type:application/json;charset=UTF-8')); | ||
50 | + } | ||
51 | + | ||
52 | + if (!empty($cookie)) { | ||
53 | + $cookie_str = array(); | ||
54 | + foreach ($cookie as $key => $val) { | ||
55 | + $cookie_str[] = urlencode($key) . '=' . urlencode($val); | ||
56 | + } | ||
57 | + curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str)); | ||
58 | + } | ||
59 | + | ||
60 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
61 | + curl_setopt($ch, CURLOPT_POST, true); | ||
62 | + if (!empty($data)) { | ||
63 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | ||
64 | + } | ||
65 | + $result = curl_exec($ch); | ||
66 | +// $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
67 | + curl_close($ch); | ||
68 | + return $result; | ||
69 | + } | ||
70 | + | ||
71 | +} |
yaf/Hood/Concurrent/Http/CurlAbstract.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 15/4/8 | ||
6 | + * Time: 下午1:55 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Concurrent\Http; | ||
10 | + | ||
11 | + | ||
12 | +class CurlAbstract | ||
13 | +{ | ||
14 | + public static function makeUrl($url, array $data) | ||
15 | + { | ||
16 | + $params = ''; | ||
17 | + if (!empty($data)) { | ||
18 | + $params = http_build_query($data, '', '&'); | ||
19 | + } | ||
20 | + if (strpos($url, '?') === false) { | ||
21 | + $url = $url . '?' . $params; | ||
22 | + } else { | ||
23 | + if (!empty($params)) { | ||
24 | + $url = $url . '&' . $params; | ||
25 | + } | ||
26 | + } | ||
27 | + return $url; | ||
28 | + } | ||
29 | +} |
yaf/Hood/Concurrent/Http/CurlMulti.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 15/4/7 | ||
6 | + * Time: 下午9:15 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Concurrent\Http; | ||
10 | + | ||
11 | +class CurlMulti extends CurlAbstract | ||
12 | +{ | ||
13 | + | ||
14 | + private $_curls = array(); | ||
15 | + | ||
16 | + private $_handle = NULL; | ||
17 | + | ||
18 | + private $wait_for_connect = false; | ||
19 | + | ||
20 | + private $headerData = array(); | ||
21 | + | ||
22 | + | ||
23 | + public function __construct() | ||
24 | + { | ||
25 | + $this->_handle = curl_multi_init(); | ||
26 | + } | ||
27 | + | ||
28 | + public function __destruct() | ||
29 | + { | ||
30 | + foreach ($this->_curls as $handle_id => $data) { | ||
31 | + curl_multi_remove_handle($this->_handle, $data['handle']); | ||
32 | + curl_close($data['handle']); | ||
33 | + } | ||
34 | + curl_multi_close($this->_handle); | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * 设置是否等待 | ||
39 | + * @param $wait_for_connect | ||
40 | + * @return $this | ||
41 | + */ | ||
42 | + public function wait($wait_for_connect) | ||
43 | + { | ||
44 | + $this->wait_for_connect = $wait_for_connect; | ||
45 | + return $this; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * 设置header | ||
50 | + * @param array $headerData | ||
51 | + * @return $this | ||
52 | + */ | ||
53 | + public function header(array $headerData) | ||
54 | + { | ||
55 | + $this->headerData = $headerData; | ||
56 | + return $this; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * 调用 | ||
61 | + * @param $url | ||
62 | + * @param $callback | ||
63 | + * @param $data | ||
64 | + * @return $this | ||
65 | + * @throws Exception | ||
66 | + */ | ||
67 | + public function get($url, $callback, array $data = array()) | ||
68 | + { | ||
69 | + $ch = curl_init(self::makeUrl($url, $data)); | ||
70 | + $this->addHandle($ch, $callback, $data, $this->wait_for_connect); | ||
71 | + return $this; | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * 调用 | ||
76 | + * @param $url | ||
77 | + * @param $callback | ||
78 | + * @param $data | ||
79 | + * @return $this | ||
80 | + * @throws Exception | ||
81 | + */ | ||
82 | + public function post($url, $callback, $data) | ||
83 | + { | ||
84 | + $this->callRest($url, 'POST', $callback, $data); | ||
85 | + return $this; | ||
86 | + } | ||
87 | + | ||
88 | + | ||
89 | + /** | ||
90 | + * rest 请求方法 | ||
91 | + * @param $url | ||
92 | + * @param $method | ||
93 | + * @param $callback | ||
94 | + * @param null $data | ||
95 | + * @return $this | ||
96 | + * @throws Exception | ||
97 | + */ | ||
98 | + public function callRest($url, $method, $callback, $data = NULL) | ||
99 | + { | ||
100 | + switch (strtoupper($method)) { | ||
101 | + case 'POST': | ||
102 | + $ch = curl_init($url); | ||
103 | + curl_setopt($ch, CURLOPT_POST, TRUE); | ||
104 | + $this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: POST")); | ||
105 | + if ($data != null) { | ||
106 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | ||
107 | + } | ||
108 | + break; | ||
109 | + case 'DELETE': | ||
110 | + $ch = curl_init(self::makeUrl($url, $data)); | ||
111 | + $this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: DELETE")); | ||
112 | + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); | ||
113 | + break; | ||
114 | + case 'PUT': | ||
115 | + $ch = curl_init($url); | ||
116 | + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); | ||
117 | + $this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: PUT")); | ||
118 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
119 | + if ($data != null) { | ||
120 | + $params = http_build_query($data, '', '&'); | ||
121 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); | ||
122 | + curl_setopt($ch, CURLOPT_INFILESIZE, strlen($params)); | ||
123 | + } | ||
124 | + break; | ||
125 | + case 'GET': | ||
126 | + $ch = curl_init(self::makeUrl($url, $data)); | ||
127 | + $this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: GET")); | ||
128 | + break; | ||
129 | + } | ||
130 | + $this->addHandle($ch, $callback, $data, $this->wait_for_connect); | ||
131 | + return $this; | ||
132 | + } | ||
133 | + | ||
134 | + /** | ||
135 | + * 添加一个handle | ||
136 | + * @param $curl_handle | ||
137 | + * @param $callback | ||
138 | + * @param $data | ||
139 | + * @param bool $wait_for_connect #是否等待 | ||
140 | + * @return bool | ||
141 | + * @throws Exception | ||
142 | + */ | ||
143 | + private function addHandle($curl_handle, $callback, $data, $wait_for_connect = false) | ||
144 | + { | ||
145 | + if (get_resource_type($curl_handle) !== 'curl' || !is_callable($callback)) { | ||
146 | + throw new \Exception("Invalid curl handle or callback"); | ||
147 | + } | ||
148 | + curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE); | ||
149 | + if (!empty($this->headerData)) { | ||
150 | + curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $this->headerData); | ||
151 | + } | ||
152 | + $this->_curls[(int)$curl_handle] = array( | ||
153 | + 'handle' => $curl_handle, | ||
154 | + 'callback' => $callback, | ||
155 | + 'callback_data' => $data, | ||
156 | + ); | ||
157 | + curl_multi_add_handle($this->_handle, $curl_handle); | ||
158 | + if ($wait_for_connect) { | ||
159 | + $this->poll(); | ||
160 | + } | ||
161 | + return TRUE; | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * 移除会话中的hendle | ||
166 | + * @param $curl_handle | ||
167 | + * @return bool | ||
168 | + */ | ||
169 | + public function removeHandle($curl_handle) | ||
170 | + { | ||
171 | + if (!isset($this->_curls[(int)$curl_handle])) { | ||
172 | + return FALSE; | ||
173 | + } | ||
174 | + curl_multi_remove_handle($this->_handle, $curl_handle); | ||
175 | + unset($this->_curls[(int)$curl_handle]); | ||
176 | + return TRUE; | ||
177 | + } | ||
178 | + | ||
179 | + /** | ||
180 | + * 等待所有会话 | ||
181 | + * @return bool | ||
182 | + */ | ||
183 | + public function poll() | ||
184 | + { | ||
185 | + $still_running = 0; | ||
186 | + do { | ||
187 | + $result = curl_multi_exec($this->_handle, $still_running); | ||
188 | + if ($result == CURLM_OK) { | ||
189 | + do { | ||
190 | + $messages_in_queue = 0; | ||
191 | + $info = curl_multi_info_read($this->_handle, $messages_in_queue); | ||
192 | + if ($info && isset($info['handle']) && isset($this->_curls[(int)$info['handle']])) { | ||
193 | + $callback_info = $this->_curls[(int)$info['handle']]; | ||
194 | + $curl_data = curl_multi_getcontent($info['handle']); | ||
195 | + $curl_info = curl_getinfo($info['handle']); | ||
196 | + call_user_func($callback_info['callback'], $curl_data, $curl_info); | ||
197 | + $this->removeHandle($info['handle']); | ||
198 | + curl_close($info['handle']); | ||
199 | + } | ||
200 | + } while ($messages_in_queue > 0); | ||
201 | + } | ||
202 | + } while ($result == CURLM_CALL_MULTI_PERFORM && $still_running > 0); | ||
203 | + return (boolean)$this->_curls; | ||
204 | + } | ||
205 | + | ||
206 | + /** | ||
207 | + * 设置堵塞中的会话超时时间 | ||
208 | + * @param float $timeout | ||
209 | + * @return bool | ||
210 | + */ | ||
211 | + public function select($timeout = 1.0) | ||
212 | + { | ||
213 | + $result = $this->poll(); | ||
214 | + if ($result) { | ||
215 | + curl_multi_select($this->_handle, $timeout); | ||
216 | + $result = $this->poll(); | ||
217 | + } | ||
218 | + return $result; | ||
219 | + } | ||
220 | + | ||
221 | + /** | ||
222 | + * 刷新所有会话超时时间 | ||
223 | + * @return bool | ||
224 | + */ | ||
225 | + public function finish() | ||
226 | + { | ||
227 | + while ($this->select() === TRUE) { | ||
228 | + } | ||
229 | + return TRUE; | ||
230 | + } | ||
231 | +} |
yaf/Hood/Concurrent/Yar/Client.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/15 | ||
6 | + * Time: 上午2:02 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Concurrent\Yar; | ||
10 | + | ||
11 | +use Hood\Core\Root; | ||
12 | + | ||
13 | +class Client extends Root | ||
14 | +{ | ||
15 | + /** | ||
16 | + * @var array | ||
17 | + */ | ||
18 | + private $_instances = array(); | ||
19 | + | ||
20 | + /** | ||
21 | + * @var \Yar_Client | ||
22 | + */ | ||
23 | + private $client; | ||
24 | + | ||
25 | + /** | ||
26 | + * Set timeout to 3s | ||
27 | + * @var int | ||
28 | + */ | ||
29 | + private $_timeout = 3000; | ||
30 | + | ||
31 | + /** | ||
32 | + * @param $uri | ||
33 | + */ | ||
34 | + public function __construct($uri) | ||
35 | + { | ||
36 | + parent::__construct(); | ||
37 | + $yarKey = md5($uri); | ||
38 | + if (!isset($this->_instances[$yarKey])) { | ||
39 | + $this->_instances[$yarKey] = new \Yar_Client($uri); | ||
40 | + } | ||
41 | + $this->client = $this->_instances[$yarKey]; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 设置yar参数 | ||
46 | + * @param $name | ||
47 | + * @param $value | ||
48 | + */ | ||
49 | + public function setOpt($name, $value) | ||
50 | + { | ||
51 | + $this->client->setOpt($name, $value); | ||
52 | + return $this; | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * 数据包类型 | ||
57 | + * @param string $packagerType | ||
58 | + */ | ||
59 | + public function setPackager($packagerType = YAR_PACKAGER_PHP) | ||
60 | + { | ||
61 | + $this->client->setOpt(YAR_OPT_PACKAGER, $packagerType); | ||
62 | + return $this; | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * 连接超时(毫秒为单位) | ||
67 | + * @param $timeout | ||
68 | + */ | ||
69 | + public function setConnectTimeout($timeout = 1000) | ||
70 | + { | ||
71 | + $this->client->setOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout); | ||
72 | + return $this; | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * Set timeout to 3s | ||
77 | + * 处理超时(毫秒为单位) | ||
78 | + * @param $timeout | ||
79 | + * @return $this | ||
80 | + */ | ||
81 | + public function setTimeout($timeout = 3000) | ||
82 | + { | ||
83 | + $this->client->setOpt(YAR_OPT_TIMEOUT, $timeout); | ||
84 | + return $this; | ||
85 | + } | ||
86 | + | ||
87 | + /** | ||
88 | + * @param $name | ||
89 | + * @param array $arguments | ||
90 | + * @return mixed | ||
91 | + */ | ||
92 | + public function __call($method, $parameters) | ||
93 | + { | ||
94 | + return $this->client->__call($method, $parameters); | ||
95 | + } | ||
96 | +} |
yaf/Hood/Concurrent/Yar/Concurrent.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/15 | ||
6 | + * Time: 上午2:02 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Concurrent\Yar; | ||
10 | + | ||
11 | +use Hood\Core\Root; | ||
12 | + | ||
13 | +class Concurrent extends Root | ||
14 | +{ | ||
15 | + private $uri; | ||
16 | + | ||
17 | + public function __construct($uri) | ||
18 | + { | ||
19 | + parent::__construct(); | ||
20 | + $this->uri = $uri; | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * 注册一个并行的服务调用 | ||
25 | + * @param $uri | ||
26 | + * @param $method | ||
27 | + * @param $parameters | ||
28 | + * @param string $callback | ||
29 | + */ | ||
30 | + public function call($uri, $method, $parameters, $callback = '') | ||
31 | + { | ||
32 | + \Yar_Concurrent_Client::call($uri, $method, $parameters, $callback); | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * 链式调用 | ||
37 | + * @param $method | ||
38 | + * @param $parameters | ||
39 | + * @param string $callback | ||
40 | + * @return $this | ||
41 | + */ | ||
42 | + public function calls($method, $parameters, $callback = '') | ||
43 | + { | ||
44 | + $this->call($this->uri, $method, $parameters, $callback); | ||
45 | + return $this; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * 发送所有注册的并行调用 | ||
50 | + * @param string $callback | ||
51 | + * @param callable $errorCallback | ||
52 | + */ | ||
53 | + public function loop($callback = '', $errorCallback = '') | ||
54 | + { | ||
55 | + \Yar_Concurrent_Client::loop($callback, $errorCallback); | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * 缓存tag | ||
60 | + * @param $tagName | ||
61 | + * @return $this | ||
62 | + */ | ||
63 | + public function tag($tagName) | ||
64 | + { | ||
65 | + $this->_cacheTagName = $tagName; | ||
66 | + return $this; | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * 缓存key | ||
71 | + * @param string $key | ||
72 | + * @param null $prefix | ||
73 | + * @return $this | ||
74 | + */ | ||
75 | + public function key($key) | ||
76 | + { | ||
77 | + $this->_cacheKey = (string)$key; | ||
78 | + return $this; | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * 缓存时间 | ||
83 | + * @param $expire | ||
84 | + * @return $this | ||
85 | + */ | ||
86 | + public function expire($expire) | ||
87 | + { | ||
88 | + $this->_cacheExpire = (int)$expire; | ||
89 | + return $this; | ||
90 | + } | ||
91 | +} |
yaf/Hood/Cookie.php
0 → 100644
1 | +<?php | ||
2 | +namespace Hood; | ||
3 | + | ||
4 | +use Hood\Debug\DebugException; | ||
5 | + | ||
6 | +class Cookie | ||
7 | +{ | ||
8 | + /** | ||
9 | + * 取得所有的cookie值 | ||
10 | + * | ||
11 | + * @return array | ||
12 | + * @since 0.2.2 | ||
13 | + */ | ||
14 | + public static function all() | ||
15 | + { | ||
16 | + return $_COOKIE; | ||
17 | + } | ||
18 | + | ||
19 | + /** | ||
20 | + * @param $name | ||
21 | + * @param string $default | ||
22 | + * @return string | ||
23 | + * @throws DebugException | ||
24 | + */ | ||
25 | + public static function get($name, $default = '') | ||
26 | + { | ||
27 | + if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { | ||
28 | + throw new DebugException(sprintf('The cookie name "%s" contains invalid characters.', $name)); | ||
29 | + } | ||
30 | + return isset ($_COOKIE [$name]) ? $_COOKIE [$name] : $default; | ||
31 | + } | ||
32 | + | ||
33 | + /** | ||
34 | + * 设置cookie | ||
35 | + * @param string $name | ||
36 | + * @param string $domain | ||
37 | + * @param string $value | ||
38 | + * @param int $expire (0:Session、-1:删除、time():过期时间 ) | ||
39 | + * @param string $path | ||
40 | + * @param bool $httponly | ||
41 | + * @param bool $secureAuto | ||
42 | + */ | ||
43 | + public static function set($name, $value, $minutes = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) | ||
44 | + { | ||
45 | + if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { | ||
46 | + throw new DebugException(sprintf('The cookie name "%s" contains invalid characters.', $name)); | ||
47 | + } | ||
48 | + $expire = $minutes; | ||
49 | + if ($minutes == 0) { | ||
50 | + $expire = 0; | ||
51 | + } else if ($minutes == -1) { | ||
52 | + $expire = time() - 3600; | ||
53 | + } | ||
54 | + setcookie($name, $value, $expire, $path, $domain, (bool)$secure, $httpOnly); | ||
55 | + } | ||
56 | +} |
yaf/Hood/Core/Root.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/7 | ||
6 | + * Time: 上午12:45 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Core; | ||
10 | + | ||
11 | +use Hood\Core\Server; | ||
12 | + | ||
13 | +class Root | ||
14 | +{ | ||
15 | + | ||
16 | + /** | ||
17 | + * server file | ||
18 | + * @var String | ||
19 | + */ | ||
20 | + protected $serviceFile; | ||
21 | + | ||
22 | + /** | ||
23 | + * 应用环境 | ||
24 | + * @var string | ||
25 | + */ | ||
26 | + protected $applicationEnv; | ||
27 | + | ||
28 | + | ||
29 | + /** | ||
30 | + * 缓存时间 | ||
31 | + * @var int | ||
32 | + */ | ||
33 | + protected $_cacheExpire = 3600; | ||
34 | + | ||
35 | + /** | ||
36 | + * 缓存 | ||
37 | + * @var bool | ||
38 | + */ | ||
39 | + protected $_cacheStatus = true; | ||
40 | + | ||
41 | + /** | ||
42 | + * 缓存key | ||
43 | + * @var null | ||
44 | + */ | ||
45 | + protected $_cacheKey = null; | ||
46 | + | ||
47 | + /** | ||
48 | + * 缓存tagName | ||
49 | + * @var string | ||
50 | + */ | ||
51 | + protected $_cacheTagName = ''; | ||
52 | + | ||
53 | + | ||
54 | + /** | ||
55 | + * 删除多个缓存tag | ||
56 | + */ | ||
57 | + protected $_delTags = array(); | ||
58 | + | ||
59 | + | ||
60 | + public function __construct() | ||
61 | + { | ||
62 | + defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'developer'); | ||
63 | + defined('APPLICATION_SYSTEM_CONFIG') || define('APPLICATION_SYSTEM_CONFIG', '/Data/Code/SystemConfig'); | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * 获取应用环境 | ||
68 | + * @return string | ||
69 | + */ | ||
70 | + public function getApplicationEnv() | ||
71 | + { | ||
72 | + return $this->applicationEnv; | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * 设置应用环境 | ||
77 | + * @param $env | ||
78 | + * @return $this | ||
79 | + */ | ||
80 | + public function setApplicationEnv($env) | ||
81 | + { | ||
82 | + define('APPLICATION_ENV', $env); | ||
83 | + return $this; | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * | ||
88 | + * @param $configFile | ||
89 | + * @return $this | ||
90 | + */ | ||
91 | + public function setApplicationSystemConfig($configFile) | ||
92 | + { | ||
93 | + define('APPLICATION_SYSTEM_CONFIG', $configFile); | ||
94 | + return $this; | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
98 | + * 获取server | ||
99 | + * @param $serviceName | ||
100 | + * @param string $suffix | ||
101 | + * @return Server | ||
102 | + */ | ||
103 | + public function getServerHost($serviceName, $suffix = 'config.ini') | ||
104 | + { | ||
105 | + $serviceFileArray = array( | ||
106 | + $serviceName, | ||
107 | + APPLICATION_ENV, | ||
108 | + $suffix | ||
109 | + ); | ||
110 | + $this->serviceFile = $serviceFile = APPLICATION_SYSTEM_CONFIG . DIRECTORY_SEPARATOR . implode('.', $serviceFileArray); | ||
111 | + return new Server($serviceFile); | ||
112 | + } | ||
113 | +} |
yaf/Hood/Core/Security/AuthCode.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace Hood\Core\Security; | ||
4 | +/** | ||
5 | + * Class AuthCode | ||
6 | + * @package Hood\Core\Security | ||
7 | + */ | ||
8 | +class AuthCode | ||
9 | +{ | ||
10 | + | ||
11 | + /** | ||
12 | + * 验证编码 | ||
13 | + * | ||
14 | + * @param String $string | ||
15 | + * @param String $operation | ||
16 | + * @param Integer $expiry | ||
17 | + * @param String $key | ||
18 | + * @return String | ||
19 | + */ | ||
20 | + private static function auth($string, $key, $expiry = 0, $operation = 'decode') | ||
21 | + { | ||
22 | + $ckey_length = 4; | ||
23 | + $key = md5($key); | ||
24 | + $keya = md5(substr($key, 0, 16)); | ||
25 | + $keyb = md5(substr($key, 16, 16)); | ||
26 | + $keyc = $ckey_length ? ($operation == 'decode' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; | ||
27 | + $cryptkey = $keya . md5($keya . $keyc); | ||
28 | + $key_length = strlen($cryptkey); | ||
29 | + $string = $operation == 'decode' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; | ||
30 | + $string_length = strlen($string); | ||
31 | + | ||
32 | + $result = ''; | ||
33 | + $box = range(0, 255); | ||
34 | + | ||
35 | + $rndkey = array(); | ||
36 | + for ($i = 0; $i <= 255; $i++) { | ||
37 | + $rndkey[$i] = ord($cryptkey[$i % $key_length]); | ||
38 | + } | ||
39 | + | ||
40 | + for ($j = $i = 0; $i < 256; $i++) { | ||
41 | + $j = ($j + $box[$i] + $rndkey[$i]) % 256; | ||
42 | + $tmp = $box[$i]; | ||
43 | + $box[$i] = $box[$j]; | ||
44 | + $box[$j] = $tmp; | ||
45 | + } | ||
46 | + | ||
47 | + for ($a = $j = $i = 0; $i < $string_length; $i++) { | ||
48 | + $a = ($a + 1) % 256; | ||
49 | + $j = ($j + $box[$a]) % 256; | ||
50 | + $tmp = $box[$a]; | ||
51 | + $box[$a] = $box[$j]; | ||
52 | + $box[$j] = $tmp; | ||
53 | + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); | ||
54 | + } | ||
55 | + | ||
56 | + if ($operation == 'decode') { | ||
57 | + if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) { | ||
58 | + return substr($result, 26); | ||
59 | + } else { | ||
60 | + return false; | ||
61 | + } | ||
62 | + } else { | ||
63 | + return $keyc . str_replace('=', '', base64_encode($result)); | ||
64 | + } | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * 解密 | ||
69 | + * | ||
70 | + * @param String $string | ||
71 | + * @param String $key | ||
72 | + * @param Integer $expiry | ||
73 | + * @return String | ||
74 | + */ | ||
75 | + public static function decode($string, $key, $expiry = 0) | ||
76 | + { | ||
77 | + return self::auth($string, $key, $expiry, __FUNCTION__); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * 加密 | ||
82 | + * | ||
83 | + * @param String $string | ||
84 | + * @param String $key | ||
85 | + * @param Integer $expiry | ||
86 | + * @return String | ||
87 | + */ | ||
88 | + public static function encode($string, $key, $expiry = 0) | ||
89 | + { | ||
90 | + return self::auth($string, $key, $expiry, __FUNCTION__); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 获取编码 | ||
95 | + * | ||
96 | + * @param String $plaintext | ||
97 | + * @param String $salt | ||
98 | + * @param String $encryption | ||
99 | + * @param bool $show_encrypt | ||
100 | + * @return String | ||
101 | + */ | ||
102 | + public static function getCrypted($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false) | ||
103 | + { | ||
104 | + $salt = self::getSalt($encryption, $salt, $plaintext); | ||
105 | + switch ($encryption) { | ||
106 | + case 'plain' : | ||
107 | + return $plaintext; | ||
108 | + case 'sha' : | ||
109 | + $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext)); | ||
110 | + return ($show_encrypt) ? '{SHA}' . $encrypted : $encrypted; | ||
111 | + case 'crypt' : | ||
112 | + case 'crypt-des' : | ||
113 | + case 'crypt-md5' : | ||
114 | + case 'crypt-blowfish' : | ||
115 | + return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt); | ||
116 | + case 'md5-base64' : | ||
117 | + $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext)); | ||
118 | + return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted; | ||
119 | + case 'ssha' : | ||
120 | + $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext . $salt) . $salt); | ||
121 | + return ($show_encrypt) ? '{SSHA}' . $encrypted : $encrypted; | ||
122 | + case 'smd5' : | ||
123 | + $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext . $salt) . $salt); | ||
124 | + return ($show_encrypt) ? '{SMD5}' . $encrypted : $encrypted; | ||
125 | + case 'aprmd5' : | ||
126 | + $length = strlen($plaintext); | ||
127 | + $context = $plaintext . '$apr1$' . $salt; | ||
128 | + $binary = self::_bin(md5($plaintext . $salt . $plaintext)); | ||
129 | + for ($i = $length; $i > 0; $i -= 16) { | ||
130 | + $context .= substr($binary, 0, ($i > 16 ? 16 : $i)); | ||
131 | + } | ||
132 | + for ($i = $length; $i > 0; $i >>= 1) { | ||
133 | + $context .= ($i & 1) ? chr(0) : $plaintext[0]; | ||
134 | + } | ||
135 | + $binary = self::_bin(md5($context)); | ||
136 | + | ||
137 | + for ($i = 0; $i < 1000; $i++) { | ||
138 | + $new = ($i & 1) ? $plaintext : substr($binary, 0, 16); | ||
139 | + if ($i % 3) { | ||
140 | + $new .= $salt; | ||
141 | + } | ||
142 | + if ($i % 7) { | ||
143 | + $new .= $plaintext; | ||
144 | + } | ||
145 | + $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext; | ||
146 | + $binary = self::_bin(md5($new)); | ||
147 | + } | ||
148 | + | ||
149 | + $p = array(); | ||
150 | + for ($i = 0; $i < 5; $i++) { | ||
151 | + $k = $i + 6; | ||
152 | + $j = $i + 12; | ||
153 | + if ($j == 16) { | ||
154 | + $j = 5; | ||
155 | + } | ||
156 | + $p[] = self::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5); | ||
157 | + } | ||
158 | + | ||
159 | + return '$apr1$' . $salt . '$' . implode('', $p) . self::_toAPRMD5(ord($binary[11]), 3); | ||
160 | + | ||
161 | + case 'md5-hex' : | ||
162 | + | ||
163 | + default : | ||
164 | + $encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext); | ||
165 | + return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted; | ||
166 | + } | ||
167 | + } | ||
168 | + | ||
169 | + /** | ||
170 | + * Enter description here... | ||
171 | + * | ||
172 | + * @param unknown_type $encryption | ||
173 | + * @param unknown_type $seed | ||
174 | + * @param unknown_type $plaintext | ||
175 | + * @return unknown | ||
176 | + */ | ||
177 | + public static function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '') | ||
178 | + { | ||
179 | + switch ($encryption) { | ||
180 | + case 'crypt' : | ||
181 | + case 'crypt-des' : | ||
182 | + if ($seed) { | ||
183 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2); | ||
184 | + } else { | ||
185 | + return substr(md5(mt_rand()), 0, 2); | ||
186 | + } | ||
187 | + break; | ||
188 | + | ||
189 | + case 'crypt-md5' : | ||
190 | + if ($seed) { | ||
191 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12); | ||
192 | + } else { | ||
193 | + return '$1$' . substr(md5(mt_rand()), 0, 8) . '$'; | ||
194 | + } | ||
195 | + break; | ||
196 | + | ||
197 | + case 'crypt-blowfish' : | ||
198 | + if ($seed) { | ||
199 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16); | ||
200 | + } else { | ||
201 | + return '$2$' . substr(md5(mt_rand()), 0, 12) . '$'; | ||
202 | + } | ||
203 | + break; | ||
204 | + | ||
205 | + case 'ssha' : | ||
206 | + if ($seed) { | ||
207 | + return substr(preg_replace('|^{SSHA}|', '', $seed), -20); | ||
208 | + } else { | ||
209 | + return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4); | ||
210 | + } | ||
211 | + break; | ||
212 | + | ||
213 | + case 'smd5' : | ||
214 | + if ($seed) { | ||
215 | + return substr(preg_replace('|^{SMD5}|', '', $seed), -16); | ||
216 | + } else { | ||
217 | + return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4); | ||
218 | + } | ||
219 | + break; | ||
220 | + | ||
221 | + case 'aprmd5' : | ||
222 | + /* 64 characters that are valid for APRMD5 passwords. */ | ||
223 | + $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||
224 | + | ||
225 | + if ($seed) { | ||
226 | + return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8); | ||
227 | + } else { | ||
228 | + $salt = ''; | ||
229 | + for ($i = 0; $i < 8; $i++) { | ||
230 | + $salt .= $APRMD5{rand(0, 63)}; | ||
231 | + } | ||
232 | + return $salt; | ||
233 | + } | ||
234 | + break; | ||
235 | + | ||
236 | + default : | ||
237 | + $salt = ''; | ||
238 | + if ($seed) { | ||
239 | + $salt = $seed; | ||
240 | + } | ||
241 | + return $salt; | ||
242 | + break; | ||
243 | + } | ||
244 | + } | ||
245 | + | ||
246 | + public static function genRandom($length = 8) | ||
247 | + { | ||
248 | + $salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
249 | + $len = strlen($salt); | ||
250 | + $makepass = ''; | ||
251 | + | ||
252 | + $stat = @stat(__FILE__); | ||
253 | + if (empty($stat) || !is_array($stat)) | ||
254 | + $stat = array( | ||
255 | + php_uname() | ||
256 | + ); | ||
257 | + | ||
258 | + mt_srand(crc32(microtime() . implode('|', $stat))); | ||
259 | + | ||
260 | + for ($i = 0; $i < $length; $i++) { | ||
261 | + $makepass .= $salt[mt_rand(0, $len - 1)]; | ||
262 | + } | ||
263 | + | ||
264 | + return $makepass; | ||
265 | + } | ||
266 | + | ||
267 | + public static function _toAPRMD5($value, $count) | ||
268 | + { | ||
269 | + /* 64 characters that are valid for APRMD5 passwords. */ | ||
270 | + $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||
271 | + $aprmd5 = ''; | ||
272 | + $count = abs($count); | ||
273 | + while (--$count) { | ||
274 | + $aprmd5 .= $APRMD5[$value & 0x3f]; | ||
275 | + $value >>= 6; | ||
276 | + } | ||
277 | + return $aprmd5; | ||
278 | + } | ||
279 | + | ||
280 | + public static function _bin($hex) | ||
281 | + { | ||
282 | + $bin = ''; | ||
283 | + $length = strlen($hex); | ||
284 | + for ($i = 0; $i < $length; $i += 2) { | ||
285 | + $tmp = sscanf(substr($hex, $i, 2), '%x'); | ||
286 | + $bin .= chr(array_shift($tmp)); | ||
287 | + } | ||
288 | + return $bin; | ||
289 | + } | ||
290 | + | ||
291 | + /** | ||
292 | + * 组合一个安全的密码 | ||
293 | + * @param $code | ||
294 | + * @return String | ||
295 | + */ | ||
296 | + public static function makePass($code) | ||
297 | + { | ||
298 | + $salt = self::genRandom(32); | ||
299 | + $crypt = self::getCrypted($code . $salt, $salt); | ||
300 | + return $crypt . ':' . $salt; | ||
301 | + } | ||
302 | + | ||
303 | + /** | ||
304 | + * 验证密码 | ||
305 | + * | ||
306 | + * @param String $inputPassword | ||
307 | + * @param String $password | ||
308 | + * @return bool | ||
309 | + */ | ||
310 | + public static function authPassword($inputPassword, $password) | ||
311 | + { | ||
312 | + if (empty($password) || empty($inputPassword)) { | ||
313 | + return false; | ||
314 | + } | ||
315 | + $passwordList = explode(':', trim($password)); | ||
316 | + if (count($passwordList) != 2) { | ||
317 | + return false; | ||
318 | + } | ||
319 | + list($crypt, $salt) = $passwordList; | ||
320 | + $decode = self::getCrypted($inputPassword . $salt, $salt); | ||
321 | + if ($crypt != $decode) { | ||
322 | + return false; | ||
323 | + } | ||
324 | + return true; | ||
325 | + } | ||
326 | + | ||
327 | + ############################ 加密规则 ######################## | ||
328 | + /** | ||
329 | + * 排序参数 | ||
330 | + * @param array $package | ||
331 | + * @return array | ||
332 | + */ | ||
333 | + static function packageSort(array $package) | ||
334 | + { | ||
335 | + ksort($package); | ||
336 | + reset($package); | ||
337 | + return $package; | ||
338 | + } | ||
339 | + | ||
340 | + /** | ||
341 | + * 组合签名 | ||
342 | + * @param array $package | ||
343 | + * @return string | ||
344 | + */ | ||
345 | + static function makeSign(array $package) | ||
346 | + { | ||
347 | + $packageList = array(); | ||
348 | + foreach ($package as $key => $val) { | ||
349 | + $packageList[] = trim($key . '=' . $val); | ||
350 | + } | ||
351 | + return strtolower(md5(implode('&', $packageList))); | ||
352 | + } | ||
353 | + | ||
354 | + /** | ||
355 | + * 获取签名 | ||
356 | + * | ||
357 | + * @param array $package | ||
358 | + * @return string | ||
359 | + */ | ||
360 | + static function getSign(array $package) | ||
361 | + { | ||
362 | + $package = self::packageSort($package); | ||
363 | + return self::makeSign($package); | ||
364 | + } | ||
365 | + | ||
366 | + /** | ||
367 | + * 校验签名 | ||
368 | + * @param $submitSign | ||
369 | + * @param $makeSign | ||
370 | + * @return bool | ||
371 | + */ | ||
372 | + static function verifySign($submitSign, $makeSign) | ||
373 | + { | ||
374 | + return strtolower($submitSign) == strtolower($makeSign); | ||
375 | + } | ||
376 | +} |
yaf/Hood/Core/Server.php
0 → 100644
1 | +<?php | ||
2 | +/** | ||
3 | + * Created by PhpStorm. | ||
4 | + * User: Zip | ||
5 | + * Date: 14/12/7 | ||
6 | + * Time: 上午12:11 | ||
7 | + */ | ||
8 | + | ||
9 | +namespace Hood\Core; | ||
10 | + | ||
11 | +use Hood\Debug\DebugException; | ||
12 | + | ||
13 | +class Server extends Root | ||
14 | +{ | ||
15 | + /** | ||
16 | + * 服务器随机选择模式 | ||
17 | + * @var Integer | ||
18 | + */ | ||
19 | + const SERVER_SELECT_MODEL_RAND = 1; | ||
20 | + | ||
21 | + /** | ||
22 | + * 服务器选择静态 | ||
23 | + * @var Integer | ||
24 | + */ | ||
25 | + const SERVER_SELECT_MODEL_STATIC = 2; | ||
26 | + | ||
27 | + /** | ||
28 | + * @var string | ||
29 | + */ | ||
30 | + protected $_sectionSeparator = ':'; | ||
31 | + | ||
32 | + /** | ||
33 | + * 字符分割 | ||
34 | + * @var string | ||
35 | + */ | ||
36 | + protected $_nestSeparator = '.'; | ||
37 | + | ||
38 | + /** | ||
39 | + * 服务器选择模式 | ||
40 | + * @var int | ||
41 | + */ | ||
42 | + private $serverSelectModel = 1; | ||
43 | + | ||
44 | + /** | ||
45 | + * ini 数组 | ||
46 | + * @var array | ||
47 | + */ | ||
48 | + private $iniArray = array(); | ||
49 | + | ||
50 | + /** | ||
51 | + * 检查服务状态 | ||
52 | + * @var bool | ||
53 | + */ | ||
54 | + private $checkServerStatus = true; | ||
55 | + | ||
56 | + | ||
57 | + public function __construct($filename) | ||
58 | + { | ||
59 | + $this->iniArray = $this->_loadIniFile($filename); | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * 设置服务器选择模式 | ||
64 | + * @param $model | ||
65 | + * @return $this | ||
66 | + */ | ||
67 | + public function setSelectModel($model) | ||
68 | + { | ||
69 | + $this->serverSelectModel = $model; | ||
70 | + return $this; | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * 获取服务器地址 | ||
75 | + * @param $section | ||
76 | + * @param $node | ||
77 | + * @param int $model | ||
78 | + * @return array|mixed | ||
79 | + * @throws DebugException | ||
80 | + */ | ||
81 | + public function getServerConfig($section, $node = null) | ||
82 | + { | ||
83 | + $sectionArray = $this->_processSection($section); | ||
84 | + if ($node == null) { | ||
85 | + return $sectionArray; | ||
86 | + } elseif (isset($sectionArray[$node])) { | ||
87 | + return $sectionArray[$node]; | ||
88 | + } | ||
89 | + return array(); | ||
90 | + | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 选择服务器 | ||
95 | + * @param $servers | ||
96 | + * @param $model | ||
97 | + * @return array|mixed | ||
98 | + * @throws DebugException | ||
99 | + */ | ||
100 | + public function getServer($servers, $model = 1) | ||
101 | + { | ||
102 | + $serverArray = $this->_parseServer($servers); | ||
103 | + switch ($model) { | ||
104 | + case 1: | ||
105 | + if (count($serverArray) <= 1) { | ||
106 | + $servers = $serverArray; | ||
107 | + } else { | ||
108 | + $servers = $this->_randServer($serverArray); | ||
109 | + } | ||
110 | + break; | ||
111 | + case 2: | ||
112 | + $servers = $serverArray; | ||
113 | + break; | ||
114 | + default: | ||
115 | + throw new DebugException('Server select model not ' . $model); | ||
116 | + } | ||
117 | + return $servers; | ||
118 | + } | ||
119 | + | ||
120 | + /** | ||
121 | + * 获取服务器Map | ||
122 | + * @param $section | ||
123 | + * @param $node | ||
124 | + * @param int $model | ||
125 | + * @return array | ||
126 | + * @throws DebugException | ||
127 | + */ | ||
128 | + public function getServerMap($servers, $model = 1) | ||
129 | + { | ||
130 | + $_servers = $this->getServer($servers, $model); | ||
131 | + if (empty($_servers)) { | ||
132 | + return array(); | ||
133 | + } | ||
134 | + $_serversMap = array(); | ||
135 | + if ($model == 1 && count($_servers) == 1) { | ||
136 | + $_serversMap = $this->_processHost($_servers[0]); | ||
137 | + } elseif ($model == 2) { | ||
138 | + foreach ($_servers as $key => $host) { | ||
139 | + $_serversMap[] = $this->_processHost($host); | ||
140 | + } | ||
141 | + } | ||
142 | + return $_serversMap; | ||
143 | + } | ||
144 | + | ||
145 | + /** | ||
146 | + * 获取所有配置Map | ||
147 | + * @param $section | ||
148 | + * @param $node | ||
149 | + * @return array | ||
150 | + */ | ||
151 | + public function getSectionConfig($section, $node) | ||
152 | + { | ||
153 | + $servers = $this->getServerConfig($section, $node); | ||
154 | + $_serversMap = array(); | ||
155 | + foreach ($servers as $key => $host) { | ||
156 | + $_serversMap[] = $this->_processHost($host); | ||
157 | + } | ||
158 | + return $_serversMap; | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * 随机&权重随机 | ||
163 | + * @param array $server | ||
164 | + * @return mixed | ||
165 | + */ | ||
166 | + private function _randServer(array $server) | ||
167 | + { | ||
168 | + if (substr_count($server[0], ':') == 2) { | ||
169 | + $_domain = array(); | ||
170 | + foreach ($server as $key => $domain) { | ||
171 | + $_domain[] = $this->_processHost($domain); | ||
172 | + } | ||
173 | + $_server = $this->_countWeight($_domain); | ||
174 | + $_server = $_server['host'] . ':' . $_server['port'] . ':' . $_server['weight']; | ||
175 | + } else { | ||
176 | + $_server = $server[array_rand($server)]; | ||
177 | + } | ||
178 | + return $_server; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * 权重计算 | ||
183 | + * @param array $data | ||
184 | + * @return mixed | ||
185 | + */ | ||
186 | + private function _countWeight(array $data) | ||
187 | + { | ||
188 | + $weight = 0; | ||
189 | + $tempArray = array(); | ||
190 | + foreach ($data as $v) { | ||
191 | + $weight += (int)$v['weight']; | ||
192 | + for ($i = 0; $i < $v['weight']; $i++) { | ||
193 | + $tempArray[] = $v;//放大数组 | ||
194 | + } | ||
195 | + } | ||
196 | + $int = mt_rand(0, $weight - 1);//获取一个随机数 | ||
197 | + return $tempArray[$int]; | ||
198 | + } | ||
199 | + | ||
200 | + /** | ||
201 | + * 解析host | ||
202 | + * @param $domain | ||
203 | + * @return array | ||
204 | + */ | ||
205 | + private function _processHost($domain) | ||
206 | + { | ||
207 | + $_hostMap = array(); | ||
208 | + $domainArray = explode(':', $domain); | ||
209 | + switch (count($domainArray)) { | ||
210 | + case 2 : | ||
211 | + list($host, $port) = $domainArray; | ||
212 | + $_hostMap = array( | ||
213 | + 'host' => (string)$host, | ||
214 | + 'port' => (int)intval($port) | ||
215 | + ); | ||
216 | + break; | ||
217 | + case 3 : | ||
218 | + list($host, $port, $weight) = $domainArray; | ||
219 | + $_hostMap = array( | ||
220 | + 'host' => (string)$host, | ||
221 | + 'port' => (int)intval($port), | ||
222 | + 'weight' => (int)intval($weight) | ||
223 | + ); | ||
224 | + break; | ||
225 | + } | ||
226 | + return $_hostMap; | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
230 | + * 设置检测服务状态 | ||
231 | + * @param $check | ||
232 | + * @return $this | ||
233 | + */ | ||
234 | + public function setCheckServer($check) | ||
235 | + { | ||
236 | + $this->checkServerStatus = $check; | ||
237 | + return $this; | ||
238 | + } | ||
239 | + | ||
240 | + /** | ||
241 | + * 检查服务 | ||
242 | + * @param array $servers | ||
243 | + * @return array | ||
244 | + */ | ||
245 | + public function checkServer(array $servers) | ||
246 | + { | ||
247 | + $_servers = array(); | ||
248 | + foreach ($servers as $key => $val) { | ||
249 | + $status = $this->ping($val['host'], $val['port']); | ||
250 | + if ($status > 0) { | ||
251 | + $_servers[] = $val; | ||
252 | + } | ||
253 | + } | ||
254 | + return $_servers; | ||
255 | + } | ||
256 | + | ||
257 | + /** | ||
258 | + * 解析Server | ||
259 | + * @param $ips | ||
260 | + * @return array|mixed | ||
261 | + */ | ||
262 | + protected function _parseServer($serverString) | ||
263 | + { | ||
264 | + return explode(',', str_replace(array( | ||
265 | + ' ', | ||
266 | + "\n" | ||
267 | + ), '', $serverString)); | ||
268 | + } | ||
269 | + | ||
270 | + public function getSection($section) | ||
271 | + { | ||
272 | + return $this->_processSection($section); | ||
273 | + } | ||
274 | + | ||
275 | + public function get($name, $section = null) | ||
276 | + { | ||
277 | + return $this->_processSection($section); | ||
278 | + } | ||
279 | + | ||
280 | + /** | ||
281 | + * 加载ini | ||
282 | + * @param $filename | ||
283 | + * @return array | ||
284 | + * @throws DebugException | ||
285 | + */ | ||
286 | + private function _loadIniFile($filename) | ||
287 | + { | ||
288 | + $loaded = $this->_parseIniFile($filename); | ||
289 | + $iniArray = array(); | ||
290 | + foreach ($loaded as $key => $data) { | ||
291 | + $pieces = explode($this->_sectionSeparator, $key); | ||
292 | + $thisSection = trim($pieces[0]); | ||
293 | + switch (count($pieces)) { | ||
294 | + case 1: | ||
295 | + $iniArray[$thisSection] = $data; | ||
296 | + break; | ||
297 | + case 2: | ||
298 | + $extendedSection = trim($pieces[1]); | ||
299 | + $iniArray[$thisSection] = array_merge(array(';extends' => $extendedSection), $data); | ||
300 | + break; | ||
301 | + default: | ||
302 | + throw new DebugException("Section '$thisSection' may not extend multiple sections in $filename"); | ||
303 | + } | ||
304 | + } | ||
305 | + return $iniArray; | ||
306 | + } | ||
307 | + | ||
308 | + /** | ||
309 | + * 解析ini | ||
310 | + * @param $filename | ||
311 | + * @return array | ||
312 | + */ | ||
313 | + private function _parseIniFile($filename) | ||
314 | + { | ||
315 | + if (!file_exists($filename)) { | ||
316 | + throw new DebugException($filename . ' Not Find,'); | ||
317 | + } | ||
318 | + $iniArray = parse_ini_file($filename, true); | ||
319 | + if ($iniArray == false) { | ||
320 | + throw new DebugException($filename . ' Not Array.'); | ||
321 | + } | ||
322 | + return $iniArray; | ||
323 | + } | ||
324 | + | ||
325 | + /** | ||
326 | + * 解析节点 | ||
327 | + * @param $section | ||
328 | + * @return array | ||
329 | + * @throws DebugException | ||
330 | + */ | ||
331 | + protected function _processSection($section) | ||
332 | + { | ||
333 | + $config = array(); | ||
334 | + $thisSection = array(); | ||
335 | + if (isset($this->iniArray[$section])) { | ||
336 | + $thisSection = $this->iniArray[$section]; | ||
337 | + } | ||
338 | + foreach ($thisSection as $key => $value) { | ||
339 | + if (strtolower($key) == ';extends') { | ||
340 | + if (isset($this->iniArray[$value])) { | ||
341 | + $config = $this->iniArray[$value] + $config; | ||
342 | + } else { | ||
343 | + throw new DebugException("Parent section '$section' cannot be found"); | ||
344 | + } | ||
345 | + } else { | ||
346 | + $config = $this->_processKey($config, $key, $value); | ||
347 | + } | ||
348 | + } | ||
349 | + return $config; | ||
350 | + } | ||
351 | + | ||
352 | + /** | ||
353 | + * 解析键值 | ||
354 | + * @param array $config | ||
355 | + * @param $key | ||
356 | + * @param string $val | ||
357 | + * @return array | ||
358 | + */ | ||
359 | + protected function _processKey(array $config, $key, $val = '') | ||
360 | + { | ||
361 | + if (strpos($key, $this->_nestSeparator) !== false) { | ||
362 | + $pieces = explode($this->_nestSeparator, $key, 2); | ||
363 | + if (strlen($pieces[0]) && strlen($pieces[1])) { | ||
364 | + if (!isset($config[$pieces[0]])) { | ||
365 | + if ($pieces[0] === '0' && !empty($config)) { | ||
366 | + $config = array($pieces[0] => $config); | ||
367 | + } else { | ||
368 | + $config[$pieces[0]] = array(); | ||
369 | + } | ||
370 | + } | ||
371 | + $config[$pieces[0]] = $this->_processKey($config[$pieces[0]], $pieces[1], $val); | ||
372 | + } | ||
373 | + } else { | ||
374 | + $config[$key] = $val; | ||
375 | + } | ||
376 | + return $config; | ||
377 | + } | ||
378 | + | ||
379 | + /** | ||
380 | + * ping | ||
381 | + * @param $domain | ||
382 | + * @param $port | ||
383 | + * @param int $timeout | ||
384 | + * @return float|int|mixed | ||
385 | + */ | ||
386 | + public function ping($domain, $port, $timeout = 3) | ||
387 | + { | ||
388 | + $starttime = microtime(true); | ||
389 | + $file = @fsockopen($domain, $port, $errno, $errstr, $timeout); | ||
390 | + $stoptime = microtime(true); | ||
391 | + $status = -1; | ||
392 | + if ($file) { | ||
393 | + stream_set_blocking($file, false);//非堵塞 | ||
394 | + stream_set_timeout($file, 3); | ||
395 | + fclose($file); | ||
396 | + $status = ($stoptime - $starttime) * 1000; | ||
397 | + $status = floor($status); | ||
398 | + } | ||
399 | + return $status; | ||
400 | + } | ||
401 | +} |
-
Please register or login to post a comment