作者 xwp

第一版

deny from all
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: luofei614 <weibo.com/luofei614>
// +----------------------------------------------------------------------
// | 修改者: anuo (本权限类在原3.2.3的基础上修改过来的)
// +----------------------------------------------------------------------
namespace fast;
use think\Db;
use think\Config;
use think\Session;
use think\Request;
/**
* 权限认证类
* 功能特性:
* 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
* $auth=new Auth(); $auth->check('规则名称','用户id')
* 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
* $auth=new Auth(); $auth->check('规则1,规则2','用户id','and')
* 第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
* 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)
* 4,支持规则表达式。
* 在think_auth_rule 表中定义一条规则,condition字段就可以定义规则表达式。 如定义{score}>5 and {score}<100
* 表示用户的分数在5-100之间时这条规则才会通过。
*/
class Auth
{
/**
* @var object 对象实例
*/
protected static $instance;
protected $rules = [];
/**
* 当前请求实例
* @var Request
*/
protected $request;
//默认配置
protected $config = [
'auth_on' => 1, // 权限开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'auth_group', // 用户组数据表名
'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
'auth_rule' => 'auth_rule', // 权限规则表
'auth_user' => 'user', // 用户信息表
];
public function __construct()
{
if ($auth = Config::get('auth')) {
$this->config = array_merge($this->config, $auth);
}
// 初始化request
$this->request = Request::instance();
}
/**
* 初始化
* @access public
* @param array $options 参数
* @return Auth
*/
public static function instance($options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
return self::$instance;
}
/**
* 检查权限
* @param string|array $name 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
* @param int $uid 认证用户的id
* @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
* @param string $mode 执行验证的模式,可分为url,normal
* @return bool 通过验证返回true;失败返回false
*/
public function check($name, $uid, $relation = 'or', $mode = 'url')
{
if (!$this->config['auth_on']) {
return true;
}
// 获取用户需要验证的所有有效规则列表
$rulelist = $this->getRuleList($uid);
if (in_array('*', $rulelist)) {
return true;
}
if (is_string($name)) {
$name = strtolower($name);
if (strpos($name, ',') !== false) {
$name = explode(',', $name);
} else {
$name = [$name];
}
}
$list = []; //保存验证通过的规则名
if ('url' == $mode) {
$REQUEST = unserialize(strtolower(serialize($this->request->param())));
}
foreach ($rulelist as $rule) {
$query = preg_replace('/^.+\?/U', '', $rule);
if ('url' == $mode && $query != $rule) {
parse_str($query, $param); //解析规则中的param
$intersect = array_intersect_assoc($REQUEST, $param);
$rule = preg_replace('/\?.*$/U', '', $rule);
if (in_array($rule, $name) && $intersect == $param) {
//如果节点相符且url参数满足
$list[] = $rule;
}
} else {
if (in_array($rule, $name)) {
$list[] = $rule;
}
}
}
if ('or' == $relation && !empty($list)) {
return true;
}
$diff = array_diff($name, $list);
if ('and' == $relation && empty($diff)) {
return true;
}
return false;
}
/**
* 根据用户id获取用户组,返回值为数组
* @param int $uid 用户id
* @return array 用户所属的用户组 array(
* array('uid'=>'用户id','group_id'=>'用户组id','name'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
* ...)
*/
public function getGroups($uid)
{
static $groups = [];
if (isset($groups[$uid])) {
return $groups[$uid];
}
// 执行查询
$user_groups = Db::name($this->config['auth_group_access'])
->alias('aga')
->join('__' . strtoupper($this->config['auth_group']) . '__ ag', 'aga.group_id = ag.id', 'LEFT')
->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules')
->where("aga.uid='{$uid}' and ag.status='normal'")
->select();
$groups[$uid] = $user_groups ?: [];
return $groups[$uid];
}
/**
* 获得权限规则列表
* @param int $uid 用户id
* @return array
*/
public function getRuleList($uid)
{
static $_rulelist = []; //保存用户验证通过的权限列表
if (isset($_rulelist[$uid])) {
return $_rulelist[$uid];
}
if (2 == $this->config['auth_type'] && Session::has('_rule_list_' . $uid)) {
return Session::get('_rule_list_' . $uid);
}
// 读取用户规则节点
$ids = $this->getRuleIds($uid);
if (empty($ids)) {
$_rulelist[$uid] = [];
return [];
}
// 筛选条件
$where = [
'status' => 'normal'
];
if (!in_array('*', $ids)) {
$where['id'] = ['in', $ids];
}
//读取用户组所有权限规则
$this->rules = Db::name($this->config['auth_rule'])->where($where)->field('id,pid,condition,icon,name,title,ismenu')->select();
//循环规则,判断结果。
$rulelist = []; //
if (in_array('*', $ids)) {
$rulelist[] = "*";
}
foreach ($this->rules as $rule) {
//超级管理员无需验证condition
if (!empty($rule['condition']) && !in_array('*', $ids)) {
//根据condition进行验证
$user = $this->getUserInfo($uid); //获取用户信息,一维数组
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
@(eval('$condition=(' . $command . ');'));
if ($condition) {
$rulelist[$rule['id']] = strtolower($rule['name']);
}
} else {
//只要存在就记录
$rulelist[$rule['id']] = strtolower($rule['name']);
}
}
$_rulelist[$uid] = $rulelist;
//登录验证则需要保存规则列表
if (2 == $this->config['auth_type']) {
//规则列表结果保存到session
Session::set('_rule_list_' . $uid, $rulelist);
}
return array_unique($rulelist);
}
public function getRuleIds($uid)
{
//读取用户所属用户组
$groups = $this->getGroups($uid);
$ids = []; //保存用户所属用户组设置的所有权限规则id
foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
}
$ids = array_unique($ids);
return $ids;
}
/**
* 获得用户资料
* @param int $uid 用户id
* @return mixed
*/
protected function getUserInfo($uid)
{
static $user_info = [];
$user = Db::name($this->config['auth_user']);
// 获取用户表主键
$_pk = is_string($user->getPk()) ? $user->getPk() : 'uid';
if (!isset($user_info[$uid])) {
$user_info[$uid] = $user->where($_pk, $uid)->find();
}
return $user_info[$uid];
}
}
\ No newline at end of file
... ...
<?php
namespace fast;
use DateTime;
use DateTimeZone;
/**
* 日期时间处理类
*/
class Date
{
const YEAR = 31536000;
const MONTH = 2592000;
const WEEK = 604800;
const DAY = 86400;
const HOUR = 3600;
const MINUTE = 60;
/**
* 计算两个时区间相差的时长,单位为秒
*
* $seconds = self::offset('America/Chicago', 'GMT');
*
* [!!] A list of time zones that PHP supports can be found at
* <http://php.net/timezones>.
*
* @param string $remote timezone that to find the offset of
* @param string $local timezone used as the baseline
* @param mixed $now UNIX timestamp or date string
* @return integer
*/
public static function offset($remote, $local = null, $now = null)
{
if ($local === null) {
// Use the default timezone
$local = date_default_timezone_get();
}
if (is_int($now)) {
// Convert the timestamp into a string
$now = date(DateTime::RFC2822, $now);
}
// Create timezone objects
$zone_remote = new DateTimeZone($remote);
$zone_local = new DateTimeZone($local);
// Create date objects from timezones
$time_remote = new DateTime($now, $zone_remote);
$time_local = new DateTime($now, $zone_local);
// Find the offset
$offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local);
return $offset;
}
/**
* 计算两个时间戳之间相差的时间
*
* $span = self::span(60, 182, 'minutes,seconds'); // array('minutes' => 2, 'seconds' => 2)
* $span = self::span(60, 182, 'minutes'); // 2
*
* @param int $remote timestamp to find the span of
* @param int $local timestamp to use as the baseline
* @param string $output formatting string
* @return string when only a single output is requested
* @return array associative list of all outputs requested
* @from https://github.com/kohana/ohanzee-helpers/blob/master/src/Date.php
*/
public static function span($remote, $local = null, $output = 'years,months,weeks,days,hours,minutes,seconds')
{
// Normalize output
$output = trim(strtolower((string)$output));
if (!$output) {
// Invalid output
return false;
}
// Array with the output formats
$output = preg_split('/[^a-z]+/', $output);
// Convert the list of outputs to an associative array
$output = array_combine($output, array_fill(0, count($output), 0));
// Make the output values into keys
extract(array_flip($output), EXTR_SKIP);
if ($local === null) {
// Calculate the span from the current time
$local = time();
}
// Calculate timespan (seconds)
$timespan = abs($remote - $local);
if (isset($output['years'])) {
$timespan -= self::YEAR * ($output['years'] = (int)floor($timespan / self::YEAR));
}
if (isset($output['months'])) {
$timespan -= self::MONTH * ($output['months'] = (int)floor($timespan / self::MONTH));
}
if (isset($output['weeks'])) {
$timespan -= self::WEEK * ($output['weeks'] = (int)floor($timespan / self::WEEK));
}
if (isset($output['days'])) {
$timespan -= self::DAY * ($output['days'] = (int)floor($timespan / self::DAY));
}
if (isset($output['hours'])) {
$timespan -= self::HOUR * ($output['hours'] = (int)floor($timespan / self::HOUR));
}
if (isset($output['minutes'])) {
$timespan -= self::MINUTE * ($output['minutes'] = (int)floor($timespan / self::MINUTE));
}
// Seconds ago, 1
if (isset($output['seconds'])) {
$output['seconds'] = $timespan;
}
if (count($output) === 1) {
// Only a single output was requested, return it
return array_pop($output);
}
// Return array
return $output;
}
/**
* 格式化 UNIX 时间戳为人易读的字符串
*
* @param int Unix 时间戳
* @param mixed $local 本地时间
*
* @return string 格式化的日期字符串
*/
public static function human($remote, $local = null)
{
$timediff = (is_null($local) || $local ? time() : $local) - $remote;
$chunks = array(
array(60 * 60 * 24 * 365, 'year'),
array(60 * 60 * 24 * 30, 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24, 'day'),
array(60 * 60, 'hour'),
array(60, 'minute'),
array(1, 'second')
);
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
if (($count = floor($timediff / $seconds)) != 0) {
break;
}
}
return __("%d {$name}%s ago", $count, ($count > 1 ? 's' : ''));
}
/**
* 获取一个基于时间偏移的Unix时间戳
*
* @param string $type 时间类型,默认为day,可选minute,hour,day,week,month,quarter,year
* @param int $offset 时间偏移量 默认为0,正数表示当前type之后,负数表示当前type之前
* @param string $position 时间的开始或结束,默认为begin,可选前(begin,start,first,front),end
* @param int $year 基准年,默认为null,即以当前年为基准
* @param int $month 基准月,默认为null,即以当前月为基准
* @param int $day 基准天,默认为null,即以当前天为基准
* @param int $hour 基准小时,默认为null,即以当前年小时基准
* @param int $minute 基准分钟,默认为null,即以当前分钟为基准
* @return int 处理后的Unix时间戳
*/
public static function unixtime($type = 'day', $offset = 0, $position = 'begin', $year = null, $month = null, $day = null, $hour = null, $minute = null)
{
$year = is_null($year) ? date('Y') : $year;
$month = is_null($month) ? date('m') : $month;
$day = is_null($day) ? date('d') : $day;
$hour = is_null($hour) ? date('H') : $hour;
$minute = is_null($minute) ? date('i') : $minute;
$position = in_array($position, array('begin', 'start', 'first', 'front'));
switch ($type) {
case 'minute':
$time = $position ? mktime($hour, $minute + $offset, 0, $month, $day, $year) : mktime($hour, $minute + $offset, 59, $month, $day, $year);
break;
case 'hour':
$time = $position ? mktime($hour + $offset, 0, 0, $month, $day, $year) : mktime($hour + $offset, 59, 59, $month, $day, $year);
break;
case 'day':
$time = $position ? mktime(0, 0, 0, $month, $day + $offset, $year) : mktime(23, 59, 59, $month, $day + $offset, $year);
break;
case 'week':
$time = $position ?
mktime(0, 0, 0, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 1 - 7 * (-$offset), $year) :
mktime(23, 59, 59, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 7 - 7 * (-$offset), $year);
break;
case 'month':
$time = $position ? mktime(0, 0, 0, $month + $offset, 1, $year) : mktime(23, 59, 59, $month + $offset, cal_days_in_month(CAL_GREGORIAN, $month + $offset, $year), $year);
break;
case 'quarter':
$time = $position ?
mktime(0, 0, 0, 1 + ((ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) - 1) * 3, 1, $year) :
mktime(23, 59, 59, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, cal_days_in_month(CAL_GREGORIAN, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, $year), $year);
break;
case 'year':
$time = $position ? mktime(0, 0, 0, 1, 1, $year + $offset) : mktime(23, 59, 59, 12, 31, $year + $offset);
break;
default:
$time = mktime($hour, $minute, 0, $month, $day, $year);
break;
}
return $time;
}
}
... ...
<?php
namespace fast;
use ArrayAccess;
/**
* 表单元素生成
* @class Form
* @package fast
* @method string token() static 生成Token
* @method string label(string $name, string $value = null, array $options = []) static label标签
* @method string input($type, $name, string $value = null, array $options = []) static 按类型生成文本框
* @method string text(string $name, string $value = null, array $options = []) static 普通文本框
* @method string password(string $name, array $options = []) static 密码文本框
* @method string hidden(string $name, string $value = null, array $options = []) static 隐藏文本框
* @method string email(string $name, string $value = null, array $options = []) static Email文本框
* @method string url(string $name, string $value = null, array $options = []) static URL文本框
* @method string file(string $name, array $options = []) static 文件上传组件
* @method string textarea(string $name, string $value = null, array $options = []) static 多行文本框
* @method string editor(string $name, string $value = null, array $options = []) static 富文本编辑器
* @method string select(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件
* @method string selects(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(多选)
* @method string selectpicker(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(友好)
* @method string selectpickers(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(友好)(多选)
* @method string selectpage(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) static 动态下拉列表组件
* @method string selectpages(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) static 动态下拉列表组件(多选)
* @method string citypicker(string $name, string $value, array $options = []) static 城市选择组件
* @method string switcher(string $name, string $value, array $options = []) static 切换组件
* @method string datepicker(string $name, string $value, array $options = []) static 日期选择组件
* @method string timepicker(string $name, string $value, array $options = []) static 时间选择组件
* @method string datetimepicker(string $name, string $value, array $options = []) static 日期时间选择组件
* @method string daterange(string $name, string $value, array $options = []) static 日期区间组件
* @method string timerange(string $name, string $value, array $options = []) static 时间区间组件
* @method string datetimerange(string $name, string $value, array $options = []) static 日期时间区间组件
* @method string fieldlist(string $name, string $value, string $title = null, string $template = null, array $options = []) static 字段列表组件
* @method string cxselect(string $url, array $names = [], array $values = [], array $options = []) static 联动组件
* @method string selectRange(string $name, string $begin, string $end, string $selected = null, array $options = []) static 选择数字区间
* @method string selectYear(string $name, string $begin, string $end, string $selected = null, array $options = []) static 选择年
* @method string selectMonth(string $name, string $selected = null, array $options = [], string $format = '%m') static 选择月
* @method string checkbox(string $name, string $value = '1', string $checked = null, array $options = []) static 单个复选框
* @method string checkboxs(string $name, array $list = [], string $checked = null, array $options = []) static 一组复选框
* @method string radio(string $name, string $value = null, string $checked = null, array $options = [])) static 单个单选框
* @method string radios(string $name, array $list = [], string $checked = null, array $options = [])) static 一组单选框
* @method string image(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传图片组件
* @method string images(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传图片组件(多图))
* @method string upload(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传文件组件
* @method string uploads(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传文件组件(多文件))
* @method string button(string $value = null, array $options = []) static 表单button
*/
class Form
{
/**
* @param $name
* @param $arguments
* @return FormBuilder
*/
public static function __callStatic($name, $arguments)
{
return call_user_func_array([FormBuilder::instance(), $name], $arguments);
}
}
/**
*
* 表单元素生成
* @from https://github.com/illuminate/html
* @package fast
*/
class FormBuilder
{
/**
* Token
*
* @var string
*/
protected $csrfToken = array('name' => '__token__');
/**
* 已创建的标签名称
*
* @var array
*/
protected $labels = [];
/**
* 跳过的填充value值的类型
*
* @var array
*/
protected $skipValueTypes = array('file', 'password', 'checkbox', 'radio');
/**
* 转义HTML
* @var boolean
*/
protected $escapeHtml = true;
protected static $instance;
/**
* 获取单例
* @param array $options
* @return static
*/
public static function instance($options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
return self::$instance;
}
/**
* 设置是否转义
* @param boolean $escape
*/
public function setEscapeHtml($escape)
{
$this->escapeHtml = $escape;
}
/**
* 获取转义编码后的值
* @param string $value
* @return string
*/
public function escape($value)
{
if (!$this->escapeHtml) {
return $value;
}
if (is_array($value)) {
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
}
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
}
/**
* 生成Token
*
* @param string $name
* @param string $type
* @return string
*/
public function token($name = '__token__', $type = 'md5')
{
if (function_exists('token')) {
return token($name, $type);
}
return '';
}
/**
* 生成Label标签
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function label($name, $value = null, $options = [])
{
$this->labels[] = $name;
$options = $this->attributes($options);
$value = $this->escape($this->formatLabel($name, $value));
return '<label for="' . $name . '"' . $options . '>' . $value . '</label>';
}
/**
* Format the label value.
*
* @param string $name
* @param string|null $value
* @return string
*/
protected function formatLabel($name, $value)
{
return $value ?: ucwords(str_replace('_', ' ', $name));
}
/**
* 生成文本框(按类型)
*
* @param string $type
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function input($type, $name, $value = null, $options = [])
{
if (!isset($options['name'])) {
$options['name'] = $name;
}
$id = $this->getIdAttribute($name, $options);
if (!in_array($type, $this->skipValueTypes)) {
$value = $this->getValueAttribute($name, $value);
$options['class'] = isset($options['class']) ? $options['class'] . (stripos($options['class'], 'form-control') !== false ? '' : ' form-control') : 'form-control';
}
$merge = compact('type', 'value', 'id');
$options = array_merge($options, $merge);
return '<input' . $this->attributes($options) . '>';
}
/**
* 生成普通文本框
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function text($name, $value = null, $options = [])
{
return $this->input('text', $name, $value, $options);
}
/**
* 生成密码文本框
*
* @param string $name
* @param array $options
* @return string
*/
public function password($name, $options = [])
{
return $this->input('password', $name, '', $options);
}
/**
* 生成隐藏文本框
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function hidden($name, $value = null, $options = [])
{
return $this->input('hidden', $name, $value, $options);
}
/**
* 生成Email文本框
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function email($name, $value = null, $options = [])
{
return $this->input('email', $name, $value, $options);
}
/**
* 生成URL文本框
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function url($name, $value = null, $options = [])
{
return $this->input('url', $name, $value, $options);
}
/**
* 生成上传文件组件
*
* @param string $name
* @param array $options
* @return string
*/
public function file($name, $options = [])
{
return $this->input('file', $name, null, $options);
}
/**
* 生成多行文本框
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function textarea($name, $value = null, $options = [])
{
if (!isset($options['name'])) {
$options['name'] = $name;
}
$options = $this->setTextAreaSize($options);
$options['id'] = $this->getIdAttribute($name, $options);
$value = (string)$this->getValueAttribute($name, $value);
unset($options['size']);
$options['class'] = isset($options['class']) ? $options['class'] . (stripos($options['class'], 'form-control') !== false ? '' : ' form-control') : 'form-control';
$options = $this->attributes($options);
return '<textarea' . $options . '>' . $this->escape($value) . '</textarea>';
}
/**
* 生成富文本编辑器
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function editor($name, $value = null, $options = [])
{
$options['class'] = isset($options['class']) ? $options['class'] . ' editor' : 'editor';
return $this->textarea($name, $value, $options);
}
/**
* 设置默认的文本框行列数
*
* @param array $options
* @return array
*/
protected function setTextAreaSize($options)
{
if (isset($options['size'])) {
return $this->setQuickTextAreaSize($options);
}
$cols = array_get($options, 'cols', 50);
$rows = array_get($options, 'rows', 5);
return array_merge($options, compact('cols', 'rows'));
}
/**
* 根据size设置行数和列数
*
* @param array $options
* @return array
*/
protected function setQuickTextAreaSize($options)
{
$segments = explode('x', $options['size']);
return array_merge($options, array('cols' => $segments[0], 'rows' => $segments[1]));
}
/**
* 生成滑块
*
* @param string $name
* @param string $min
* @param string $max
* @param string $step
* @param string $value
* @param array $options
* @return string
*/
public function slider($name, $min, $max, $step, $value = null, $options = [])
{
$options = array_merge($options, ['data-slider-min' => $min, 'data-slider-max' => $max, 'data-slider-step' => $step, 'data-slider-value' => $value ? $value : '']);
$options['class'] = isset($options['class']) ? $options['class'] . (stripos($options['class'], 'form-control') !== false ? '' : ' slider form-control') : 'slider form-control';
return $this->input('text', $name, $value, $options);
}
/**
* 生成下拉列表框
*
* @param string $name
* @param array $list
* @param mixed $selected
* @param array $options
* @return string
*/
public function select($name, $list = [], $selected = null, $options = [])
{
$selected = $this->getValueAttribute($name, $selected);
$options['id'] = $this->getIdAttribute($name, $options);
if (!isset($options['name'])) {
$options['name'] = $name;
}
$html = [];
foreach ($list as $value => $display) {
$html[] = $this->getSelectOption($display, $value, $selected);
}
$options['class'] = isset($options['class']) ? $options['class'] . (stripos($options['class'], 'form-control') !== false ? '' : ' form-control') : 'form-control';
$options = $this->attributes($options);
$list = implode('', $html);
return "<select{$options}>{$list}</select>";
}
/**
* 下拉列表(多选)
*
* @param string $name
* @param array $list
* @param mixed $selected
* @param array $options
* @return string
*/
public function selects($name, $list = [], $selected = null, $options = [])
{
$options[] = 'multiple';
return $this->select($name, $list, $selected, $options);
}
/**
* 下拉列表(友好)
*
* @param string $name
* @param array $list
* @param mixed $selected
* @param array $options
* @return string
*/
public function selectpicker($name, $list = [], $selected = null, $options = [])
{
$options['class'] = isset($options['class']) ? $options['class'] . ' selectpicker' : 'selectpicker';
return $this->select($name, $list, $selected, $options);
}
/**
* 下拉列表(友好)(多选)
*
* @param string $name
* @param array $list
* @param mixed $selected
* @param array $options
* @return string
*/
public function selectpickers($name, $list = [], $selected = null, $options = [])
{
$options[] = 'multiple';
return $this->selectpicker($name, $list, $selected, $options);
}
/**
* 生成动态下拉列表
*
* @param string $name 名称
* @param mixed $value
* @param string $url 数据源地址
* @param string $field 显示的字段名称,默认为name
* @param string $primaryKey 主键,数据库中保存的值,默认为id
* @param array $options
* @return string
*/
public function selectpage($name, $value, $url, $field = null, $primaryKey = null, $options = [])
{
$options = array_merge($options, ['data-source' => $url, 'data-field' => $field ? $field : 'name', 'data-primary-key' => $primaryKey ? $primaryKey : 'id']);
$options['class'] = isset($options['class']) ? $options['class'] . ' selectpage' : 'selectpage';
return $this->text($name, $value, $options);
}
/**
* 生成动态下拉列表(复选)
*
* @param string $name 名称
* @param mixed $value
* @param string $url 数据源地址
* @param string $field 显示的字段名称,默认为name
* @param string $primaryKey 主键,数据库中保存的值,默认为id
* @param array $options
* @return string
*/
public function selectpages($name, $value, $url, $field = null, $primaryKey = null, $options = [])
{
$options['data-multiple'] = "true";
return $this->selectpage($name, $value, $url, $field, $primaryKey, $options);
}
/**
* 生成城市选择框
*
* @param string $name
* @param mixed $value
* @param array $options
* @return string
*/
public function citypicker($name, $value, $options = [])
{
$options['data-toggle'] = 'city-picker';
return "<div class='control-relative'>" . $this->text($name, $value, $options) . "</div>";
}
/**
* 生成switch组件
*
* @param string $name
* @param mixed $value
* @param array $options
* @return string
*/
public function switcher($name, $value, $options = [])
{
$domname = str_replace(['[', ']', '.'], '', $name);
$btn = $this->hidden($name, $value, ['id' => "c-{$domname}"]);
$yes = 1;
$no = 0;
if (isset($options['yes']) && isset($options['no'])) {
$yes = $options['yes'];
$no = $options['no'];
}
$selected = $no == $value ? "fa-flip-horizontal text-gray" : "";
$disabled = (isset($options['disabled']) && $options['disabled']) || in_array('disabled', $options) ? "disabled" : '';
$color = isset($options['color']) ? $options['color'] : 'success';
unset($options['yes'], $options['no'], $options['color'], $options['disabled']);
$attr = $this->attributes($options);
$html = <<<EOD
{$btn}
<a href="javascript:;" data-toggle="switcher" class="btn-switcher {$disabled}" data-input-id="c-{$domname}" data-yes="{$yes}" data-no="{$no}" {$attr}><i class="fa fa-toggle-on text-{$color} {$selected} fa-2x"></i></a>
EOD;
return $html;
}
/**
* 日期选择器
* @param string $name
* @param mixed $value
* @param array $options
* @return string
*/
public function datepicker($name, $value, $options = [])
{
$defaults = [
'data-date-format' => "YYYY-MM-DD",
];
$options = array_merge($defaults, $options);
$value = is_numeric($value) ? date("Y-m-d", $value) : $value;
return $this->datetimepicker($name, $value, $options);
}
/**
* 时间选择器
*
* @param string $name
* @param mixed $value
* @param array $options
* @return string
*/
public function timepicker($name, $value, $options = [])
{
$defaults = [
'data-date-format' => "HH:mm:ss",
];
$options = array_merge($defaults, $options);
$value = is_numeric($value) ? date("H:i:s", $value) : $value;
return $this->datetimepicker($name, $value, $options);
}
/**
* 日期时间选择器
*
* @param string $name
* @param mixed $value
* @param array $options
* @return string
*/
public function datetimepicker($name, $value, $options = [])
{
$defaults = [
'data-date-format' => "YYYY-MM-DD HH:mm:ss",
'data-use-current' => "true",
];
$value = is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
$options = array_merge($defaults, $options);
$options['class'] = isset($options['class']) ? $options['class'] . ' datetimepicker' : 'datetimepicker';
return $this->text($name, $value, $options);
}
/**
* 日期区间
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function daterange($name, $value, $options = [])
{
$defaults = [
'data-locale' => [
'format' => 'YYYY-MM-DD'
]
];
$options = array_merge($defaults, $options);
return $this->datetimerange($name, $value, $options);
}
/**
* 时间区间
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function timerange($name, $value, $options = [])
{
$defaults = [
'data-locale' => [
'format' => 'HH:mm:ss'
],
'data-ranges' => [],
'data-show-custom-range-label' => "false",
'data-time-picker' => "true",
];
$options = array_merge($defaults, $options);
return $this->datetimerange($name, $value, $options);
}
/**
* 日期时间区间
*
* @param string $name
* @param string $value
* @param array $options
* @return string
*/
public function datetimerange($name, $value, $options = [])
{
$defaults = [
'data-locale' => [
'format' => 'YYYY-MM-DD HH:mm:ss'
]
];
$options = array_merge($defaults, $options);
$options['class'] = isset($options['class']) ? $options['class'] . ' datetimerange' : 'datetimerange';
return $this->text($name, $value, $options);
}
/**
* 生成字段列表组件
*
* @param string $name
* @param mixed $value
* @param array $title
* @param string $template
* @param array $options
* @return string
*/
public function fieldlist($name, $value, $title = null, $template = null, $options = [])
{
$append = __('Append');
$template = $template ? 'data-template="' . $template . '"' : '';
$attributes = $this->attributes($options);
if (is_null($title)) {
$title = [__('Key'), __('Value')];
}
$ins = implode("\n", array_map(function ($value) {
return "<ins>{$value}</ins>";
}, $title));
$value = is_array($value) ? json_encode($value) : $value;
$html = <<<EOD
<dl class="fieldlist" data-name="{$name}" {$template} {$attributes}>
<dd>
{$ins}
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {$append}</a></dd>
<textarea name="{$name}" class="form-control hide" cols="30" rows="5">{$value}</textarea>
</dl>
EOD;
return $html;
}
/**
* 生成联动下拉列表
*
* @param string $url 联动获取数据源的URL地址
* @param array $names 联动字段名称
* @param array $values 联动字段默认选中的值
* @param array $options 扩展属性
* @return string
*/
public function cxselect($url, $names = [], $values = [], $options = [])
{
$classes = [];
$cxselect = [];
$attributes = $this->attributes($options);
foreach ($names as $index => $value) {
$level = $index + 1;
$class = "cxselect-{$level}";
$classes[] = $class;
$selectValue = isset($values[$value]) ? $values[$value] : (isset($values[$index]) ? $values[$index] : '');
$cxselect[] = <<<EOD
<select class="{$class} form-control" name="{$value}" data-value="{$selectValue}" data-url="{$url}?level={$level}&name={$value}" {$attributes}></select>
EOD;
}
$cxselect = implode("\n", $cxselect);
$selects = implode(',', $classes);
$html = <<<EOD
<div class="form-inline" data-toggle="cxselect" data-selects="{$selects}">
{$cxselect}
</div>
EOD;
return $html;
}
/**
* 创建一个下拉列表选择区间组件
*
* @param string $name
* @param string $begin
* @param string $end
* @param string $selected
* @param array $options
* @return string
*/
public function selectRange($name, $begin, $end, $selected = null, $options = [])
{
$range = array_combine($range = range($begin, $end), $range);
return $this->select($name, $range, $selected, $options);
}
/**
* 生成选择年组件
*
* @param string $name
* @param string $begin
* @param string $end
* @param string $selected
* @param array $options
* @return string
*/
public function selectYear($name, $begin, $end, $selected, $options)
{
return call_user_func_array(array($this, 'selectRange'), func_get_args());
}
/**
* 生成选择月组件
*
* @param string $name
* @param string $selected
* @param array $options
* @param string $format
* @return string
*/
public function selectMonth($name, $selected = null, $options = [], $format = '%m')
{
$months = [];
foreach (range(1, 12) as $month) {
$months[$month] = strftime($format, mktime(0, 0, 0, $month, 1));
}
return $this->select($name, $months, $selected, $options);
}
/**
* 根据传递的值生成option
*
* @param string $display
* @param string $value
* @param string $selected
* @return string
*/
public function getSelectOption($display, $value, $selected)
{
if (is_array($display)) {
return $this->optionGroup($display, $value, $selected);
}
return $this->option($display, $value, $selected);
}
/**
* 生成optionGroup
*
* @param array $list
* @param string $label
* @param string $selected
* @return string
*/
protected function optionGroup($list, $label, $selected)
{
$html = [];
foreach ($list as $value => $display) {
$html[] = $this->option($display, $value, $selected);
}
return '<optgroup label="' . $this->escape($label) . '">' . implode('', $html) . '</optgroup>';
}
/**
* 生成option选项
*
* @param string $display
* @param string $value
* @param string $selected
* @return string
*/
protected function option($display, $value, $selected)
{
$selected = $this->getSelectedValue($value, $selected);
$options = array('value' => $this->escape($value), 'selected' => $selected);
return '<option' . $this->attributes($options) . '>' . $this->escape($display) . '</option>';
}
/**
* 检测value是否选中
*
* @param string $value
* @param string $selected
* @return string
*/
protected function getSelectedValue($value, $selected)
{
if (is_array($selected)) {
return in_array($value, $selected) ? 'selected' : null;
}
return ((string)$value == (string)$selected) ? 'selected' : null;
}
/**
* 生成复选按钮
*
* @param string $name
* @param mixed $value
* @param bool $checked
* @param array $options
* @return string
*/
public function checkbox($name, $value = 1, $checked = null, $options = [])
{
if ($checked) {
$options['checked'] = 'checked';
}
return $this->input('checkbox', $name, $value, $options);
}
/**
* 生成一组筛选框
*
* @param string $name
* @param array $list
* @param mixed $checked
* @param array $options
* @return string
*/
public function checkboxs($name, $list, $checked, $options = [])
{
$html = [];
$checked = is_null($checked) ? [] : $checked;
$checked = is_array($checked) ? $checked : explode(',', $checked);
foreach ($list as $k => $v) {
$options['id'] = "{$name}-{$k}";
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox("{$name}[{$k}}]", $k, in_array($k, $checked), $options));
}
return '<div class="checkbox">' . implode(' ', $html) . '</div>';
}
/**
* 生成单选按钮
*
* @param string $name
* @param mixed $value
* @param bool $checked
* @param array $options
* @return string
*/
public function radio($name, $value = null, $checked = null, $options = [])
{
if (is_null($value)) {
$value = $name;
}
if ($checked) {
$options['checked'] = 'checked';
}
return $this->input('radio', $name, $value, $options);
}
/**
* 生成一组单选框
*
* @param string $name
* @param array $list
* @param mixed $checked
* @param array $options
* @return string
*/
public function radios($name, $list, $checked = null, $options = [])
{
$html = [];
$checked = is_null($checked) ? key($list) : $checked;
$checked = is_array($checked) ? $checked : explode(',', $checked);
foreach ($list as $k => $v) {
$options['id'] = "{$name}-{$k}";
$html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $checked), $options));
}
return '<div class="radio">' . implode(' ', $html) . '</div>';
}
/**
* 生成上传图片组件(单图)
*
* @param string $name
* @param string $value
* @param array $inputAttr
* @param array $uploadAttr
* @param array $chooseAttr
* @param array $previewAttr
* @return string
*/
public function image($name = null, $value, $inputAttr = [], $uploadAttr = [], $chooseAttr = [], $previewAttr = [])
{
$default = [
'data-mimetype' => 'image/gif,image/jpeg,image/png,image/jpg,image/bmp'
];
$uploadAttr = is_array($uploadAttr) ? array_merge($default, $uploadAttr) : $uploadAttr;
$chooseAttr = is_array($chooseAttr) ? array_merge($default, $chooseAttr) : $chooseAttr;
return $this->uploader($name, $value, $inputAttr, $uploadAttr, $chooseAttr, $previewAttr);
}
/**
* 生成上传图片组件(多图)
*
* @param string $name
* @param string $value
* @param array $inputAttr
* @param array $uploadAttr
* @param array $chooseAttr
* @param array $previewAttr
* @return string
*/
public function images($name = null, $value, $inputAttr = [], $uploadAttr = [], $chooseAttr = [], $previewAttr = [])
{
$default = [
'data-multiple' => 'true',
'data-mimetype' => 'image/gif,image/jpeg,image/png,image/jpg,image/bmp'
];
$uploadAttr = is_array($uploadAttr) ? array_merge($default, $uploadAttr) : $uploadAttr;
$chooseAttr = is_array($chooseAttr) ? array_merge($default, $chooseAttr) : $chooseAttr;
return $this->uploader($name, $value, $inputAttr, $uploadAttr, $chooseAttr, $previewAttr);
}
/**
* 生成上传文件组件(单文件)
*
* @param string $name
* @param string $value
* @param array $inputAttr
* @param array $uploadAttr
* @param array $chooseAttr
* @param array $previewAttr
* @return string
*/
public function upload($name = null, $value, $inputAttr = [], $uploadAttr = [], $chooseAttr = [], $previewAttr = [])
{
return $this->uploader($name, $value, $inputAttr, $uploadAttr, $chooseAttr, $previewAttr);
}
/**
* 生成上传文件组件(多文件)
*
* @param string $name
* @param string $value
* @param array $inputAttr
* @param array $uploadAttr
* @param array $chooseAttr
* @param array $previewAttr
* @return string
*/
public function uploads($name = null, $value, $inputAttr = [], $uploadAttr = [], $chooseAttr = [], $previewAttr = [])
{
$default = [
'data-multiple' => 'true',
];
$uploadAttr = is_array($uploadAttr) ? array_merge($default, $uploadAttr) : $uploadAttr;
$chooseAttr = is_array($chooseAttr) ? array_merge($default, $chooseAttr) : $chooseAttr;
return $this->uploader($name, $value, $inputAttr, $uploadAttr, $chooseAttr, $previewAttr);
}
protected function uploader($name = null, $value, $inputAttr = [], $uploadAttr = [], $chooseAttr = [], $previewAttr = [])
{
$domname = str_replace(['[', ']', '.'], '', $name);
$options = [
'id' => "plupload-{$domname}",
'class' => "btn btn-danger plupload",
'data-input-id' => "c-{$domname}",
];
$upload = $uploadAttr === false ? false : true;
$choose = $chooseAttr === false ? false : true;
$preview = $previewAttr === false ? false : true;
if ($preview) {
$options['data-preview-id'] = "p-{$domname}";
}
$uploadBtn = $upload ? $this->button('<i class="fa fa-upload"></i> ' . __('Upload'), array_merge($options, $uploadAttr)) : '';
$options = [
'id' => "fachoose-{$domname}",
'class' => "btn btn-danger fachoose",
'data-input-id' => "c-{$domname}",
];
if ($preview) {
$options['data-preview-id'] = "p-{$domname}";
}
$chooseBtn = $choose ? $this->button('<i class="fa fa-list"></i> ' . __('Choose'), array_merge($options, $chooseAttr)) : '';
$previewAttrHtml = $this->attributes($previewAttr);
$previewArea = $preview ? '<ul class="row list-inline plupload-preview" id="p-' . $domname . '" ' . $previewAttrHtml . '></ul>' : '';
$input = $this->text($name, $value, array_merge(['size' => 50, 'id' => "c-{$domname}"], $inputAttr));
$html = <<<EOD
<div class="input-group">
{$input}
<div class="input-group-addon no-border no-padding">
<span>{$uploadBtn}</span>
<span>{$chooseBtn}</span>
</div>
<span class="msg-box n-right" for="c-{$domname}"></span>
</div>
{$previewArea}
EOD;
return $html;
}
/**
* 生成一个按钮
*
* @param string $value
* @param array $options
* @return string
*/
public function button($value = null, $options = [])
{
if (!array_key_exists('type', $options)) {
$options['type'] = 'button';
}
return '<button' . $this->attributes($options) . '>' . $value . '</button>';
}
/**
* 获取ID属性值
*
* @param string $name
* @param array $attributes
* @return string
*/
public function getIdAttribute($name, $attributes)
{
if (array_key_exists('id', $attributes)) {
return $attributes['id'];
}
if (in_array($name, $this->labels)) {
return $name;
}
}
/**
* 获取Value属性值
*
* @param string $name
* @param string $value
* @return string
*/
public function getValueAttribute($name, $value = null)
{
if (is_null($name)) {
return $value;
}
if (!is_null($value)) {
return $value;
}
}
/**
* 数组转换成一个HTML属性字符串。
*
* @param array $attributes
* @return string
*/
public function attributes($attributes)
{
$html = [];
// 假设我们的keys 和 value 是相同的,
// 拿HTML“required”属性来说,假设是['required']数组,
// 会已 required="required" 拼接起来,而不是用数字keys去拼接
foreach ((array)$attributes as $key => $value) {
$element = $this->attributeElement($key, $value);
if (!is_null($element)) {
$html[] = $element;
}
}
return count($html) > 0 ? ' ' . implode(' ', $html) : '';
}
/**
* 拼接成一个属性。
*
* @param string $key
* @param string $value
* @return string
*/
protected function attributeElement($key, $value)
{
if (is_numeric($key)) {
$key = $value;
}
if (!is_null($value)) {
if (is_array($value) || stripos($value, '"') !== false) {
$value = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
return $key . "='" . $value . "'";
} else {
return $key . '="' . $value . '"';
}
}
}
}
class Arr
{
/**
* Determine whether the given value is array accessible.
*
* @param mixed $value
* @return bool
*/
public static function accessible($value)
{
return is_array($value) || $value instanceof ArrayAccess;
}
/**
* Determine if the given key exists in the provided array.
*
* @param \ArrayAccess|array $array
* @param string|int $key
* @return bool
*/
public static function exists($array, $key)
{
if ($array instanceof ArrayAccess) {
return $array->offsetExists($key);
}
return array_key_exists($key, $array);
}
/**
* Get an item from an array using "dot" notation.
*
* @param \ArrayAccess|array $array
* @param string $key
* @param mixed $default
* @return mixed
*/
public static function get($array, $key, $default = null)
{
if (!static::accessible($array)) {
return $default;
}
if (is_null($key)) {
return $array;
}
if (static::exists($array, $key)) {
return $array[$key];
}
foreach (explode('.', $key) as $segment) {
if (static::accessible($array) && static::exists($array, $segment)) {
$array = $array[$segment];
} else {
return $default;
}
}
return $array;
}
/**
* Get all of the given array except for a specified array of items.
*
* @param array $array
* @param array|string $keys
* @return array
*/
public static function except($array, $keys)
{
static::forget($array, $keys);
return $array;
}
/**
* Remove one or many array items from a given array using "dot" notation.
*
* @param array $array
* @param array|string $keys
* @return void
*/
public static function forget(&$array, $keys)
{
$original = &$array;
$keys = (array)$keys;
if (count($keys) === 0) {
return;
}
foreach ($keys as $key) {
// if the exact key exists in the top-level, remove it
if (static::exists($array, $key)) {
unset($array[$key]);
continue;
}
$parts = explode('.', $key);
// clean up before each pass
$array = &$original;
while (count($parts) > 1) {
$part = array_shift($parts);
if (isset($array[$part]) && is_array($array[$part])) {
$array = &$array[$part];
} else {
continue 2;
}
}
unset($array[array_shift($parts)]);
}
}
}
if (!function_exists('array_get')) {
/**
* Get an item from an array using "dot" notation.
*
* @param \ArrayAccess|array $array
* @param string $key
* @param mixed $default
* @return mixed
*/
function array_get($array, $key, $default = null)
{
return Arr::get($array, $key, $default);
}
}
if (!function_exists('e')) {
/**
* Escape HTML special characters in a string.
*
*
* @return string
*/
function e($value)
{
if (is_array($value)) {
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
}
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
}
}
if (!function_exists('array_except')) {
/**
* Get all of the given array except for a specified array of items.
*
* @param array $array
* @param array|string $keys
* @return array
*/
function array_except($array, $keys)
{
return Arr::except($array, $keys);
}
}
... ...
<?php
namespace fast;
/**
* 字符串类
*/
class Http
{
/**
* 发送一个POST请求
* @param string $url 请求URL
* @param array $params 请求参数
* @param array $options 扩展参数
* @return mixed|string
*/
public static function post($url, $params = [], $options = [])
{
$req = self::sendRequest($url, $params, 'POST', $options);
return $req['ret'] ? $req['msg'] : '';
}
/**
* 发送一个GET请求
* @param string $url 请求URL
* @param array $params 请求参数
* @param array $options 扩展参数
* @return mixed|string
*/
public static function get($url, $params = [], $options = [])
{
$req = self::sendRequest($url, $params, 'GET', $options);
return $req['ret'] ? $req['msg'] : '';
}
/**
* CURL发送Request请求,含POST和REQUEST
* @param string $url 请求的链接
* @param mixed $params 传递的参数
* @param string $method 请求的方法
* @param mixed $options CURL的参数
* @return array
*/
public static function sendRequest($url, $params = [], $method = 'POST', $options = [])
{
$method = strtoupper($method);
$protocol = substr($url, 0, 5);
$query_string = is_array($params) ? http_build_query($params) : $params;
$ch = curl_init();
$defaults = [];
if ('GET' == $method) {
$geturl = $query_string ? $url . (stripos($url, "?") !== false ? "&" : "?") . $query_string : $url;
$defaults[CURLOPT_URL] = $geturl;
} else {
$defaults[CURLOPT_URL] = $url;
if ($method == 'POST') {
$defaults[CURLOPT_POST] = 1;
} else {
$defaults[CURLOPT_CUSTOMREQUEST] = $method;
}
$defaults[CURLOPT_POSTFIELDS] = $query_string;
}
$defaults[CURLOPT_HEADER] = false;
$defaults[CURLOPT_USERAGENT] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36";
$defaults[CURLOPT_FOLLOWLOCATION] = true;
$defaults[CURLOPT_RETURNTRANSFER] = true;
$defaults[CURLOPT_CONNECTTIMEOUT] = 3;
$defaults[CURLOPT_TIMEOUT] = 3;
// disable 100-continue
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
if ('https' == $protocol) {
$defaults[CURLOPT_SSL_VERIFYPEER] = false;
$defaults[CURLOPT_SSL_VERIFYHOST] = false;
}
curl_setopt_array($ch, (array)$options + $defaults);
$ret = curl_exec($ch);
$err = curl_error($ch);
if (false === $ret || !empty($err)) {
$errno = curl_errno($ch);
$info = curl_getinfo($ch);
curl_close($ch);
return [
'ret' => false,
'errno' => $errno,
'msg' => $err,
'info' => $info,
];
}
curl_close($ch);
return [
'ret' => true,
'msg' => $ret,
];
}
/**
* 异步发送一个请求
* @param string $url 请求的链接
* @param mixed $params 请求的参数
* @param string $method 请求的方法
* @return boolean TRUE
*/
public static function sendAsyncRequest($url, $params = [], $method = 'POST')
{
$method = strtoupper($method);
$method = $method == 'POST' ? 'POST' : 'GET';
//构造传递的参数
if (is_array($params)) {
$post_params = [];
foreach ($params as $k => &$v) {
if (is_array($v)) {
$v = implode(',', $v);
}
$post_params[] = $k . '=' . urlencode($v);
}
$post_string = implode('&', $post_params);
} else {
$post_string = $params;
}
$parts = parse_url($url);
//构造查询的参数
if ($method == 'GET' && $post_string) {
$parts['query'] = isset($parts['query']) ? $parts['query'] . '&' . $post_string : $post_string;
$post_string = '';
}
$parts['query'] = isset($parts['query']) && $parts['query'] ? '?' . $parts['query'] : '';
//发送socket请求,获得连接句柄
$fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 3);
if (!$fp) {
return false;
}
//设置超时时间
stream_set_timeout($fp, 3);
$out = "{$method} {$parts['path']}{$parts['query']} HTTP/1.1\r\n";
$out .= "Host: {$parts['host']}\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= "Content-Length: " . strlen($post_string) . "\r\n";
$out .= "Connection: Close\r\n\r\n";
if ($post_string !== '') {
$out .= $post_string;
}
fwrite($fp, $out);
//不用关心服务器返回结果
//echo fread($fp, 1024);
fclose($fp);
return true;
}
/**
* 发送文件到客户端
* @param string $file
* @param bool $delaftersend
* @param bool $exitaftersend
*/
public static function sendToBrowser($file, $delaftersend = true, $exitaftersend = true)
{
if (file_exists($file) && is_readable($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;filename = ' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check = 0, pre-check = 0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
if ($delaftersend) {
unlink($file);
}
if ($exitaftersend) {
exit;
}
}
}
}
... ...
<?php
namespace fast;
/**
* 中文转拼音类
*/
class Pinyin
{
protected static $keys = "a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|bu|ca|cai|can|cang|cao|ce|ceng|cha|chai|chan|chang|chao|che|chen|cheng|chi|chong|chou|chu|chuai|chuan|chuang|chui|chun|chuo|ci|cong|cou|cu|cuan|cui|cun|cuo|da|dai|dan|dang|dao|de|deng|di|dian|diao|die|ding|diu|dong|dou|du|duan|dui|dun|duo|e|en|er|fa|fan|fang|fei|fen|feng|fo|fou|fu|ga|gai|gan|gang|gao|ge|gei|gen|geng|gong|gou|gu|gua|guai|guan|guang|gui|gun|guo|ha|hai|han|hang|hao|he|hei|hen|heng|hong|hou|hu|hua|huai|huan|huang|hui|hun|huo|ji|jia|jian|jiang|jiao|jie|jin|jing|jiong|jiu|ju|juan|jue|jun|ka|kai|kan|kang|kao|ke|ken|keng|kong|kou|ku|kua|kuai|kuan|kuang|kui|kun|kuo|la|lai|lan|lang|lao|le|lei|leng|li|lia|lian|liang|liao|lie|lin|ling|liu|long|lou|lu|lv|luan|lue|lun|luo|ma|mai|man|mang|mao|me|mei|men|meng|mi|mian|miao|mie|min|ming|miu|mo|mou|mu|na|nai|nan|nang|nao|ne|nei|nen|neng|ni|nian|niang|niao|nie|nin|ning|niu|nong|nu|nv|nuan|nue|nuo|o|ou|pa|pai|pan|pang|pao|pei|pen|peng|pi|pian|piao|pie|pin|ping|po|pu|qi|qia|qian|qiang|qiao|qie|qin|qing|qiong|qiu|qu|quan|que|qun|ran|rang|rao|re|ren|reng|ri|rong|rou|ru|ruan|rui|run|ruo|sa|sai|san|sang|sao|se|sen|seng|sha|shai|shan|shang|shao|she|shen|sheng|shi|shou|shu|shua|shuai|shuan|shuang|shui|shun|shuo|si|song|sou|su|suan|sui|sun|suo|ta|tai|tan|tang|tao|te|teng|ti|tian|tiao|tie|ting|tong|tou|tu|tuan|tui|tun|tuo|wa|wai|wan|wang|wei|wen|weng|wo|wu|xi|xia|xian|xiang|xiao|xie|xin|xing|xiong|xiu|xu|xuan|xue|xun|ya|yan|yang|yao|ye|yi|yin|ying|yo|yong|you|yu|yuan|yue|yun|za|zai|zan|zang|zao|ze|zei|zen|zeng|zha|zhai|zhan|zhang|zhao|zhe|zhen|zheng|zhi|zhong|zhou|zhu|zhua|zhuai|zhuan|zhuang|zhui|zhun|zhuo|zi|zong|zou|zu|zuan|zui|zun|zuo";
protected static $values = "-20319|-20317|-20304|-20295|-20292|-20283|-20265|-20257|-20242|-20230|-20051|-20036|-20032|-20026|-20002|-19990|-19986|-19982|-19976|-19805|-19784|-19775|-19774|-19763|-19756|-19751|-19746|-19741|-19739|-19728|-19725|-19715|-19540|-19531|-19525|-19515|-19500|-19484|-19479|-19467|-19289|-19288|-19281|-19275|-19270|-19263|-19261|-19249|-19243|-19242|-19238|-19235|-19227|-19224|-19218|-19212|-19038|-19023|-19018|-19006|-19003|-18996|-18977|-18961|-18952|-18783|-18774|-18773|-18763|-18756|-18741|-18735|-18731|-18722|-18710|-18697|-18696|-18526|-18518|-18501|-18490|-18478|-18463|-18448|-18447|-18446|-18239|-18237|-18231|-18220|-18211|-18201|-18184|-18183|-18181|-18012|-17997|-17988|-17970|-17964|-17961|-17950|-17947|-17931|-17928|-17922|-17759|-17752|-17733|-17730|-17721|-17703|-17701|-17697|-17692|-17683|-17676|-17496|-17487|-17482|-17468|-17454|-17433|-17427|-17417|-17202|-17185|-16983|-16970|-16942|-16915|-16733|-16708|-16706|-16689|-16664|-16657|-16647|-16474|-16470|-16465|-16459|-16452|-16448|-16433|-16429|-16427|-16423|-16419|-16412|-16407|-16403|-16401|-16393|-16220|-16216|-16212|-16205|-16202|-16187|-16180|-16171|-16169|-16158|-16155|-15959|-15958|-15944|-15933|-15920|-15915|-15903|-15889|-15878|-15707|-15701|-15681|-15667|-15661|-15659|-15652|-15640|-15631|-15625|-15454|-15448|-15436|-15435|-15419|-15416|-15408|-15394|-15385|-15377|-15375|-15369|-15363|-15362|-15183|-15180|-15165|-15158|-15153|-15150|-15149|-15144|-15143|-15141|-15140|-15139|-15128|-15121|-15119|-15117|-15110|-15109|-14941|-14937|-14933|-14930|-14929|-14928|-14926|-14922|-14921|-14914|-14908|-14902|-14894|-14889|-14882|-14873|-14871|-14857|-14678|-14674|-14670|-14668|-14663|-14654|-14645|-14630|-14594|-14429|-14407|-14399|-14384|-14379|-14368|-14355|-14353|-14345|-14170|-14159|-14151|-14149|-14145|-14140|-14137|-14135|-14125|-14123|-14122|-14112|-14109|-14099|-14097|-14094|-14092|-14090|-14087|-14083|-13917|-13914|-13910|-13907|-13906|-13905|-13896|-13894|-13878|-13870|-13859|-13847|-13831|-13658|-13611|-13601|-13406|-13404|-13400|-13398|-13395|-13391|-13387|-13383|-13367|-13359|-13356|-13343|-13340|-13329|-13326|-13318|-13147|-13138|-13120|-13107|-13096|-13095|-13091|-13076|-13068|-13063|-13060|-12888|-12875|-12871|-12860|-12858|-12852|-12849|-12838|-12831|-12829|-12812|-12802|-12607|-12597|-12594|-12585|-12556|-12359|-12346|-12320|-12300|-12120|-12099|-12089|-12074|-12067|-12058|-12039|-11867|-11861|-11847|-11831|-11798|-11781|-11604|-11589|-11536|-11358|-11340|-11339|-11324|-11303|-11097|-11077|-11067|-11055|-11052|-11045|-11041|-11038|-11024|-11020|-11019|-11018|-11014|-10838|-10832|-10815|-10800|-10790|-10780|-10764|-10587|-10544|-10533|-10519|-10331|-10329|-10328|-10322|-10315|-10309|-10307|-10296|-10281|-10274|-10270|-10262|-10260|-10256|-10254";
/**
* 获取文字的拼音
* @param string $chinese 中文汉字
* @param boolean $onlyfirst 是否只返回拼音首字母
* @param string $delimiter 分隔符
* @param string $charset 文字编码
* @return string
*/
public static function get($chinese, $onlyfirst = false, $delimiter = '', $ucfirst = false, $charset = 'utf-8')
{
$keys_a = explode('|', self::$keys);
$values_a = explode('|', self::$values);
$data = array_combine($keys_a, $values_a);
arsort($data);
reset($data);
if ($charset != 'gb2312') {
$chinese = self::_u2_utf8_gb($chinese);
}
$result = '';
for ($i = 0; $i < strlen($chinese); $i++) {
$_P = ord(substr($chinese, $i, 1));
if ($_P > 160) {
$_Q = ord(substr($chinese, ++$i, 1));
$_P = $_P * 256 + $_Q - 65536;
}
$result .= ($onlyfirst ? substr(self::_pinyin($_P, $data), 0, 1) : self::_pinyin($_P, $data));
$result .= $delimiter;
}
if ($delimiter) {
$result = rtrim($result, $delimiter);
}
return preg_replace("/[^a-z0-9_\-]*/i", '', $result);
}
private static function _pinyin($num, $data)
{
if ($num > 0 && $num < 160) {
return chr($num);
} elseif ($num < -20319 || $num > -10247) {
return '';
} else {
foreach ($data as $k => $v) {
if ($v <= $num) {
break;
}
}
return $k;
}
}
private static function _u2_utf8_gb($c)
{
$string = '';
if ($c < 0x80) {
$string .= $c;
} elseif ($c < 0x800) {
$string .= chr(0xC0 | $c >> 6);
$string .= chr(0x80 | $c & 0x3F);
} elseif ($c < 0x10000) {
$string .= chr(0xE0 | $c >> 12);
$string .= chr(0x80 | $c >> 6 & 0x3F);
$string .= chr(0x80 | $c & 0x3F);
} elseif ($c < 0x200000) {
$string .= chr(0xF0 | $c >> 18);
$string .= chr(0x80 | $c >> 12 & 0x3F);
$string .= chr(0x80 | $c >> 6 & 0x3F);
$string .= chr(0x80 | $c & 0x3F);
}
return iconv('UTF-8', 'GB2312//IGNORE', $string);
}
}
... ...
<?php
namespace fast;
/**
* 随机生成类
*/
class Random
{
/**
* 生成数字和字母
*
* @param int $len 长度
* @return string
*/
public static function alnum($len = 6)
{
return self::build('alnum', $len);
}
/**
* 仅生成字符
*
* @param int $len 长度
* @return string
*/
public static function alpha($len = 6)
{
return self::build('alpha', $len);
}
/**
* 生成指定长度的随机数字
*
* @param int $len 长度
* @return string
*/
public static function numeric($len = 4)
{
return self::build('numeric', $len);
}
/**
* 数字和字母组合的随机字符串
*
* @param int $len 长度
* @return string
*/
public static function nozero($len = 4)
{
return self::build('nozero', $len);
}
/**
* 能用的随机数生成
* @param string $type 类型 alpha/alnum/numeric/nozero/unique/md5/encrypt/sha1
* @param int $len 长度
* @return string
*/
public static function build($type = 'alnum', $len = 8)
{
switch ($type) {
case 'alpha':
case 'alnum':
case 'numeric':
case 'nozero':
switch ($type) {
case 'alpha':
$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
break;
case 'alnum':
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
break;
case 'numeric':
$pool = '0123456789';
break;
case 'nozero':
$pool = '123456789';
break;
}
return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
case 'unique':
case 'md5':
return md5(uniqid(mt_rand()));
case 'encrypt':
case 'sha1':
return sha1(uniqid(mt_rand(), true));
}
}
/**
* 根据数组元素的概率获得键名
*
* @param array $ps array('p1'=>20, 'p2'=>30, 'p3'=>50);
* @param int $num 默认为1,即随机出来的数量
* @param bool $unique 默认为true,即当num>1时,随机出的数量是否唯一
* @return mixed 当num为1时返回键名,反之返回一维数组
*/
public static function lottery($ps, $num = 1, $unique = true)
{
if (!$ps) {
return $num == 1 ? '' : [];
}
if ($num >= count($ps) && $unique) {
$res = array_keys($ps);
return $num == 1 ? $res[0] : $res;
}
$max_exp = 0;
$res = [];
foreach ($ps as $key => $value) {
$value = substr($value, 0, stripos($value, ".") + 6);
$exp = strlen(strchr($value, '.')) - 1;
if ($exp > $max_exp) {
$max_exp = $exp;
}
}
$pow_exp = pow(10, $max_exp);
if ($pow_exp > 1) {
reset($ps);
foreach ($ps as $key => $value) {
$ps[$key] = $value * $pow_exp;
}
}
$pro_sum = array_sum($ps);
if ($pro_sum < 1) {
return $num == 1 ? '' : [];
}
for ($i = 0; $i < $num; $i++) {
$rand_num = mt_rand(1, $pro_sum);
reset($ps);
foreach ($ps as $key => $value) {
if ($rand_num <= $value) {
break;
} else {
$rand_num -= $value;
}
}
if ($num == 1) {
$res = $key;
break;
} else {
$res[$i] = $key;
}
if ($unique) {
$pro_sum -= $value;
unset($ps[$key]);
}
}
return $res;
}
/**
* 获取全球唯一标识
* @return string
*/
public static function uuid()
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
}
}
... ...
<?php
namespace fast;
/**
* RSA签名类
*/
class Rsa
{
public $publicKey = '';
public $privateKey = '';
private $_privKey;
/**
* * private key
*/
private $_pubKey;
/**
* * public key
*/
private $_keyPath;
/**
* * the keys saving path
*/
/**
* * the construtor,the param $path is the keys saving path
* @param string $publicKey 公钥
* @param string $privateKey 私钥
*/
public function __construct($publicKey = null, $privateKey = null)
{
$this->setKey($publicKey, $privateKey);
}
/**
* 设置公钥和私钥
* @param string $publicKey 公钥
* @param string $privateKey 私钥
*/
public function setKey($publicKey = null, $privateKey = null)
{
if (!is_null($publicKey)) {
$this->publicKey = $publicKey;
}
if (!is_null($privateKey)) {
$this->privateKey = $privateKey;
}
}
/**
* * setup the private key
*/
private function setupPrivKey()
{
if (is_resource($this->_privKey)) {
return true;
}
$pem = chunk_split($this->privateKey, 64, "\n");
$pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
$this->_privKey = openssl_pkey_get_private($pem);
return true;
}
/**
* * setup the public key
*/
private function setupPubKey()
{
if (is_resource($this->_pubKey)) {
return true;
}
$pem = chunk_split($this->publicKey, 64, "\n");
$pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
$this->_pubKey = openssl_pkey_get_public($pem);
return true;
}
/**
* * encrypt with the private key
*/
public function privEncrypt($data)
{
if (!is_string($data)) {
return null;
}
$this->setupPrivKey();
$r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
if ($r) {
return base64_encode($encrypted);
}
return null;
}
/**
* * decrypt with the private key
*/
public function privDecrypt($encrypted)
{
if (!is_string($encrypted)) {
return null;
}
$this->setupPrivKey();
$encrypted = base64_decode($encrypted);
$r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
if ($r) {
return $decrypted;
}
return null;
}
/**
* * encrypt with public key
*/
public function pubEncrypt($data)
{
if (!is_string($data)) {
return null;
}
$this->setupPubKey();
$r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
if ($r) {
return base64_encode($encrypted);
}
return null;
}
/**
* * decrypt with the public key
*/
public function pubDecrypt($crypted)
{
if (!is_string($crypted)) {
return null;
}
$this->setupPubKey();
$crypted = base64_decode($crypted);
$r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
if ($r) {
return $decrypted;
}
return null;
}
/**
* 构造签名
* @param string $dataString 被签名数据
* @return string
*/
public function sign($dataString)
{
$this->setupPrivKey();
$signature = false;
openssl_sign($dataString, $signature, $this->_privKey);
return base64_encode($signature);
}
/**
* 验证签名
* @param string $dataString 被签名数据
* @param string $signString 已经签名的字符串
* @return number 1签名正确 0签名错误
*/
public function verify($dataString, $signString)
{
$this->setupPubKey();
$signature = base64_decode($signString);
$flg = openssl_verify($dataString, $signature, $this->_pubKey);
return $flg;
}
public function __destruct()
{
is_resource($this->_privKey) && @openssl_free_key($this->_privKey);
is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey);
}
}
... ...
<?php
namespace fast;
use think\Config;
/**
* 通用的树型类
* @author XiaoYao <476552238li@gmail.com>
*/
class Tree
{
protected static $instance;
//默认配置
protected $config = [];
public $options = [];
/**
* 生成树型结构所需要的2维数组
* @var array
*/
public $arr = [];
/**
* 生成树型结构所需修饰符号,可以换成图片
* @var array
*/
public $icon = array('│', '├', '└');
public $nbsp = "&nbsp;";
public $pidname = 'pid';
public function __construct($options = [])
{
if ($config = Config::get('tree')) {
$this->options = array_merge($this->config, $config);
}
$this->options = array_merge($this->config, $options);
}
/**
* 初始化
* @access public
* @param array $options 参数
* @return Tree
*/
public static function instance($options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
return self::$instance;
}
/**
* 初始化方法
* @param array $arr 2维数组,例如:
* array(
* 1 => array('id'=>'1','pid'=>0,'name'=>'一级栏目一'),
* 2 => array('id'=>'2','pid'=>0,'name'=>'一级栏目二'),
* 3 => array('id'=>'3','pid'=>1,'name'=>'二级栏目一'),
* 4 => array('id'=>'4','pid'=>1,'name'=>'二级栏目二'),
* 5 => array('id'=>'5','pid'=>2,'name'=>'二级栏目三'),
* 6 => array('id'=>'6','pid'=>3,'name'=>'三级栏目一'),
* 7 => array('id'=>'7','pid'=>3,'name'=>'三级栏目二')
* )
* @param string $pidname 父字段名称
* @param string $nbsp 空格占位符
* @return Tree
*/
public function init($arr = [], $pidname = null, $nbsp = null)
{
$this->arr = $arr;
if (!is_null($pidname)) {
$this->pidname = $pidname;
}
if (!is_null($nbsp)) {
$this->nbsp = $nbsp;
}
return $this;
}
/**
* 得到子级数组
* @param int
* @return array
*/
public function getChild($myid)
{
$newarr = [];
foreach ($this->arr as $value) {
if (!isset($value['id'])) {
continue;
}
if ($value[$this->pidname] == $myid) {
$newarr[$value['id']] = $value;
}
}
return $newarr;
}
/**
* 读取指定节点的所有孩子节点
* @param int $myid 节点ID
* @param boolean $withself 是否包含自身
* @return array
*/
public function getChildren($myid, $withself = false)
{
$newarr = [];
foreach ($this->arr as $value) {
if (!isset($value['id'])) {
continue;
}
if ($value[$this->pidname] == $myid) {
$newarr[] = $value;
$newarr = array_merge($newarr, $this->getChildren($value['id']));
} elseif ($withself && $value['id'] == $myid) {
$newarr[] = $value;
}
}
return $newarr;
}
/**
* 读取指定节点的所有孩子节点ID
* @param int $myid 节点ID
* @param boolean $withself 是否包含自身
* @return array
*/
public function getChildrenIds($myid, $withself = false)
{
$childrenlist = $this->getChildren($myid, $withself);
$childrenids = [];
foreach ($childrenlist as $k => $v) {
$childrenids[] = $v['id'];
}
return $childrenids;
}
/**
* 得到当前位置父辈数组
* @param int
* @return array
*/
public function getParent($myid)
{
$pid = 0;
$newarr = [];
foreach ($this->arr as $value) {
if (!isset($value['id'])) {
continue;
}
if ($value['id'] == $myid) {
$pid = $value[$this->pidname];
break;
}
}
if ($pid) {
foreach ($this->arr as $value) {
if ($value['id'] == $pid) {
$newarr[] = $value;
break;
}
}
}
return $newarr;
}
/**
* 得到当前位置所有父辈数组
* @param int
* @param bool $withself 是否包含自己
* @return array
*/
public function getParents($myid, $withself = false)
{
$pid = 0;
$newarr = [];
foreach ($this->arr as $value) {
if (!isset($value['id'])) {
continue;
}
if ($value['id'] == $myid) {
if ($withself) {
$newarr[] = $value;
}
$pid = $value[$this->pidname];
break;
}
}
if ($pid) {
$arr = $this->getParents($pid, true);
$newarr = array_merge($arr, $newarr);
}
return $newarr;
}
/**
* 读取指定节点所有父类节点ID
* @param int $myid
* @param boolean $withself
* @return array
*/
public function getParentsIds($myid, $withself = false)
{
$parentlist = $this->getParents($myid, $withself);
$parentsids = [];
foreach ($parentlist as $k => $v) {
$parentsids[] = $v['id'];
}
return $parentsids;
}
/**
* 树型结构Option
* @param int $myid 表示获得这个ID下的所有子级
* @param string $itemtpl 条目模板 如:"<option value=@id @selected @disabled>@spacer@name</option>"
* @param mixed $selectedids 被选中的ID,比如在做树型下拉框的时候需要用到
* @param mixed $disabledids 被禁用的ID,比如在做树型下拉框的时候需要用到
* @param string $itemprefix 每一项前缀
* @param string $toptpl 顶级栏目的模板
* @return string
*/
public function getTree($myid, $itemtpl = "<option value=@id @selected @disabled>@spacer@name</option>", $selectedids = '', $disabledids = '', $itemprefix = '', $toptpl = '')
{
$ret = '';
$number = 1;
$childs = $this->getChild($myid);
if ($childs) {
$total = count($childs);
foreach ($childs as $value) {
$id = $value['id'];
$j = $k = '';
if ($number == $total) {
$j .= $this->icon[2];
$k = $itemprefix ? $this->nbsp : '';
} else {
$j .= $this->icon[1];
$k = $itemprefix ? $this->icon[0] : '';
}
$spacer = $itemprefix ? $itemprefix . $j : '';
$selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : '';
$disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : '';
$value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled, 'spacer' => $spacer));
$value = array_combine(array_map(function ($k) {
return '@' . $k;
}, array_keys($value)), $value);
$nstr = strtr((($value["@{$this->pidname}"] == 0 || $this->getChild($id)) && $toptpl ? $toptpl : $itemtpl), $value);
$ret .= $nstr;
$ret .= $this->getTree($id, $itemtpl, $selectedids, $disabledids, $itemprefix . $k . $this->nbsp, $toptpl);
$number++;
}
}
return $ret;
}
/**
* 树型结构UL
* @param int $myid 表示获得这个ID下的所有子级
* @param string $itemtpl 条目模板 如:"<li value=@id @selected @disabled>@name @childlist</li>"
* @param string $selectedids 选中的ID
* @param string $disabledids 禁用的ID
* @param string $wraptag 子列表包裹标签
* @param string $wrapattr 子列表包裹属性
* @return string
*/
public function getTreeUl($myid, $itemtpl, $selectedids = '', $disabledids = '', $wraptag = 'ul', $wrapattr = '')
{
$str = '';
$childs = $this->getChild($myid);
if ($childs) {
foreach ($childs as $value) {
$id = $value['id'];
unset($value['child']);
$selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : '';
$disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : '';
$value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled));
$value = array_combine(array_map(function ($k) {
return '@' . $k;
}, array_keys($value)), $value);
$nstr = strtr($itemtpl, $value);
$childdata = $this->getTreeUl($id, $itemtpl, $selectedids, $disabledids, $wraptag, $wrapattr);
$childlist = $childdata ? "<{$wraptag} {$wrapattr}>" . $childdata . "</{$wraptag}>" : "";
$str .= strtr($nstr, array('@childlist' => $childlist));
}
}
return $str;
}
/**
* 菜单数据
* @param int $myid
* @param string $itemtpl
* @param mixed $selectedids
* @param mixed $disabledids
* @param string $wraptag
* @param string $wrapattr
* @param int $deeplevel
* @return string
*/
public function getTreeMenu($myid, $itemtpl, $selectedids = '', $disabledids = '', $wraptag = 'ul', $wrapattr = '', $deeplevel = 0)
{
$str = '';
$childs = $this->getChild($myid);
if ($childs) {
foreach ($childs as $value) {
$id = $value['id'];
unset($value['child']);
$selected = in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : '';
$disabled = in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : '';
$value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled));
$value = array_combine(array_map(function ($k) {
return '@' . $k;
}, array_keys($value)), $value);
$bakvalue = array_intersect_key($value, array_flip(['@url', '@caret', '@class']));
$value = array_diff_key($value, $bakvalue);
$nstr = strtr($itemtpl, $value);
$value = array_merge($value, $bakvalue);
$childdata = $this->getTreeMenu($id, $itemtpl, $selectedids, $disabledids, $wraptag, $wrapattr, $deeplevel + 1);
$childlist = $childdata ? "<{$wraptag} {$wrapattr}>" . $childdata . "</{$wraptag}>" : "";
$childlist = strtr($childlist, array('@class' => $childdata ? 'last' : ''));
$value = array(
'@childlist' => $childlist,
'@url' => $childdata || !isset($value['@url']) ? "javascript:;" : url($value['@url']),
'@addtabs' => $childdata || !isset($value['@url']) ? "" : (stripos($value['@url'], "?") !== false ? "&" : "?") . "ref=addtabs",
'@caret' => ($childdata && (!isset($value['@badge']) || !$value['@badge']) ? '<i class="fa fa-angle-left"></i>' : ''),
'@badge' => isset($value['@badge']) ? $value['@badge'] : '',
'@class' => ($selected ? ' active' : '') . ($disabled ? ' disabled' : '') . ($childdata ? ' treeview' : ''),
);
$str .= strtr($nstr, $value);
}
}
return $str;
}
/**
* 特殊
* @param integer $myid 要查询的ID
* @param string $itemtpl1 第一种HTML代码方式
* @param string $itemtpl2 第二种HTML代码方式
* @param mixed $selectedids 默认选中
* @param mixed $disabledids 禁用
* @param string $itemprefix 前缀
* @return string
*/
public function getTreeSpecial($myid, $itemtpl1, $itemtpl2, $selectedids = 0, $disabledids = 0, $itemprefix = '')
{
$ret = '';
$number = 1;
$childs = $this->getChild($myid);
if ($childs) {
$total = count($childs);
foreach ($childs as $id => $value) {
$j = $k = '';
if ($number == $total) {
$j .= $this->icon[2];
$k = $itemprefix ? $this->nbsp : '';
} else {
$j .= $this->icon[1];
$k = $itemprefix ? $this->icon[0] : '';
}
$spacer = $itemprefix ? $itemprefix . $j : '';
$selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : '';
$disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : '';
$value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled, 'spacer' => $spacer));
$value = array_combine(array_map(function ($k) {
return '@' . $k;
}, array_keys($value)), $value);
$nstr = strtr(!isset($value['@disabled']) || !$value['@disabled'] ? $itemtpl1 : $itemtpl2, $value);
$ret .= $nstr;
$ret .= $this->getTreeSpecial($id, $itemtpl1, $itemtpl2, $selectedids, $disabledids, $itemprefix . $k . $this->nbsp);
$number++;
}
}
return $ret;
}
/**
*
* 获取树状数组
* @param string $myid 要查询的ID
* @param string $itemprefix 前缀
* @return array
*/
public function getTreeArray($myid, $itemprefix = '')
{
$childs = $this->getChild($myid);
$n = 0;
$data = [];
$number = 1;
if ($childs) {
$total = count($childs);
foreach ($childs as $id => $value) {
$j = $k = '';
if ($number == $total) {
$j .= $this->icon[2];
$k = $itemprefix ? $this->nbsp : '';
} else {
$j .= $this->icon[1];
$k = $itemprefix ? $this->icon[0] : '';
}
$spacer = $itemprefix ? $itemprefix . $j : '';
$value['spacer'] = $spacer;
$data[$n] = $value;
$data[$n]['childlist'] = $this->getTreeArray($id, $itemprefix . $k . $this->nbsp);
$n++;
$number++;
}
}
return $data;
}
/**
* 将getTreeArray的结果返回为二维数组
* @param array $data
* @param string $field
* @return array
*/
public function getTreeList($data = [], $field = 'name')
{
$arr = [];
foreach ($data as $k => $v) {
$childlist = isset($v['childlist']) ? $v['childlist'] : [];
unset($v['childlist']);
$v[$field] = $v['spacer'] . ' ' . $v[$field];
$v['haschild'] = $childlist ? 1 : 0;
if ($v['id']) {
$arr[] = $v;
}
if ($childlist) {
$arr = array_merge($arr, $this->getTreeList($childlist, $field));
}
}
return $arr;
}
}
... ...
<?php
namespace fast;
/**
* 版本检测和对比
*/
class Version
{
/**
* 检测版本是否的版本要求的数据中
*
* @param string $version
* @param array $data
* @return bool
*/
public static function check($version, $data = [])
{
//版本号以.分隔
$data = is_array($data) ? $data : [$data];
if ($data) {
if (in_array("*", $data) || in_array($version, $data)) {
return true;
}
$ver = explode('.', $version);
if ($ver) {
$versize = count($ver);
//验证允许的版本
foreach ($data as $m) {
$c = explode('.', $m);
if (!$c || $versize != count($c)) {
continue;
}
$i = 0;
foreach ($c as $a => $k) {
if (!self::compare($ver[$a], $k)) {
continue 2;
} else {
$i++;
}
}
if ($i == $versize) {
return true;
}
}
}
}
return false;
}
/**
* 比较两个版本号
*
* @param string $v1
* @param string $v2
* @return boolean
*/
public static function compare($v1, $v2)
{
if ($v2 == "*" || $v1 == $v2) {
return true;
} else {
$values = [];
$k = explode(',', $v2);
foreach ($k as $v) {
if (strpos($v, '-') !== false) {
list($start, $stop) = explode('-', $v);
for ($i = $start; $i <= $stop; $i++) {
$values[] = $i;
}
} else {
$values[] = $v;
}
}
return in_array($v1, $values) ? true : false;
}
}
}
... ...
<?php
namespace nsms;
date_default_timezone_set('PRC');//设置时区
/**
* 发送API
* demo仅供参考,demo最低运行环境PHP5.3
* 请确认开启PHP CURL 扩展
*/
class sendAPI {
public $data; //发送数据
public $timeout = 30; //超时
private $apiUrl; //发送地址
private $username; //用户名
private $password; //密码
function __construct($url, $username, $password) {
$this->apiUrl = $url;
$this->username = $username;
$this->password = $password;
}
private function httpGet() {
$url = $this->apiUrl . '?' . http_build_query($this->data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_URL, $url);
$res = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Error GET '.curl_error($curl);
}
curl_close($curl);
return $res;
}
private function httpPost(){ // 模拟提交数据函数
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $this->apiUrl); // 要访问的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($this->data)); // Post提交的数据包
curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout); // 设置超时限制防止死循环
curl_setopt($curl, CURLOPT_HEADER, false); // 显示返回的Header区域内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
$result = curl_exec($curl); // 执行操作
if (curl_errno($curl)) {
echo 'Error POST'.curl_error($curl);
}
curl_close($curl); // 关键CURL会话
return $result; // 返回数据
}
/**
* @param $type|提交类型 POST/GET
* @param $isTranscoding|是否需要转 $isTranscoding 是否需要转utf-8 默认 false
* @return mixed
*/
public function sendSMS($type, $isTranscoding = false) {
$this->data['content'] = $isTranscoding === true ? mb_convert_encoding($this->data['content'], "UTF-8") : $this->data['content'];
$this->data['username'] = $this->username;
$this->data['tkey'] = date('YmdHis');
$this->data['password'] = md5(md5($this->password) . $this->data['tkey']);
return $type == "POST" ? $this->httpPost() : $this->httpGet();
}
}
\ No newline at end of file
... ...