Authored by Rock Zhang

Merge branch 'beta' into develop

Showing 48 changed files with 4710 additions and 17 deletions

Too many changes to show.

To preserve performance only 48 of 48+ files are displayed.

<?php return function ($in, $debugopt = 1) {
$cx = array(
'flags' => array(
'jstrue' => false,
'jsobj' => false,
'spvar' => true,
'prop' => false,
'method' => false,
'mustlok' => true,
'echo' => false,
'debug' => $debugopt,
),
'constants' => array(),
'helpers' => array(),
'blockhelpers' => array(),
'hbhelpers' => array(),
'partials' => array(),
'scopes' => array(),
'sp_vars' => array('root' => $in),
'lcrun' => 'Plugin\LCRun3',
);
return '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('staticTitle')), ENT_QUOTES, 'UTF-8').'</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<style>
*{margin: 0;padding: 0;}
#coupon-container {width: 100%;}
#coupon-container img {width: 100%; height: auto; display: block;overflow: hidden;}
.img-box {width: 100%;position: relative;}
.img-box .href {width: 50%; height: 100%;position: absolute;top: 0;}
.img-box .href-left {left: 0}
.img-box .href-right {right: 0}
.img-box .href-center {width: 90%;height: 100%;position: absolute;top: 0;left: 5%;}
.show-more {height: 100%;width: 25%;position: absolute;top: 0;right: 10%;}
.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;}
</style>
<link rel="dns-prefetch" href="//cdn.yoho.cn">
<link rel="dns-prefetch" href="//static.yohobuy.com">
</head>
<body>
<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').'">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/01.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/02.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/03-a.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/04-a.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/05-a.jpg">
<a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_yohope')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/06.jpg">
<a class="href href-center" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_mycoupon')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-2.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/07.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/08.jpg">
<a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a>
<a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/09.jpg">
<span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17443"></span>
<span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17445"></span>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/10.jpg">
<a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_more')), ENT_QUOTES, 'UTF-8').'"></a>
<a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_1')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/11.jpg">
<span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17463"></span>
<span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17451"></span>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/12.jpg">
<a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_2')), ENT_QUOTES, 'UTF-8').'"></a>
<a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_3')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/13.jpg">
<span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17461"></span>
<span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17459"></span>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/14.jpg">
<a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_4')), ENT_QUOTES, 'UTF-8').'"></a>
<a class="href href-right" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_5')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/15.jpg">
<span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17453"></span>
<span class="href href-right get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17455"></span>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/16.jpg">
<a class="href href-left" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_6')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/17.jpg">
<span class="href href-left get-coupon" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jumpUrl')), ENT_QUOTES, 'UTF-8').'" param="17449"></span>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-1.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-1.jpg">
<div class="img-box">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-2.jpg">
<a class="show-more" href="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('url_help')), ENT_QUOTES, 'UTF-8').'"></a>
</div>
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/24-3.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/line-2.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-1-a.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-2-a.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/25-3-a.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/26-a.jpg">
<img src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/img/newuser/160107/27-a.jpg">
</div>
<script type="text/javascript" src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/js/jquery.min.js"></script>
<script type="text/javascript" src="'.htmlentities((string)Plugin\LCRun3::v($cx, $in, array('jsUrl')), ENT_QUOTES, 'UTF-8').'/cuxiao/js/newuser/coupon2.js"></script>
</body>
</html>';
}
?>
\ No newline at end of file
... ...
... ... @@ -23,18 +23,18 @@ class Yohobuy
const SERVICE_URL = 'http://service.api.yohobuy.com/';
const YOHOBUY_URL = 'http://www.yohobuy.com/';**/
// const API_URL = 'http://apih5.yoho.cn/';
// const API_URL2 = 'http://apih5.yoho.cn/';
// const SERVICE_URL = 'http://serviceh5.yoho.cn/';
// const YOHOBUY_URL = 'http://www.yohobuy.com/';
// const API_OLD = 'http://api2.open.yohobuy.com/';
const API_URL = 'http://apih5.yoho.cn/';
const API_URL2 = 'http://apih5.yoho.cn/';
const SERVICE_URL = 'http://serviceh5.yoho.cn/';
const YOHOBUY_URL = 'http://www.yohobuy.com/';
const API_OLD = 'http://api2.open.yohobuy.com/';
// /* 测试环境 */
// const API_URL = 'http://192.168.102.205:8080/gateway/'; // 先临时使用网关
const API_URL = 'http://testapi.yoho.cn:28078/';
/*const API_URL = 'http://testapi.yoho.cn:28078/';
const SERVICE_URL = 'http://testservice.yoho.cn:28077/';
const YOHOBUY_URL = 'http://www.yohobuy.com/';
const API_OLD = 'http://test2.open.yohobuy.com/';
const API_OLD = 'http://test2.open.yohobuy.com/';*/
/* 预览环境 */
// const API_URL = 'http://preapi.yoho.cn/';
... ...
No preview for this file type
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
... ... @@ -2,7 +2,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
Created by FontForge 20120731 at Wed Jan 13 13:50:02 2016
Created by FontForge 20120731 at Wed Jan 20 14:25:44 2016
By Ads
</metadata>
<defs>
... ... @@ -19,7 +19,7 @@ Created by FontForge 20120731 at Wed Jan 13 13:50:02 2016
bbox="-0.75 -224 3943 896"
underline-thickness="50"
underline-position="-100"
unicode-range="U+0078-E644"
unicode-range="U+0078-E645"
/>
<missing-glyph horiz-adv-x="374"
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
... ... @@ -278,5 +278,10 @@ q0 -14 -3.5 -27t-10 -23.5t-16 -20t-20.5 -15.5t-24 -10t-27 -4zM848 367q-42 0 -71.
d="M523 881q-101 0 -192.5 -39.5t-158 -105.5t-105.5 -158t-39 -193q0 -205 145 -350t350 -145q67 0 131.5 18t119 49.5t100 77.5t77.5 100.5t49.5 118.5t17.5 131q0 101 -39 193t-105.5 158t-158 105.5t-192.5 39.5zM739 224q8 -8 7 -19q0 -2 -0.5 -4.5t-1.5 -5t-2.5 -4.5
t-3.5 -3q-11 -10 -15 -14q-7 -7 -17 -7t-18 7l-34 34q-59 -42 -131 -42q-94 0 -160.5 66.5t-66.5 160.5q0 46 18 88t48.5 72.5t72.5 48.5t88 18t88 -18t72.5 -48.5t48.5 -72.5t18 -88q0 -75 -45 -135zM592 337q8 7 18 6.5t17 -7.5l27 -27q25 39 25 84q0 64 -45.5 109.5
t-110 45.5t-110 -45.5t-45.5 -109.5t45.5 -109.5t109.5 -45.5q44 0 80 21l-27 28q-8 7 -7.5 18t7.5 18z" />
<glyph glyph-name="uniE645" unicode="&#xe645;"
d="M512 798q-104 0 -198 -40.5t-162.5 -109t-109 -162.5t-40.5 -198t40.5 -198t109 -162.5t162.5 -109t198 -40.5t198 40.5t162.5 109t109 162.5t40.5 198t-40.5 198t-109 162.5t-162.5 109t-198 40.5zM512 -149q-89 0 -170 34.5t-139.5 93t-93 139.5t-34.5 170
q0 71 22 137.5t62.5 120.5t94.5 94.5t120.5 62.5t137.5 22t137.5 -22t120.5 -62.5t94.5 -94.5t62.5 -120.5t22 -137.5q0 -89 -34.5 -170t-93 -139.5t-139.5 -93t-170 -34.5zM659 288q15 0 25.5 10.5t10.5 25.5t-10.5 26t-25.5 11h-111v17l135 141q5 5 8 12t2.5 14t-3 13.5
t-8.5 11.5q-10 11 -25 10.5t-26 -11.5l-115 -121l-123 122q-11 11 -26 10.5t-25 -10.5q-7 -7 -10 -16.5t-0.5 -19t9.5 -16.5l135 -135v-22h-108q-8 0 -14.5 -3t-11.5 -8t-8 -11.5t-3 -14.5q0 -9 5 -17.5t13.5 -13.5t18.5 -5h108v-73h-108q-8 0 -14.5 -3t-11.5 -7.5t-8 -11.5
t-3 -14.5t3 -14t8 -11.5t11.5 -8t14.5 -3h108v-108q0 -15 10.5 -25.5t25.5 -10.5q10 0 18.5 4.5t13 13t4.5 18.5v108h111q10 0 18.5 5t13 13.5t4.5 18.5q0 7 -2.5 14t-7.5 11.5t-12 7.5t-14 3h-111v73h111z" />
</font>
</defs></svg>
... ...
... ... @@ -23,11 +23,11 @@
<div id="coupon-container" param="{{activityId}}" isLogged="{{isLogged}}">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/01.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/02.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/03.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/03-a.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-1.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/04.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/04-a.jpg">
<div class="img-box">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/05.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/05-a.jpg">
<a class="href href-right" href="{{url_yohope}}"></a>
</div>
<div class="img-box">
... ... @@ -98,11 +98,11 @@
</div>
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/24-3.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/line-2.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-1.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-2.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-3.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/26.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/27.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-1-a.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-2-a.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/25-3-a.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/26-a.jpg">
<img src="{{jsUrl}}/cuxiao/img/newuser/160107/27-a.jpg">
</div>
<script type="text/javascript" src="{{jsUrl}}/cuxiao/js/jquery.min.js"></script>
<script type="text/javascript" src="{{jsUrl}}/cuxiao/js/newuser/coupon2.js"></script>
... ...
<?php
namespace Hood;
use Yaf\Controller_Abstract;
use Hood\Helper\View as hoodView;
use Yaf;
use Hood\Validator as hoodValidator;
class Action extends Controller_Abstract
{
private $_viewLink = array();
private $_viewScript = array();
private $_headTitle;
private $_headmeta;
/**
* Meta
* @return \Hood\Helper\View\Meta
*/
public function _headMeta()
{
if (empty($this->_headmeta)) {
$this->_headmeta = new hoodView\Meta();
$this->getView()->assign("_headmeta", $this->_headmeta);
}
return $this->_headmeta;
}
/**
* Script
* @return \Hood\Helper\View\Script
*/
public function _viewScript($scriptName = '_headScript')
{
if (!isset($this->_viewScript[$scriptName])) {
$this->_viewScript[$scriptName] = new hoodView\Script();
$this->getView()->assign($scriptName, $this->_viewScript[$scriptName]);
}
return $this->_viewScript[$scriptName];
}
/**
*
* @return \Hood\Helper\View\Link
*/
public function _viewLink($linkName = '_headLink')
{
if (!isset($this->_viewLink[$linkName])) {
$this->_viewLink[$linkName] = new hoodView\Link();
$this->getView()->assign($linkName, $this->_viewLink[$linkName]);
}
return $this->_viewLink[$linkName];
}
/**
* Title
* @return \Hood\Helper\View\Title
*/
public function _headTitle($title)
{
if (empty($this->_headTitle)) {
$this->_headTitle = new hoodView\Title();
$this->getView()->assign("_headTitle", $this->_headTitle);
}
return $this->_headTitle->headTitle($title);
}
/**
* js 跳转 并 提示
*
* @param String $url
* @param String $expression
*/
protected function helpJsRedirect($message = '', $script = "history.back();")
{
$html = '';
if (!empty($message)) {
header("content-type: text/html; charset=utf-8");
$message = str_replace("\n", "\\n", $message);
$html .= "<script language=\"javascript\">";
$html .= "alert(\"{$message}\");";
$html .= "</script>";
}
$html .= "<script language=\"javascript\">";
$html .= $script;
$html .= "</script>";
die($html);
}
/**
* 跳转
* @param String $url
*/
protected function helpLocation($url)
{
header('Location: ' . $url);
}
/**
* refresh跳转
* @param $url
* @param string $message
*/
protected function helpRefresh($url, $message = '')
{
$html = '';
if (!empty($message)) {
header("content-type: text/html; charset=utf-8");
$message = str_replace("\n", "\\n", $message);
$html .= "<script language=\"javascript\">";
$html .= "alert(\"{$message}\");";
$html .= "</script>";
}
$html .= "<script language=\"javascript\">";
$html .= "window.location.href='{$url}';";
$html .= "</script>";
echo $html;
}
/**
* JSON输出
* @param $code
* @param null $message
* @param null $data
*/
protected function helpJsonResult($code, $message = null, $data = null)
{
header('Content-type: application/json');
echo json_encode(array('code' => $code, 'message' => $message, 'data' => $data));
exit();
}
/**
* JSON输出
* @param array $data
*/
protected function helpJson(array $data)
{
header('Content-type: application/json');
echo json_encode($data);
exit();
}
/**
* JSONP Callback输出,用于远程调用
* @param $callbackString
* @param $code
* @param null $message
* @param null $data
*/
protected function helpJsonCallbackResult($callbackString, $code, $message = null, $data = null)
{
header('Content-type: application/json');
echo $callbackString . "(";
echo json_encode(array('code' => $code, 'message' => $message, 'data' => $data));
echo ")";
exit();
}
/**
* @param string $namespace
* @return \Hood\Core\Session\SessionNamespace
*/
public function session($namespace = 'session_default', $sessionName = null)
{
return Session::start($namespace, $sessionName);
}
/**
* 数据校验
* @param array $data
* @param array $rules
* @param array $messagesAttribute
* @return Helper\Validation\Validator
*/
public function validator(array $data, array $rules, array $messagesAttribute = array())
{
return hoodValidator::make($data, $rules, $messagesAttribute);
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/9
* Time: 下午7:40
*/
namespace Hood;
use Hood\Cache\Memcached as Mcd;
use Hood\Cache\Memcache as Mc;
use Hood\Cache\CacheRedis;
use Hood\Cache\FileCache;
class Cache
{
/**
*
* @param null $node
* @return Mcd
*/
static public function Memcached($node = null, $childNode = 'hosts')
{
$mc = new Mcd();
$mc->setNode($node)->setChildNodes($childNode);
return $mc;
}
/**
* @param null $node
* @param string $childNode
* @return Mc
*/
static public function Memcache($node = null, $childNode = 'hosts')
{
$mc = new Mc();
$mc->setNode($node)->setChildNodes($childNode);
return $mc;
}
/**
* @return CacheRedis
*/
static public function Redis()
{
$servers = array();
$persistentID = '';
return new CacheRedis($servers, $persistentID);
}
/**
*
* @param null $childNode
* @param string $node
* @param null $cachePath
* @return FileCache
*/
static public function File($childNode = null, $node = 'cache', $cachePath = null)
{
return new FileCache($childNode, $node, $cachePath);
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/9
* Time: 下午10:35
*/
namespace Hood\Cache;
interface CacheInterface
{
/**
* @param $key
* @return mixed
*/
public function get($key);
/**
* @param $key
* @param $value
* @param $minutes
* @return mixed
*/
public function add($key, $value, $minutes);
/**
* @param $key
* @param $value
* @param $minutes
* @return mixed
*/
public function set($key, $value, $minutes);
/**
* @param $key
* @param int $value
* @return mixed
*/
public function increment($key, $value = 1);
/**
* @param $key
* @param int $value
* @return mixed
*/
public function decrement($key, $value = 1);
/**
* @param $key
* @return mixed
*/
public function delete($key);
/**
* @param $tagName
* @return $this
*/
public function tag($tagName);
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/11/23
* Time: 上午1:39
*/
namespace Hood\Cache;
use \Redis;
class CacheRedis
{
/**
*
* Enter description here ...
* @var Redis
*/
private $redis;
private $timeout = 2.5;
public function __construct(array $servers, $persistentID = '')
{
if (empty($servers)) {
throw new Q_Cache_Exception('redis server is null.');
}
$this->redis = new Redis();
$this->redis->connect($servers['host'], $servers['port'], $this->timeout);
}
/**
*
* 返回key所关联的字符串值,如果key不存在则返回特殊值nil。
* @param String $key
* @return Mixed or nil
*/
public function get($key)
{
assert(is_string($key));
return $this->redis->get($key);
}
/**
*
* 将字符串值value关联到key
* @param String $key
* @param Mixed $val
* @return bool
*/
public function set($key, $val)
{
assert(is_string($key));
return $this->redis->set($key, $val);
}
/**
*
* 同时设置一个或多个key-value对。
* @param array $keys
* @return bool
*/
public function mset(array $keys)
{
return $this->redis->mset($keys);
}
/**
*
* 返回所有(一个或多个)给定key的值.如果某个指定key不存在,那么返回特殊值nil。因此,该命令永不失败。
* @param array $keys
* @return Mixed
*/
public function mget(array $keys)
{
return $this->redis->mget($keys);
}
/**
*
* 返回key中字符串值的子字符串,字符串的截取范围由start和end两个偏移量决定(包括start和end在内)。
* 负数偏移量表示从字符串最后开始计数,-1表示最后一个字符,-2表示倒数第二个,以此类推
* @param String $key
* @param Integer $start
* @param Integer $end
* @return String
*/
public function getRange($key, $start, $end)
{
assert(is_string($key));
return $this->redis->getRange($key, $start, $end);
}
/**
*
* 删除数据 ( 返回删除个数 )
* @param String $key
* @return bool
*/
public function del($key)
{
assert(is_string($key));
return $this->redis->del($key);
}
/**
* 查找符合给定模式的key。
*
* 可以使用正则
* =========================================
* *命中数据库中所有key
* h?llo命中hello, hallo and hxllo等
* h*llo命中hllo和heeeeello等
* h[ae]llo命中hello和hallo,但不命中hillo
* =========================================
* KEYS的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(set)结构。
* @param String $keys
* @return Mixed
*/
public function keys($keys)
{
return $this->redis->keys($keys);
}
/**
*
* 选择数据库
* @param String $db
* @return bool
*/
public function select($db = 9)
{
return $this->redis->select($db);
}
/**
*
* 获取 hash 集合中的键值
* @param String $hashName
* @param String $key
* @param Mixed $val
* @return Mixed
*/
public function hget($hashName, $key, $val)
{
assert(is_string($hashName)) && assert(is_string($key));
return $this->redis->hget($hashName, $key, $val);
}
/**
*
* 将哈希表key中的域field的值设为value。
* @param String $hashName
* @param String $key
* @param Mixed $val
* @return bool
*/
public function hset($hashName, $key, $val)
{
assert(is_string($hashName)) && assert(is_string($key));
return $this->redis->hset($hashName, $key, $val);
}
/**
*
* 排序
*
* @param String $key
* @param array $options
* 'by' => 'some_pattern_*',
* 'limit' => array(0, 1),
* 'get' => 'some_other_pattern_*' or an array of patterns,
* 'sort' => 'asc' or 'desc',
* 'alpha' => TRUE,
* 'store' => 'external-key'
* @return array
*/
public function sort($key, array $options = array())
{
assert(is_string($key));
return $this->redis->sort($key, $options);
}
/**
*
* 从当前数据库中随机返回(不删除)一个key。
* @return String or Mixed
*/
public function randomkey()
{
return $this->redis->randomKey();
}
/**
*
* 返回给定key的剩余生存时间(time to live)(以秒为单位)。
* @param String $key
* @return Integer
*/
public function ttl($key)
{
assert(is_string($key));
return $this->redis->ttl($key);
}
/**
*
* 检查给定key是否存在
* @param String $key
* @return bool
*/
public function exists($key)
{
assert(is_string($key));
return $this->redis->exists($key);
}
/**
*
* 移动key 到另外一个数据库
* @param String $key
* @param Integer $dbName
* @return bool
*/
public function move($key, $dbName)
{
assert(is_string($key));
return $this->redis->move($key, $dbName);
}
/**
*
* 将key改名为newkey
* @param String $key
* @param String $newKey
* @return bool
*/
public function rename($key, $newKey)
{
assert(is_string($key)) && assert(is_string($newKey));
return $this->redis->rename($key, $newKey);
}
/**
*
* 返回key所储存的值的类型
* @param String $key
* @return Mixed
* ================================
* none(key不存在) string(字符串) list(列表) set(集合) zset(有序集) hash(哈希表)
* ================================
*/
public function type($key)
{
return $this->redis->type($key);
}
/**
*
* 为给定key设置生存时间
* @param String $key
* @param Integer $expire
* @return bool
*/
public function setTimeout($key, $expire)
{
assert(is_string($key)) && assert(is_int($expire));
return $this->redis->setTimeout($key, $expire);
}
/**
*
* 不同在于EXPIREAT命令接受的时间参数是UNIX时间戳(unix timestamp)。
* @param String $key
* @param Integer $expire
* @return bool
*/
public function expireAt($key, $expire)
{
assert(is_string($key)) && assert(is_int($expire));
return $this->redis->expireAt($key, $expire);
}
/**
*
* 移除给定key的生存时间
* @param String $key
* @return bool
*/
public function persist($key)
{
assert(is_string($key));
return $this->redis->persist($key);
}
/**
*
* 将值value关联到key,并将key的生存时间设为seconds(以秒为单位)
* @param String $key
* @param Mixed $val
* @param Integer $expire
* @return bool
*/
public function setex($key, $val, $expire)
{
assert(is_string($key)) && assert(is_int($expire));
return $this->redis->setex($key, $expire, $val);
}
/**
*
* 如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后
* @param String $key
* @param Mixed $val
* @return bool
*/
public function append($key, $val)
{
assert(is_string($key));
return $this->redis->append($key, $val);
}
/**
*
* 将给定key的值设为value,并返回key的旧值
* @param String $key
* @param Mixed $val
* @return Mixed
*/
public function getSet($key, $val)
{
assert(is_string($key));
return $this->redis->getSet($key, $val);
}
/**
*
* 返回key所储存的字符串值的长度
* @param String $key
* @return integer
*/
public function strlen($key)
{
return $this->redis->strlen($key);
}
/**
*
* 将key中储存的数字值减一
* @param String $key
* @return Integer
*/
public function decr($key)
{
assert(is_string($key));
return $this->redis->decr($key);
}
/**
*
* 将key所储存的值减去减量decrement。
* @param String $key
* @param Integer $value
* @return intger
*/
public function decrBy($key, $value = 1)
{
assert(is_string($key)) && assert(is_int($value));
return $this->redis->decrBy($key, $value);
}
/**
*
* 将key中储存的数字值增一
* @param String $key
* @param Integer $val
* @return Integer
*/
public function incrBy($key, $val = 1)
{
return $this->redis->incrBy($key, $val);
}
/**
*
* 同时将多个field - value(域-值)对设置到哈希表key中
* @param String $key
* @param array $vals
* @return bool
*/
public function hMset($hashKey, array $keys)
{
assert(is_string($hashKey));
return $this->redis->hMset($hashKey, $keys);
}
/**
*
* 返回哈希表key中,一个或多个给定域的值
* @param String $hashKey
* @param array $keys
* @return Mixed
*/
public function hmGet($hashKey, array $keys)
{
assert(is_string($hashKey));
return $this->redis->hmGet($hashKey, $keys);
}
/**
*
* 返回哈希表key中,所有的域和值
* @param String $hashKey
* @return Mixed
*/
public function hGetAll($hashKey)
{
assert(is_string($hashKey));
return $this->redis->hGetAll($hashKey);
}
/**
*
* 删除哈希表key中的一个或多个指定域
* @param String $hashKey
* @return bool
*/
public function hDel($hashKey, $hashKey2 = null, $hashKeyN = null)
{
$this->redis->hDel($hashKey, $hashKey2, $hashKeyN);
}
/**
*
* 返回哈希表key中域的数量
* @param String $hashKey
* @return Integer
*/
public function hLen($hashKey)
{
return $this->redis->hLen($hashKey);
}
/**
*
* 查看哈希表key中,给定域field是否存在
* @param String $hashKey
* @return bool
*/
public function hExists($key, $hashKey)
{
return $this->redis->hExists($key, $hashKey);
}
/**
*
* 为哈希表key中的域field的值加上增量increment。
* @param String $hashKey
* @param String $key
* @param Integer $member
* @return Integer
*/
public function hincrby($hashKey, $key, $member)
{
return $this->redis->hIncrBy($hashKey, $key, $member);
}
/**
*
* 返回哈希表key中的所有域
* @param String $hashKey
* @return array
*/
public function hKeys($hashKey)
{
return $this->redis->hKeys($hashKey);
}
/**
*
* 返回哈希表key中的所有值
* @param String $hashKey
* @return Array
*/
public function hVals($hashKey)
{
return $this->redis->hVals($hashKey);
}
###########################
# 表 List
###########################
/**
*
* 将值value插入到列表key的表头
* @param String $key
* @param Mixed $value
* @return bool
*/
public function lPush($key, $value)
{
assert(is_string($key));
return $this->redis->lPush($key, $value);
}
/**
*
* 将值value插入到列表key的表头,当且仅当key存在并且是一个列表
* @param String $key
* @param Mixed $value
* @return bool
*/
public function lPushx($key, $value)
{
assert(is_string($key));
return $this->redis->lPushx($key, $value);
}
/**
*
* 将值value插入到列表key的表尾
* @param String $key
* @param Mixed $value
* @return bool
*/
public function rPush($key, $value)
{
assert(is_string($key));
return $this->redis->rPush($key, $value);
}
/**
*
* 将值value插入到列表key的表尾,当且仅当key存在并且是一个列表
* @param String $key
* @param Mixed $value
* @return bool
*/
public function rPushx($key, $value)
{
assert(is_string($key));
return $this->redis->rPushx($key, $value);
}
/**
*
* 移除并返回列表key的头元素
* @param String $key
* @return bool or nil
*/
public function lPop($key)
{
return $this->redis->lPop($key);
}
/**
*
* 移除并返回列表key的尾元素
* @param String $key
* @return bool or nil
*/
public function rPop($key)
{
return $this->redis->rPop($key);
}
/**
*
* BLPOP是列表的阻塞式(blocking)弹出原语
* ===================================
* 类似 Gearman 等待移除
* ===================================
* @param array $keys
* @param Integer $timeout
* @return array
*/
public function blPop(array $keys, $timeout = 2)
{
return $this->redis->blPop($keys, (int)$timeout);
}
/**
*
* BRPOP是列表的阻塞式(blocking)弹出原语。
* ===================================
* 类似 Gearman 等待移除
* ===================================
* @param array $keys
* @param Integer $timeout
*
*/
public function brPop(array $keys, $timeout = 2)
{
return $this->redis->brPop($keys, (int)$timeout);
}
/**
* TODO
* 返回列表key的长度。
*/
public function llen()
{
}
/**
*
* 返回列表key中指定区间内的元素,区间以偏移量start和stop指定。
* @param String $key
* @param Integer $start
* @param Integer $end
* @return array
*/
public function lRange($key, $start = 0, $end = 0)
{
return $this->redis->lRange($key, (int)$start, (int)$end);
}
/**
*
* 根据参数count的值,移除列表中与参数value相等的元素
* ============================================
* count的值可以是以下几种:
* count > 0: 从表头开始向表尾搜索,移除与value相等的元素,数量为count
* count < 0: 从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值
* count = 0: 移除表中所有与value相等的值
* ============================================
* @param String $key
* @param String $value
* @param Integer $count
* @return Integer
*/
public function lRem($key, $value, $count)
{
$this->redis->lRem((string)$key, (string)$value, (int)$count);
}
/**
*
* 将列表key下标为index的元素的值甚至为value
* (当index参数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误)
* @param String $key
* @param Integer $index
* @param String $value
* @return bool
*/
public function lSet($key, $index, $value)
{
return $this->redis->lSet((string)$key, (int)$index, (string)$value);
}
/**
*
* 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除
* @param String $key
* @param Integer $start
* @param Integer $stop
* @return bool
*/
public function lTrim($key, $start, $stop)
{
return $this->redis->lTrim((string)$key, (int)$start, (int)$stop);
}
/**
*
* 返回列表key中,下标为index的元素
* @param String $key
* @param Integer $index
* @return bool or nil
*/
public function lGet($key, $index)
{
return $this->redis->lGet((string)$key, (int)$index);
}
##################################################################
# SET
##################################################################
/**
*
* 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略
* @param String $key
* @param Mixed $value
* @return bool
*/
public function sAdd($skey, $value)
{
return $this->redis->sAdd($skey, $value);
}
/**
*
* ( 扩展 ) 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略
* @param String $key
* @param Mixed $value
* @param Integer $expiration
* @return bool
*/
public function sAdd2($skey, $value, $expiration = 0)
{
$result = $this->redis->sAdd($skey, $value);
$this->redis->setTimeout($skey, $expiration);
return $result;
}
/**
*
* 移除集合key中的一个或多个member元素,不存在的member元素会被忽略
* @param String $key
* @param String $member
* @return bool
*/
public function sRem($skey, $member)
{
return $this->redis->sRem((string)$skey, (string)$member);
}
/**
*
* 返回集合key中的所有成员
* @param String $key
* @return array
*/
public function sMembers($skey)
{
return $this->redis->sMembers((string)$skey);
}
/**
*
* 判断member元素是否是集合key的成员
* @param String $key
* @param String $value
*/
public function sIsMember($skey, $value)
{
return $this->redis->sIsMember((string)$skey, (string)$value);
}
/**
*
* 返回集合key的基数(集合中元素的数量)
* @param String $skey
* @return Integer
*/
public function sCard($skey)
{
return $this->redis->sCard((string)$skey);
}
/**
*
* 将member元素从source集合移动到destination集合
* @param String $srcKey
* @param String $dstKey
* @param String $member
* @return bool
*/
public function sMove($srcKey, $dstKey, $member)
{
return $this->redis->sMove((string)$srcKey, (string)$dstKey, (string)$member);
}
/**
*
* 移除并返回集合中的一个随机元素
* @param String $skey
* @return string or bool
*/
public function sPop($skey)
{
return $this->redis->sPop((string)$skey);
}
/**
*
* 返回集合中的一个随机元素。
* @param String $skey
* @return array or nil
*/
public function sRandMember($skey)
{
return $this->redis->sRandMember((string)$skey);
}
########################################################
# 有序集(Sorted Set)
########################################################
/**
*
* 将一个或多个member元素及其score值加入到有序集key当中
* @param String $zKey
* @param Integer $score
* @param String $value
* @return Integer
*/
public function zAdd($zKey, $score, $value)
{
assert(is_string($zKey)) && assert(is_int($score)) && assert(is_string($value));
return $this->redis->zAdd($zKey, $score, $value);
}
/**
*
* 移除有序集key中的一个或多个成员,不存在的成员将被忽略
* @param String $zKey
* @param String $member
* @return Integer
*/
public function zRem($zKey, $member)
{
return $this->redis->zRem((string)$zKey, (string)$member);
}
/**
*
* 返回有序集key的基数
* @param String $zKey
* @return Integer
*/
public function zSize($zKey)
{
return $this->redis->zSize((string)$zKey);
}
/**
*
* 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @return array
*/
public function zCount($zKey, $start, $end)
{
return $this->redis->zCount($zKey, $start, $end);
}
/**
*
* 返回有序集key中,成员member的score值
* @param String $zKey
* @param String $member
* @return String
*/
public function zScore($zKey, $member)
{
return $this->redis->zScore($zKey, $member);
}
/**
*
* 为有序集key的成员member的score值加上增量increment
* @param String $zKey
* @param Integer $value
* @param String $member
* @return Integer
*/
public function zIncrBy($zKey, $value, $member)
{
return $this->redis->zIncrBy($zKey, $value, $member);
}
/**
*
* 返回有序集key中,指定区间内的成员
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @param bool $withscores
* @return bool ( 默认False无键值/True有键值 )
*/
public function zRange($zKey, $start, $end, $withscores = false)
{
return $this->redis->zRange($zKey, $start, $end, $withscores);
}
/**
*
* 返回有序集key中,指定区间内的成员
* 其中成员的位置按score值递减(从大到小)来排列
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @param bool $withscores
* @return bool ( 默认False无键值/True有键值 )
*/
public function zRevRange($zKey, $start, $end, $withscores = false)
{
return $this->redis->zRevRange($zKey, $start, $end, $withscores);
}
/**
*
* 返回有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。有序集成员按score值递增(从小到大 or 从大到小)次序排列
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @param array $options
* @return array
* =========================================================
* $redis->zRangeByScore('key', 0, 3);
* array('val0', 'val2')
* $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE);
* array('val0' => 0, 'val2' => 2)
* $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));
* array('val2' => 2)
* $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));
* array('val2')
* $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE, 'limit' => array(1, 1));
* array('val2' => 2)
* =========================================================
*
*/
public function zRangeByScore($zKey, $start, $end, array $options)
{
return $this->redis->zRangeByScore($zKey, $start, $end, $options);
}
/**
*
* 返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大 or 从大到小)顺序排列
* @param String $zKey
* @param String $member
* @param String $order ( desc or asc )
* @return array
*/
public function zRank($zKey, $member, $order = 'desc')
{
return $order == 'desc' ? $this->redis->zRank($zKey, $member) : $this->redis->zRevRank($zKey, $member);
}
/**
* 移除有序集key中,指定排名(rank)区间内的所有成员
* 区间分别以下标参数start和stop指出,包含start和stop在内
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @return Integer
*/
public function zRemRangeByRank($zKey, $start, $end)
{
return $this->redis->zRemRangeByRank($zKey, $start, $end);
}
public function tag($tagName)
{
}
/**
* 移除有序集key中,指定(socre)区间内的所有成员
* 区间分别以下标参数start和stop指出,包含start和stop在内
* @param String $zKey
* @param Integer $start
* @param Integer $end
* @return Integer
*/
public function zRemRangeByScore($zKey, $start, $end)
{
return $this->redis->zRemRangeByScore($zKey, $start, $end);
}
public function zRevRangeByScore($zkey, $start, $end, array $options)
{
return $this->redis->zRevRangeByScore($zkey, $start, $end, $options);
}
/**
* 发布消息
*
* @param String $channel
* @param String $message
* @return Integer
*/
public function publish($channel, $message)
{
return $this->redis->publish($channel, $message);
}
/**
* 订阅消息
* @param String $channel
* @return String
*/
public function subscribe(array $channel, $callback)
{
return $this->redis->subscribe($channel, $callback);
}
/**
* 退订
* @param String $channel
*/
public function unsubscribe($channel)
{
return $this->redis->unsubscribe($channel);
}
/**
* 按照模式匹配订阅多个频道
*
* @param String $pattern (如:news.* 可订阅news.开头的所有频道)
*/
public function psubscribe($pattern, $callback)
{
return $this->redis->psubscribe($pattern, $callback);
}
/**
* 退订给定模式的所有渠道
*
* @param String $pattern
*/
public function punsubscribe($pattern)
{
return $this->redis->punsubscribe($pattern);
}
public function pubsub($pattern)
{
return $this->redis->pubsub($pattern);
}
}
\ No newline at end of file
... ...
<?php
namespace Hood\Cache;
use Hood\Core\Root;
use Yaf\Exception;
/**
* Description of cache
*
* @author 13011908
*/
class FileCache extends Root implements CacheInterface
{
const DEFAULT_EXPIRE = 3600;
protected static $default = 'file';
protected static $instances = array();
protected $_cache_dir;
protected $_tag = null;
private $section = 'file';
private $node = 'cache';
public function __construct($childNode = null, $node = 'cache', $cachePath = null)
{
if ($cachePath == null) {
$server = $this->getServerHost('cache');
$this->node = ($node == null ? 'cache' : $node);
$_pathList = $cachePath = $server->getServerConfig($this->section, $this->node);
if ($childNode == null && is_array($cachePath)) {
$cachePath = (sys_get_temp_dir() . 'cached' . DIRECTORY_SEPARATOR);
} else {
$cachePath = $_pathList[$childNode];
}
}
$this->initFileInfo($cachePath);
}
private function initFileInfo($directory)
{
try {
$this->_cache_dir = new \SplFileInfo($directory);
} // PHP < 5.3 exception handle
catch (ErrorException $e) {
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
} // PHP >= 5.3 exception handle
catch (UnexpectedValueException $e) {
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
}
// If the defined directory is a file, get outta here
if ($this->_cache_dir->isFile()) {
throw new Exception('Unable to create cache directory as a file already exists : ' . $this->_cache_dir->getRealPath());
}
if (!$this->_cache_dir->isDir()) {
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
}
// Check the read status of the directory
if (!$this->_cache_dir->isReadable()) {
throw new Exception('Unable to read from the cache directory ' . $this->_cache_dir->getRealPath());
}
// Check the write status of the directory
if (!$this->_cache_dir->isWritable()) {
throw new Exception('Unable to write to the cache directory ' . $this->_cache_dir->getRealPath());
}
}
public function add($key, $value, $minutes)
{
}
public function increment($key, $value = 1)
{
$tag = $this->_tag;
if ($get = $this->get($key)) {
if (preg_match('/^\d+$/', $get)) {
$value = intval($get) + $value;
} else {
return false;
}
}
if ($tag) {
$this->tag($tag);
}
return $this->set($key, $value);
}
public function decrement($key, $value = 1)
{
$tag = $this->_tag;
if ($get = $this->get($key)) {
if (preg_match('/^\d+$/', $get)) {
$value = intval($get) - $value;
} else {
return false;
}
}
if ($tag) {
$this->tag($tag);
}
return $this->set($key, $value);
}
public function tag($tagName = null)
{
if ($tagName) {
$this->_tag = md5($tagName);
return $this;
} elseif (!empty($this->_tag)) {
$tag = $this->_tag;
unset($this->_tag);
return $tag . DIRECTORY_SEPARATOR;
} else {
return '';
}
}
public static function instance($group = NULL)
{
// If there is no group supplied
if ($group === NULL) {
// Use the default setting
$group = self::$default;
}
if (isset(self::$instances[$group])) {
// Return the current group if initiated already
return self::$instances[$group];
}
// Create a new cache type instance
self::$instances[$group] = new self();
// Return the instance
return self::$instances[$group];
}
/**
* Retrieve a cached value entry by id.
*
* // Retrieve cache entry from file group
* $data = self::instance('file')->get('foo');
*
* // Retrieve cache entry from file group and return 'bar' if miss
* $data = self::instance('file')->get('foo', 'bar');
*
* @param string id of cache to entry
* @param string default value to return if cache miss
* @return mixed
* @throws Cache_Exception
*/
public function get($id, $default = NULL)
{
$filename = self::filename($this->_sanitize_id($id));
$directory = $this->_resolve_directory($filename);
// Wrap operations in try/catch to handle notices
try {
// Open file
$file = new \SplFileInfo($directory . $filename);
// If file does not exist
if (!$file->isFile()) {
// Return default value
return $default;
} else {
// Open the file and parse data
$created = $file->getMTime();
$data = $file->openFile();
$lifetime = $data->fgets();
// If we're at the EOF at this point, corrupted!
if ($data->eof()) {
return false;
throw new Exception(__METHOD__ . ' corrupted cache file!');
}
$cache = '';
while ($data->eof() === FALSE) {
$cache .= $data->fgets();
}
// Test the expiry
if (($created + (int)$lifetime) < time()) {
// Delete the file
$this->_delete_file($file, NULL, TRUE);
return $default;
} else {
return unserialize($cache);
}
}
} catch (ErrorException $e) {
// Handle ErrorException caused by failed unserialization
if ($e->getCode() === E_NOTICE) {
throw new Exception(__METHOD__ . ' failed to unserialize cached object with message : ' . $e->getMessage());
}
// Otherwise throw the exception
throw $e;
}
}
/**
* Set a value to cache with id and lifetime
*
* $data = 'bar';
*
* // Set 'bar' to 'foo' in file group, using default expiry
* self::instance('file')->set('foo', $data);
*
* // Set 'bar' to 'foo' in file group for 30 seconds
* self::instance('file')->set('foo', $data, 30);
*
* @param string id of cache entry
* @param string data to set to cache
* @param integer lifetime in seconds
* @return boolean
*/
public function set($id, $data, $lifetime = NULL)
{
$filename = self::filename($this->_sanitize_id($id));
$directory = $this->_resolve_directory($filename);
// If lifetime is NULL
if ($lifetime === NULL) {
// Set to the default expiry
$lifetime = self::DEFAULT_EXPIRE;
}
// Open directory
$dir = new \SplFileInfo($directory);
// If the directory path is not a directory
if (!$dir->isDir()) {
// Create the directory
if (!mkdir($directory, 0777, TRUE)) {
throw new Exception(__METHOD__ . ' unable to create directory : ' . $directory);
}
// chmod to solve potential umask issues
chmod($directory, 0777);
}
// Open file to inspect
$resouce = new \SplFileInfo($directory . $filename);
$file = $resouce->openFile('w');
try {
$data = $lifetime . "\n" . serialize($data);
$file->fwrite($data, strlen($data));
return (bool)$file->fflush();
} catch (ErrorException $e) {
// If serialize through an error exception
if ($e->getCode() === E_NOTICE) {
// Throw a caching error
throw new Exception(__METHOD__ . ' failed to serialize data for caching with message : ' . $e->getMessage());
}
// Else rethrow the error exception
throw $e;
}
}
protected static function filename($string)
{
return sha1($string) . '.cache';
}
/**
* Delete a cache entry based on id
*
* // Delete 'foo' entry from the file group
* self::instance('file')->delete('foo');
*
* @param string id to remove from cache
* @return boolean
*/
public function delete($id)
{
$filename = self::filename($this->_sanitize_id($id));
$directory = $this->_resolve_directory($filename);
return $this->_delete_file(new \SplFileInfo($directory . $filename), NULL, TRUE);
}
/**
* Delete all cache entries.
*
* Beware of using this method when
* using shared memory cache systems, as it will wipe every
* entry within the system for all clients.
*
* // Delete all cache entries in the file group
* self::instance('file')->delete_all();
*
* @return boolean
*/
public function delete_all()
{
return $this->_delete_file($this->_cache_dir, TRUE);
}
protected function _delete_file(\SplFileInfo $file, $retain_parent_directory = FALSE, $ignore_errors = FALSE, $only_expired = FALSE)
{
// Allow graceful error handling
try {
// If is file
if ($file->isFile()) {
try {
if ($only_expired === FALSE) {
// We want to delete the file
$delete = TRUE;
} // Otherwise...
else {
// Assess the file expiry to flag it for deletion
$json = $file->openFile('r')->current();
$data = json_decode($json);
$delete = $data->expiry < time();
}
// If the delete flag is set delete file
if ($delete === TRUE)
return @unlink($file->getRealPath());
else
return FALSE;
} catch (ErrorException $e) {
// Catch any delete file warnings
if ($e->getCode() === E_WARNING) {
throw new Exception(__METHOD__ . ' failed to delete file : ' . $file->getRealPath());
}
}
} // Else, is directory
elseif ($file->isDir()) {
// Create new DirectoryIterator
$files = new DirectoryIterator($file->getPathname());
// Iterate over each entry
while ($files->valid()) {
// Extract the entry name
$name = $files->getFilename();
// If the name is not a dot
if ($name != '.' AND $name != '..') {
// Create new file resource
$fp = new \SplFileInfo($files->getRealPath());
// Delete the file
$this->_delete_file($fp);
}
// Move the file pointer on
$files->next();
}
// If set to retain parent directory, return now
if ($retain_parent_directory) {
return TRUE;
}
try {
// Remove the files iterator
// (fixes Windows PHP which has permission issues with open iterators)
unset($files);
// Try to remove the parent directory
return rmdir($file->getRealPath());
} catch (ErrorException $e) {
// Catch any delete directory warnings
if ($e->getCode() === E_WARNING) {
throw new Exception(__METHOD__ . ' failed to delete directory : ' . $file->getRealPath());
}
throw $e;
}
} else {
// We get here if a file has already been deleted
return FALSE;
}
} // Catch all exceptions
catch (Exception $e) {
// If ignore_errors is on
if ($ignore_errors === TRUE) {
// Return
return FALSE;
}
// Throw exception
throw $e;
}
}
protected function _resolve_directory($filename)
{
return $this->_cache_dir->getRealPath() . DIRECTORY_SEPARATOR . $this->tag() . $filename[0] . $filename[1] . DIRECTORY_SEPARATOR;
}
protected function _sanitize_id($id)
{
// Change slashes and spaces to underscores
return str_replace(array('/', '\\', ' '), '_', $id);
}
/**
* Makes the cache directory if it doesn't exist. Simply a wrapper for
* `mkdir` to ensure DRY principles
*
* @see http://php.net/manual/en/function.mkdir.php
* @param string directory
* @param string mode
* @param string recursive
* @param string context
* @return \SplFileInfo
* @throws Cache_Exception
*/
protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL)
{
if (!mkdir($directory, $mode, $recursive)) {
throw new Exception('Failed to create the defined cache directory : ' . $directory);
}
chmod($directory, $mode);
return new \SplFileInfo($directory);;
}
/**
* Garbage collection method that cleans any expired
* cache entries from the cache.
*
* @return void
*/
public function garbage_collect()
{
$this->_delete_file($this->_cache_dir, TRUE, FALSE, TRUE);
return;
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 15/4/28
* Time: 下午3:16
*/
namespace Hood\Cache;
use Hood\Core\Root;
class Memcache extends Root implements CacheInterface
{
private $mcInstances = array();
private $persistentIDs = array();
private $section = 'memcached';
private $node = 'servers';
private $tagName = '';
private $prefix = '';
private $persistentID = 'hood.cache';
private $childNodes = 'hosts';
public function __construct($prefix = '', $persistentID = 'hood.cache')
{
parent::__construct();
$this->prefix = $prefix;
$this->persistentIDs[] = $this->persistentID = $persistentID;
}
public function init()
{
if (isset($this->mcInstances[$this->persistentID])) {
$mc = $this->mcInstances[$this->persistentID];
} else {
$instance = new \Memcache();
$server = $this->getServerHost('cache');
$_serverHosts = $server->getServerConfig($this->section, $this->node);
$mcServers = $this->_makeHosts($server->getServer($_serverHosts[$this->childNodes], 2));
foreach ($mcServers as $key => $val) {
$weight = 100;
if (count($val) == 3) {
list($host, $port, $weight) = $val;
} else {
list($host, $port) = $val;
}
$instance->addServer($host, $port, $this->persistentID, $weight);
}
$this->mcInstances[$this->persistentID] = $mc = $instance;
}
return $mc;
}
/**
* 组织host
* @param array $hosts
* @return array
*/
private function _makeHosts(array $hosts)
{
$_server = array();
foreach ($hosts as $key => $val) {
$_server[] = explode(':', $val);
}
return $_server;
}
/**
* 设置mc配置的块节点
* @param $node
* @return $this
*/
public function setNode($node = null)
{
if ($node != null) $this->node = $node;
return $this;
}
/**
* 设置子节点
* @param $childNode
* @return $this
*/
public function setChildNodes($childNode)
{
$this->childNodes = $childNode;
return $this;
}
/**
* 构建tag
* @param bool $mode
* @return string
*/
private function _makeTag($mode = false)
{
if (empty($this->tagName)) return '';
$_tagVal = $this->init()->get($this->tagName);
if (empty($_tagVal) && $mode == true) {
$_tagVal = md5(microtime() . mt_rand() . uniqid());
$this->init()->set($this->tagName, $_tagVal, 0);
}
unset($this->tagName);
return empty($_tagVal) ? '' : $_tagVal . '.';
}
/**
* 检索一个元素
* @param $key
* @param callable $flags
* @return mixed
*/
public function get($key, &$flags = \MEMCACHE_COMPRESSED)
{
return $this->init()->get($this->_makeTag() . $key, $flags);
}
/**
* 向一个新的key下面增加一个元素
* @param $key
* @param $value
* @param $expiration
* @return bool
*/
public function add($key, $value, $expiration = 0)
{
return $this->init()->add($this->_makeTag(true) . $key, $value, $expiration);
}
/**
* 减小数值元素的值
* @param $key
* @param int $offset
* @return int
*/
public function decrement($key, $offset = 1)
{
return $this->init()->decrement($this->_makeTag() . $key, $offset);
}
/**
* @param $key
* @param int $time
* @return bool
*/
public function delete($key, $time = 0)
{
return $this->init()->delete($this->_makeTag() . $key, $time);
}
/**
* 增加数值元素的值
* @param $key
* @param int $offset
* @param int $initialValue
* @param int $expiry
* @return int
*/
public function increment($key, $offset = 1, $initialValue = 0, $expiry = 0)
{
return $this->init()->increment($this->_makeTag() . $key, $offset, $initialValue, $expiry);
}
/**
* 设置
* @param $key
* @param $value
* @param int $expiration
* @return bool
*/
public function set($key, $var, $expire = 0, $flag = \MEMCACHE_COMPRESSED)
{
return $this->init()->set($this->_makeTag(true) . $key, $var, $flag, $expire);
}
/**
* 设置tag
* @param $tagName
* @return $this
*/
public function tag($tagName)
{
$this->tagName = $tagName;
return $this;
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/11/23
* Time: 上午1:39
*/
namespace Hood\Cache;
use Hood\Core\Root;
use Hood\Debug\DebugException;
class Memcached extends Root implements CacheInterface
{
private $mcInstances = array();
private $persistentIDs = array();
private $timeout = 150;
private $section = 'memcached';
private $node = 'servers';
private $tagName = '';
private $prefix = '';
private $persistentID = 'hood.cache';
private $childNodes = 'hosts';
public function __construct($prefix = '', $persistentID = 'hood.cache')
{
parent::__construct();
$this->prefix = $prefix;
$this->persistentIDs[] = $this->persistentID = $persistentID;
}
/**
* 设置子节点
* @param $childNode
* @return $this
*/
public function setChildNodes($childNode)
{
$this->childNodes = $childNode;
return $this;
}
/**
* 设置前缀
* @param $prefix
* @return $this
*/
public function setPrefix($prefix)
{
$this->prefix = $prefix;
return $this;
}
/**
* 设置共享连接ID
* @param $persistentID
* @return $this
*/
public function setPersistentID($persistentID)
{
$this->persistentID = $persistentID;
return $this;
}
/**
* @param $persistentID
* @return \Memcached
* @throws \Hood\Debug\DebugException
*/
private function init()
{
if (isset($this->mcInstances[$this->persistentID])) {
$mc = $this->mcInstances[$this->persistentID];
} else {
$instance = new \Memcached();
$instance->setOption(\Memcached::OPT_PREFIX_KEY, $this->prefix);
$instance->setOption(\Memcached::OPT_DISTRIBUTION, \Memcached::DISTRIBUTION_CONSISTENT); // 开启一致性哈希 取模(默认)/ 一致性
$instance->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);//ketama算法兼容 设置为md5并且分布算法将会 采用带有权重的一致性hash分布
$instance->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->timeout);
if (count($instance->getServerList()) < 1) {
$server = $this->getServerHost('cache');
$_serverHosts = $server->getServerConfig($this->section, $this->node);
if (empty($_serverHosts[$this->childNodes])) {
throw new DebugException('Memcache Host Config is Null.');
}
$mcServers = $this->_makeHosts($server->getServer($_serverHosts[$this->childNodes], 2));
$instance->addServers($mcServers);
unset($mcServers);
}
$this->mcInstances[$this->persistentID] = $mc = $instance;
}
return $mc;
}
/**
* 设置mc配置的块
* @param $section
* @return $this
*/
public function setSection($section)
{
$this->section = $section;
return $this;
}
/**
* 设置mc配置的块节点
* @param $node
* @return $this
*/
public function setNode($node = null)
{
if ($node != null) $this->node = $node;
return $this;
}
/**
* 组织host
* @param array $hosts
* @return array
*/
private function _makeHosts(array $hosts)
{
$_server = array();
foreach ($hosts as $key => $val) {
$_server[] = explode(':', $val);
}
return $_server;
}
/**
* 构建tag
* @param bool $mode
* @return string
*/
private function _makeTag($mode = false)
{
if (empty($this->tagName)) return '';
$_tagVal = $this->init()->get($this->tagName);
if (empty($_tagVal) && $mode == true) {
$_tagVal = md5(microtime() . mt_rand() . uniqid());
$this->init()->set($this->tagName, $_tagVal, 0);
}
unset($this->tagName);
return empty($_tagVal) ? '' : $_tagVal . '.';
}
/**
* 检索一个元素
* @param $key
* @param callable $cache_cb
* @param float $cas_token
* @return mixed
*/
public function get($key, $cacheCb = null, &$casToken = null)
{
return $this->init()->get($this->_makeTag() . $key, $cacheCb, $casToken);
}
/**
* 向一个新的key下面增加一个元素
* @param $key
* @param $value
* @param $expiration
* @return bool
*/
public function add($key, $value, $expiration = 0)
{
return $this->init()->add($this->_makeTag(true) . $key, $value, $expiration);
}
/**
* 向已存在元素后追加数据
* @param $key
* @param $value
* @return bool
*/
public function append($key, $value)
{
return $this->init()->append($this->_makeTag(true) . $key, $value);
}
/**
* 比较并交换值
* @param $casToken
* @param $key
* @param $value
* @param int $expiration
* @return bool
*/
public function cas($casToken, $key, $value, $expiration = 0)
{
return $this->init()->cas($casToken, $this->_makeTag(true) . $key, $value, $expiration);
}
/**
* 减小数值元素的值
* @param $key
* @param int $offset
* @return int
*/
public function decrement($key, $offset = 1)
{
return $this->init()->decrement($this->_makeTag() . $key, $offset);
}
/**
* @param $key
* @param int $time
* @return bool
*/
public function delete($key, $time = 0)
{
return $this->init()->delete($this->_makeTag() . $key, $time);
}
/**
* 删除多个数据
* @param array $keys
* @param int $time
* @return bool
*/
public function deleteMulti(array $keys, $time = 0)
{
return $this->init()->deleteMulti($this->_makeMultiKey($keys), $time);
}
/**
* 组合多key 数据
* @param $keys
* @return array
*/
private function _makeMultiKey($keys, $mode = false)
{
$_keys = array();
$tag = $this->_makeTag($mode);
foreach ($keys as $key) {
$_keys[] = $tag . $key;
}
return $_keys;
}
/**
* 请求多个元素
* @param array $keys
* @param null $withCas
* @param callable $valueCb
* @return bool
*/
public function getDelayed(array $keys, $withCas = null, callable $valueCb = null)
{
return $this->init()->getDelayed($this->_makeMultiKey($keys), $withCas, $valueCb);
}
/**
* 抓取所有剩余的结果
* @return array
*/
public function fetchAll()
{
return $this->init()->fetchAll();
}
/**
* 检索多个元素
* @param array $keys
* @param array $cas_tokens
* @param null $flags
* @return mixed
*/
public function getMulti(array $keys, array &$casTokens = null, $flags = null)
{
return $this->init()->getMulti($this->_makeMultiKey($keys), $casTokens, $flags);
}
/**
* 增加数值元素的值
* @param $key
* @param int $offset
* @param int $initialValue
* @param int $expiry
* @return int
*/
public function increment($key, $offset = 1, $initialValue = 0, $expiry = 0)
{
return $this->init()->increment($this->_makeTag() . $key, $offset, $initialValue, $expiry);
}
/**
* 检查memcache是否长连接
* @return bool
*/
public function isPersistent()
{
return $this->init()->isPersistent();
}
/**
* 设置
* @param $key
* @param $value
* @param int $expiration
* @return bool
*/
public function set($key, $value, $expiration = 0)
{
return $this->init()->set($this->_makeTag(true) . $key, $value, $expiration);
}
/**
* 设置多个数据
* @param array $items
* @param int $expiration
* @return bool
*/
public function setMulti(array $items, $expiration = 0)
{
$_items = array();
$tag = $this->_makeTag(true);
foreach ($items as $key => $val) {
$_items[$tag . $key] = $val;
}
return $this->init()->setMulti($_items, $expiration);
}
/**
* 设置tag
* @param $tagName
* @return $this
*/
public function tag($tagName)
{
$this->tagName = $tagName;
return $this;
}
/**
* 清除服务列表
* @return $this
*/
public function resetServerList()
{
$this->init()->resetServerList();
return $this;
}
}
\ No newline at end of file
... ...
#File
缓存路径配置在cache.config.ini里面,如果config里面不设置路径的话使用系统默认的临时文件路径
[file]
cache=/tmp/yoho
$file = Cache::File();
[file]
cache.path = /tmp/yoho
$file = Cache::File('path');
[file]
fileCache.path = /tmp/yoho
$file = Cache::File('path','fileCache');
实现了get、set、del 等方法
$file = Cache::File('path','cache');
$file->set('a', '00');
$file->get('a');
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 1/27/15
* Time: 10:50 PM
*/
namespace Hood\Cache\Ssdb;
class Client
{
private $debug = false;
public $sock = null;
private $_closed = false;
private $recv_buf = '';
private $_easy = false;
public $last_resp = null;
function __construct($host, $port, $timeout_ms = 2000)
{
$timeout_f = (float)$timeout_ms / 1000;
$this->sock = @stream_socket_client("$host:$port", $errno, $errstr, $timeout_f);
if (!$this->sock) {
throw new SSDBException("$errno: $errstr");
}
$timeout_sec = intval($timeout_ms / 1000);
$timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000;
@stream_set_timeout($this->sock, $timeout_sec, $timeout_usec);
if (function_exists('stream_set_chunk_size')) {
@stream_set_chunk_size($this->sock, 1024 * 1024);
}
}
/**
* After this method invoked with yesno=true, all requesting methods
* will not return a Response object.
* And some certain methods like get/zget will return false
* when response is not ok(not_found, etc)
*/
function easy()
{
$this->_easy = true;
}
function close()
{
if (!$this->_closed) {
@fclose($this->sock);
$this->_closed = true;
$this->sock = null;
}
}
function closed()
{
return $this->_closed;
}
private $batch_mode = false;
private $batch_cmds = array();
function batch()
{
$this->batch_mode = true;
$this->batch_cmds = array();
return $this;
}
function multi()
{
return $this->batch();
}
function exec()
{
$ret = array();
foreach ($this->batch_cmds as $op) {
list($cmd, $params) = $op;
$this->send_req($cmd, $params);
}
foreach ($this->batch_cmds as $op) {
list($cmd, $params) = $op;
$resp = $this->recv_resp($cmd, $params);
$resp = $this->check_easy_resp($cmd, $resp);
$ret[] = $resp;
}
$this->batch_mode = false;
$this->batch_cmds = array();
return $ret;
}
function request()
{
$args = func_get_args();
$cmd = array_shift($args);
return $this->__call($cmd, $args);
}
private $async_auth_password = null;
function auth($password)
{
$this->async_auth_password = $password;
return null;
}
function __call($cmd, $params = array())
{
$cmd = strtolower($cmd);
if ($this->async_auth_password !== null) {
$pass = $this->async_auth_password;
$this->async_auth_password = null;
$auth = $this->__call('auth', array($pass));
if ($auth !== true) {
throw new Exception("Authentication failed");
}
}
if ($this->batch_mode) {
$this->batch_cmds[] = array($cmd, $params);
return $this;
}
try {
if ($this->send_req($cmd, $params) === false) {
$resp = new Response('error', 'send error');
} else {
$resp = $this->recv_resp($cmd, $params);
}
} catch (SSDBException $e) {
if ($this->_easy) {
throw $e;
} else {
$resp = new Response('error', $e->getMessage());
}
}
if ($resp->code == 'noauth') {
$msg = $resp->message;
throw new Exception($msg);
}
$resp = $this->check_easy_resp($cmd, $resp);
return $resp;
}
private function check_easy_resp($cmd, $resp)
{
$this->last_resp = $resp;
if ($this->_easy) {
if ($resp->not_found()) {
return NULL;
} else if (!$resp->ok() && !is_array($resp->data)) {
return false;
} else {
return $resp->data;
}
} else {
$resp->cmd = $cmd;
return $resp;
}
}
function multi_set($kvs = array())
{
$args = array();
foreach ($kvs as $k => $v) {
$args[] = $k;
$args[] = $v;
}
return $this->__call(__FUNCTION__, $args);
}
function multi_hset($name, $kvs = array())
{
$args = array($name);
foreach ($kvs as $k => $v) {
$args[] = $k;
$args[] = $v;
}
return $this->__call(__FUNCTION__, $args);
}
function multi_zset($name, $kvs = array())
{
$args = array($name);
foreach ($kvs as $k => $v) {
$args[] = $k;
$args[] = $v;
}
return $this->__call(__FUNCTION__, $args);
}
function incr($key, $val = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
function decr($key, $val = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
function zincr($name, $key, $score = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
function zdecr($name, $key, $score = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
function zadd($key, $score, $value)
{
$args = array($key, $value, $score);
return $this->__call('zset', $args);
}
function zRevRank($name, $key)
{
$args = func_get_args();
return $this->__call("zrrank", $args);
}
function zRevRange($name, $offset, $limit)
{
$args = func_get_args();
return $this->__call("zrrange", $args);
}
function hincr($name, $key, $val = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
function hdecr($name, $key, $val = 1)
{
$args = func_get_args();
return $this->__call(__FUNCTION__, $args);
}
private function send_req($cmd, $params)
{
$req = array($cmd);
foreach ($params as $p) {
if (is_array($p)) {
$req = array_merge($req, $p);
} else {
$req[] = $p;
}
}
return $this->send($req);
}
private function recv_resp($cmd, $params)
{
$resp = $this->recv();
if ($resp === false) {
return new Response('error', 'Unknown error');
} else if (!$resp) {
return new Response('disconnected', 'Connection closed');
}
if ($resp[0] == 'noauth') {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
switch ($cmd) {
case 'dbsize':
case 'ping':
case 'qset':
case 'getbit':
case 'setbit':
case 'countbit':
case 'strlen':
case 'set':
case 'setx':
case 'setnx':
case 'zset':
case 'hset':
case 'qpush':
case 'qpush_front':
case 'qpush_back':
case 'qtrim_front':
case 'qtrim_back':
case 'del':
case 'zdel':
case 'hdel':
case 'hsize':
case 'zsize':
case 'qsize':
case 'hclear':
case 'zclear':
case 'qclear':
case 'multi_set':
case 'multi_del':
case 'multi_hset':
case 'multi_hdel':
case 'multi_zset':
case 'multi_zdel':
case 'incr':
case 'decr':
case 'zincr':
case 'zdecr':
case 'hincr':
case 'hdecr':
case 'zget':
case 'zrank':
case 'zrrank':
case 'zcount':
case 'zsum':
case 'zremrangebyrank':
case 'zremrangebyscore':
if ($resp[0] == 'ok') {
$val = isset($resp[1]) ? intval($resp[1]) : 0;
return new Response($resp[0], $val);
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
case 'zavg':
if ($resp[0] == 'ok') {
$val = isset($resp[1]) ? floatval($resp[1]) : (float)0;
return new Response($resp[0], $val);
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
case 'get':
case 'substr':
case 'getset':
case 'hget':
case 'qget':
case 'qfront':
case 'qback':
if ($resp[0] == 'ok') {
if (count($resp) == 2) {
return new Response('ok', $resp[1]);
} else {
return new Response('server_error', 'Invalid response');
}
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
break;
case 'qpop':
case 'qpop_front':
case 'qpop_back':
if ($resp[0] == 'ok') {
$size = 1;
if (isset($params[1])) {
$size = intval($params[1]);
}
if ($size <= 1) {
if (count($resp) == 2) {
return new Response('ok', $resp[1]);
} else {
return new Response('server_error', 'Invalid response');
}
} else {
$data = array_slice($resp, 1);
return new Response('ok', $data);
}
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
break;
case 'keys':
case 'zkeys':
case 'hkeys':
case 'hlist':
case 'zlist':
case 'qslice':
if ($resp[0] == 'ok') {
$data = array();
if ($resp[0] == 'ok') {
$data = array_slice($resp, 1);
}
return new Response($resp[0], $data);
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
case 'auth':
case 'exists':
case 'hexists':
case 'zexists':
if ($resp[0] == 'ok') {
if (count($resp) == 2) {
return new Response('ok', (bool)$resp[1]);
} else {
return new Response('server_error', 'Invalid response');
}
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
break;
case 'multi_exists':
case 'multi_hexists':
case 'multi_zexists':
if ($resp[0] == 'ok') {
if (count($resp) % 2 == 1) {
$data = array();
for ($i = 1; $i < count($resp); $i += 2) {
$data[$resp[$i]] = (bool)$resp[$i + 1];
}
return new Response('ok', $data);
} else {
return new Response('server_error', 'Invalid response');
}
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
break;
case 'scan':
case 'rscan':
case 'zscan':
case 'zrscan':
case 'zrange':
case 'zrrange':
case 'hscan':
case 'hrscan':
case 'hgetall':
case 'multi_hsize':
case 'multi_zsize':
case 'multi_get':
case 'multi_hget':
case 'multi_zget':
if ($resp[0] == 'ok') {
if (count($resp) % 2 == 1) {
$data = array();
for ($i = 1; $i < count($resp); $i += 2) {
if ($cmd[0] == 'z') {
$data[$resp[$i]] = intval($resp[$i + 1]);
} else {
$data[$resp[$i]] = $resp[$i + 1];
}
}
return new Response('ok', $data);
} else {
return new Response('server_error', 'Invalid response');
}
} else {
$errmsg = isset($resp[1]) ? $resp[1] : '';
return new Response($resp[0], $errmsg);
}
break;
default:
return new Response($resp[0], array_slice($resp, 1));
}
return new Response('error', 'Unknown command: $cmd');
}
private function send($data)
{
$ps = array();
foreach ($data as $p) {
$ps[] = strlen($p);
$ps[] = $p;
}
$s = join("\n", $ps) . "\n\n";
if ($this->debug) {
echo '> ' . str_replace(array("\r", "\n"), array('\r', '\n'), $s) . "\n";
}
try {
while (true) {
$ret = @fwrite($this->sock, $s);
if ($ret === false) {
$this->close();
throw new SSDBException('Connection lost');
}
$s = substr($s, $ret);
if (strlen($s) == 0) {
break;
}
@fflush($this->sock);
}
} catch (Exception $e) {
$this->close();
throw new SSDBException($e->getMessage());
}
return $ret;
}
private function recv()
{
$this->step = self::STEP_SIZE;
while (true) {
$ret = $this->parse();
if ($ret === null) {
try {
$data = @fread($this->sock, 1024 * 1024);
if ($this->debug) {
echo '< ' . str_replace(array("\r", "\n"), array('\r', '\n'), $data) . "\n";
}
} catch (Exception $e) {
$data = '';
}
if ($data === false || $data === '') {
if (feof($this->sock)) {
$this->close();
throw new SSDBException('Connection lost');
} else {
throw new SSDBTimeoutException('Connection timeout');
}
}
$this->recv_buf .= $data;
# echo "read " . strlen($data) . " total: " . strlen($this->recv_buf) . "\n";
} else {
return $ret;
}
}
}
const STEP_SIZE = 0;
const STEP_DATA = 1;
public $resp = array();
public $step;
public $block_size;
private function parse()
{
$spos = 0;
$epos = 0;
$buf_size = strlen($this->recv_buf);
// performance issue for large reponse
//$this->recv_buf = ltrim($this->recv_buf);
while (true) {
$spos = $epos;
if ($this->step === self::STEP_SIZE) {
$epos = strpos($this->recv_buf, "\n", $spos);
if ($epos === false) {
break;
}
$epos += 1;
$line = substr($this->recv_buf, $spos, $epos - $spos);
$spos = $epos;
$line = trim($line);
if (strlen($line) == 0) { // head end
$this->recv_buf = substr($this->recv_buf, $spos);
$ret = $this->resp;
$this->resp = array();
return $ret;
}
$this->block_size = intval($line);
$this->step = self::STEP_DATA;
}
if ($this->step === self::STEP_DATA) {
$epos = $spos + $this->block_size;
if ($epos <= $buf_size) {
$n = strpos($this->recv_buf, "\n", $epos);
if ($n !== false) {
$data = substr($this->recv_buf, $spos, $epos - $spos);
$this->resp[] = $data;
$epos = $n + 1;
$this->step = self::STEP_SIZE;
continue;
}
}
break;
}
}
// packet not ready
if ($spos > 0) {
$this->recv_buf = substr($this->recv_buf, $spos);
}
return null;
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 1/27/15
* Time: 10:30 PM
*/
namespace Hood\Cache\Ssdb;
class Response
{
public $cmd;
public $code;
public $data = null;
public $message;
function __construct($code = 'ok', $data_or_message = null)
{
$this->code = $code;
if ($code == 'ok') {
$this->data = $data_or_message;
} else {
$this->message = $data_or_message;
}
}
function __toString()
{
if ($this->code == 'ok') {
$s = $this->data === null ? '' : json_encode($this->data);
} else {
$s = $this->message;
}
return sprintf('%-13s %12s %s', $this->cmd, $this->code, $s);
}
function ok()
{
return $this->code == 'ok';
}
function not_found()
{
return $this->code == 'not_found';
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 1/27/15
* Time: 10:51 PM
*/
namespace Hood\Cache\Ssdb;
class SSDBException extends \Exception {
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 1/27/15
* Time: 10:51 PM
*/
namespace Hood\Cache\Ssdb;
class SSDBTimeoutException extends SSDBException {
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 1/27/15
* Time: 11:25 PM
*/
namespace Hood\Cache\Ssdb;
class SimpleSSDB extends Client
{
private $node;
private $childNode;
function __construct($host, $port, $timeout_ms = 2000)
{
parent::__construct($host, $port, $timeout_ms);
$this->easy();
}
public function setNode($node)
{
}
public function setChildNodes($childNode)
{
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/16
* Time: 下午5:05
*/
namespace Hood;
use Hood\Concurrent\Yar;
use Hood\Concurrent\Http;
class Concurrent
{
/**
* @param $url
* @return Yar\Client
*/
static public function yarClient($url)
{
return new Yar\Client($url);
}
/**
* @param $uri
* @return Yar\Concurrent
*/
static public function yarConcurrent($uri)
{
return new Yar\Concurrent($uri);
}
/**
*
* @return Http\CurlMulti
*/
static public function curlMulti()
{
return new Http\CurlMulti();
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/15
* Time: 上午2:04
*/
namespace Hood\Concurrent;
interface ConcurrentInterface {
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/22
* Time: 下午12:23
*/
namespace Hood\Concurrent\Http;
class Curl extends CurlAbstract
{
/**
* GET方式网络请求
* @param $url
* @param array $data
* @param int $timeout
* @return mixed
*/
public static function get($url, array $data = array(), $timeout = 20)
{
$ch = curl_init(self::makeUrl($url, $data));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* post提交数据
* @param $url
* @param $data
* @param int $timeout
* @param array $header
* @param array $cookie
* @return mixed
*/
public static function post($url, $data, $timeout = 20, array $header = array(), array $cookie = array())
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
if (!empty($header)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);// array('Content-Type:application/json;charset=UTF-8'));
}
if (!empty($cookie)) {
$cookie_str = array();
foreach ($cookie as $key => $val) {
$cookie_str[] = urlencode($key) . '=' . urlencode($val);
}
curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str));
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$result = curl_exec($ch);
// $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $result;
}
}
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 15/4/8
* Time: 下午1:55
*/
namespace Hood\Concurrent\Http;
class CurlAbstract
{
public static function makeUrl($url, array $data)
{
$params = '';
if (!empty($data)) {
$params = http_build_query($data, '', '&');
}
if (strpos($url, '?') === false) {
$url = $url . '?' . $params;
} else {
if (!empty($params)) {
$url = $url . '&' . $params;
}
}
return $url;
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 15/4/7
* Time: 下午9:15
*/
namespace Hood\Concurrent\Http;
class CurlMulti extends CurlAbstract
{
private $_curls = array();
private $_handle = NULL;
private $wait_for_connect = false;
private $headerData = array();
public function __construct()
{
$this->_handle = curl_multi_init();
}
public function __destruct()
{
foreach ($this->_curls as $handle_id => $data) {
curl_multi_remove_handle($this->_handle, $data['handle']);
curl_close($data['handle']);
}
curl_multi_close($this->_handle);
}
/**
* 设置是否等待
* @param $wait_for_connect
* @return $this
*/
public function wait($wait_for_connect)
{
$this->wait_for_connect = $wait_for_connect;
return $this;
}
/**
* 设置header
* @param array $headerData
* @return $this
*/
public function header(array $headerData)
{
$this->headerData = $headerData;
return $this;
}
/**
* 调用
* @param $url
* @param $callback
* @param $data
* @return $this
* @throws Exception
*/
public function get($url, $callback, array $data = array())
{
$ch = curl_init(self::makeUrl($url, $data));
$this->addHandle($ch, $callback, $data, $this->wait_for_connect);
return $this;
}
/**
* 调用
* @param $url
* @param $callback
* @param $data
* @return $this
* @throws Exception
*/
public function post($url, $callback, $data)
{
$this->callRest($url, 'POST', $callback, $data);
return $this;
}
/**
* rest 请求方法
* @param $url
* @param $method
* @param $callback
* @param null $data
* @return $this
* @throws Exception
*/
public function callRest($url, $method, $callback, $data = NULL)
{
switch (strtoupper($method)) {
case 'POST':
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, TRUE);
$this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: POST"));
if ($data != null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
break;
case 'DELETE':
$ch = curl_init(self::makeUrl($url, $data));
$this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: DELETE"));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
case 'PUT':
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
$this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: PUT"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($data != null) {
$params = http_build_query($data, '', '&');
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($params));
}
break;
case 'GET':
$ch = curl_init(self::makeUrl($url, $data));
$this->headerData = array_merge($this->headerData, array("X-HTTP-Method-Override: GET"));
break;
}
$this->addHandle($ch, $callback, $data, $this->wait_for_connect);
return $this;
}
/**
* 添加一个handle
* @param $curl_handle
* @param $callback
* @param $data
* @param bool $wait_for_connect #是否等待
* @return bool
* @throws Exception
*/
private function addHandle($curl_handle, $callback, $data, $wait_for_connect = false)
{
if (get_resource_type($curl_handle) !== 'curl' || !is_callable($callback)) {
throw new \Exception("Invalid curl handle or callback");
}
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
if (!empty($this->headerData)) {
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $this->headerData);
}
$this->_curls[(int)$curl_handle] = array(
'handle' => $curl_handle,
'callback' => $callback,
'callback_data' => $data,
);
curl_multi_add_handle($this->_handle, $curl_handle);
if ($wait_for_connect) {
$this->poll();
}
return TRUE;
}
/**
* 移除会话中的hendle
* @param $curl_handle
* @return bool
*/
public function removeHandle($curl_handle)
{
if (!isset($this->_curls[(int)$curl_handle])) {
return FALSE;
}
curl_multi_remove_handle($this->_handle, $curl_handle);
unset($this->_curls[(int)$curl_handle]);
return TRUE;
}
/**
* 等待所有会话
* @return bool
*/
public function poll()
{
$still_running = 0;
do {
$result = curl_multi_exec($this->_handle, $still_running);
if ($result == CURLM_OK) {
do {
$messages_in_queue = 0;
$info = curl_multi_info_read($this->_handle, $messages_in_queue);
if ($info && isset($info['handle']) && isset($this->_curls[(int)$info['handle']])) {
$callback_info = $this->_curls[(int)$info['handle']];
$curl_data = curl_multi_getcontent($info['handle']);
$curl_info = curl_getinfo($info['handle']);
call_user_func($callback_info['callback'], $curl_data, $curl_info);
$this->removeHandle($info['handle']);
curl_close($info['handle']);
}
} while ($messages_in_queue > 0);
}
} while ($result == CURLM_CALL_MULTI_PERFORM && $still_running > 0);
return (boolean)$this->_curls;
}
/**
* 设置堵塞中的会话超时时间
* @param float $timeout
* @return bool
*/
public function select($timeout = 1.0)
{
$result = $this->poll();
if ($result) {
curl_multi_select($this->_handle, $timeout);
$result = $this->poll();
}
return $result;
}
/**
* 刷新所有会话超时时间
* @return bool
*/
public function finish()
{
while ($this->select() === TRUE) {
}
return TRUE;
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/15
* Time: 上午2:02
*/
namespace Hood\Concurrent\Yar;
use Hood\Core\Root;
class Client extends Root
{
/**
* @var array
*/
private $_instances = array();
/**
* @var \Yar_Client
*/
private $client;
/**
* Set timeout to 3s
* @var int
*/
private $_timeout = 3000;
/**
* @param $uri
*/
public function __construct($uri)
{
parent::__construct();
$yarKey = md5($uri);
if (!isset($this->_instances[$yarKey])) {
$this->_instances[$yarKey] = new \Yar_Client($uri);
}
$this->client = $this->_instances[$yarKey];
}
/**
* 设置yar参数
* @param $name
* @param $value
*/
public function setOpt($name, $value)
{
$this->client->setOpt($name, $value);
return $this;
}
/**
* 数据包类型
* @param string $packagerType
*/
public function setPackager($packagerType = YAR_PACKAGER_PHP)
{
$this->client->setOpt(YAR_OPT_PACKAGER, $packagerType);
return $this;
}
/**
* 连接超时(毫秒为单位)
* @param $timeout
*/
public function setConnectTimeout($timeout = 1000)
{
$this->client->setOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout);
return $this;
}
/**
* Set timeout to 3s
* 处理超时(毫秒为单位)
* @param $timeout
* @return $this
*/
public function setTimeout($timeout = 3000)
{
$this->client->setOpt(YAR_OPT_TIMEOUT, $timeout);
return $this;
}
/**
* @param $name
* @param array $arguments
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->client->__call($method, $parameters);
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/15
* Time: 上午2:02
*/
namespace Hood\Concurrent\Yar;
use Hood\Core\Root;
class Concurrent extends Root
{
private $uri;
public function __construct($uri)
{
parent::__construct();
$this->uri = $uri;
}
/**
* 注册一个并行的服务调用
* @param $uri
* @param $method
* @param $parameters
* @param string $callback
*/
public function call($uri, $method, $parameters, $callback = '')
{
\Yar_Concurrent_Client::call($uri, $method, $parameters, $callback);
}
/**
* 链式调用
* @param $method
* @param $parameters
* @param string $callback
* @return $this
*/
public function calls($method, $parameters, $callback = '')
{
$this->call($this->uri, $method, $parameters, $callback);
return $this;
}
/**
* 发送所有注册的并行调用
* @param string $callback
* @param callable $errorCallback
*/
public function loop($callback = '', $errorCallback = '')
{
\Yar_Concurrent_Client::loop($callback, $errorCallback);
}
/**
* 缓存tag
* @param $tagName
* @return $this
*/
public function tag($tagName)
{
$this->_cacheTagName = $tagName;
return $this;
}
/**
* 缓存key
* @param string $key
* @param null $prefix
* @return $this
*/
public function key($key)
{
$this->_cacheKey = (string)$key;
return $this;
}
/**
* 缓存时间
* @param $expire
* @return $this
*/
public function expire($expire)
{
$this->_cacheExpire = (int)$expire;
return $this;
}
}
\ No newline at end of file
... ...
<?php
namespace Hood;
use Hood\Debug\DebugException;
class Cookie
{
/**
* 取得所有的cookie值
*
* @return array
* @since 0.2.2
*/
public static function all()
{
return $_COOKIE;
}
/**
* @param $name
* @param string $default
* @return string
* @throws DebugException
*/
public static function get($name, $default = '')
{
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
throw new DebugException(sprintf('The cookie name "%s" contains invalid characters.', $name));
}
return isset ($_COOKIE [$name]) ? $_COOKIE [$name] : $default;
}
/**
* 设置cookie
* @param string $name
* @param string $domain
* @param string $value
* @param int $expire (0:Session、-1:删除、time():过期时间 )
* @param string $path
* @param bool $httponly
* @param bool $secureAuto
*/
public static function set($name, $value, $minutes = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
{
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
throw new DebugException(sprintf('The cookie name "%s" contains invalid characters.', $name));
}
$expire = $minutes;
if ($minutes == 0) {
$expire = 0;
} else if ($minutes == -1) {
$expire = time() - 3600;
}
setcookie($name, $value, $expire, $path, $domain, (bool)$secure, $httpOnly);
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/7
* Time: 上午12:45
*/
namespace Hood\Core;
use Hood\Core\Server;
class Root
{
/**
* server file
* @var String
*/
protected $serviceFile;
/**
* 应用环境
* @var string
*/
protected $applicationEnv;
/**
* 缓存时间
* @var int
*/
protected $_cacheExpire = 3600;
/**
* 缓存
* @var bool
*/
protected $_cacheStatus = true;
/**
* 缓存key
* @var null
*/
protected $_cacheKey = null;
/**
* 缓存tagName
* @var string
*/
protected $_cacheTagName = '';
/**
* 删除多个缓存tag
*/
protected $_delTags = array();
public function __construct()
{
defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'developer');
defined('APPLICATION_SYSTEM_CONFIG') || define('APPLICATION_SYSTEM_CONFIG', '/Data/Code/SystemConfig');
}
/**
* 获取应用环境
* @return string
*/
public function getApplicationEnv()
{
return $this->applicationEnv;
}
/**
* 设置应用环境
* @param $env
* @return $this
*/
public function setApplicationEnv($env)
{
define('APPLICATION_ENV', $env);
return $this;
}
/**
*
* @param $configFile
* @return $this
*/
public function setApplicationSystemConfig($configFile)
{
define('APPLICATION_SYSTEM_CONFIG', $configFile);
return $this;
}
/**
* 获取server
* @param $serviceName
* @param string $suffix
* @return Server
*/
public function getServerHost($serviceName, $suffix = 'config.ini')
{
$serviceFileArray = array(
$serviceName,
APPLICATION_ENV,
$suffix
);
$this->serviceFile = $serviceFile = APPLICATION_SYSTEM_CONFIG . DIRECTORY_SEPARATOR . implode('.', $serviceFileArray);
return new Server($serviceFile);
}
}
\ No newline at end of file
... ...
<?php
namespace Hood\Core\Security;
/**
* Class AuthCode
* @package Hood\Core\Security
*/
class AuthCode
{
/**
* 验证编码
*
* @param String $string
* @param String $operation
* @param Integer $expiry
* @param String $key
* @return String
*/
private static function auth($string, $key, $expiry = 0, $operation = 'decode')
{
$ckey_length = 4;
$key = md5($key);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'decode' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'decode' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for ($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if ($operation == 'decode') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return false;
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}
}
/**
* 解密
*
* @param String $string
* @param String $key
* @param Integer $expiry
* @return String
*/
public static function decode($string, $key, $expiry = 0)
{
return self::auth($string, $key, $expiry, __FUNCTION__);
}
/**
* 加密
*
* @param String $string
* @param String $key
* @param Integer $expiry
* @return String
*/
public static function encode($string, $key, $expiry = 0)
{
return self::auth($string, $key, $expiry, __FUNCTION__);
}
/**
* 获取编码
*
* @param String $plaintext
* @param String $salt
* @param String $encryption
* @param bool $show_encrypt
* @return String
*/
public static function getCrypted($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)
{
$salt = self::getSalt($encryption, $salt, $plaintext);
switch ($encryption) {
case 'plain' :
return $plaintext;
case 'sha' :
$encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext));
return ($show_encrypt) ? '{SHA}' . $encrypted : $encrypted;
case 'crypt' :
case 'crypt-des' :
case 'crypt-md5' :
case 'crypt-blowfish' :
return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt);
case 'md5-base64' :
$encrypted = base64_encode(mhash(MHASH_MD5, $plaintext));
return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
case 'ssha' :
$encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext . $salt) . $salt);
return ($show_encrypt) ? '{SSHA}' . $encrypted : $encrypted;
case 'smd5' :
$encrypted = base64_encode(mhash(MHASH_MD5, $plaintext . $salt) . $salt);
return ($show_encrypt) ? '{SMD5}' . $encrypted : $encrypted;
case 'aprmd5' :
$length = strlen($plaintext);
$context = $plaintext . '$apr1$' . $salt;
$binary = self::_bin(md5($plaintext . $salt . $plaintext));
for ($i = $length; $i > 0; $i -= 16) {
$context .= substr($binary, 0, ($i > 16 ? 16 : $i));
}
for ($i = $length; $i > 0; $i >>= 1) {
$context .= ($i & 1) ? chr(0) : $plaintext[0];
}
$binary = self::_bin(md5($context));
for ($i = 0; $i < 1000; $i++) {
$new = ($i & 1) ? $plaintext : substr($binary, 0, 16);
if ($i % 3) {
$new .= $salt;
}
if ($i % 7) {
$new .= $plaintext;
}
$new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext;
$binary = self::_bin(md5($new));
}
$p = array();
for ($i = 0; $i < 5; $i++) {
$k = $i + 6;
$j = $i + 12;
if ($j == 16) {
$j = 5;
}
$p[] = self::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5);
}
return '$apr1$' . $salt . '$' . implode('', $p) . self::_toAPRMD5(ord($binary[11]), 3);
case 'md5-hex' :
default :
$encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext);
return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
}
}
/**
* Enter description here...
*
* @param unknown_type $encryption
* @param unknown_type $seed
* @param unknown_type $plaintext
* @return unknown
*/
public static function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '')
{
switch ($encryption) {
case 'crypt' :
case 'crypt-des' :
if ($seed) {
return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2);
} else {
return substr(md5(mt_rand()), 0, 2);
}
break;
case 'crypt-md5' :
if ($seed) {
return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12);
} else {
return '$1$' . substr(md5(mt_rand()), 0, 8) . '$';
}
break;
case 'crypt-blowfish' :
if ($seed) {
return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16);
} else {
return '$2$' . substr(md5(mt_rand()), 0, 12) . '$';
}
break;
case 'ssha' :
if ($seed) {
return substr(preg_replace('|^{SSHA}|', '', $seed), -20);
} else {
return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
}
break;
case 'smd5' :
if ($seed) {
return substr(preg_replace('|^{SMD5}|', '', $seed), -16);
} else {
return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
}
break;
case 'aprmd5' :
/* 64 characters that are valid for APRMD5 passwords. */
$APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($seed) {
return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8);
} else {
$salt = '';
for ($i = 0; $i < 8; $i++) {
$salt .= $APRMD5{rand(0, 63)};
}
return $salt;
}
break;
default :
$salt = '';
if ($seed) {
$salt = $seed;
}
return $salt;
break;
}
}
public static function genRandom($length = 8)
{
$salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$len = strlen($salt);
$makepass = '';
$stat = @stat(__FILE__);
if (empty($stat) || !is_array($stat))
$stat = array(
php_uname()
);
mt_srand(crc32(microtime() . implode('|', $stat)));
for ($i = 0; $i < $length; $i++) {
$makepass .= $salt[mt_rand(0, $len - 1)];
}
return $makepass;
}
public static function _toAPRMD5($value, $count)
{
/* 64 characters that are valid for APRMD5 passwords. */
$APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$aprmd5 = '';
$count = abs($count);
while (--$count) {
$aprmd5 .= $APRMD5[$value & 0x3f];
$value >>= 6;
}
return $aprmd5;
}
public static function _bin($hex)
{
$bin = '';
$length = strlen($hex);
for ($i = 0; $i < $length; $i += 2) {
$tmp = sscanf(substr($hex, $i, 2), '%x');
$bin .= chr(array_shift($tmp));
}
return $bin;
}
/**
* 组合一个安全的密码
* @param $code
* @return String
*/
public static function makePass($code)
{
$salt = self::genRandom(32);
$crypt = self::getCrypted($code . $salt, $salt);
return $crypt . ':' . $salt;
}
/**
* 验证密码
*
* @param String $inputPassword
* @param String $password
* @return bool
*/
public static function authPassword($inputPassword, $password)
{
if (empty($password) || empty($inputPassword)) {
return false;
}
$passwordList = explode(':', trim($password));
if (count($passwordList) != 2) {
return false;
}
list($crypt, $salt) = $passwordList;
$decode = self::getCrypted($inputPassword . $salt, $salt);
if ($crypt != $decode) {
return false;
}
return true;
}
############################ 加密规则 ########################
/**
* 排序参数
* @param array $package
* @return array
*/
static function packageSort(array $package)
{
ksort($package);
reset($package);
return $package;
}
/**
* 组合签名
* @param array $package
* @return string
*/
static function makeSign(array $package)
{
$packageList = array();
foreach ($package as $key => $val) {
$packageList[] = trim($key . '=' . $val);
}
return strtolower(md5(implode('&', $packageList)));
}
/**
* 获取签名
*
* @param array $package
* @return string
*/
static function getSign(array $package)
{
$package = self::packageSort($package);
return self::makeSign($package);
}
/**
* 校验签名
* @param $submitSign
* @param $makeSign
* @return bool
*/
static function verifySign($submitSign, $makeSign)
{
return strtolower($submitSign) == strtolower($makeSign);
}
}
\ No newline at end of file
... ...
<?php
/**
* Created by PhpStorm.
* User: Zip
* Date: 14/12/7
* Time: 上午12:11
*/
namespace Hood\Core;
use Hood\Debug\DebugException;
class Server extends Root
{
/**
* 服务器随机选择模式
* @var Integer
*/
const SERVER_SELECT_MODEL_RAND = 1;
/**
* 服务器选择静态
* @var Integer
*/
const SERVER_SELECT_MODEL_STATIC = 2;
/**
* @var string
*/
protected $_sectionSeparator = ':';
/**
* 字符分割
* @var string
*/
protected $_nestSeparator = '.';
/**
* 服务器选择模式
* @var int
*/
private $serverSelectModel = 1;
/**
* ini 数组
* @var array
*/
private $iniArray = array();
/**
* 检查服务状态
* @var bool
*/
private $checkServerStatus = true;
public function __construct($filename)
{
$this->iniArray = $this->_loadIniFile($filename);
}
/**
* 设置服务器选择模式
* @param $model
* @return $this
*/
public function setSelectModel($model)
{
$this->serverSelectModel = $model;
return $this;
}
/**
* 获取服务器地址
* @param $section
* @param $node
* @param int $model
* @return array|mixed
* @throws DebugException
*/
public function getServerConfig($section, $node = null)
{
$sectionArray = $this->_processSection($section);
if ($node == null) {
return $sectionArray;
} elseif (isset($sectionArray[$node])) {
return $sectionArray[$node];
}
return array();
}
/**
* 选择服务器
* @param $servers
* @param $model
* @return array|mixed
* @throws DebugException
*/
public function getServer($servers, $model = 1)
{
$serverArray = $this->_parseServer($servers);
switch ($model) {
case 1:
if (count($serverArray) <= 1) {
$servers = $serverArray;
} else {
$servers = $this->_randServer($serverArray);
}
break;
case 2:
$servers = $serverArray;
break;
default:
throw new DebugException('Server select model not ' . $model);
}
return $servers;
}
/**
* 获取服务器Map
* @param $section
* @param $node
* @param int $model
* @return array
* @throws DebugException
*/
public function getServerMap($servers, $model = 1)
{
$_servers = $this->getServer($servers, $model);
if (empty($_servers)) {
return array();
}
$_serversMap = array();
if ($model == 1 && count($_servers) == 1) {
$_serversMap = $this->_processHost($_servers[0]);
} elseif ($model == 2) {
foreach ($_servers as $key => $host) {
$_serversMap[] = $this->_processHost($host);
}
}
return $_serversMap;
}
/**
* 获取所有配置Map
* @param $section
* @param $node
* @return array
*/
public function getSectionConfig($section, $node)
{
$servers = $this->getServerConfig($section, $node);
$_serversMap = array();
foreach ($servers as $key => $host) {
$_serversMap[] = $this->_processHost($host);
}
return $_serversMap;
}
/**
* 随机&权重随机
* @param array $server
* @return mixed
*/
private function _randServer(array $server)
{
if (substr_count($server[0], ':') == 2) {
$_domain = array();
foreach ($server as $key => $domain) {
$_domain[] = $this->_processHost($domain);
}
$_server = $this->_countWeight($_domain);
$_server = $_server['host'] . ':' . $_server['port'] . ':' . $_server['weight'];
} else {
$_server = $server[array_rand($server)];
}
return $_server;
}
/**
* 权重计算
* @param array $data
* @return mixed
*/
private function _countWeight(array $data)
{
$weight = 0;
$tempArray = array();
foreach ($data as $v) {
$weight += (int)$v['weight'];
for ($i = 0; $i < $v['weight']; $i++) {
$tempArray[] = $v;//放大数组
}
}
$int = mt_rand(0, $weight - 1);//获取一个随机数
return $tempArray[$int];
}
/**
* 解析host
* @param $domain
* @return array
*/
private function _processHost($domain)
{
$_hostMap = array();
$domainArray = explode(':', $domain);
switch (count($domainArray)) {
case 2 :
list($host, $port) = $domainArray;
$_hostMap = array(
'host' => (string)$host,
'port' => (int)intval($port)
);
break;
case 3 :
list($host, $port, $weight) = $domainArray;
$_hostMap = array(
'host' => (string)$host,
'port' => (int)intval($port),
'weight' => (int)intval($weight)
);
break;
}
return $_hostMap;
}
/**
* 设置检测服务状态
* @param $check
* @return $this
*/
public function setCheckServer($check)
{
$this->checkServerStatus = $check;
return $this;
}
/**
* 检查服务
* @param array $servers
* @return array
*/
public function checkServer(array $servers)
{
$_servers = array();
foreach ($servers as $key => $val) {
$status = $this->ping($val['host'], $val['port']);
if ($status > 0) {
$_servers[] = $val;
}
}
return $_servers;
}
/**
* 解析Server
* @param $ips
* @return array|mixed
*/
protected function _parseServer($serverString)
{
return explode(',', str_replace(array(
' ',
"\n"
), '', $serverString));
}
public function getSection($section)
{
return $this->_processSection($section);
}
public function get($name, $section = null)
{
return $this->_processSection($section);
}
/**
* 加载ini
* @param $filename
* @return array
* @throws DebugException
*/
private function _loadIniFile($filename)
{
$loaded = $this->_parseIniFile($filename);
$iniArray = array();
foreach ($loaded as $key => $data) {
$pieces = explode($this->_sectionSeparator, $key);
$thisSection = trim($pieces[0]);
switch (count($pieces)) {
case 1:
$iniArray[$thisSection] = $data;
break;
case 2:
$extendedSection = trim($pieces[1]);
$iniArray[$thisSection] = array_merge(array(';extends' => $extendedSection), $data);
break;
default:
throw new DebugException("Section '$thisSection' may not extend multiple sections in $filename");
}
}
return $iniArray;
}
/**
* 解析ini
* @param $filename
* @return array
*/
private function _parseIniFile($filename)
{
if (!file_exists($filename)) {
throw new DebugException($filename . ' Not Find,');
}
$iniArray = parse_ini_file($filename, true);
if ($iniArray == false) {
throw new DebugException($filename . ' Not Array.');
}
return $iniArray;
}
/**
* 解析节点
* @param $section
* @return array
* @throws DebugException
*/
protected function _processSection($section)
{
$config = array();
$thisSection = array();
if (isset($this->iniArray[$section])) {
$thisSection = $this->iniArray[$section];
}
foreach ($thisSection as $key => $value) {
if (strtolower($key) == ';extends') {
if (isset($this->iniArray[$value])) {
$config = $this->iniArray[$value] + $config;
} else {
throw new DebugException("Parent section '$section' cannot be found");
}
} else {
$config = $this->_processKey($config, $key, $value);
}
}
return $config;
}
/**
* 解析键值
* @param array $config
* @param $key
* @param string $val
* @return array
*/
protected function _processKey(array $config, $key, $val = '')
{
if (strpos($key, $this->_nestSeparator) !== false) {
$pieces = explode($this->_nestSeparator, $key, 2);
if (strlen($pieces[0]) && strlen($pieces[1])) {
if (!isset($config[$pieces[0]])) {
if ($pieces[0] === '0' && !empty($config)) {
$config = array($pieces[0] => $config);
} else {
$config[$pieces[0]] = array();
}
}
$config[$pieces[0]] = $this->_processKey($config[$pieces[0]], $pieces[1], $val);
}
} else {
$config[$key] = $val;
}
return $config;
}
/**
* ping
* @param $domain
* @param $port
* @param int $timeout
* @return float|int|mixed
*/
public function ping($domain, $port, $timeout = 3)
{
$starttime = microtime(true);
$file = @fsockopen($domain, $port, $errno, $errstr, $timeout);
$stoptime = microtime(true);
$status = -1;
if ($file) {
stream_set_blocking($file, false);//非堵塞
stream_set_timeout($file, 3);
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
return $status;
}
}
\ No newline at end of file
... ...