111
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 

704 рядки
20 KiB

  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2017年11月5日
  7. * 助手函数
  8. */
  9. use core\basic\Config;
  10. use core\basic\Json;
  11. use core\view\View;
  12. use core\view\Paging;
  13. use core\basic\Response;
  14. use core\basic\Url;
  15. use core\basic\Basic;
  16. use core\basic\Smtp;
  17. /**
  18. * 生成实际跳转路径
  19. *
  20. * @param string $url
  21. * 接收控制器方法访问完整路径,如:/home/index/index
  22. * @return mixed
  23. */
  24. function url($url, $addExt = true)
  25. {
  26. return Url::get($url, $addExt);
  27. }
  28. /**
  29. * 自定义错误页面
  30. *
  31. * @param string $_string内容
  32. * @param string $_url跳转地址
  33. * @param number $_time时间
  34. */
  35. function error($string, $jump_url = null, $time = 2)
  36. {
  37. @ob_clean();
  38. if (! $string)
  39. $string = '未知错误!';
  40. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  41. Response::json(0, strip_tags($string));
  42. } else {
  43. $err_tpl = CORE_PATH . '/template/error.html';
  44. if ($jump_url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
  45. $jump_url = $_SERVER['HTTP_REFERER'];
  46. if (strpos($jump_url, get_http_url()) !== 0) {
  47. $jump_url = '/';
  48. }
  49. } elseif ($jump_url == '-1') {
  50. $jump_url = null;
  51. }
  52. echo parse_info_tpl($err_tpl, $string, $jump_url, $time);
  53. }
  54. exit();
  55. }
  56. /**
  57. * 自定义错误页面
  58. *
  59. * @param string $_string内容
  60. * @param string $_url跳转地址
  61. * @param number $_time时间
  62. */
  63. function success($string, $jump_url = null, $time = 2)
  64. {
  65. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  66. Response::json(1, strip_tags($string));
  67. } else {
  68. $err_tpl = CORE_PATH . '/template/success.html';
  69. if ($jump_url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
  70. $jump_url = $_SERVER['HTTP_REFERER'];
  71. if (strpos($jump_url, get_http_url()) !== 0) {
  72. $jump_url = '/';
  73. }
  74. } elseif ($jump_url == '-1') {
  75. $jump_url = null;
  76. }
  77. echo parse_info_tpl($err_tpl, $string, $jump_url, $time);
  78. }
  79. exit();
  80. }
  81. /**
  82. * 弹窗
  83. *
  84. * @param string $info信息
  85. */
  86. function alert($info, $status = 0)
  87. {
  88. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  89. Response::json($status, strip_tags($info));
  90. } else {
  91. echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");</script>';
  92. }
  93. }
  94. /**
  95. * 弹窗并返回前页
  96. *
  97. * @param string $info信息
  98. */
  99. function alert_back($info, $status = 0)
  100. {
  101. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  102. Response::json($status, strip_tags($info));
  103. } else {
  104. echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");window.history.go(-1);</script>';
  105. exit();
  106. }
  107. }
  108. /**
  109. * 跳转
  110. *
  111. * @param string $url跳转地址
  112. */
  113. function location($url)
  114. {
  115. if ($url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
  116. $url = $_SERVER['HTTP_REFERER'];
  117. if (strpos($url, get_http_url()) !== 0) {
  118. $url = '/';
  119. }
  120. }
  121. header('Location:' . $url);
  122. exit();
  123. }
  124. /**
  125. * 弹窗并跳转
  126. *
  127. * @param string $info信息
  128. * @param string $url跳转地址
  129. */
  130. function alert_location($info, $url, $status = 0)
  131. {
  132. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  133. Response::json($status, strip_tags($info));
  134. } else {
  135. if ($url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
  136. $url = $_SERVER['HTTP_REFERER'];
  137. if (strpos($url, get_http_url()) !== 0) {
  138. $url = '/';
  139. }
  140. }
  141. echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");location.href="' . $url . '";</script>';
  142. exit();
  143. }
  144. }
  145. /**
  146. * 弹窗并关闭
  147. *
  148. * @param string $info信息
  149. */
  150. function alert_close($info, $status = 0)
  151. {
  152. if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
  153. Response::json($status, strip_tags($info));
  154. } else {
  155. echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");window.close();</script>';
  156. exit();
  157. }
  158. }
  159. /**
  160. * 实例化模型对象助手
  161. *
  162. * @param string $name
  163. * 需要实力化的模型名称
  164. * @param string $new
  165. * 是否强制新建对象
  166. * @return mixed
  167. */
  168. function model($name = null, $new = false)
  169. {
  170. return Basic::createModel($name, $new);
  171. }
  172. /**
  173. * api读取数据
  174. *
  175. * @param string $name
  176. * 接口名称,如:add或 admin.user.addd
  177. * @param array $param
  178. * 参数
  179. * @param string $rsOriginal
  180. * 结果不处理直接返回
  181. * @param string $jsonRsArray
  182. * 返回Json数组方式
  183. * @return mixed
  184. */
  185. function api($name, $param = null, $rsOriginal = false, $jsonRsArray = false)
  186. {
  187. return Basic::createApi($name, $param, $rsOriginal, $jsonRsArray);
  188. }
  189. // 输出模板内容
  190. function display($tpl)
  191. {
  192. $view = View::getInstance();
  193. echo $view->parser($tpl);
  194. }
  195. // 解析模板内容
  196. function parser($tpl)
  197. {
  198. $view = View::getInstance();
  199. return $view->parser($tpl);
  200. }
  201. // 设置模板
  202. function set_theme($theme_name)
  203. {
  204. $view = View::getInstance();
  205. $view->assign('theme', $theme_name);
  206. }
  207. // 注入模板变量
  208. function assign($var, $value)
  209. {
  210. $view = View::getInstance();
  211. $view->assign($var, $value);
  212. }
  213. // 变量获取接口
  214. function get_var($var)
  215. {
  216. $view = View::getInstance();
  217. return $view->getVar($var);
  218. }
  219. // 手动生成分页信息,返回限制语句
  220. function page($tatal, $morePageStr = false)
  221. {
  222. $page = Paging::getInstance();
  223. return $page->limit($tatal, $morePageStr);
  224. }
  225. // 内容输出助手函数
  226. function response($data)
  227. {
  228. return core\basic\Response::handle($data);
  229. }
  230. // Json内容输出助手函数
  231. function json($code, $data)
  232. {
  233. return core\basic\Response::json($code, $data);
  234. }
  235. /**
  236. * 数据过滤
  237. *
  238. * @param mixed $varname
  239. * 字符串或参数名称
  240. * @param array $condition
  241. * array('d_source'=>'post','d_none'=>true,'d_require'=>true,'d_type'=>'int','d_max'=>5,'d_min'=2,'d_default'=>'')
  242. * 字段名称:$varname,用字段名称做key传递文本
  243. * 数据源:d_source,[post、get、cookie、session、both、string]
  244. * 是否允许空:d_none,[true、false],如果为false接受的收据为空,则直接报错
  245. * 是否必须:d_require,[true、false],如果为true意味着如果数据不满足要求直接报错,否则返回null
  246. * 数据类型:d_type,[int、float、num、letter、var、bool、date、array、object]
  247. * 正则表达:d_regular,接受正则表达式
  248. * 最大值|最大长度:d_max
  249. * 最小值|最小长度:d_min
  250. * 默认值:d_default
  251. * @return mixed
  252. */
  253. function filter($varname, $condition)
  254. {
  255. // 变量名称文本
  256. if (array_key_exists($varname, $condition) && $condition[$varname]) {
  257. $vartext = $condition[$varname];
  258. } else {
  259. $vartext = $varname;
  260. }
  261. // 数据源
  262. if (array_key_exists('d_source', $condition)) {
  263. switch ($condition['d_source']) {
  264. case 'post':
  265. $data = @$_POST[$varname];
  266. break;
  267. case 'get':
  268. $data = @$_GET[$varname];
  269. break;
  270. case 'cookie':
  271. $data = @$_COOKIE[$varname];
  272. break;
  273. case 'session':
  274. $data = session($varname);
  275. break;
  276. case 'both':
  277. $data = @$_POST[$varname] ?: @$_GET[$varname];
  278. break;
  279. case 'string':
  280. $data = $varname;
  281. default:
  282. error($vartext . '数据获取方式设置错误!');
  283. }
  284. // 去空格
  285. if (is_string($data))
  286. $data = trim($data);
  287. } else {
  288. $data = $varname; // 没有数据源指定时直接按照字符串过滤处理
  289. }
  290. // 数据为空时,进行是否允许空检测
  291. if (! $data && array_key_exists('d_none', $condition) && $condition['d_none'] === false) {
  292. error($vartext . '不能为空!');
  293. }
  294. // 判断是否强制检测,为true时,意味着如果数据不满足要求直接报错,否则返回null
  295. if (array_key_exists('d_require', $condition) && $condition['d_require'] == true) {
  296. $require = true;
  297. } else {
  298. $require = false;
  299. }
  300. // 数据类型检测
  301. if (array_key_exists('d_type', $condition)) {
  302. switch ($condition['d_type']) {
  303. case 'int':
  304. if (! preg_match('/^[0-9]+$/', $data)) {
  305. $err = '必须为整数!';
  306. }
  307. break;
  308. case 'float':
  309. if (! is_float($data)) {
  310. $err = '必须为浮点数!';
  311. }
  312. break;
  313. case 'num':
  314. if (! is_numeric($data)) {
  315. $err = '必须为数字!';
  316. }
  317. break;
  318. case 'letter':
  319. if (! preg_match('/^[a-zA-Z]+$/', $data)) {
  320. $err = '只能包含字母!';
  321. }
  322. break;
  323. case 'var':
  324. if (! preg_match('/^[\w\-\.]+$/', $data)) {
  325. $err = '只能包含字母、数字、划线、点!';
  326. }
  327. break;
  328. case 'bool':
  329. if (! is_bool($data)) {
  330. $err = '必须为布尔类型!';
  331. }
  332. break;
  333. case 'date':
  334. if (! strtotime($data)) {
  335. $err = '必须为日期类型!';
  336. }
  337. break;
  338. case 'array':
  339. if (! is_array($data)) {
  340. $err = '必须为数组类型!';
  341. }
  342. break;
  343. case 'object':
  344. if (! is_object($data)) {
  345. $err = '必须为对象类型!';
  346. }
  347. break;
  348. case 'vars':
  349. if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.,\s]+$/u', $data)) {
  350. $err = '只能包含中文、字母、数字、横线、点、逗号、空格!';
  351. }
  352. break;
  353. default:
  354. if ($condition['d_type'])
  355. error($vartext . '数据类型设置错误!');
  356. }
  357. }
  358. // 非必须或必须但无错误时执行
  359. if ((! $require || ($require && ! isset($err)))) {
  360. // 正则匹配
  361. if (array_key_exists('d_regular', $condition)) {
  362. if (! preg_match($condition['d_regular'], $data)) {
  363. $err = '不符合正则表达式规则!';
  364. }
  365. }
  366. // 最大值匹配
  367. if (array_key_exists('d_max', $condition)) {
  368. if (is_numeric($data)) {
  369. if ($data > $condition['d_max']) {
  370. $err = '不能大于' . $condition['d_max'];
  371. }
  372. } else {
  373. if (mb_strlen($data) > $condition['d_max']) {
  374. $err = '长度不能大于' . $condition['d_max'];
  375. }
  376. }
  377. }
  378. // 最小值匹配
  379. if (array_key_exists('d_min', $condition)) {
  380. if (is_numeric($data)) {
  381. if ($data < $condition['d_min']) {
  382. $err = '不能小于' . $condition['d_min'];
  383. }
  384. } else {
  385. if (mb_strlen($data) < $condition['d_min']) {
  386. $err = '长度不能小于' . $condition['d_min'];
  387. }
  388. }
  389. }
  390. }
  391. // 如果为必须且有错误,则显示错误,如果非必须,但有错误,则设置数据为null
  392. if ($require && isset($err)) {
  393. error($vartext . $err);
  394. } elseif (isset($err)) {
  395. $data = null;
  396. }
  397. // 如果设置有默认值,默认值
  398. if (array_key_exists('d_default', $condition)) {
  399. $data = (! is_null($data)) ? $data : $condition['d_default'];
  400. }
  401. // 去空格
  402. if (is_string($data)) {
  403. $data = trim($data);
  404. }
  405. // 销毁错误
  406. unset($err);
  407. // 返回收据
  408. return escape_string($data);
  409. }
  410. /**
  411. * 获取GET参数
  412. *
  413. * @param string $name
  414. * 参数名称
  415. * @param mixed $type
  416. * 数据类型
  417. * @param string $require
  418. * 是否为必须,为true是,如果不满足条件直接错误
  419. * @param string $vartext
  420. * 变量描述文本
  421. * @param string $default
  422. * 在非必需情况下默认值
  423. * @return mixed
  424. */
  425. function get($name, $type = null, $require = false, $vartext = null, $default = null)
  426. {
  427. $condition = array(
  428. 'd_source' => 'get',
  429. 'd_type' => $type,
  430. 'd_require' => $require,
  431. $name => $vartext,
  432. 'd_default' => $default
  433. );
  434. return filter($name, $condition);
  435. }
  436. /**
  437. * * 获取POST参数
  438. *
  439. * @param string $name
  440. * 参数名称
  441. * @param mixed $type
  442. * 数据类型
  443. * @param string $require
  444. * 是否为必须,为true是,如果不满足条件直接错误
  445. * @param string $vartext
  446. * 变量描述文本
  447. * @param string $default
  448. * 在非必需情况下默认值
  449. * @return mixed
  450. */
  451. function post($name, $type = null, $require = false, $vartext = null, $default = null)
  452. {
  453. $condition = array(
  454. 'd_source' => 'post',
  455. 'd_type' => $type,
  456. 'd_require' => $require,
  457. $name => $vartext,
  458. 'd_default' => $default
  459. );
  460. return filter($name, $condition);
  461. }
  462. /**
  463. * * 获取参数,post或get
  464. *
  465. * @param string $name
  466. * 参数名称
  467. * @param mixed $type
  468. * 数据类型
  469. * @param string $require
  470. * 是否为必须,为true是,如果不满足条件直接错误
  471. * @param string $vartext
  472. * 变量描述文本
  473. * @param string $default
  474. * 在非必需情况下默认值
  475. * @return mixed
  476. */
  477. function request($name, $type = null, $require = false, $vartext = null, $default = null)
  478. {
  479. if (isset($_POST[$name])) {
  480. $d_source = 'post';
  481. } else {
  482. $d_source = 'get';
  483. }
  484. $condition = array(
  485. 'd_source' => $d_source,
  486. 'd_type' => $type,
  487. 'd_require' => $require,
  488. $name => $vartext,
  489. 'd_default' => $default
  490. );
  491. return filter($name, $condition);
  492. }
  493. /**
  494. * 读取或写入Cookie信息
  495. *
  496. * @param string $name
  497. * 名称
  498. * @param string $value
  499. * 值
  500. * @param int $expire
  501. * 秒数
  502. * @param string $path
  503. * 路径,默认站点目录
  504. */
  505. function cookie($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httponly = true)
  506. {
  507. if (! is_null($value)) {
  508. $path = SITE_DIR . '/';
  509. if (is_string($value))
  510. $value = trim($value);
  511. $_COOKIE[$name] = $value; // 让cookie立即生效
  512. if (! is_null($expire)) {
  513. return setcookie($name, $value, time() + $expire, $path, $domain, $secure, $httponly);
  514. } else {
  515. return setcookie($name, $value, 0, $path, $domain, $secure, $httponly);
  516. }
  517. } else {
  518. if (isset($_COOKIE[$name])) {
  519. return escape_string($_COOKIE[$name]);
  520. } else {
  521. return null;
  522. }
  523. }
  524. }
  525. /**
  526. * 读取或写入session信息
  527. *
  528. * @param string $name
  529. * 支持点分多级获取
  530. * @param mixed $value
  531. * 设置值
  532. * @return string|NULL|unknown
  533. */
  534. function session($name, $value = null)
  535. {
  536. if (! isset($_SESSION)) {
  537. session_start(); // 自动启动会话
  538. }
  539. if (! is_null($value)) {
  540. if (isset($_SESSION[$name])) {
  541. if ($_SESSION[$name] != $value) {
  542. $_SESSION[$name] = $value;
  543. }
  544. } else {
  545. $_SESSION[$name] = $value;
  546. }
  547. return $value;
  548. } else {
  549. if (strpos($name, '.')) {
  550. if (isset($_SESSION[$name])) {
  551. return $_SESSION[$name];
  552. }
  553. $names = explode('.', $name);
  554. if (! isset($_SESSION[$names[0]])) {
  555. return null;
  556. }
  557. $var = $_SESSION[$names[0]];
  558. $len = count($names);
  559. for ($i = 1; $i < $len; $i ++) {
  560. if (is_array($var)) {
  561. if (isset($var[$names[$i]])) {
  562. $var = $var[$names[$i]];
  563. } else {
  564. return null;
  565. }
  566. } elseif (is_object($var)) {
  567. if (isset($var->{$names[$i]})) {
  568. $var = $var->{$names[$i]};
  569. } else {
  570. return null;
  571. }
  572. } else {
  573. break;
  574. }
  575. }
  576. return $var;
  577. } else {
  578. if (isset($_SESSION[$name])) {
  579. return $_SESSION[$name];
  580. } else {
  581. return null;
  582. }
  583. }
  584. }
  585. }
  586. // 检查会话参数是否存在
  587. function issetSession($name)
  588. {
  589. if (! isset($_SESSION)) {
  590. session_start(); // 自动启动会话
  591. }
  592. return isset($_SESSION[$name]);
  593. }
  594. /**
  595. * 快速发送邮件函数
  596. *
  597. * @param array $config
  598. * 邮件服务器连接数组,需包含 smtp_server、smtp_username、smtp_password、smtp_port、smtp_port
  599. * @param string $to
  600. * 邮件接收人
  601. * @param string $subject
  602. * 邮件主题
  603. * @param string $body
  604. * 邮件正文
  605. */
  606. function sendmail(array $config, $to, $subject, $body)
  607. {
  608. $smtp = new Smtp($config['smtp_server'], $config['smtp_username'], $config['smtp_password'], $config['smtp_port'], $config['smtp_ssl']);
  609. if ($smtp->sendMail($to, $subject, $body)) {
  610. return true;
  611. } else {
  612. return $smtp->error();
  613. }
  614. }
  615. // 发送短信
  616. function sendsms(array $config, $to, $content)
  617. {
  618. if (! $to || ! $content) {
  619. return false;
  620. }
  621. if (! isset($config['sms_account']) || ! isset($config['sms_pwd']) || ! isset($config['sms_signid'])) {
  622. alert_back('短信发送参数配置有误');
  623. }
  624. $data['Account'] = $config['sms_account'];
  625. $data['Pwd'] = $config['sms_pwd'];
  626. $data['SignId'] = $config['sms_signid'];
  627. $data['Content'] = $content;
  628. $to = str_replace("\r\n", ",", $to); // 替换回车
  629. $to = str_replace(",", ",", $to); // 替换中文逗号分割符
  630. $data['Mobile'] = str_replace(" ", "", $to); // 替换空格
  631. $url = "http://api.feige.ee/SmsService/Send";
  632. if (! ! $res = get_url($url, $data)) {
  633. $result = json_decode($res);
  634. if (! ($result->Code === 0)) {
  635. error('短信发送失败,' . $result->Message);
  636. } else {
  637. return true;
  638. }
  639. }
  640. }
  641. // 查询短信余额
  642. function get_sms_balance(array $config)
  643. {
  644. $data['Account'] = $config['sms_account'];
  645. $data['Pwd'] = $config['sms_pwd'];
  646. $url = "http://api.feige.ee/Account/Balance";
  647. if (! ! $res = get_url($url, $data)) {
  648. $result = json_decode($res);
  649. if (! ($result->Code === 0)) {
  650. error('查询失败,' . $result->Message);
  651. } else {
  652. return $result->Balance;
  653. }
  654. }
  655. }