Authored by 梁志锋

Merge remote-tracking branch 'origin/master' into beta

Too many changes to show.

To preserve performance only 34 of 34+ 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,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
... ...