common.php 139 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 流年 <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // 应用公共文件
  12. use app\common\model\Plugin;
  13. use app\common\model\Module;
  14. use app\common\model\User AS UserModel;
  15. use app\common\model\Msg AS MsgModel;
  16. use think\Db;
  17. use think\Request;
  18. use app\common\controller\Base;
  19. use app\common\util\Cache2;
  20. error_reporting(E_ERROR | E_PARSE );
  21. if (is_file(APP_PATH.'function.php')) { //用户二开的方法优先级更高,可以把下面默认的替换掉
  22. include_once APP_PATH.'function.php';
  23. }
  24. if(!function_exists('fun')){
  25. /**
  26. * 扩展函数,第一项是函数文件名@方法名,之后可以设置任意多项参数,它会对应到你自己定义的函数,比如这里第二项,会对应到你的函数第一项
  27. * 注意,唯一不足的是:用不了引用参数
  28. * @param string $fun 文件名@方法名
  29. * @return void|mixed
  30. */
  31. function fun($fun='sort@get'){
  32. static $fun_array = [];
  33. list($class_name,$action) = explode('@',$fun);
  34. $class = "app\\common\\fun\\".ucfirst($class_name);
  35. $obj = $fun_array[$class_name];
  36. if(empty($obj)){
  37. if(!class_exists($class)){
  38. return ;
  39. }
  40. $obj = $fun_array[$class_name] = new $class;
  41. }
  42. if(!method_exists($obj, $action)){
  43. return ;
  44. }
  45. $params = func_get_args();
  46. unset($params[0]);
  47. $params = array_values($params);
  48. static $default_params_array = [];
  49. $_params = $default_params_array[$fun];
  50. if (!isset($_params)) {
  51. $_params = [];
  52. $_obj = new \ReflectionMethod($obj, $action);
  53. $_array = $_obj->getParameters();
  54. foreach($_array AS $key=>$value){
  55. if($value->isOptional()){
  56. $_params[$key] = $value->getDefaultValue();
  57. }else{
  58. $_params[$key] = null;
  59. }
  60. }
  61. $default_params_array[$fun] = $_params;
  62. }
  63. foreach($_params AS $key=>$value){
  64. if(isset($params[$key])){
  65. $_params[$key] = $params[$key];
  66. }
  67. }
  68. return call_user_func_array([$obj, $action], $_params); //这个函数没办法处理传递引用参数 func_get_args 也是变量的复制,没办法传递
  69. // try {
  70. // $reuslt = $_obj->invokeArgs($obj, $_params);
  71. // } catch(\Exception $e) {
  72. // $_params[0] = &$quote;
  73. // arsort($_params);
  74. // $reuslt = $_obj->invokeArgs($obj, $_params);
  75. // }
  76. // return $reuslt;
  77. //return call_user_func_array([$obj, $action], $_params); //这个函数没办法处理传递引用参数
  78. }
  79. }
  80. if (!function_exists('get_real_path')) {
  81. /**
  82. * 解决有的虚拟服务器不支持../这样的相对路径的问题
  83. * @param unknown $path
  84. * @return string
  85. */
  86. function get_real_path($path) {
  87. if(!strstr($path,'..')){
  88. return $path;
  89. }
  90. $path = str_replace('\\','/',$path);
  91. $path = str_replace('//','/',$path);
  92. $detail = explode('/',$path);
  93. foreach($detail AS $key=>$value){
  94. if($value=='.'||$value===''){
  95. unset($detail[$key]);
  96. }
  97. }
  98. $detail = array_values($detail);
  99. $max = count($detail)-1;
  100. for($i=$max;$i>=0;$i--){
  101. if (!isset($detail[$i])) {
  102. continue;
  103. }
  104. if($detail[$i]=='..'){
  105. unset($detail[$i]);
  106. if($detail[$i-1]=='..'){
  107. if($detail[$i-2]=='..'){
  108. if($detail[$i-3]=='..'){
  109. unset($detail[$i-6]);
  110. unset($detail[$i-7]);
  111. }
  112. unset($detail[$i-4]);
  113. unset($detail[$i-5]);
  114. }
  115. unset($detail[$i-2]);
  116. unset($detail[$i-3]);
  117. }
  118. unset($detail[$i-1]);
  119. }
  120. }
  121. return (substr($path,0,1)=='/'?'/':'').implode('/',$detail);
  122. }
  123. }
  124. if (!function_exists('clear_js')) {
  125. /**
  126. * 过滤js内容
  127. * @param string $str 要过滤的字符串
  128. * @return mixed|string
  129. */
  130. function clear_js($str = '')
  131. {
  132. $search ="/<script[^>]*?>.*?<\/script>/si";
  133. $str = preg_replace($search, '', $str);
  134. return $str;
  135. }
  136. }
  137. if (!function_exists('hook_listen')) {
  138. /**
  139. * 监听标签的行为
  140. * 钩子若执行错误,错误日志会写在 runtime\hook_run_error.php 这个文件里边
  141. * @param string $tag 标签名称
  142. * @param mixed $params 传入参数
  143. * @param mixed $extra 额外参数
  144. * @param bool $once 只获取一个有效返回值
  145. * @return string|mixed|mixed[]
  146. */
  147. function hook_listen($tag = '', &$params = null, $extra = null, $once = false) {
  148. if ($once===true && hook_if_load($tag)===false) { //这个纯属是为了兼容以前的模板中放的钩子
  149. get_hook($tag,$params,$extra,['from'=>'hook'],$once);
  150. }
  151. try {
  152. $result = \think\Hook::listen($tag, $params, $extra, $once);
  153. } catch(\Exception $e) {
  154. if($e->getCode()===0||$e->getCode()===1){ //成功或报错页,即$this->error('');与$this->success('');
  155. throw $e;
  156. }else{
  157. //钩子若执行错误,错误日志会写在 runtime\hook_run_error.php 这个文件里边
  158. file_put_contents(RUNTIME_PATH.'hook_run_error.php', '<?php die();'.var_export($e,true)."\r\n$tag\r\n" );
  159. }
  160. }
  161. return $result;
  162. }
  163. }
  164. if (!function_exists('hook_if_load')) {
  165. /**
  166. * 检查是否重复加载钩子
  167. * @param string $tag
  168. * @return boolean
  169. */
  170. function hook_if_load($tag=''){
  171. static $array = [];
  172. if ($array[$tag]) {
  173. return true;
  174. }else{
  175. $array[$tag] = true;
  176. return false;
  177. }
  178. }
  179. }
  180. if (!function_exists('get_hook')) {
  181. /**
  182. * 齐博首创 钩子文件扩展接口
  183. * 详细使用教程 https://www.kancloud.cn/php168/x1_of_qibo/1010065
  184. * @param string $type 钩子标志,不能重复
  185. * @param array $data POST表单数据
  186. * @param array $info 数据库资料
  187. * @param array $array 其它参数
  188. * @param string $use_common 默认同时调用全站通用的
  189. * @param string $dirname 可以指定模块目录,比如在模型里边被其它调用的话,就需要预先指定目录,避免获取不到真实目录
  190. * @return unknown|NULL
  191. */
  192. function get_hook($type='',&$data=[],$info=[],$array=[],$use_common=true,$dirname=''){
  193. if (hook_if_load($type)===true && $array['from']!='hook') {
  194. return NULL;
  195. }
  196. $path_array = [];
  197. $dirname = $dirname?:config('system_dirname');
  198. if ( empty($dirname) ) {
  199. if (defined('IN_PLUGIN')) {
  200. $dirname = input('plugin_controller');
  201. }else{
  202. $dispatch=request()->dispatch();
  203. if ($dispatch['module'][0]) {
  204. $dirname = $dispatch['module'][0];
  205. }else{
  206. $dirname = 'index';
  207. }
  208. }
  209. }
  210. $path_array[] = (defined('IN_PLUGIN')?PLUGINS_PATH:APP_PATH).($dirname?$dirname.DS:'').'ext'.DS.$type.DS;
  211. if ($use_common===true) {
  212. $path_array[] = APP_PATH.'common'.DS.'ext'.DS.$type.DS;
  213. }
  214. $file_array = [];
  215. foreach ($path_array AS $path){
  216. if (is_dir($path)) {
  217. $sarray = [];
  218. $dir = opendir($path);
  219. while($file = readdir($dir)){
  220. if(preg_match("/^([\w\.-]*)\.php$/i", $file,$sar)){
  221. if (in_array($sar[1], $file_array)) {
  222. continue ; //出现同名,就跳过
  223. }
  224. $sarray[$path.DS.$file] = $sar[1];
  225. }
  226. }
  227. asort($sarray);
  228. $file_array = array_merge($file_array,$sarray);
  229. }
  230. }
  231. if ($file_array) {
  232. foreach($file_array AS $file=>$v){
  233. $result = include($file);
  234. if ($result===true||$result===false) {
  235. return $result;
  236. }elseif(is_string($result) || is_array($result)){
  237. return $result;
  238. }
  239. }
  240. }
  241. return NULL;
  242. }
  243. }
  244. if (!function_exists('format_time')) {
  245. /**
  246. * 时间戳格式化
  247. * @param string $time 时间戳
  248. * @param string $format 输出格式 设置为true的话,就按 刚刚 几分钟前的格式显示
  249. * @param string $type 当$format设置为true的时候,设置超过一个月后的时间格式
  250. * @return false|string
  251. */
  252. function format_time($time = '', $format='Y-m-d H:i',$type='Y-m-d H:i') {
  253. if(!preg_match('/^([\d]+)$/', $time)){
  254. $time = strtotime($time);
  255. }
  256. if($format===true){
  257. $_time = time() - $time;
  258. if($_time<60){
  259. $msg = '刚刚';
  260. }elseif($_time<1800){
  261. $msg = intval($_time/60).'分钟前';
  262. }elseif($_time<3600){
  263. $msg = '半小时前';
  264. }elseif($_time<3600*24){
  265. $msg = intval($_time/3600).'小时前';
  266. }elseif($_time<3600*24*30){
  267. $msg = intval($_time/(3600*24)).'天前';
  268. }elseif($_time<3600*24*30*12){
  269. $msg = intval($_time/(3600*24*30)).'个月前';
  270. }else{
  271. $msg = empty($time) ? '' : date($type,$time);
  272. }
  273. }else{
  274. $msg = !$time ? '' : date($format, intval($time));
  275. }
  276. return $msg;
  277. }
  278. }
  279. if (!function_exists('plugin_action_exists')) {
  280. /**
  281. * 检查插件控制器是否存在某操作
  282. * @param string $name 插件名
  283. * @param string $controller 控制器
  284. * @param string $action 动作
  285. * @return bool
  286. */
  287. function plugin_action_exists($name = '', $controller = '', $action = '')
  288. {
  289. $dir = '';
  290. if (strpos($name, '/')) {
  291. list($name, $controller, $action) = explode('/', $name);
  292. }
  293. if(strpos($controller,'.')){
  294. list($dir,$controller) = explode('.', $controller);
  295. }
  296. $class = "plugins\\{$name}\\".ENTRANCE."\\". ($dir?"$dir\\":'') . format_class_name($controller);
  297. return (method_exists($class, $action) ||method_exists($class, '_initialize'));
  298. }
  299. }
  300. if (!function_exists('plugin_model_exists')) {
  301. /**
  302. * 检查插件模型是否存在
  303. * @param string $name 插件名
  304. * @return bool
  305. */
  306. function plugin_model_exists($name = '')
  307. {
  308. $class = "plugins\\{$name}\\model\\".format_class_name($name);
  309. return class_exists($class);
  310. }
  311. }
  312. if (!function_exists('downFile')) {
  313. /**
  314. * 下载远程文件
  315. * @param unknown $url 远程文件网址
  316. * @param string $filename 保存在空间上哪个目录
  317. * @param number $type 下载方式
  318. * @throws \Exception
  319. * @return void|boolean
  320. */
  321. function downFile($url,$filename='',$type=0){
  322. if($url==''){
  323. return false;
  324. }
  325. if($type===1){
  326. $fp_output = fopen($filename, 'w');
  327. $ch = curl_init($url);
  328. curl_setopt($ch, CURLOPT_FILE, $fp_output);
  329. curl_exec($ch);
  330. curl_close($ch);
  331. if(filesize($filename)>2){
  332. return ;
  333. }
  334. }elseif($type===2){
  335. ob_end_clean();
  336. ob_start();
  337. readfile($url);
  338. $data=ob_get_contents();
  339. ob_end_clean();
  340. if($data!=''){
  341. file_put_contents($filename,$data);
  342. return ;
  343. }
  344. }
  345. if( copy($url,$filename) ){
  346. return ;
  347. }
  348. if(($data=file_get_contents($url))==false){
  349. // $ch=curl_init();
  350. // $timeout = 600;
  351. // curl_setopt($ch,CURLOPT_URL,$url);
  352. // curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
  353. // curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);//最长执行时间
  354. // curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);//最长等待时间
  355. // $data=curl_exec($ch);
  356. // curl_close($ch);
  357. $data = http_curl($url);
  358. }
  359. if($data!=''){
  360. write_file($filename,$data);
  361. }
  362. }
  363. }
  364. if (!function_exists('get_plugin_model')) {
  365. /**
  366. * 获取插件模型实例
  367. * @param string $name 插件名
  368. * @return object
  369. */
  370. function get_plugin_model($name)
  371. {
  372. $class = "plugins\\{$name}\\model\\{$name}";
  373. return new $class;
  374. }
  375. }
  376. if (!function_exists('plugin_action')) {
  377. /**
  378. * 执行插件动作
  379. * 也可以用这种方式调用:plugin_action('插件名/控制器/动作', [参数1,参数2...])
  380. * @param string $name 插件名
  381. * @param string $controller 控制器
  382. * @param string $action 动作
  383. * @param mixed $params 参数
  384. * @return mixed
  385. */
  386. function plugin_action($name = '', $controller = '', $action = '', $params = [])
  387. {
  388. $dir = '';
  389. if (strpos($name, '/')) {
  390. $params = is_array($controller) ? $controller : (array)$controller;
  391. list($name, $controller, $action) = explode('/', $name);
  392. }
  393. if (!is_array($params)) {
  394. $params = (array)$params;
  395. }
  396. if(strpos($controller,'.')){
  397. list($dir,$controller) = explode('.', $controller);
  398. }
  399. $class = "plugins\\{$name}\\".ENTRANCE."\\". ($dir?"$dir\\":'') . format_class_name($controller);
  400. $obj = new $class;
  401. //反射,获取方法里边的参数
  402. $_params = [];
  403. if (!empty($params)) {
  404. $_obj = new \ReflectionMethod($obj, $action);
  405. $_array = $_obj->getParameters();
  406. foreach($_array AS $value){
  407. $_params[$value->name] = $params[$value->name];
  408. }
  409. //类似给函数赋值一样,可以只给前面的赋值,后面的可以保留原值
  410. if( end($_params)=='' ){
  411. $ar = array_reverse($_params);
  412. foreach($ar AS $key=>$value){
  413. if($value==''){
  414. unset($ar[$key]);
  415. break;
  416. }
  417. }
  418. $_params = array_reverse($ar);
  419. }
  420. }
  421. //把插件的配置文件也像模块那样引入进去
  422. if(is_file(ROOT_PATH."plugins/{$name}/config.php")){
  423. $array = include(ROOT_PATH."plugins/{$name}/config.php");
  424. config($array) ;
  425. }
  426. return call_user_func_array([$obj, $action], $_params);
  427. }
  428. }
  429. if (!function_exists('urls')) {
  430. /**
  431. * 重写 url 对于缺少模块与控制器的URL地址,自动补上
  432. * @param string $url
  433. * @param string $vars
  434. * @param string $suffix
  435. * @param string $domain
  436. * @return unknown
  437. */
  438. function urls($url = '', $vars = '', $suffix = true, $domain = false)
  439. {
  440. $url = full_url($url);
  441. list($module) = explode('/',$url);
  442. $_url = url($url, $vars, $suffix, $domain);
  443. if($module=='index' && ENTRANCE!='index'){
  444. $_url = str_replace(array(ADMIN_FILENAME,'member.php'), 'index.php', $_url);
  445. }elseif($module=='member' && ENTRANCE!='member'){
  446. if(preg_match('/^\/member\//i', $_url)){
  447. $_url = '/member.php'.$_url;
  448. }else{
  449. $_url = str_replace(array(ADMIN_FILENAME,'index.php'), 'member.php', $_url);
  450. $_url = preg_replace("/^(http|https):\/\/([^\/]+)\/([\w-]+)\//i", "\\1://\\2/member.php/\\3/", $_url);
  451. }
  452. }
  453. return $_url ;
  454. }
  455. }
  456. if (!function_exists('auto_url')) {
  457. /**
  458. * 自适应插件或模块链接
  459. * @param string $url
  460. * @param string $vars
  461. * @param string $suffix
  462. * @param string $domain
  463. * @return unknown
  464. */
  465. function auto_url($url = '', $vars = '', $suffix = true, $domain = false)
  466. {
  467. $detail = Request::instance()->dispatch();
  468. if ($detail['module'][1]=='plugin' && $detail['module'][2]=='execute') {
  469. return purl($url, $vars);
  470. }else{
  471. return url(full_url($url), $vars, $suffix, $domain);
  472. }
  473. }
  474. }
  475. if (!function_exists('purl')) {
  476. /**
  477. * 生成插件操作链接
  478. * @param string $url 链接:插件名称/控制器/操作
  479. * @param array $param 参数
  480. * @param string $module 模块名,admin需要登录验证,index不需要登录验证
  481. */
  482. function purl($url = '', $param = [], $module = '')
  483. {
  484. $params = [];
  485. if (strstr($url,'/')) {
  486. $url = explode('/', $url);
  487. if( count($url)==3 ){
  488. $params['plugin_name'] = $url[0];
  489. $params['plugin_controller'] = $url[1];
  490. $params['plugin_action'] = $url[2];
  491. }elseif(count($url)==2){
  492. $params['plugin_name'] = input('route.plugin_name');
  493. $params['plugin_controller'] = $url[0];
  494. $params['plugin_action'] = $url[1];
  495. }
  496. }else{
  497. $params['plugin_name'] = input('plugin_name');
  498. $params['plugin_controller'] = input('plugin_controller');
  499. $params['plugin_action'] = $url=='' ? input('plugin_action') : $url;
  500. }
  501. empty($param) && $param=[];
  502. if (!is_array($param)) {
  503. parse_str($param, $param);
  504. }
  505. // 合并参数
  506. $params = array_merge($params, $param);
  507. //没有特别指定的话,就进入相应的前台或后台
  508. $module || $module = ENTRANCE;
  509. $url = url($module .'/plugin/execute', $params);
  510. if($module=='index' && ENTRANCE!='index'){
  511. $url = str_replace(array(ADMIN_FILENAME,'member.php'), 'index.php', $url);
  512. }elseif($module=='member' && ENTRANCE!='member'){
  513. if(preg_match('/^\/member\//i', $url)){
  514. $url = '/member.php'.$url;
  515. }else{
  516. $url = str_replace(array(ADMIN_FILENAME,'index.php'), 'member.php', $url);
  517. $url = preg_replace("/^(http|https):\/\/([^\/]+)\/([\w-]+)\//i", "\\1://\\2/member.php/\\3/", $url);
  518. }
  519. }
  520. return $url;
  521. }
  522. }
  523. if (!function_exists('iurl')) {
  524. /**
  525. * 强制使用前台URL地址,比如会员中心与后台是最常使用的.他们要访问前台内容
  526. * @param string $url
  527. * @param string $vars
  528. * @param string $suffix
  529. * @param string $domain
  530. * @param string $type 频道或者是插件
  531. * @return mixed
  532. */
  533. function iurl($url = '', $vars = '', $suffix = true, $domain = false , $type = '')
  534. {
  535. $detail = Request::instance()->dispatch();
  536. if($type==''){ //主要是标签那里使用,判断是频道还是插件
  537. static $typedb = [];
  538. $_detail = explode('/',$url);
  539. if(count($_detail)==3){
  540. $module = $_detail[0];
  541. if(empty($typedb[$module])){
  542. if(is_dir(APP_PATH.$module)){
  543. $typedb[$module] = 'module';
  544. }else{
  545. $typedb[$module] = 'plugin';
  546. }
  547. }
  548. $type = $typedb[$module];
  549. }
  550. }
  551. if($type=='m'||$type=='module'){
  552. $_url = url(full_url($url), $vars, $suffix, $domain);
  553. }elseif($type=='plugin'){
  554. $_url = purl($url, $vars, '');
  555. //是否在插件里
  556. }elseif ($detail['module'][1]=='plugin' && $detail['module'][2]=='execute') {
  557. //如果是index/xxx/xxx模块要特殊处理
  558. $_url = preg_match('/^index\/([\w]+)\/([\w]+)/', $url) ? url($url, $vars, $suffix, $domain) : purl($url, $vars, 'index');
  559. }else{
  560. $_url = url(full_url($url), $vars, $suffix, $domain);
  561. }
  562. $url = str_replace(array(ADMIN_FILENAME,'member.php'), 'index.php', $_url);
  563. if(config('webdb.hiden_index_php') && preg_match('/\/index\.php\//', $url)){
  564. $url = str_replace('/index.php/', '/', $url);
  565. }
  566. return $url;
  567. }
  568. }
  569. if (!function_exists('murl')) {
  570. /**
  571. * 强制使用会员中心URL地址
  572. * @param string $url
  573. * @param string $vars
  574. * @param string $suffix
  575. * @param string $domain
  576. * @param string $type 强制指定频道或插件
  577. * @return string|mixed
  578. */
  579. function murl($url = '', $vars = '', $suffix = true, $domain = false,$type='')
  580. {
  581. $detail = Request::instance()->dispatch();
  582. if($type==''){
  583. static $typedb = [];
  584. $_detail = explode('/',$url);
  585. if(count($_detail)==3){
  586. $module = $_detail[0];
  587. if(empty($typedb[$module])){
  588. if(is_dir(APP_PATH.$module)){
  589. $typedb[$module] = 'module';
  590. }else{
  591. $typedb[$module] = 'plugin';
  592. }
  593. }
  594. $type = $typedb[$module];
  595. }
  596. }
  597. if($type=='m'||$type=='module'){
  598. $_url = url($url, $vars, $suffix, $domain);
  599. }elseif($type=='p'||$type=='plugin'){
  600. $_url = purl($url, $vars);
  601. }
  602. // $_detail = explode('/',$url);
  603. // if(count($_detail)==3){
  604. // if($_detail[0]=='member'){
  605. // $_url = url($url, $vars, $suffix, $domain);
  606. // }elseif($type=='p'){
  607. // $_url = purl($url, $vars);
  608. // }
  609. // }
  610. if(empty($_url)){
  611. //是否是插件
  612. if ($detail['module'][1]=='plugin' && $detail['module'][2]=='execute') {
  613. $_url = purl($url, $vars, 'index');
  614. }else{
  615. $_url = url($url, $vars, $suffix, $domain);
  616. }
  617. }
  618. if(preg_match('/^\/[\w]+\//', $_url)){
  619. $url = '/member.php'.$_url;
  620. }else{
  621. $url = str_replace([ADMIN_FILENAME.'/admin','index.php/index'],'member.php/member', $_url);
  622. $url = str_replace([ADMIN_FILENAME,'index.php'],'member.php', $url);
  623. $url = preg_replace("/^(http|https):\/\/([^\/]+)\/([\w-]+)\//i", "\\1://\\2/member.php/\\3/", $url);
  624. }
  625. //if(!preg_match('/^member.php/', $url)){
  626. //$url = '/index.php'.$url;
  627. //}
  628. return $url;
  629. }
  630. }
  631. if (!function_exists('full_url')) {
  632. /**
  633. * 补全缺少模块与控制器的URL
  634. * @param string $url
  635. * @return string
  636. */
  637. function full_url($url=''){
  638. $detail = explode('/',$url);
  639. if (count($detail)==3) {
  640. return $url;
  641. }
  642. static $_m = null;
  643. $_m===null && $_m = Request::instance()->dispatch();
  644. $m = $_m['module'];
  645. if(count($detail)==1){
  646. $url = $m[0] . '/' . $m[1] . '/' . $url;
  647. }elseif(count($detail)==2){
  648. $url = $m[0] . '/' . $url;
  649. }
  650. return $url;
  651. }
  652. }
  653. if (!function_exists('format_class_name')) {
  654. /**
  655. * 主要是插件那里用到,统一TP那样的文件命名原理,文件名中的某个大写字母,在URL中要用_隔开
  656. * @param unknown $name
  657. * @return string
  658. */
  659. function format_class_name($name){
  660. $detail = explode('_',$name);
  661. $classname = '';
  662. foreach($detail AS $value){
  663. $value && $classname .= ucfirst($value);
  664. }
  665. return $classname;
  666. }
  667. }
  668. if (!function_exists('into_sql')) {
  669. /**
  670. * 批量导入SQL数据
  671. * @param unknown $sql SQL数据,可以是多条
  672. * @param string $replace_pre 默认true替换为当前数据表前缀
  673. * @param number $type 2是遇到错误直接终止,1是显示错误,但不终止程序,0是屏蔽错误
  674. */
  675. function into_sql($sql, $replace_pre=true,$type=2){
  676. if(preg_match('/\.sql$/', $sql)||is_file($sql)){
  677. $sql = check_bom(read_file($sql));
  678. }
  679. $prefix = $replace_pre===true ? ['qb_'=>config('database.prefix')] : [];
  680. $sql_list = parse_sql($sql,$prefix);
  681. $result = false;
  682. foreach ($sql_list as $v) {
  683. if($type==2){ //直接终止
  684. $result = Db::execute($v);
  685. }else{
  686. try {
  687. $result = Db::execute($v);
  688. } catch(\Exception $e) {
  689. if($type==1){ //显示错误,不终止后面的程序运行
  690. echo '<br>导入SQL失败,请检查install.sql的语句是否正确<pre>'.$v."\n\n".$e.'</pre>';
  691. }else{
  692. //为0的时候,屏蔽错误
  693. }
  694. }
  695. }
  696. }
  697. return $result;
  698. }
  699. }
  700. if (!function_exists('parse_sql')) {
  701. /**
  702. * 分割sql语句
  703. * @param string $content sql内容
  704. * @param array $prefix 替换前缀
  705. * @param bool $limit 如果为1,则只返回一条sql语句,默认返回所有 *
  706. * @return array|string 除去注释之后的sql语句数组或一条语句
  707. */
  708. function parse_sql($sql = '', $prefix = [], $limit = 0) {
  709. // 被替换的前缀
  710. $from = '';
  711. // 要替换的前缀
  712. $to = '';
  713. // 替换表前缀
  714. if (!empty($prefix)) {
  715. $to = current($prefix);
  716. $from = current(array_flip($prefix));
  717. }
  718. if ($sql != '') {
  719. // 纯sql内容
  720. $pure_sql = [];
  721. // 多行注释标记
  722. $comment = false;
  723. // 按行分割,兼容多个平台
  724. $sql = str_replace(["\r\n", "\r"], "\n", $sql);
  725. $sql = explode("\n", trim($sql));
  726. // 循环处理每一行
  727. foreach ($sql as $key => $line) {
  728. // 跳过空行
  729. if ($line == '') {
  730. continue;
  731. }
  732. // 跳过以#或者--开头的单行注释
  733. if (preg_match("/^(#|--)/", $line)) {
  734. continue;
  735. }
  736. // 跳过以/**/包裹起来的单行注释
  737. if (preg_match("/^\/\*(.*?)\*\//", $line)) {
  738. continue;
  739. }
  740. // 多行注释开始
  741. if (substr($line, 0, 2) == '/*') {
  742. $comment = true;
  743. continue;
  744. }
  745. // 多行注释结束
  746. if (substr($line, -2) == '*/') {
  747. $comment = false;
  748. continue;
  749. }
  750. // 多行注释没有结束,继续跳过
  751. if ($comment) {
  752. continue;
  753. }
  754. // 替换表前缀
  755. if ($from != '') {
  756. $line = str_replace('`'.$from, '`'.$to, $line);
  757. }
  758. if ($line == 'BEGIN;' || $line =='COMMIT;') {
  759. continue;
  760. }
  761. // sql语句
  762. array_push($pure_sql, $line);
  763. }
  764. // 只返回一条语句
  765. if ($limit == 1) {
  766. return implode($pure_sql, "");
  767. }
  768. // 以数组形式返回sql语句
  769. $pure_sql = implode($pure_sql, "\n");
  770. $pure_sql = explode(";\n", $pure_sql);
  771. return $pure_sql;
  772. } else {
  773. return $limit == 1 ? '' : [];
  774. }
  775. }
  776. }
  777. if (!function_exists('str_array')) {
  778. /**
  779. * 把字符串转为数组 换行符或者是, 隔开的字符串
  780. * 第二项,最好指定,不然的话,只有一项参数的话,容易判断失败
  781. * @param string $value 字符串
  782. * @param string $explode 指定用什么符号做切割分隔,留空则自动识别,如果只有一个参数的话,容易判断失败
  783. * @return string|array|unknown[]
  784. */
  785. function str_array($value = '',$explode='') {
  786. $value = trim($value, " ,;\r\n|");
  787. if( strpos($value,"\n") || $explode=="\n" ){ //常用换行符做分割,比如后台参数
  788. $value = str_replace("\r","",$value);
  789. $exp = "\n";
  790. }elseif($explode!==''){
  791. $exp = $explode;
  792. }elseif( strpos($value,"|") ){
  793. $exp = "|";
  794. }elseif( strpos($value,",") ){
  795. $exp = ",";
  796. }elseif( strpos($value,";") ){
  797. $exp = ";";
  798. }elseif( strpos($value," ") ){
  799. $exp = " ";
  800. }elseif($value===''||$value===null){
  801. return [];
  802. }else{
  803. return [$value];
  804. }
  805. $array = explode($exp,$value);
  806. if ( $exp == "\n" && strpos($value, '|') ) {
  807. $ar = [];
  808. foreach ($array as $val) {
  809. list($k, $v) = explode( '|' , $val);
  810. $ar[$k] = $v;
  811. }
  812. } else {
  813. $ar = $array;
  814. }
  815. return $ar;
  816. }
  817. }
  818. if(!function_exists('get_post')){
  819. /**
  820. * 获取数据,POST优化级最高 然后是GET 最后是路由
  821. * @param string $type 指定要什么数据
  822. * @return mixed
  823. */
  824. function get_post($type=''){
  825. if($type=='post'){
  826. $array = input('post.');
  827. }elseif($type=='get'){
  828. $array = input('get.');
  829. }elseif($type=='route'){
  830. $array = input('route.');
  831. }else{
  832. //优先级 post > get > route
  833. $array_route = input('route.');
  834. is_array($array_route) || $array_route=[];
  835. $array_get = input('get.');
  836. is_array($array_get) || $array_get=[];
  837. $array_post = input('post.');
  838. is_array($array_post) || $array_post=[];
  839. $array = array_merge($array_route,$array_get,$array_post);
  840. }
  841. return $array;
  842. }
  843. }
  844. //根据用户的用户组ID得到用户组的名称
  845. if (!function_exists('getGroupByid')) {
  846. /**
  847. * 取用户组的数据, 默认只取对应用户组ID的标题名称,也可以取用户组的所有数据
  848. * @param unknown $gid 用户组ID,如果为NULL的话,就取出所有
  849. * @param string $only_title 默认只取名称,设置为false的话,可以取所有数据
  850. * @return unknown
  851. */
  852. function getGroupByid($gid = null , $only_title = true)
  853. {
  854. $group = cache('group_title');
  855. if (empty($group)) {
  856. $group = model('common/group')->getList();
  857. cache('group_title',$group,3600);
  858. }
  859. foreach ($group AS $key=>$rs){
  860. if ($rs['type']==0) {
  861. $rs['_level'] = [];
  862. if (strstr($rs['level'],'=')) {
  863. $detail = explode(',', $rs['level']);
  864. foreach ($detail AS $v){
  865. list($day,$money) = explode('=', $v);
  866. if ($day>0 && $money>0) {
  867. $rs['_level'][$day] = $money;
  868. }
  869. }
  870. }else{
  871. $rs['_level'][$rs['daytime']] = $rs['level'];
  872. }
  873. }
  874. $group[$key] = $rs;
  875. }
  876. if($gid>0){
  877. return $only_title==true ? $group[$gid]['title'] : $group[$gid];
  878. }else{
  879. if($only_title==true){
  880. $array = [];
  881. foreach($group AS $key=>$rs){
  882. $array[$rs['id']] = $rs['title'];
  883. }
  884. return $array;
  885. }else{
  886. return $group;
  887. }
  888. }
  889. }
  890. }
  891. if (!function_exists('get_role')) {
  892. /**
  893. * 获取用户角色名称
  894. * @param unknown $id 非数字的话,就获取所有名称,指定数字的话, 就是对应的角色名称
  895. * @return mixed|array
  896. */
  897. function get_role($id=null){
  898. $array = explode("\r\n", trim(config('webdb.role_name')?:"个人\r\n企业","\r\n"));
  899. if (is_numeric($id)) {
  900. return $array[$id];
  901. }else{
  902. return $array;
  903. }
  904. }
  905. }
  906. if (!function_exists('get_user')) {
  907. /**
  908. * 一般是根据UID获取用户的信息.
  909. * @param string $value UID值
  910. * @param string $type 一般都是UID,默认也是
  911. * @return array
  912. */
  913. function get_user($value='',$type='uid'){
  914. static $mod = null;
  915. $rarray = [];
  916. if($value && $type=='uid' && is_numeric($value)){
  917. static $user_array = [];
  918. $rarray = $user_array[$value];
  919. if($rarray===null){
  920. if(!$rarray=cache('user_'.$value)){
  921. $mod===null && $mod = model('common/user');
  922. $rarray = $mod->getById($value) ?: [];
  923. cache('user_'.$value,$rarray,3600*12);
  924. }
  925. $user_array[$value] = $rarray;
  926. }
  927. }elseif($value!==''){
  928. $mod===null && $mod = model('common/user');
  929. $rarray = $mod->get_info($value,$type);
  930. }
  931. return $rarray;
  932. }
  933. }
  934. if (!function_exists('get_user_name')) {
  935. /**
  936. * 获取用户帐号或昵称
  937. * @param number $uid
  938. * @return unknown|mixed
  939. */
  940. function get_user_name($uid=0)
  941. {
  942. $info = get_user($uid);
  943. if( !empty($info) ){
  944. return config('webdb.show_nickname') ? $info['nickname'] : $info['username'];
  945. }
  946. }
  947. }
  948. if (!function_exists('get_user_icon')) {
  949. /**
  950. * 获取用户头像
  951. * @param unknown $value
  952. * @return string|void|string
  953. */
  954. function get_user_icon($value)
  955. {
  956. static $domain = null;
  957. if($domain === null){
  958. $domain = request()->domain() ;
  959. }
  960. $info = get_user($value);
  961. if(empty($info) || empty($info['icon'])){
  962. return $domain.'/public/static/images/nobody.gif';
  963. }
  964. return tempdir($info['icon']);
  965. }
  966. }
  967. if (!function_exists('get_user_money')) {
  968. /**
  969. * 获取用户虚拟币
  970. * @param number $type 虚拟币类型
  971. * @param number $uid 用户的UID
  972. * @return number
  973. */
  974. function get_user_money($type=0,$uid=0)
  975. {
  976. if (!$uid) {
  977. $uid = login_user('uid');
  978. }
  979. if (!$uid) {
  980. return 0;
  981. }
  982. if ($type==0) {
  983. return get_user($uid)['money'];
  984. }elseif($type==-1){
  985. return get_user($uid)['rmb'];
  986. }
  987. static $array = null;
  988. if(empty($array[$uid])){
  989. $array[$uid] = \plugins\marketing\model\Money::where('uid',$uid)->column('type,money');
  990. }
  991. return intval($array[$uid][$type]);
  992. }
  993. }
  994. if(!function_exists('getArray')){
  995. /**
  996. * 把数据库取出的对象数据转成数组
  997. * @param unknown $row_list
  998. * @return array|NULL[]|unknown
  999. */
  1000. function getArray($row_list)
  1001. {
  1002. if (is_array($row_list)) {
  1003. if (empty($row_list)) return [];
  1004. if (is_object(current($row_list))) {
  1005. $items = [];
  1006. foreach ($row_list as $key => $value) {
  1007. $items[$key] = $value->toArray();
  1008. }
  1009. return $items;
  1010. }
  1011. return $row_list;
  1012. }
  1013. //if ($row_list->isEmpty()) return [];
  1014. if (is_object($row_list)) {
  1015. return $row_list->toArray();
  1016. }
  1017. return $row_list;
  1018. }
  1019. }
  1020. if(!function_exists('table_field')){
  1021. /**
  1022. * 数据表字段信息处理函数
  1023. * @param unknown $table 表名
  1024. * @param string $field 赋值的话,判断某个字段是否存在,留空的话,取所有字段
  1025. * @param string $add_pre 是否需要补全数据表前缀,true 需要再补全,false 不需要再补.
  1026. * @return boolean|unknown
  1027. */
  1028. function table_field($table,$field='',$add_pre=true){
  1029. $add_pre == true && $table = config('database.prefix') .$table;
  1030. $array = Db::getTableFields($table);
  1031. if(!empty($field)){
  1032. if(in_array($field,$array) ){
  1033. return true;
  1034. }else{
  1035. return false;
  1036. }
  1037. }else{ //返回所有字段
  1038. return $array;
  1039. }
  1040. //$result = Db::query("SHOW CREATE TABLE `{$table}`");
  1041. //preg_match_all("/`([^`]+)`/is", $result[0]['Create Table'],$array);
  1042. }
  1043. }
  1044. if(!function_exists('is_table')){
  1045. /**
  1046. * 判断数据表是否存在
  1047. * @param unknown $table 数据表名,可以不加区分符前缀
  1048. * @param string $add_pre 默认值true 自动补全前缀
  1049. * @return boolean
  1050. */
  1051. function is_table($table,$add_pre=true){
  1052. $add_pre == true && $table = config('database.prefix') .$table;
  1053. $result = Db::query("SHOW TABLES LIKE '{$table}'");
  1054. return empty($result) ? false : true;
  1055. }
  1056. }
  1057. if(!function_exists('copy_dir')){
  1058. /**
  1059. * 复制目录
  1060. * @param unknown $path 原目录名
  1061. * @param unknown $newp 新目录名
  1062. * @param string $isover 默认值为true 强制替换原来的文件
  1063. */
  1064. function copy_dir($path,$newp,$isover=true){
  1065. if(!is_dir($newp)){
  1066. if(!mkdir($newp) && !makepath($newp) ){
  1067. showerr($newp.'目录创建失败');
  1068. }
  1069. }
  1070. if (file_exists($path)){
  1071. if(is_file($path)){
  1072. if($isover==true || !is_file($newp)){
  1073. copy($path,$newp);
  1074. }
  1075. } else{
  1076. $handle = opendir($path);
  1077. while (($file = readdir($handle))!=false) {
  1078. if ( ($file!=".") && ($file!="..") ){
  1079. if (is_dir("$path/$file")){
  1080. copy_dir("$path/$file","$newp/$file",$isover);
  1081. } else{
  1082. if($isover==true || !is_file("$newp/$file")){
  1083. copy("$path/$file","$newp/$file");
  1084. }
  1085. }
  1086. }
  1087. }
  1088. closedir($handle);
  1089. }
  1090. }
  1091. }
  1092. }
  1093. if(!function_exists('sort_get_father')){
  1094. /**
  1095. * 模块中获取当前栏目的所有父ID
  1096. * @param number $id
  1097. * @param string $sys_type
  1098. * @return void|number
  1099. */
  1100. function sort_get_father($id=0,$sys_type=''){
  1101. if($id<1){
  1102. return ;
  1103. }
  1104. $array = sort_config($sys_type);
  1105. $pid = $array[$id]['pid'];
  1106. if($pid>0){
  1107. $farray[$pid] = $array[$pid]['name'];
  1108. $ar = sort_get_father($pid,$sys_type);
  1109. if(!empty($ar)){
  1110. $farray = $ar+$farray;
  1111. }
  1112. return $farray;
  1113. }
  1114. }
  1115. }
  1116. if(!function_exists('category_get_father')){
  1117. /**
  1118. * 模块中获取当前辅栏目的所有父ID
  1119. * @param number $id
  1120. * @param string $sys_type
  1121. * @return void|number
  1122. */
  1123. function category_get_father($id=0,$sys_type=''){
  1124. if($id<1){
  1125. return ;
  1126. }
  1127. $array = category_config($sys_type);
  1128. $pid = $array[$id]['pid'];
  1129. if($pid>0){
  1130. $farray[$pid] = $array[$pid]['name'];
  1131. $ar = category_get_father($pid,$sys_type);
  1132. if(!empty($ar)){
  1133. $farray = $ar+$farray;
  1134. }
  1135. return $farray;
  1136. }
  1137. }
  1138. }
  1139. if(!function_exists('get_sort')){
  1140. /**
  1141. * 获取具体某个频道下面的栏目相关信息
  1142. * @param number $id 为0时,取出所有栏目,大于0时,根据$type参数取值
  1143. * @param string $field 取某个字段对应的值,config或者是不存在的字段名,则取出所有配置参数
  1144. * @param string $type father时取出所有父级栏目,sons时取出所有下一级栏目,other时优先取子栏目,若无再取同级,若无再取父级兄弟栏目
  1145. * @param string $sys_type 指定频道模块
  1146. * @return void|number|number[]|array[]|unknown[]|number[]|unknown[]|array|unknown
  1147. */
  1148. function get_sort($id=0,$field='name',$type='',$sys_type=''){
  1149. $array = sort_config($sys_type);
  1150. $_type = $type==='' ? $field : $type; //兼容处理
  1151. if($id>0){
  1152. if($_type=='father'){ //所有父栏目,也包括自身,一般用在面包屑导航
  1153. $farray = sort_get_father($id,$sys_type);
  1154. $self_array = [$id=>$array[$id]['name']];
  1155. return empty($farray) ? $self_array : $farray+$self_array;
  1156. }elseif($_type=='sons'){ //所有下一级级栏目,也包括自身,一般用在查询数据库
  1157. $s_array = [
  1158. $id => $field=='name' ? $array[$id]['name'] : $id,
  1159. ];
  1160. $_pid = 0;
  1161. $fpid = []; //把所有父分类都加入到容器
  1162. foreach($array AS $key=>$rs){
  1163. if(!$rs['pid'])continue;
  1164. //$rs['pid']==$id 仅仅第一层直属下级, $rs['pid']==$_pid 下级的下级
  1165. if($rs['pid']==$id||$rs['pid']==$_pid||in_array($rs['pid'], $fpid)){
  1166. $s_array[$key] = $field=='name' ? $array[$key]['name'] : $key;
  1167. if(!in_array($rs['pid'], $fpid)){ //把所有父分类都加入容器
  1168. $fpid[] = $rs['pid'];
  1169. }
  1170. $_pid = $key;
  1171. }
  1172. }
  1173. return $s_array;
  1174. }elseif($_type=='brother'){ //取同级栏目
  1175. $s_array = [];
  1176. $_pid = $array[$id]['pid'];
  1177. foreach($array AS $key=>$rs){
  1178. if($rs['pid']==$_pid){
  1179. $s_array[$key]=$rs['name'];
  1180. }
  1181. }
  1182. return $s_array;
  1183. }elseif($_type=='other'){ //取父级兄弟栏目及本级兄弟栏目及子栏目,一般用在栏目页面方便展示布局
  1184. $m_array = [];
  1185. $pid = $array[$id]['pid'];
  1186. $fpid = $pid ? $array[$pid]['pid'] : null;
  1187. $_pid = null;
  1188. foreach($array AS $key=>$rs){
  1189. if($fpid!==null&&$rs['pid']==$fpid){ //父级栏目
  1190. $m_array[$key] = $rs['name'];
  1191. }elseif($rs['pid']==$pid){ //同级栏目
  1192. $m_array[$key] = $rs['name'];
  1193. }elseif ($rs['pid']==$_pid){ //子栏目
  1194. $m_array[$key] = $rs['name'];
  1195. }
  1196. if($key==$id){
  1197. $_pid = $id;
  1198. }
  1199. }
  1200. return $m_array;
  1201. }elseif($_type=='config'){
  1202. return $array[$id];
  1203. }elseif(isset($array[$id][$_type])){
  1204. return $array[$id][$_type];
  1205. }else{
  1206. return $array[$id];
  1207. }
  1208. }elseif($_type=='other' && $array){ //fid不存在的话,就只取一级栏目
  1209. $farray = [];
  1210. foreach($array AS $key=>$rs){
  1211. if($rs['pid']==0){
  1212. $farray[$key]=$rs['name'];
  1213. }
  1214. }
  1215. return $farray;
  1216. }elseif ($_type=='all'){
  1217. $farray = [];
  1218. foreach($array AS $key=>$rs){
  1219. $farray[$key]=$rs['name'];
  1220. }
  1221. return $farray;
  1222. }
  1223. return $array;
  1224. }
  1225. }
  1226. //模块的栏目配置参数
  1227. if(!function_exists('sort_config')){
  1228. /**
  1229. * 获取模块里边的栏目配置参数
  1230. * @param string $sys_type 可以指定其他频道的目录名
  1231. * @param unknown $pid 可以指定只调取哪些父栏目的下的子栏目数据
  1232. * @param string $field_name 默认指定取什么字段,设置true的话,就可以获取所有字段
  1233. * @return array|unknown
  1234. */
  1235. function sort_config($sys_type='',$pid=null,$field_name='name'){
  1236. if(empty($sys_type)){
  1237. $sys_type=config('system_dirname');
  1238. }
  1239. if(empty($sys_type)){
  1240. return [];
  1241. }
  1242. static $sort_array = [];
  1243. $array = $sort_array[$sys_type];
  1244. if(empty($array)){
  1245. $array = cache('sort_config_'.$sys_type);
  1246. if (empty($array)) {
  1247. if (!modules_config($sys_type)&&!plugins_config($sys_type)) {
  1248. return [];
  1249. }elseif (!is_file(APP_PATH.$sys_type.'/model/Sort.php')&&!is_file(PLUGINS_PATH.$sys_type.'/model/Sort.php')) {
  1250. return [];
  1251. }
  1252. //$array = model($sys_type.'/sort')->getTreeList();
  1253. $array = get_model_class($sys_type,'sort')->getTreeList();
  1254. cache('sort_config_'.$sys_type,$array);
  1255. }
  1256. $sort_array[$sys_type] = $array;
  1257. }
  1258. if(ENTRANCE!=='admin'){
  1259. foreach($array AS $id=>$rs){
  1260. if($rs['allow_viewtitle']!='' && trim($rs['allow_viewtitle'],',')!=''){ //没有权限查看标题,也即隐藏栏目
  1261. if (!login_user('groupid')||!in_array(login_user('groupid'), explode(',',trim($rs['allow_viewtitle'],',')))) {
  1262. unset($array[$id]);
  1263. }
  1264. }
  1265. }
  1266. }
  1267. if($pid!==null){ //取子栏目
  1268. $_array = [];
  1269. foreach ($array AS $id=>$rs){
  1270. if($rs['pid']==$pid){
  1271. $_array[$id] = (is_string($field_name)&&$field_name&&isset($rs[$field_name]))?$rs[$field_name]:$rs;
  1272. }
  1273. }
  1274. return $_array;
  1275. }else{
  1276. return $array;
  1277. }
  1278. }
  1279. }
  1280. if(!function_exists('get_category')){
  1281. /**
  1282. * 获取具体某个频道下面的辅栏目相关信息
  1283. * @param number $id 为0时,取出所有栏目,大于0时,根据$type参数取值
  1284. * @param string $field 取某个字段对应的值,config或者是不存在的字段名,则取出所有配置参数
  1285. * @param string $type father时取出所有父级栏目,sons时取出所有下一级栏目,other时优先取子栏目,若无再取同级,若无再取父级兄弟栏目
  1286. * @param string $sys_type 指定频道模块
  1287. * @return void|number|number[]|array[]|unknown[]|number[]|unknown[]|array|unknown
  1288. */
  1289. function get_category($id=0,$field='name',$type='',$sys_type=''){
  1290. $array = category_config($sys_type);
  1291. $_type = $type==='' ? $field : $type; //兼容处理
  1292. if($id>0){
  1293. if($_type=='father'){ //所有父栏目,也包括自身,一般用在面包屑导航
  1294. $farray = category_get_father($id,$sys_type);
  1295. $self_array = [$id=>$array[$id]['name']];
  1296. return empty($farray) ? $self_array : $farray+$self_array;
  1297. }elseif($_type=='sons'){ //所有下一级级栏目,也包括自身,一般用在查询数据库
  1298. $s_array = [
  1299. $id => $field=='name' ? $array[$id]['name'] : $id,
  1300. ];
  1301. $_pid = 0;
  1302. foreach($array AS $key=>$rs){
  1303. if(!$rs['pid'])continue;
  1304. if($rs['pid']==$id||$rs['pid']==$_pid){
  1305. $s_array[$key] = $field=='name' ? $array[$key]['name'] : $key;
  1306. $_pid = $key;
  1307. }
  1308. }
  1309. return $s_array;
  1310. }elseif($_type=='brother'){ //取同级栏目
  1311. $s_array = [];
  1312. $_pid = $array[$id]['pid'];
  1313. foreach($array AS $key=>$rs){
  1314. if($rs['pid']==$_pid){
  1315. $s_array[$key]=$rs['name'];
  1316. }
  1317. }
  1318. return $s_array;
  1319. }elseif($_type=='other'){ //取父级兄弟栏目及本级兄弟栏目及子栏目,一般用在栏目页面方便展示布局
  1320. $m_array = [];
  1321. $pid = $array[$id]['pid'];
  1322. $fpid = $pid ? $array[$pid]['pid'] : null;
  1323. $_pid = null;
  1324. foreach($array AS $key=>$rs){
  1325. if($fpid!==null&&$rs['pid']==$fpid){ //父级栏目
  1326. $m_array[$key] = $rs['name'];
  1327. }elseif($rs['pid']==$pid){ //同级栏目
  1328. $m_array[$key] = $rs['name'];
  1329. }elseif ($rs['pid']==$_pid){ //子栏目
  1330. $m_array[$key] = $rs['name'];
  1331. }
  1332. if($key==$id){
  1333. $_pid = $id;
  1334. }
  1335. }
  1336. return $m_array;
  1337. }elseif($_type=='config'){
  1338. return $array[$id];
  1339. }elseif(isset($array[$id][$_type])){
  1340. return $array[$id][$_type];
  1341. }else{
  1342. return $array[$id];
  1343. }
  1344. }elseif($_type=='other' && $array){ //fid不存在的话,就只取一级栏目
  1345. $farray = [];
  1346. foreach($array AS $key=>$rs){
  1347. if($rs['pid']==0){
  1348. $farray[$key]=$rs['name'];
  1349. }
  1350. }
  1351. return $farray;
  1352. }elseif ($_type=='all'){
  1353. $farray = [];
  1354. foreach($array AS $key=>$rs){
  1355. $farray[$key]=$rs['name'];
  1356. }
  1357. return $farray;
  1358. }
  1359. return $array;
  1360. }
  1361. }
  1362. if(!function_exists('category_config')){
  1363. /**
  1364. * 获取模块里边的辅栏目配置参数
  1365. * @param string $sys_type 可以指定其他频道的目录名
  1366. * @param unknown $pid 可以指定只调取哪些父栏目的下的子栏目数据
  1367. * @return array|unknown
  1368. */
  1369. function category_config($sys_type='',$pid=null){
  1370. if(empty($sys_type)){
  1371. $sys_type=config('system_dirname');
  1372. }
  1373. if(empty($sys_type)){
  1374. return [];
  1375. }
  1376. static $sort_array = [];
  1377. $array = $sort_array[$sys_type];
  1378. if(empty($array)){
  1379. $array = cache('category_config_'.$sys_type);
  1380. if (empty($array)) {
  1381. $obj = get_model_class($sys_type,'category');
  1382. if ($obj===false) {
  1383. return [];
  1384. }
  1385. $array = $obj->getTreeList();
  1386. cache('category_config_'.$sys_type,$array);
  1387. }
  1388. $sort_array[$sys_type] = $array;
  1389. }
  1390. if($pid!==null){ //取子栏目
  1391. $_array = [];
  1392. foreach ($array AS $id=>$rs){
  1393. if($rs['pid']==$pid){
  1394. $_array[$id] = $rs['name'];
  1395. }
  1396. }
  1397. return $_array;
  1398. }else{
  1399. return $array;
  1400. }
  1401. }
  1402. }
  1403. if(!function_exists('modules_config')){
  1404. /**
  1405. * 获取系统安装的频道模块信息
  1406. * @param unknown $id 可以为频道ID也可以是频道目录名 为空的话,就是取出所有
  1407. * @param string $getcache 是否取缓存数据
  1408. * @return NULL|unknown|string|array|NULL[]|string|array|unknown|NULL[]
  1409. */
  1410. function modules_config($id=null , $getcache=true){
  1411. static $data = null;
  1412. $array = $getcache===true ? ($data?:cache('cache_modules_config')) : '';
  1413. if(empty($array)){
  1414. $result = Module::getList(['ifopen'=>1]);
  1415. foreach($result AS $rs){
  1416. $array[$rs['id']] = $rs;
  1417. }
  1418. cache('cache_modules_config',$array);
  1419. }
  1420. $data = $array;
  1421. if(is_numeric($id)){ //根据模块ID返回数组
  1422. return $array[$id];
  1423. }elseif($id!==null){ //根据模块目录名返回数组
  1424. foreach($array AS $rs){
  1425. if($rs['keywords']==$id){
  1426. return $rs;
  1427. }
  1428. }
  1429. return [];
  1430. }else{
  1431. return $array;
  1432. }
  1433. }
  1434. }
  1435. if(!function_exists('plugins_config')){
  1436. /**
  1437. * 获取插件配置参数,也即缓存数据,可以给赋值数字或关键字目录名,取相应频道的配置参数,为NULL取所有频道的配置参数
  1438. * @param unknown $id 可为数字或目录名关键字,也可为null 为NULL的话,取出所有
  1439. * @param string $getcache 默认是取缓存,设置为false不要缓存
  1440. * @return NULL|unknown|string|array|NULL[]|string|array|unknown|NULL[]
  1441. */
  1442. function plugins_config($id=null , $getcache=true){
  1443. static $data = null;
  1444. $array = $getcache===true ? ($data?:cache('cache_plugins_config')) : '';
  1445. if(empty($array)){
  1446. $result = Plugin::getList(['ifopen'=>1]);
  1447. foreach($result AS $rs){
  1448. $array[$rs['id']] = $rs;
  1449. }
  1450. cache('cache_plugins_config',$array);
  1451. }
  1452. $data = $array;
  1453. if(is_numeric($id)){ //根据插件ID返回数组
  1454. return $array[$id];
  1455. }elseif($id!==null){ //根据插件目录名返回数组
  1456. foreach($array AS $rs){
  1457. if($rs['keywords']==$id){
  1458. return $rs;
  1459. }
  1460. }
  1461. return [];
  1462. }else{
  1463. return $array;
  1464. }
  1465. }
  1466. }
  1467. if(!function_exists('get_ip')){
  1468. /**
  1469. *获取用户当前的IP地址
  1470. */
  1471. function get_ip(){
  1472. static $onlineip = NULL;
  1473. if ($onlineip !== NULL) return $onlineip;
  1474. if($_SERVER['HTTP_CLIENT_IP']){
  1475. $onlineip=$_SERVER['HTTP_CLIENT_IP'];
  1476. }elseif($_SERVER['HTTP_X_FORWARDED_FOR']){
  1477. $onlineip=$_SERVER['HTTP_X_FORWARDED_FOR']; //HTTP_X_REAL_FORWARDED_FOR
  1478. }else{
  1479. $onlineip=$_SERVER['REMOTE_ADDR'];
  1480. }
  1481. $onlineip = preg_replace("/^([\d\.]+).*/", "\\1", filtrate($onlineip));
  1482. preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipArray);
  1483. $onlineip = $onlineipArray[0] ? $onlineipArray[0] : '0.0.0.0';
  1484. return $onlineip;
  1485. }
  1486. }
  1487. if(!function_exists('ipfrom')){
  1488. /**
  1489. * 根据IP获取来源地
  1490. * 示例Array
  1491. (
  1492. [0] => 广东省茂名市
  1493. [city] => 茂名市
  1494. [province] => 广东省
  1495. )
  1496. * @param string $ip
  1497. * @return string|unknown[]|mixed[]|string[]
  1498. */
  1499. function ipfrom($ip=''){
  1500. if(!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {
  1501. return '';
  1502. }elseif(preg_match("/(127\.0\.0\.1|192\.168\.\d{1,3}\.\d{1,3})/", $ip)){
  1503. return '局域网';
  1504. }
  1505. $str = file_get_contents("http://api.map.baidu.com/location/ip?ak=MGdbmO6pP5Eg1hiPhpYB0IVd&ip=".$ip."&coor=bd09ll");
  1506. $array = json_decode($str ,true);
  1507. $city = $array['content'] ? $array['content']['address_detail']['city'] : '';
  1508. if (empty($city)) {
  1509. return '未知地址';
  1510. }
  1511. return [
  1512. 0=>$array['content']['address'],
  1513. 'city'=>$city,
  1514. 'province'=>$array['content']['address_detail']['province'],
  1515. ];
  1516. }
  1517. }
  1518. if(!function_exists('mymd5')){
  1519. /**
  1520. * 站点私有的加密与解密函数.
  1521. * @param unknown $string
  1522. * @param string $action 默认EN加密,DE解密
  1523. * @param string $rand 自定义加密混淆码
  1524. * @return string|mixed|string|NULL|boolean
  1525. */
  1526. function mymd5($string,$action="EN",$rand=''){ //字符串加密和解密
  1527. if($action=="DE"){//处理+号在URL传递过程中会异常
  1528. $string = str_replace('QIBOADD','+',$string);
  1529. $string = str_replace('QIBOEDD','=',$string);
  1530. }
  1531. $secret_string = ( $rand ?: (config('webdb.mymd5').md5_file(APP_PATH.'database.php').ROOT_PATH) ).'5*j,.^&;?.%#@!'; //绝密字符串,可以任意设定
  1532. if(!is_string($string)){
  1533. $string=strval($string);
  1534. }
  1535. if($string==="") return "";
  1536. if($action=="EN") $md5code=substr(md5($string),8,10);
  1537. else{
  1538. $md5code=substr($string,-10);
  1539. $string=substr($string,0,strlen($string)-10);
  1540. }
  1541. //$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string);
  1542. $key = md5($md5code.$secret_string);
  1543. $string = ($action=="EN"?$string:base64_decode($string));
  1544. $len = strlen($key);
  1545. $code = "";
  1546. for($i=0; $i<strlen($string); $i++){
  1547. $k = $i%$len;
  1548. $code .= $string[$i]^$key[$k];
  1549. }
  1550. $code = ($action == "DE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code).$md5code);
  1551. if($action=="EN"){//处理+号在URL传递过程中会异常
  1552. $code = str_replace('+','QIBOADD',$code);
  1553. $code = str_replace('=','QIBOEDD',$code);
  1554. }
  1555. return $code;
  1556. }
  1557. }
  1558. if(!function_exists('rands')){
  1559. /**
  1560. * 生成随机数, 不能超过32位
  1561. * @param unknown $length
  1562. * @return string
  1563. */
  1564. function rands($length) {
  1565. $salt = substr(hash('sha256', microtime(true) . mt_rand()), 0, 64);
  1566. $hex = substr(hash('sha256', $salt), 0, 32);
  1567. $time_low = substr($hex, 0, 8);
  1568. $time_mid = substr($hex, 8, 4);
  1569. $time_hi_and_version = base_convert(substr($hex, 12, 4), 16, 10);
  1570. $time_hi_and_version &= 0x0FFF;
  1571. $time_hi_and_version |= (4 << 12);
  1572. $clock_seq_hi_and_reserved = base_convert(substr($hex, 16, 4), 16, 10);
  1573. $clock_seq_hi_and_reserved &= 0x3F;
  1574. $clock_seq_hi_and_reserved |= 0x80;
  1575. $clock_seq_low = substr($hex, 20, 2);
  1576. $nodes = substr($hex, 20);
  1577. $hash = sprintf('%s%s%04x%02x%02x%s',$time_low, $time_mid,$time_hi_and_version, $clock_seq_hi_and_reserved,$clock_seq_low, $nodes);
  1578. return substr($hash,0,$length);
  1579. }
  1580. }
  1581. if(!function_exists('filtrate')){
  1582. /**
  1583. * 过滤一些不太安全的字符
  1584. * @param unknown $msg
  1585. * @return mixed
  1586. */
  1587. function filtrate($msg,$type=''){
  1588. if ($type=='script') {
  1589. if (is_array($msg)) {
  1590. foreach ($msg as $k => $v) {
  1591. $msg[$k] = filtrate($v,$type);
  1592. }
  1593. return $msg;
  1594. } else {
  1595. $parten = array(
  1596. "/(javascript:)?on(click|load|key|mouse|error|abort|move|unload|change|dblclick|move|reset|resize|submit)/i",
  1597. "/<script(.*?)>(.*?)<\/script>/is",
  1598. "/<iframe(.*?)>(.*?)<\/iframe>/is",
  1599. "/<object.+<\/object>/isU"
  1600. );
  1601. $msg = preg_replace($parten, array("\\1on \\2", "", "", ""), $msg, -1, $count);
  1602. if ($count > 0) {
  1603. $msg = filtrate($msg,$type);
  1604. }
  1605. return $msg;
  1606. }
  1607. }else{
  1608. //$msg = str_replace('&','&amp;',$msg);
  1609. //$msg = str_replace(' ','&nbsp;',$msg);
  1610. $msg = str_replace('"','&quot;',$msg);
  1611. $msg = str_replace("'",'&#39;',$msg);
  1612. $msg = str_replace("<","&lt;",$msg);
  1613. $msg = str_replace(">","&gt;",$msg);
  1614. //$msg = str_replace("\t"," &nbsp; &nbsp;",$msg);
  1615. //$msg = str_replace("\r","",$msg);
  1616. //$msg = str_replace(" "," &nbsp; ",$msg);
  1617. return $msg;
  1618. }
  1619. }
  1620. }
  1621. if(!function_exists('read_file')){
  1622. /**
  1623. * 读文件,相当于file_get_contents函数
  1624. * @param unknown $filename
  1625. * @param string $method
  1626. * @return unknown
  1627. */
  1628. function read_file($filename,$method="rb"){
  1629. if($handle=@fopen($filename,$method)){
  1630. @flock($handle,LOCK_SH);
  1631. $filedata=@fread($handle,@filesize($filename));
  1632. @fclose($handle);
  1633. }
  1634. return $filedata;
  1635. }
  1636. }
  1637. if(!function_exists('write_file')){
  1638. /***
  1639. * 把内容写入文件
  1640. * @param unknown $filename 文件名
  1641. * @param unknown $data 内容
  1642. * @param string $method 默认不追加写入,要追加写入,可以改为 'a'
  1643. * @param number $iflock 锁定文件不能同时多个人同时写入
  1644. * @return number
  1645. */
  1646. function write_file($filename,$data,$method="rb+",$iflock=1){
  1647. if ($method=='a'||$method=='a+') {
  1648. file_put_contents($filename, $data,FILE_APPEND );
  1649. }else{
  1650. file_put_contents($filename, $data);
  1651. }
  1652. // @touch($filename);
  1653. // $handle=@fopen($filename,$method);
  1654. // if(!$handle){
  1655. // return "此文件不可写:$filename";
  1656. // }
  1657. // if($iflock){
  1658. // @flock($handle,LOCK_EX);
  1659. // }
  1660. // @fputs($handle,$data);
  1661. // if($method=="rb+") @ftruncate($handle,strlen($data));
  1662. // @fclose($handle);
  1663. // @chmod($filename,0777);
  1664. // if( is_writable($filename) ){
  1665. // return true;
  1666. // }else{
  1667. // return false;
  1668. // }
  1669. }
  1670. }
  1671. if(!function_exists('query')){
  1672. /**
  1673. * 数据库操作方法,可以执行原生数据库语句
  1674. * 也可以直接使用TP的数据库方法,比如 query('memberdata')->where('uid',1)->value('username');
  1675. * @param unknown $sql 可以是数据库语句,也可以是数据库表名,不带前缀
  1676. * @param array|string $array 可以是数组也可以是URL字符串
  1677. * @param number $cache_time 缓存时间 必须第二项设置了才生效
  1678. * @return mixed|\think\cache\Driver|boolean|unknown|string|number
  1679. */
  1680. function query($sql,$array=[],$cache_time=0){
  1681. if(preg_match('/^([\w]+)$/i', $sql)){
  1682. if ($cache_time>0) {
  1683. $key = md5($sql.http_build_query($array));
  1684. $_array = cache($key);
  1685. if ($_array) {
  1686. return $_array;
  1687. }
  1688. }
  1689. if (empty($array)) { //只想使用DB类的情况
  1690. return Db::name($sql);
  1691. }elseif(!is_array($array)){
  1692. $str = $array;
  1693. $array = [];
  1694. //若有where=条件的话,必须放在最后面
  1695. $str = preg_replace_callback("/&where=(.*?)$/is", function($array){
  1696. return '&where='.urlencode($array[1]);
  1697. }, $str);
  1698. parse_str($str, $array);
  1699. $array['where'] = $array['where'] ? \app\common\fun\Label::where($array['where']) : [];
  1700. if (isset($array['where']['uid']) && ($array['where']['uid']==0||$array['where']['uid']=='my')) {
  1701. $array['where']['uid'] = login_user('uid');
  1702. }
  1703. //print_r($array);exit;
  1704. }
  1705. $result = false;
  1706. $array['where'] || $array['where']=[];
  1707. $obj = Db::name($sql)->where($array['where']);
  1708. $array['alias'] && $obj->alias($array['alias']);
  1709. $array['join'] && $obj->join($array['join']);
  1710. $array['union'] && $obj->union($array['union']);
  1711. $array['field'] && $obj->field($array['field']);
  1712. $array['having'] && $obj->having($array['having']);
  1713. $array['group'] && $obj->group($array['group']);
  1714. $array['order'] && $obj->order($array['order'],preg_match('/( asc| desc)$/i', $array['order'])?null:'desc');
  1715. $array['order'] || $obj->orderRaw("1 desc");
  1716. $array['limit'] && $obj->limit($array['limit']);
  1717. $array['rows'] && $obj->limit($array['rows']);
  1718. $array['page'] && $obj->page($array['page']);
  1719. $array['value'] && $result = $obj->value($array['value']);
  1720. $array['column'] && $result = $obj->column($array['column']);
  1721. $array['count'] && $result = $obj->count($array['count']);
  1722. $array['max'] && $result = $obj->max($array['max']);
  1723. $array['min'] && $result = $obj->min($array['min']);
  1724. $array['sum'] && $result = $obj->sum($array['sum']);
  1725. $array['avg'] && $result = $obj->avg($array['avg']); //获取平均值
  1726. if($array['type']=='one'){
  1727. $result = getArray($obj->find());
  1728. }elseif($result===false){
  1729. $result = getArray($obj->select());
  1730. }
  1731. if ($cache_time>0) {
  1732. cache($key,$result);
  1733. }
  1734. return $result;
  1735. }else{
  1736. $table_pre = config('database.prefix');
  1737. $sql = str_replace([' qb_',' `qb_'],[" {$table_pre}"," `{$table_pre}"],$sql);
  1738. if( preg_match('/^(select|show) /i',trim($sql)) ){
  1739. try {
  1740. $result = Db::query($sql);
  1741. } catch(\Exception $e) {
  1742. return 'SQL执行失败,请检查语句是否正确<pre>'.$sql."\n\n".$e.'</pre>';
  1743. }
  1744. }else{
  1745. try {
  1746. $result = Db::execute($sql);
  1747. } catch(\Exception $e) {
  1748. return 'SQL执行失败,请检查语句是否正确<pre>'.$sql."\n\n".$e.'</pre>';
  1749. }
  1750. }
  1751. return $result;
  1752. }
  1753. }
  1754. }
  1755. if(!function_exists('delete_attachment')){
  1756. function delete_attachment($a='',$b=''){
  1757. }
  1758. }
  1759. if(!function_exists('delete_dir')){
  1760. /**
  1761. * 删除整个目录
  1762. * @param unknown $path
  1763. * @return string
  1764. */
  1765. function delete_dir($path){
  1766. if (file_exists($path)){
  1767. if(is_file($path)){
  1768. if( !@unlink($path) ){
  1769. $show.="$path,";
  1770. }
  1771. } else{
  1772. $handle = opendir($path);
  1773. while (($file = readdir($handle))!='') {
  1774. if (($file!=".") && ($file!="..") && ($file!="")){
  1775. if (is_dir("$path/$file")){
  1776. $show.=delete_dir("$path/$file");
  1777. } else{
  1778. if( !@unlink("$path/$file") ){
  1779. $show.="$path/$file,";
  1780. }
  1781. }
  1782. }
  1783. }
  1784. closedir($handle);
  1785. if(!@rmdir($path)){
  1786. $show.="$path,";
  1787. }
  1788. }
  1789. }
  1790. return $show;
  1791. }
  1792. }
  1793. if(!function_exists('get_word')){
  1794. /**
  1795. * 截取多少个字符
  1796. * @param unknown $string
  1797. * @param unknown $length
  1798. * @param number $more
  1799. * @param string $dot
  1800. * @return unknown|string
  1801. */
  1802. function get_word($string, $length, $more=1 ,$dot = '..') {
  1803. $more || $dot='';
  1804. if(strlen($string) <= $length) {
  1805. return $string;
  1806. }
  1807. $pre = chr(1);
  1808. $end = chr(1);
  1809. $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), $string);
  1810. $strcut = '';
  1811. if( 1 ) {
  1812. $n = $tn = $noc = 0;
  1813. while($n < strlen($string)) {
  1814. $t = ord($string[$n]);
  1815. if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
  1816. $tn = 1; $n++; $noc++;
  1817. } elseif(194 <= $t && $t <= 223) {
  1818. $tn = 2; $n += 2; $noc += 2;
  1819. } elseif(224 <= $t && $t <= 239) {
  1820. $tn = 3; $n += 3; $noc += 2;
  1821. } elseif(240 <= $t && $t <= 247) {
  1822. $tn = 4; $n += 4; $noc += 2;
  1823. } elseif(248 <= $t && $t <= 251) {
  1824. $tn = 5; $n += 5; $noc += 2;
  1825. } elseif($t == 252 || $t == 253) {
  1826. $tn = 6; $n += 6; $noc += 2;
  1827. } else {
  1828. $n++;
  1829. }
  1830. if($noc >= $length) {
  1831. break;
  1832. }
  1833. }
  1834. if($noc > $length) {
  1835. $n -= $tn;
  1836. }
  1837. $strcut = substr($string, 0, $n);
  1838. } else {
  1839. $_length = $length - 1;
  1840. for($i = 0; $i < $length; $i++) {
  1841. if(ord($string[$i]) <= 127) {
  1842. $strcut .= $string[$i];
  1843. } else if($i < $_length) {
  1844. $strcut .= $string[$i].$string[++$i];
  1845. }
  1846. }
  1847. }
  1848. $strcut = str_replace(array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
  1849. $pos = strrpos($strcut, chr(1));
  1850. if($pos !== false) {
  1851. $strcut = substr($strcut,0,$pos);
  1852. }
  1853. return $strcut.$dot;
  1854. }
  1855. }
  1856. if(!function_exists('tempdir')){
  1857. /**
  1858. * 取得文件的显示路径
  1859. * @param string $path
  1860. * @return void|string
  1861. */
  1862. function tempdir($path=''){
  1863. if($path==''){
  1864. return ;
  1865. }
  1866. if (strstr($path,'"')) {
  1867. $array = json_decode($path,true);
  1868. $path = $array[0]['picurl']?:$path;
  1869. }elseif(strstr($path,',')){
  1870. $array = explode(',',$path);
  1871. $path = $array[0]?:$path;
  1872. }
  1873. static $domain = null;
  1874. if($domain === null){
  1875. if ( config('webdb') && config('webdb.www_url')!='' ) {
  1876. $domain = config('webdb.www_url');
  1877. }elseif(!config('webdb')){ //比如app\common\behavior\Init获取缓存时使用;
  1878. $domain = Db::name('config')->where('c_key','www_url')->where('type','1')->value('c_value');
  1879. }
  1880. $domain || $domain = request()->domain();
  1881. }
  1882. if(!preg_match('/:\/\//', $path)&&!preg_match('/^\/public\//', $path)){
  1883. $path = $domain . PUBLIC_URL . $path;
  1884. }elseif(strpos($path, 'http://thirdwx') !== false){
  1885. $path = str_replace("http:","https:",$path);
  1886. }elseif(strpos($path, 'http://thirdqq') !== false){
  1887. $path = str_replace("http:","https:",$path);
  1888. }elseif( preg_match('/^\/public\//', $path) ){
  1889. $path = $domain .$path;
  1890. }
  1891. return $path;
  1892. }
  1893. }
  1894. if (!function_exists('get_cookie')) {
  1895. /**
  1896. * 取得COOKIE的值
  1897. * @param unknown $name
  1898. * @return mixed|void|boolean|NULL|unknown[]
  1899. */
  1900. function get_cookie($name=''){
  1901. config('webdb.cookiePre') && $name = config('webdb.cookiePre') . $name;
  1902. return cookie($name);
  1903. //return $_COOKIE[$webdb['cookiePre'].$name];
  1904. }
  1905. }
  1906. if (!function_exists('set_cookie')) {
  1907. /**
  1908. * 设置COOKIE
  1909. * @param string $name 变量名
  1910. * @param string $value COOKIE值,设置为null或为空的时候,就清空COOKIE
  1911. * @param unknown $option 参数,可以是数字就是有效时间,也可以设置为数组,比如 ['expire' => 3600,'path'=>'/','domain'=>'']
  1912. */
  1913. function set_cookie($name='',$value='',$option=null){
  1914. $value==='' && $value=null;
  1915. if (is_numeric($option)) {
  1916. $option = ['expire' => $option];
  1917. } elseif (is_string($option)) {
  1918. parse_str($option, $option);
  1919. }
  1920. if(empty($option['domain'])){
  1921. config('webdb.cookieDomain') && $option['domain'] = config('webdb.cookieDomain');
  1922. }
  1923. config('webdb.cookiePre') && $name = config('webdb.cookiePre') . $name;
  1924. preg_match('/ Chrome\/([\d]+)\./i', $_SERVER['HTTP_USER_AGENT'],$array);
  1925. if(!$array[1] || $array[1]<=63){ //小程序中只能用setcookie 用header有时会清除不掉 另外Chrome 63版本以上才可以
  1926. cookie($name,$value,$option);
  1927. return ;
  1928. }
  1929. //setCookie($webdb['cookiePre'].$name,$value,$cktime,$path,$domain,$S);
  1930. if($value===null){
  1931. $value = '';
  1932. $option['expire'] = -10000;
  1933. }
  1934. $time = $option['expire'];
  1935. $path = $option['path']?:'/';
  1936. $host = $option['domain'];
  1937. $cookie = $name.'='.urlencode($value);
  1938. if($time) $cookie .= "; expires=".gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT",$time + time() )."";
  1939. if($path) $cookie .= "; path={$path}";
  1940. if($host) $cookie .= "; domain={$host}";
  1941. $cookie .= ";HttpOnly";
  1942. if(strstr(request()->domain(),'https://')){
  1943. $cookie .= "; SameSite=None";
  1944. $cookie .= "; Secure";
  1945. }
  1946. header("Set-Cookie: {$cookie}",false);
  1947. }
  1948. }
  1949. if (!function_exists('makeTemplate')) {
  1950. /**
  1951. * 模板路径处理函数
  1952. * member@xxx index@xxx admin@xxx 如果是跨前后台的话,将强制使用默认的default目录的文件
  1953. * @param unknown $template
  1954. * @param string $check 是否检查文件是否存在
  1955. * @return string
  1956. */
  1957. function makeTemplate($template,$check=true)
  1958. {
  1959. if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
  1960. $detail = Request::instance()->dispatch();
  1961. if($detail['type']=='method'){
  1962. $_method = $detail['method'][1];
  1963. list(,,$_module,,$_controller) = explode('\\',$detail['method'][0]);
  1964. }else{
  1965. $_module = $detail['module'][0]?:'index'; //模块,针对主页短路由的特别处理
  1966. $_controller = $detail['module'][1]?:'index'; //控制器,针对主页短路由的特别处理
  1967. $_method = $detail['module'][2]?:'index'; //方法,针对主页短路由的特别处理
  1968. }
  1969. if (strpos($template, '@')) {
  1970. list($module, $template) = explode('@', $template);
  1971. }
  1972. if (0 !== strpos($template, '/')) {
  1973. $template = str_replace(['/', ':'], config('template.view_depr'), $template);
  1974. } else {
  1975. $template = str_replace(['/', ':'], config('template.view_depr'), substr($template, 1));
  1976. }
  1977. if (config('template.view_base')) {
  1978. if( in_array($module,['index','member','admin']) ){ //member@xxx index@xxx admin@xxx 特殊处理
  1979. if( ENTRANCE != $module){ //重要提醒*************若跨前后台,只调取默认default风格的文件
  1980. $path = config('template.view_base') .'../../'.$module.'_style/default/'.$module.'/';
  1981. }else{
  1982. //$path = config('template.view_base') .'../../'.$module.'_style/'.config('template.'.$module.'_style').'/'.$module.'/';
  1983. $path = config('template.view_base') . $module . '/';
  1984. }
  1985. }elseif($_controller=='plugin'&&$_method=='execute'){
  1986. $_module=input('param.plugin_action');
  1987. $__module = isset($module) ? $module : input('param.plugin_name');
  1988. $path = config('template.view_base') .'plugins/'. $__module.'/'.input('param.plugin_controller').'/';
  1989. }else{
  1990. $__module = isset($module) ? $module : $_module;
  1991. $path = config('template.view_base') . ($__module ? $__module . DS : '');
  1992. }
  1993. } else {
  1994. if($module=='index'){
  1995. $path = APP_PATH . $module . DS . 'view' . DS . config('template.index_style') . DS;
  1996. }elseif($module=='member'){
  1997. $path = APP_PATH . $module . DS . 'view' . DS . config('template.member_style') . DS;
  1998. }elseif($module=='admin'){
  1999. $path = APP_PATH . $module . DS . 'view' . DS;
  2000. }else{
  2001. $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS . ENTRANCE . DS . config('template.index_style') . DS : config('template.view_path');
  2002. }
  2003. }
  2004. //if (!strpos($template, '/')&&!$module) {
  2005. if (!$module) {
  2006. if($_controller=='plugin'&&$_method=='execute'){
  2007. if (config('template.view_base')) {
  2008. }else{
  2009. $_method = input('param.plugin_action');
  2010. $path = PLUGINS_PATH . input('param.plugin_name') . DS . 'view' . DS . ENTRANCE . DS;
  2011. if(ENTRANCE === 'index'){
  2012. $path .= config('template.index_style') . DS;
  2013. }elseif(ENTRANCE === 'member'){
  2014. $path .= config('template.member_style') . DS;
  2015. }
  2016. $path .= input('param.plugin_controller') . DS;
  2017. }
  2018. }else{
  2019. $path.=$_controller.DS;
  2020. }
  2021. if(empty($template)){
  2022. $path.=$_method;
  2023. }
  2024. }
  2025. $template = ($path . $template . '.' . ltrim(config('template.view_suffix'), '.'));
  2026. }
  2027. $template = get_real_path($template);
  2028. //自适应模板判断开始
  2029. $array = pathinfo($template);
  2030. $name = $array['basename'];
  2031. $path = $array['dirname'].'/';
  2032. //偿试先查找是否有对应的wap_或pc_模板
  2033. if(!defined('USE_PC_TEMPLATE') && IN_WAP===true){ //没有声明强制使用PC模板的时候,如果WAP端,就取WAP模板
  2034. if(!preg_match('/^wap_/', $name)){
  2035. if(is_file($path.'wap_'.$name)){
  2036. return $path.'wap_'.$name;
  2037. }
  2038. }
  2039. }else{
  2040. if(!preg_match('/^pc_/', $name)){
  2041. if(is_file($path.'pc_'.$name)){
  2042. return $path.'pc_'.$name;
  2043. }
  2044. }
  2045. }
  2046. //自适应模板判断结束
  2047. if ($check!==true || is_file($template)) {
  2048. return $template;
  2049. }else{
  2050. //echo($template.'文件不存在!<br>');
  2051. }
  2052. }
  2053. }
  2054. if (!function_exists('getTemplate')) {
  2055. /**
  2056. * 取得模板的路径,同时也可以自动识别PC或WAP模板
  2057. * member@xxx index@xxx admin@xxx 如果是跨前后台的话,将强制使用默认的default目录的文件
  2058. * @param unknown $template 可以为空
  2059. * @return void|string
  2060. */
  2061. function getTemplate($template='' , $check=true)
  2062. {
  2063. $_template = $template;
  2064. $template = makeTemplate($template , $check);
  2065. if (empty($template)) {
  2066. if( config('template.view_base') ){
  2067. if( config('template.default_view_base') ){ //没有使用默认风格
  2068. $view_base = config('template.view_base');
  2069. $index_style = config('template.index_style');
  2070. $member_style = config('template.member_style');
  2071. $admin_style = config('template.admin_style');
  2072. config('template.view_base',config('template.default_view_base'));
  2073. config('template.index_style','default');
  2074. config('template.member_style','default');
  2075. config('template.admin_style','default');
  2076. $template = makeTemplate($_template,true);
  2077. config('template.view_base',$view_base);
  2078. config('template.index_style',$index_style);
  2079. config('template.member_style',$member_style);
  2080. config('template.admin_style',$admin_style);
  2081. }
  2082. }else{
  2083. if(ENTRANCE === 'index'){
  2084. if(config('template.default_view_path')!=''){ //寻找默认风格的模板 后台使用无效,不适用于后台
  2085. $view_path = config('template.view_path');
  2086. $style = config('template.index_style');
  2087. $member_style = config('template.member_style');
  2088. config('template.view_path',config('template.default_view_path'));
  2089. config('template.index_style','default');
  2090. config('template.member_style','default');
  2091. $template = makeTemplate($_template,true);
  2092. config('template.view_path',$view_path);
  2093. config('template.index_style',$style);
  2094. config('template.member_style',$member_style);
  2095. }
  2096. }elseif(ENTRANCE === 'member'){
  2097. if(config('template.member_style')!='default'){ //寻找默认风格的模板 后台使用无效,不适用于后台
  2098. $view_path = config('template.view_path');
  2099. $style = config('template.index_style');
  2100. $member_style = config('template.member_style');
  2101. config('template.view_path',config('template.default_view_path'));
  2102. config('template.index_style','default');
  2103. config('template.member_style','default');
  2104. $template = makeTemplate($_template,true);
  2105. config('template.view_path',$view_path);
  2106. config('template.index_style',$style);
  2107. config('template.member_style',$member_style);
  2108. }
  2109. }
  2110. }
  2111. if(empty($template)){
  2112. return ;
  2113. }
  2114. }
  2115. // $array = pathinfo($template);
  2116. // $name = $array['basename']; //basename($template);
  2117. // $path = $array['dirname'].'/'; //dirname($template);
  2118. // if(!defined('USE_PC_TEMPLATE') && IN_WAP===true){ //没有声明强制使用PC模板的时候,如果WAP端,就取WAP模板
  2119. // if(!preg_match('/^wap_/', $name)){
  2120. // if(is_file($path.'wap_'.$name)){
  2121. // return $path.'wap_'.$name;
  2122. // }
  2123. // }
  2124. // }else{
  2125. // if(!preg_match('/^pc_/', $name)){
  2126. // if(is_file($path.'pc_'.$name)){
  2127. // return $path.'pc_'.$name;
  2128. // }
  2129. // }
  2130. // }
  2131. return $template;
  2132. }
  2133. }
  2134. if (!function_exists('sockOpenUrl')) {
  2135. //通过sock方式访问远程数据.
  2136. function sockOpenUrl($url,$method='GET',$postValue='',$Referer='Y'){
  2137. if($Referer=='Y'){
  2138. $Referer=$url;
  2139. }
  2140. $method = strtoupper($method);
  2141. if(!$url){
  2142. return '';
  2143. }elseif(!preg_match("/^http/",$url)){
  2144. $url="http://$url";
  2145. }
  2146. $urldb=parse_url($url);
  2147. $port=$urldb['port']?$urldb['port']:(preg_match("/^https/",$url)?443:80);
  2148. $host=$urldb['host'];
  2149. $query='?'.$urldb['query'];
  2150. $path=$urldb['path']?$urldb['path']:'/';
  2151. $method=$method=='GET'?"GET":'POST';
  2152. if(function_exists('fsockopen')){
  2153. $fp = fsockopen($host, $port, $errno, $errstr, 30);
  2154. }elseif(function_exists('pfsockopen')){
  2155. $fp = pfsockopen($host, $port, $errno, $errstr, 30);
  2156. }elseif(function_exists('stream_socket_client')){
  2157. $fp = stream_socket_client($host.':'.$port, $errno, $errstr, 30);
  2158. }else{
  2159. die("服务器不支持以下函数:fsockopen,pfsockopen,stream_socket_client操作失败!");
  2160. }
  2161. if(!$fp)
  2162. {
  2163. echo "$errstr ($errno)<br />\n";
  2164. }
  2165. else
  2166. {
  2167. $out = "$method $path$query HTTP/1.1\r\n";
  2168. $out .= "Host: $host\r\n";
  2169. $out .= "Cookie: c=1;c2=2\r\n";
  2170. $out .= "Referer: $Referer\r\n";
  2171. $out .= "Accept: */*\r\n";
  2172. $out .= "Connection: Close\r\n";
  2173. if ( $method == "POST" ) {
  2174. $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
  2175. $length = strlen($postValue);
  2176. $out .= "Content-Length: $length\r\n";
  2177. $out .= "\r\n";
  2178. $out .= $postValue;
  2179. }else{
  2180. $out .= "\r\n";
  2181. }
  2182. fwrite($fp, $out);
  2183. while (!feof($fp)) {
  2184. $file.= fgets($fp, 256);
  2185. }
  2186. fclose($fp);
  2187. if(!$file){
  2188. return '';
  2189. }
  2190. $ck=0;
  2191. $string='';
  2192. $detail=explode("\r\n",$file);
  2193. foreach( $detail AS $key=>$value){
  2194. if($value==''){
  2195. $ck++;
  2196. if($ck==1){
  2197. continue;
  2198. }
  2199. }
  2200. if($ck){
  2201. $stringdb[]=$value;
  2202. }
  2203. }
  2204. $string=implode("\r\n",$stringdb);
  2205. //$string=preg_replace("/([\d]+)(.*)0/is","\\2",$string);
  2206. return $string;
  2207. }
  2208. }
  2209. }
  2210. if (!function_exists('http_postfile')) {
  2211. /**
  2212. * 上传文件
  2213. * @param string $url 服务器网址
  2214. * @param string $path 本地文件路径
  2215. * @return mixed
  2216. */
  2217. function http_postfile($url='',$path=''){
  2218. $curl = curl_init();
  2219. if (class_exists('\CURLFile')) {
  2220. curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
  2221. $data = array('file' => new \CURLFile(realpath($path)));//>=5.5
  2222. } else {
  2223. if (defined('CURLOPT_SAFE_UPLOAD')) {
  2224. curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
  2225. }
  2226. $data = array('file' => '@' . realpath($path));//<=5.5
  2227. }
  2228. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  2229. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  2230. curl_setopt($curl, CURLOPT_URL, $url);
  2231. curl_setopt($curl, CURLOPT_POST, 1 );
  2232. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  2233. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  2234. curl_setopt($curl, CURLOPT_USERAGENT,"TEST");
  2235. $result = curl_exec($curl);
  2236. $error = curl_error($curl);
  2237. if (curl_errno($curl)) {
  2238. echo 'Errno'.curl_error($curl);
  2239. }
  2240. curl_close($curl);
  2241. return $result;
  2242. }
  2243. }
  2244. if (!function_exists('http_curl')) {
  2245. /**
  2246. * 访问远程数据.
  2247. * 微信接口,用得很频繁
  2248. * @param string $url 对方网址
  2249. * @param array $data 要提交的数据
  2250. * @param string $type 可以设置为 json 数据格式提交
  2251. * @param array $opt 要创建的header信息
  2252. * @return mixed
  2253. */
  2254. function http_curl($url='',$data = [],$type='',$opt=[]){
  2255. $headers = [];
  2256. if($type=='json'){
  2257. $headers = array("Content-Type:application/json;charset=UTF-8","Accept: application/json","Cache-Control: no-cache", "Pragma: no-cache");
  2258. $data = empty($data)?'{}':json_encode($data,JSON_UNESCAPED_UNICODE);
  2259. }
  2260. if ($opt) {
  2261. foreach ($opt AS $key=>$value){
  2262. $headers[] = $key.':'.$value;
  2263. }
  2264. }
  2265. $curl = curl_init();
  2266. curl_setopt($curl, CURLOPT_URL, $url);
  2267. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  2268. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  2269. //curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  2270. //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  2271. //curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  2272. if (!empty($data)){
  2273. curl_setopt($curl, CURLOPT_POST, 1);
  2274. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);//http_build_query($data);
  2275. }
  2276. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  2277. $headers && curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
  2278. $output = curl_exec($curl);
  2279. if (curl_errno($curl)) {
  2280. echo 'Errno'.curl_error($curl);
  2281. }
  2282. curl_close($curl);
  2283. return $output;
  2284. }
  2285. }
  2286. if (!function_exists('get_wxappAppid')) {
  2287. /**
  2288. * 获取商家小程序的APPID
  2289. * @return mixed|void|boolean|NULL|unknown[]
  2290. */
  2291. function get_wxappAppid(){
  2292. static $appid = null;
  2293. if($appid!==null){
  2294. return $appid;
  2295. }
  2296. $appid = input('qun_wxapp_appid') ?: (request()->header('wxappid') ?: cookie('qun_wxapp_appid'));
  2297. if ( empty($appid) || empty(wxapp_cfg($appid)) ) {
  2298. $appid = '';
  2299. }
  2300. return $appid;
  2301. }
  2302. }
  2303. if (!function_exists('wxapp_open_cfg')) {
  2304. /**
  2305. * 获取开放平台的小程序列表
  2306. * @param string $appid
  2307. * @return unknown|array|mixed|\think\cache\Driver|boolean
  2308. */
  2309. function wxapp_open_cfg($appid=true){
  2310. if (!plugins_config('wxopen')) {
  2311. return ;
  2312. }
  2313. $array = \plugins\wxopen\Fun::list_appid();
  2314. return $appid===true ? $array : $array[$appid];
  2315. }
  2316. }
  2317. if (!function_exists('wxapp_cfg')) {
  2318. /**
  2319. * 获取某个小程序的参数配置
  2320. * @param string $appid 设置为true的时候,就是获取所有非纯套壳的小程序配置参数
  2321. * @return array|array
  2322. */
  2323. function wxapp_cfg($appid=true){
  2324. $info = [];
  2325. if (class_exists("\\app\\qun\\model\\Wxset")) {
  2326. $info = \app\qun\model\Wxset::get_set($appid);
  2327. }
  2328. if ((empty($info)||$appid===true) && plugins_config('wxopen')) {
  2329. $array = wxapp_open_cfg($appid);
  2330. if ($array) {
  2331. $info = $info ? array_merge($info,$array) : $array;
  2332. }
  2333. }
  2334. return $info;
  2335. }
  2336. }
  2337. if (!function_exists('wx_getOpenAccessToken')) {
  2338. /**
  2339. * 获取开放平台的通信密钥
  2340. * @param string $check
  2341. * @return unknown|mixed|\think\cache\Driver|boolean
  2342. */
  2343. function wx_getOpenAccessToken($check=false){
  2344. $access_token = cache('open_access_token');
  2345. if (empty($access_token)) {
  2346. $webdb = config('webdb.P__wxopen');
  2347. $array = [
  2348. 'component_appid'=> $webdb['open_appid'],
  2349. 'component_appsecret'=>$webdb['open_appsecret'],
  2350. 'component_verify_ticket'=> cache2('wxopen_ticket'),
  2351. ];
  2352. if ($check&&empty(cache2('wxopen_ticket'))) {
  2353. showerr('ticket不存在,请10分钟后再偿试');
  2354. }
  2355. $string = http_curl('https://api.weixin.qq.com/cgi-bin/component/api_component_token',$array,'json');
  2356. $result = json_decode($string,true);
  2357. if($result['component_access_token']){
  2358. $access_token = $result['component_access_token'];
  2359. cache('open_access_token',$result['component_access_token'],3600);
  2360. }elseif($check){
  2361. showerr('component_token获取失败,原因如下:'.$string);
  2362. }
  2363. }
  2364. return $access_token;
  2365. }
  2366. }
  2367. if (!function_exists('wx_getAppidAccessToken')) {
  2368. /**
  2369. * 获取第三方APPID的通信密钥
  2370. * @param string $appid
  2371. * @param string $check
  2372. * @param string $authorizer_refresh_token 更新了刷新令牌
  2373. * @return unknown|mixed|\think\cache\Driver|boolean
  2374. */
  2375. function wx_getAppidAccessToken($appid='',$check=false,$authorizer_refresh_token=''){
  2376. $cache = cache('open_appid_ac'.$appid);
  2377. if (!$cache||$authorizer_refresh_token) {
  2378. $authorizer_refresh_token || $authorizer_refresh_token = Db::name('wxopen_info')->where('appid',$appid)->value('authorizer_refresh_token');
  2379. $ac = wx_getOpenAccessToken();
  2380. $array = [
  2381. 'component_appid'=>config('webdb.P__wxopen')['open_appid'],
  2382. 'authorizer_appid'=>$appid,
  2383. 'authorizer_refresh_token'=>$authorizer_refresh_token,
  2384. ];
  2385. $string = http_curl('https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token='.$ac,$array,'json');
  2386. $result = json_decode($string,true);
  2387. $cache = $result['authorizer_access_token'];
  2388. if ($cache) {
  2389. cache('open_appid_ac'.$appid,$cache,7200-600);
  2390. }elseif($check){
  2391. showerr('获取authorizer_access_token失败:'.$string);
  2392. }
  2393. }
  2394. return $cache;
  2395. }
  2396. }
  2397. if (!function_exists('wx_getAccessToken')) {
  2398. /**
  2399. * 获取微信的权限通信密钥
  2400. * @param string $check 设置为true的话,提示相关错误
  2401. * @param string $is_wxapp 设置为true的话就是小程序,否则就是公众号
  2402. * @param string $wxapp_id 方便PC修改不同的小程序相关内容
  2403. * @return void|string|mixed|\think\cache\Driver|boolean
  2404. */
  2405. function wx_getAccessToken($check=false,$is_wxapp=false,$wxapp_id=''){
  2406. if($is_wxapp){ //针对微信小程序
  2407. if( config('webdb.wxapp_appid')=='' || config('webdb.wxapp_appsecret')==''){
  2408. if($check==TRUE){
  2409. return '系统没有设置小程序的AppID或者AppSecret';
  2410. }
  2411. return ;
  2412. }
  2413. if ($wxapp_id || get_wxappAppid()) {
  2414. $appid = $wxapp_id?:get_wxappAppid();
  2415. if (plugins_config('wxopen')) {
  2416. $array = wxapp_open_cfg($appid);
  2417. if ($array) {
  2418. return wx_getAppidAccessToken($appid);
  2419. }
  2420. }
  2421. }
  2422. $appid = config('webdb.wxapp_appid');
  2423. $secret = config('webdb.wxapp_appsecret');
  2424. $token_string = '_wxapp'.get_wxappAppid();
  2425. if ($wxapp_id!='') { //主要是PC后台修改用户的直播或商品之类的东西
  2426. $ar = wxapp_cfg($wxapp_id);
  2427. if ($ar) {
  2428. $appid = $ar['wxapp_appid'];
  2429. $secret = $ar['wxapp_appsecret'];
  2430. $token_string = '_wxapp'.$wxapp_id;
  2431. }
  2432. }
  2433. }else{ //针对公众号
  2434. if(config('webdb.weixin_type')<2 || config('webdb.weixin_appid')=='' || config('webdb.weixin_appsecret')==''){
  2435. if($check==TRUE){
  2436. if(config('webdb.weixin_type')<2){
  2437. showerr('系统没有设置选择认证服务号还是认证订阅号');
  2438. }elseif(config('webdb.weixin_appid')=='' || config('webdb.weixin_appsecret')==''){
  2439. showerr('系统没有设置公众号的AppID或者AppSecret');
  2440. }
  2441. }
  2442. return ;
  2443. }
  2444. $appid = config('webdb.weixin_appid');
  2445. $secret = config('webdb.weixin_appsecret');
  2446. $token_string = '';
  2447. }
  2448. $access_token = cache('weixin_access_token'.$token_string);
  2449. if (empty($access_token)) {
  2450. $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$secret;
  2451. $string = http_curl($url);
  2452. $res = json_decode($string);
  2453. $access_token = $res->access_token;
  2454. if ($access_token) {
  2455. cache('weixin_access_token'.$token_string,$access_token,1800);
  2456. //设置了共享公众号资料,同步通知更新 access_token
  2457. if ($token_string=='' && config('webdb.wxmp_share_url') && config('webdb.wxmp_share_key') ) {
  2458. http_curl(config('webdb.wxmp_share_url').url('index/wxapp.weixin/sys_token'),[
  2459. 'code'=>mymd5(time()."\t\t".$access_token,'EN',config('webdb.wxmp_share_key'))
  2460. ]);
  2461. }
  2462. }else{
  2463. $msg = $is_wxapp?',微信小程序(不是公众号)接口问题':',微信公众号接口问题';
  2464. if (strstr($string, '40125')) {
  2465. $msg = ',初步判断是 '.($is_wxapp?'微信小程序(不是公众号)':'微信公众号(不是小程序)').' 密钥有误,请重新配置试试';
  2466. }
  2467. showerr('获取access_token失败'.$msg.',详情如下:'.$string);
  2468. }
  2469. }
  2470. return $access_token;
  2471. }
  2472. }
  2473. if (!function_exists('wx_check_attention')) {
  2474. /**
  2475. * 检查是否有关注公众号
  2476. * 务必注意使用方法:: ===ture 三个等于号才能判断已关注, ===false 才能判断没有关注 else 就是出错信息.
  2477. * @param unknown $openid 可以是用户UID,也可以是用户的公众号ID
  2478. * @return boolean
  2479. */
  2480. function wx_check_attention($openid=''){
  2481. if(!$openid){
  2482. return false;
  2483. }
  2484. if( config('webdb.weixin_appid')=='' || config('webdb.weixin_appsecret')=='' ){
  2485. return false;
  2486. }
  2487. if(is_numeric($openid)){
  2488. $array = get_user($openid);
  2489. $openid = $array['weixin_api'];
  2490. if (empty($openid)) {
  2491. return false;
  2492. }
  2493. }
  2494. $ac=wx_getAccessToken();
  2495. $s=json_decode( http_curl("https://api.weixin.qq.com/cgi-bin/user/info?access_token=$ac&openid=$openid&lang=zh_CN"));
  2496. if($s->subscribe==1){
  2497. return true;
  2498. }elseif($s->errcode){
  2499. return 'errcode:' . $s->errcode . ', errmsg:' . $s->errmsg;
  2500. }else{ //$s->subscribe==0
  2501. return false;
  2502. }
  2503. }
  2504. }
  2505. if (!function_exists('send_admin_msg')) {
  2506. /**
  2507. * 给管理员发系统提醒通知
  2508. * @param string $title 消息标题
  2509. * @param string $content 消息内容
  2510. */
  2511. function send_admin_msg($title='',$content=''){
  2512. $array = query('memberdata',[
  2513. 'where'=>['groupid'=>3],
  2514. 'column'=>'uid,weixin_api',
  2515. ]);
  2516. foreach ($array AS $uid=>$weixin_api){
  2517. send_msg($uid,$title,$content);
  2518. if ($weixin_api) {
  2519. send_wx_msg($weixin_api,$content);
  2520. }
  2521. }
  2522. }
  2523. }
  2524. if (!function_exists('send_msg')) {
  2525. /**
  2526. * 给用户发送站内短信息
  2527. * @param number $touid 接收消息的用户UID
  2528. * @param string $title 消息标题,可为空
  2529. * @param string $content 消息内容
  2530. * @param string $sys 等于true的话,不显示发送人,设置为UID数字,指定发件人
  2531. * @return \app\common\model\Msg
  2532. */
  2533. function send_msg($touid=0,$title='',$content='',$sys=true){
  2534. if ($sys===true) {
  2535. $fromuid = 0;
  2536. }elseif( is_numeric($sys) && $sys>0 ){
  2537. $fromuid = $sys;
  2538. }else{
  2539. $fromuid = login_user('uid');
  2540. }
  2541. if ($title=='') {
  2542. if($sys===true){
  2543. $title = '系统消息';
  2544. }else{
  2545. $title = '来自 ' . login_user('username') . ' 的消息';
  2546. }
  2547. }
  2548. if (!is_numeric($touid)) {
  2549. $array = get_user($touid,'username');
  2550. $touid = $array['uid'];
  2551. }
  2552. $data = [
  2553. 'touid'=>$touid,
  2554. 'title'=>$title,
  2555. 'content'=>$content,
  2556. 'create_time'=>time(),
  2557. 'uid'=>intval($fromuid),
  2558. ];
  2559. $result = MsgModel::create($data);
  2560. if ($fromuid) {
  2561. \app\common\model\Friend::add($fromuid,$touid); //给用户发消息,就相当于成为他的粉丝
  2562. }
  2563. return $result;
  2564. }
  2565. }
  2566. if (!function_exists('send_wx_msg')) {
  2567. /**
  2568. * 给用户发送微信信息
  2569. * @param string $openid 微信ID 也可以是用户的UID
  2570. * @param string $content 内容
  2571. * @param array $array 资源ID
  2572. * @return void|boolean|mixed 发送成功则返回true 发送失败会返回相应的错误代码
  2573. */
  2574. function send_wx_msg($openid,$content,$array=[]){
  2575. static $num=0;
  2576. if (empty($openid)) {
  2577. return ;
  2578. }
  2579. $user_db = [];
  2580. $content = str_replace('target="_blank"', '', $content); //微信中有这个会暴露出源代码
  2581. if(!class_exists("\\plugins\\weixin\\util\\Msg")){
  2582. return ;
  2583. }
  2584. static $obj=null;
  2585. $obj===null && $obj = new \plugins\weixin\util\Msg;
  2586. $uid = 0;
  2587. if(is_numeric($openid)){
  2588. $uid = $openid;
  2589. $user_db = get_user($openid);
  2590. $openid = $user_db['weixin_api'];
  2591. }else{
  2592. $user_db = get_user($openid,'weixin_api');
  2593. }
  2594. if (!$user_db) {
  2595. return ;
  2596. }
  2597. if ($user_db['subscribe_mp'] || $user_db['subscribe_wxapp'] || $user_db['subscribe_qun_wxapp'] || $user_db['wx_attention'] || wx_check_attention($user_db['weixin_api']) ) {
  2598. $num++;
  2599. if (!defined('IN_TASK') && $num>5) { //处理批量发送时,请求微信服务器容易卡死
  2600. $result = fun('Msg@send',$uid,'队列发送',$content,array_merge($array,['msgtype'=>'wxmsg']));
  2601. if ($result===true) {
  2602. return true;
  2603. }
  2604. }
  2605. return $obj->send($openid,$content,$array,$user_db);
  2606. }
  2607. }
  2608. }
  2609. if (!function_exists('task_config')) {
  2610. /**
  2611. * 获取定时任务列表
  2612. * @param string $refresh 设置为true则强制更新缓存配置文件
  2613. * @return mixed|\think\cache\Driver|boolean
  2614. */
  2615. function task_config($refresh=false){
  2616. $taskdb = cache('timed_task');
  2617. if (empty($taskdb)||$refresh==true) {
  2618. $taskdb = \app\common\model\Timedtask::where('ifopen',1)->order('list desc,id desc')->column(true);
  2619. cache('timed_task',$taskdb);
  2620. write_file(RUNTIME_PATH.'Task_config.txt', date('Y-m-d H:i:s')); //生成标志,给后台任务好核对是否变化过.
  2621. }
  2622. return $taskdb;
  2623. }
  2624. }
  2625. if (!function_exists('post_olpay')) {
  2626. /**
  2627. * 支付接口
  2628. * @param array $array =array(
  2629. * 'money'=>'支付金额', //单位是元,比如 0.02
  2630. * 'return_url'=>'支付成功后返回的网址', //回调网址最好加上http://开头,不加也可以
  2631. * 'banktype'=>'支付方式微信还是支付宝', //参数是 weixin 或者是 alipay
  2632. * 'numcode'=>'订单号', //可以留空, 最好不为空,避免反复生成多余的订单
  2633. * 'title'=>'商品名称',
  2634. * 'callback_class'=>'', //可以为空,即不做处理, 支付成功后,异步处理的回调类,比如 mymd5("app\\shop\\model\\Order@pay@5") 最后一项是参数,多个参数用'|'隔开
  2635. * );
  2636. * bank,numcode,title 这3项可以为空,不过订单号numcode最好不为空,避免反复生成多余的订单
  2637. * 支付成功后要异步在后端执行操作的话,请传入回调执行参数 callback_class
  2638. * callback_class=>mymd5("app\\shop\\model\\Order@pay@5") 最后一项是参数,多个参数用'|'隔开
  2639. * 这里的callback_class参数不能明名传输,必须要用mymd5加密.这个是可解密的函数
  2640. * @param string $jump 是否立即跳转到支付页,false的话,只取得支付链接的地址,不马上跳转
  2641. * @return string
  2642. */
  2643. function post_olpay( $array=['money'=>'','return_url'=>'','banktype'=>'','numcode'=>'','title'=>'','callback_class'=>''] , $jump = FALSE){
  2644. foreach ($array AS $key=>$value){
  2645. $key=='numcode' && $value=mymd5($value);
  2646. if ($key=='callback_class'&&strstr($value,'@')) {
  2647. $value = mymd5($value);
  2648. }
  2649. $url .= $key.'='.urlencode($value).'&';
  2650. }
  2651. //$return_url = urlencode($array['return_url']);
  2652. //unset($array['return_url']);
  2653. $url = iurl('index/pay/index') . '?' . $url; //参数不能放进路由,因为微信支付有授权目录的限制
  2654. if($jump==true){
  2655. header("location:$url");
  2656. exit;
  2657. }
  2658. return $url;
  2659. }
  2660. }
  2661. if (!function_exists('edit_user')) {
  2662. /**
  2663. * 修改用户任意资料
  2664. * @param array $array
  2665. * @return boolean
  2666. */
  2667. function edit_user($array=[]){
  2668. if (UserModel::edit_user($array)) {
  2669. return true;
  2670. }else{
  2671. return false;
  2672. }
  2673. }
  2674. }
  2675. if (!function_exists('add_rmb')) {
  2676. /**
  2677. * 人民币日志,用户的余额增或减
  2678. * @param number $uid
  2679. * @param number $money 变动的金额,可以是负数
  2680. * @param number $freeze_money 这项是正数,冻结金额,这里冻结的话,上面的值要对应的为负数
  2681. * @param string $about 附注说明
  2682. * @param number $refund 是否支持申请退款 1支持,0不支持
  2683. */
  2684. function add_rmb($uid,$money,$freeze_money,$about='',$refund=0){
  2685. //$money = number_format($money,2);
  2686. //$freeze_money = number_format($freeze_money,2);
  2687. if( !$uid || ($money==0&&$freeze_money==0) ){
  2688. return ;
  2689. }
  2690. $freeze = 0;
  2691. if($freeze_money == -$money){
  2692. $freeze = 1; //冻结
  2693. }
  2694. //setInc/setDec
  2695. $user = UserModel::get_info($uid);
  2696. UserModel::edit_user([
  2697. 'uid'=>$uid,
  2698. 'rmb'=>$money+$user['rmb'],
  2699. 'rmb_freeze'=>$freeze_money+$user['rmb_freeze'],
  2700. ]);
  2701. //cache('user_'.$uid,null);
  2702. //添加日志
  2703. \plugins\marketing\model\RmbConsume::create([
  2704. 'uid'=>$uid,
  2705. 'money'=> $money,
  2706. 'freeze_money'=>$freeze_money,
  2707. 'about'=>$about,
  2708. 'posttime'=>time(),
  2709. 'freeze'=>$freeze,
  2710. 'refund'=>$refund,
  2711. ]);
  2712. }
  2713. }
  2714. if (!function_exists('add_jifen')) {
  2715. /**
  2716. * 积分(包括用户自定义虚拟币)增减及日志
  2717. * @param number $uid 用户UID
  2718. * @param number $money 可以是负数,就是减积分
  2719. * @param string $about 附注说明
  2720. * @param number $type 用户自定义的积分类型,默认0是系统积分
  2721. */
  2722. function add_jifen($uid=0,$money=0,$about='',$type=0){
  2723. if ($type==-1) {
  2724. add_rmb($uid,$money,0,$about);
  2725. return ;
  2726. }
  2727. if ($type>0) { //用户自定义虚拟币
  2728. \plugins\marketing\model\Money::add($uid,$money,$type);
  2729. }else{
  2730. if ($money>0) {
  2731. UserModel::where('uid',$uid)->setInc('money',$money);
  2732. }else{
  2733. UserModel::where('uid',$uid)->setDec('money',abs($money));
  2734. }
  2735. }
  2736. cache('user_'.$uid,null);
  2737. //添加日志
  2738. \plugins\marketing\model\Moneylog::create([
  2739. 'uid'=>$uid,
  2740. 'money'=>$money,
  2741. 'about'=>$about,
  2742. 'type'=>intval($type),
  2743. 'posttime'=>time(),
  2744. ]);
  2745. }
  2746. }
  2747. if (!function_exists('jf_name')) {
  2748. /**
  2749. * 获取虚拟币名称
  2750. * 其中 jf_name(0) 就是系统积分的名称
  2751. * @param unknown $type 非数字的时候,就把所有名称以数组形式列出来
  2752. * @return mixed|array
  2753. */
  2754. function jf_name($type=null,$all=false){
  2755. $array = cache('money_types');
  2756. if (empty($array)) {
  2757. $array = \plugins\marketing\model\Moneytype::getList();
  2758. }
  2759. if ($all==false) {
  2760. foreach($array AS $key=>$rs){
  2761. $array[$key] = $rs['name'];
  2762. }
  2763. }
  2764. $default_name = config('webdb.MoneyName')?:'积分';
  2765. $array = [$default_name] + ($array?:[]);
  2766. if (is_numeric($type)) {
  2767. return $array[$type];
  2768. }else{
  2769. return $array;
  2770. }
  2771. }
  2772. }
  2773. if (!function_exists('add_dou')) {
  2774. /**
  2775. * 用户金豆变化
  2776. * @param unknown $uid 用户UID
  2777. * @param unknown $dou 可以是负数,就是减积分
  2778. * @param string $about 附注说明
  2779. */
  2780. function add_dou($uid,$dou,$about=''){
  2781. if ($dou>0) {
  2782. UserModel::where('uid',$uid)->setInc('dou',$dou);
  2783. }else{
  2784. UserModel::where('uid',$uid)->setDec('dou',abs($dou));
  2785. }
  2786. cache('user_'.$uid,null);
  2787. }
  2788. }
  2789. if (!function_exists('get_dir_file')) {
  2790. /**
  2791. * 取某个目录下的所有指定类型的文件
  2792. * @param string $path
  2793. * @param string $_suffix 文件后缀,多个用逗号隔开,比如 'htm,txt'
  2794. * @return string
  2795. */
  2796. function get_dir_file($path='',$_suffix=''){
  2797. $suffix = explode(',', $_suffix);
  2798. $dir = opendir($path);
  2799. while (false!=($file=readdir($dir))){
  2800. if(is_file($path.'/'.$file)){
  2801. $detail = explode('.', $file);
  2802. if(in_array(end($detail), $suffix)){
  2803. $array[] = $path.'/'.$file;
  2804. }
  2805. }elseif($file!='.'&&$file!='..'){
  2806. $_array = get_dir_file($path.'/'.$file,$_suffix);
  2807. if(is_array($_array)){
  2808. $array = $array ? array_merge($array,$_array) : $_array ;
  2809. }
  2810. }
  2811. }
  2812. return $array;
  2813. }
  2814. }
  2815. if (!function_exists('del_html')) {
  2816. /**
  2817. * 清除html代码
  2818. * @param string $content
  2819. * @param string $only_delhide 是否只做清除隐藏代码,比如获取内容图片的时候就用到
  2820. * @return mixed|unknown
  2821. */
  2822. function del_html($content='',$only_delhide=false){
  2823. $content = preg_replace("/\[face(\d+)\]/is",'',$content); //过滤掉QQ表情 [reply] 请在这括号范围内输入要隐藏的内容 [/reply]
  2824. $content = preg_replace("/\[reply\](.*?)\[\/reply]/is",'',$content); //过滤掉回复可见的内容
  2825. $content = preg_replace("/\[group=([\d,]+)\](.*?)\[\/group]/is",'',$content); //过滤掉指定用户可见
  2826. $content = preg_replace("/\[password=([^\]]+)\](.*?)\[\/password]/is",'',$content); //过滤掉密码才能看的内容
  2827. $content = preg_replace("/\[paymoney=([\d]+)\](.*?)\[\/paymoney]/is",'',$content); //过滤掉积分购买的内容
  2828. $content = preg_replace("/\[pay ([^\]]+)\](.*?)\[\/pay]/is",'',$content); //付费或圈内可看
  2829. $content = preg_replace("/\[qun\](.*?)\[\/qun]/is",'',$content); //过滤掉仅圈内成员可见的内容
  2830. $content = preg_replace("/\[iframe_mv\](.*?)\[\/iframe_mv]/is",'',$content); //过滤掉站外视频
  2831. $content = preg_replace("/\[topic ([^\]]+)\](.*?)\[\/topic]/is",'\\2',$content); //站内引用主题
  2832. if($only_delhide){
  2833. return $content;
  2834. }
  2835. $content = preg_replace("/<script([^>]*)>(.*?)<\/script>/is",'',$content);
  2836. $content = str_replace("\r",'',$content);
  2837. $content = str_replace("\n",'',$content);
  2838. $content = str_replace(' ',' ',$content); //全角空格换成半角空格
  2839. $content = str_replace(' ','',$content); //两个以上的全角空格清掉,一个的话,保留,即最后只有单数的一个,双数话,可能0个
  2840. $content = preg_replace('/<([^<]*)>/is','',$content); //把HTML代码过滤掉
  2841. $content = str_replace('&nbsp;','',$content); //把空格代码过滤掉
  2842. return $content;
  2843. }
  2844. }
  2845. if (!function_exists('in_wap')) {
  2846. /**
  2847. * 检查是否为wap访问,也包含微信端
  2848. * @return boolean
  2849. */
  2850. function in_wap(){
  2851. $regex_match="/(WindowsWechat|iPad|nokia|iphone|android|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|";
  2852. $regex_match.="htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|";
  2853. $regex_match.="blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|";
  2854. $regex_match.="symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|";
  2855. $regex_match.="jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220";
  2856. $regex_match.=")/i";
  2857. return isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE']) or preg_match($regex_match, strtolower($_SERVER['HTTP_USER_AGENT']));
  2858. }
  2859. }
  2860. if (!function_exists('in_weixin')) {
  2861. /**
  2862. * 是否在微信客户端浏览器中打开 , 注意 如果在小程序中打开,也返回true
  2863. * @return boolean
  2864. */
  2865. function in_weixin(){
  2866. if( strstr($_SERVER['HTTP_USER_AGENT'],"MicroMessenger") || strstr($_SERVER['HTTP_USER_AGENT'],"WindowsWechat")){
  2867. return true;
  2868. }else{
  2869. return false;
  2870. }
  2871. }
  2872. }
  2873. if (!function_exists('in_wxapp')) {
  2874. /**
  2875. * 是否在小程序中打开 , 注意 苹果系统不存在miniProgram 无法判断
  2876. * @return boolean
  2877. */
  2878. function in_wxapp(){
  2879. if( strstr($_SERVER['HTTP_USER_AGENT'],"miniProgram") ){
  2880. return true;
  2881. }else{
  2882. return false;
  2883. }
  2884. }
  2885. }
  2886. if (!function_exists('in_apiapp')) {
  2887. /**
  2888. * 是否在app中打开
  2889. * @return boolean
  2890. */
  2891. function in_apiapp(){
  2892. if( get_cookie('inApi') ){
  2893. return true;
  2894. }else{
  2895. return false;
  2896. }
  2897. }
  2898. }
  2899. if (!function_exists('get_sons')) {
  2900. /**
  2901. * 树型数组取下级子数组
  2902. * @param unknown $array
  2903. * @return unknown[]|unknown
  2904. */
  2905. function get_sons($array){
  2906. if(empty($array)){
  2907. return ;
  2908. }
  2909. $listdb = [];
  2910. $pid = 0;
  2911. foreach ($array AS $key=>$rs){
  2912. if($rs['pid']){
  2913. $listdb[$pid]['sons'][$rs['id']] = $rs;
  2914. }else{
  2915. $listdb[$rs['id']] = $rs;
  2916. $pid = $rs['id'];
  2917. }
  2918. }
  2919. return $listdb;
  2920. }
  2921. }
  2922. if (!function_exists('get_url')) {
  2923. /**
  2924. * 获取各种网址,用得很频繁
  2925. * @param unknown $type
  2926. * @param array $array
  2927. * @return string|unknown
  2928. */
  2929. function get_url($type,$array=[]){
  2930. switch ($type){
  2931. case 'msg': //即时聊天
  2932. $url = iurl('index/msg/index').'#/public/static/libs/bui/pages/chat/chat?uid='.$array;
  2933. break;
  2934. case 'reg': //通用注册
  2935. $url = iurl('index/reg/index',$array);
  2936. break;
  2937. case 'login': //通用登录
  2938. $url = iurl('index/login/index',$array).'?fromurl='.urlencode(request()->url(true));
  2939. break;
  2940. case 'wx_login': //微信登录
  2941. $url = purl('weixin/login/index',$array).'?fromurl='.urlencode(request()->url(true));
  2942. break;
  2943. case 'qq_login': //QQ登录
  2944. $url = purl('login/qq/index',$array,'index').'?fromurl='.urlencode(request()->url(true));
  2945. break;
  2946. case 'quit': //退出
  2947. $url = iurl('index/login/quit',$array);
  2948. break;
  2949. case 'from': //来源地址
  2950. $url = $_SERVER["HTTP_REFERER"];
  2951. break;
  2952. case 'location': //当前网址
  2953. $url = request()->url(true);
  2954. break;
  2955. case 'home': //访问主页
  2956. $url = request()->domain().'/';
  2957. break;
  2958. case 'member': //会员中心
  2959. $url = murl('member/index/index');//request()->domain().'/member.php';
  2960. break;
  2961. case 'user': //用户的主页
  2962. $url = murl('member/user/index',is_numeric($array)?['uid'=>$array]:$array);
  2963. break;
  2964. default: //把网址加上http域名
  2965. $url = preg_match('/:\/\//', $type)?$type:request()->domain().$type;
  2966. }
  2967. return $url;
  2968. }
  2969. }
  2970. if (!function_exists('M')) {
  2971. /**
  2972. * 查找具体某个频道模块的相关信息,比如频道ID 频道目录名关键字
  2973. * @param string $type key或keyword取目录名关键字,name值取名称,id值取模型的ID
  2974. * @return mixed|array|boolean|NULL|unknown
  2975. */
  2976. function M($type='',$dirname=''){
  2977. $dirname || $dirname = config('system_dirname');
  2978. if ($type=='key'||$type=='keyword') {
  2979. return $dirname;
  2980. }elseif($type=='name'){
  2981. $array = modules_config();
  2982. foreach($array AS $rs){
  2983. if($rs['keywords']==$dirname){
  2984. return $rs['name'];
  2985. }
  2986. }
  2987. }elseif($type=='id'){
  2988. $array = modules_config();
  2989. foreach($array AS $rs){
  2990. if($rs['keywords']==$dirname){
  2991. return $rs['id'];
  2992. }
  2993. }
  2994. }else{
  2995. $array = modules_config();
  2996. foreach($array AS $rs){
  2997. if($rs['keywords']==$dirname){
  2998. return $rs;
  2999. }
  3000. }
  3001. }
  3002. }
  3003. }
  3004. if(!function_exists('model_config')){
  3005. /**
  3006. * 获取频道的模型配置参数
  3007. * @param number $mid 模型ID,可为空,为空的话,就是取所有模型数据
  3008. * @param string $sys_type 特别指定哪个目录的频道
  3009. * @return array|unknown|mixed|\think\cache\Driver|boolean
  3010. */
  3011. function model_config($mid=null,$sys_type=''){
  3012. if(empty($sys_type)){
  3013. $sys_type=config('system_dirname');
  3014. }
  3015. if(empty($sys_type)){
  3016. return [];
  3017. }
  3018. static $model_array = [];
  3019. $array = $model_array[$sys_type];
  3020. if(empty($array)){
  3021. $array = cache('model_config_'.$sys_type);
  3022. if (empty($array)) {
  3023. //$array = model($sys_type.'/module')->getList();
  3024. $array = get_model_class($sys_type,'module')->getList();
  3025. cache('model_config_'.$sys_type,$array);
  3026. }
  3027. $model_array[$sys_type] = $array;
  3028. }
  3029. if (empty($mid)) {
  3030. return $array;
  3031. }elseif($mid=='default_id'){
  3032. return current(model_config())['id'];
  3033. }else{
  3034. return $array[$mid];
  3035. }
  3036. }
  3037. }
  3038. if (!function_exists('get_field')) {
  3039. /**
  3040. * 取得具体某个频道的模型的字段配置信息
  3041. * @param number $mid 模型ID
  3042. * @param string $dirname 频道目录名,可为空
  3043. */
  3044. function get_field($mid=0,$dirname=''){
  3045. $dirname || $dirname = config('system_dirname');
  3046. if (!$dirname) {
  3047. return [];
  3048. }
  3049. static $field_array = [];
  3050. $list_f = $field_array[$dirname];
  3051. if(empty($list_f)){
  3052. $list_f = cache($dirname.'__field');
  3053. if (empty($list_f)) {
  3054. $obj = get_model_class($dirname,'field');
  3055. if ($obj==false) {
  3056. return [];
  3057. }
  3058. $array = $obj->getFields([]);
  3059. foreach($array AS $rs){
  3060. $list_f[$rs['mid']][$rs['name']] = $rs;
  3061. }
  3062. cache($dirname.'__field',$list_f);
  3063. }
  3064. $field_array[$dirname] = $list_f;
  3065. }
  3066. return $list_f[$mid];
  3067. }
  3068. }
  3069. if (!function_exists('send_mail')) {
  3070. /**
  3071. * 发送邮件
  3072. * @param unknown $email 对方邮箱
  3073. * @param unknown $title 邮件标题
  3074. * @param unknown $content 邮件内容
  3075. * @return boolean|string 发送成功会返回true 发布失败会返回对应的错误代码
  3076. */
  3077. function send_mail($email='',$title='',$content=''){
  3078. if(is_numeric($email)){
  3079. $array = get_user($email);
  3080. $email = $array['email'];
  3081. if (empty($email)) {
  3082. return '用户邮箱不存在';
  3083. }
  3084. }
  3085. static $obj = null;
  3086. if ($obj===null) {
  3087. $obj = new \app\common\util\Email;
  3088. }
  3089. return $obj->send($email,$title,$content);
  3090. }
  3091. }
  3092. if (!function_exists('send_sms')) {
  3093. /**
  3094. * 发送短信,主要用于验证码
  3095. * @param string $phone 手机号码
  3096. * @param string $msg 验证码内容
  3097. * @return boolean|string 发送成功会返回true 发布失败会返回对应的错误代码
  3098. */
  3099. function send_sms($phone='',$msg=''){
  3100. if($phone<99999999){
  3101. $array = get_user($phone);
  3102. $phone = $array['mobphone'];
  3103. if (empty($phone)) {
  3104. return '用户手机号不存在';
  3105. }
  3106. }
  3107. static $obj = null;
  3108. if ($obj===null) {
  3109. $obj = new \app\common\util\Sms;
  3110. }
  3111. return $obj->send($phone,$msg);
  3112. }
  3113. }
  3114. if (!function_exists('get_model_class')) {
  3115. /**
  3116. * 取得对应的模型
  3117. * @param unknown $dirname 目录名
  3118. * @param unknown $type 类名
  3119. * @return unknown
  3120. */
  3121. function get_model_class($dirname,$type){
  3122. $dispatch = request()->dispatch();
  3123. if($dispatch['module'][1]=='plugin' && $dispatch['module'][2]=='execute'){
  3124. $path = 'plugins';
  3125. }else{
  3126. $path = 'app';
  3127. }
  3128. $classname = "$path\\$dirname\\model\\".ucfirst($type);
  3129. if(class_exists($classname)==false){
  3130. $_path = $path=='app'?'plugins':'app';
  3131. $classname = "$_path\\$dirname\\model\\".ucfirst($type);
  3132. if(class_exists($classname)==false){
  3133. return false;
  3134. }
  3135. }
  3136. $obj = new $classname;
  3137. return $obj;
  3138. }
  3139. }
  3140. if (!function_exists('login_user')) {
  3141. /**
  3142. * 用户登录后的个人信息
  3143. * @param string $key
  3144. * @return void|mixed|\think\cache\Driver|boolean|number|array|\think\db\false|PDOStatement|string|\think\Model
  3145. */
  3146. function login_user($key=''){
  3147. static $array = [];
  3148. if(empty($array)){
  3149. $array = UserModel::login_info();
  3150. }
  3151. if($key!=''){
  3152. return $array[$key];
  3153. }else{
  3154. return $array;
  3155. }
  3156. }
  3157. }
  3158. if (!function_exists('url_clean_domain')) {
  3159. /**
  3160. * 把本站的HTTP地址过滤掉
  3161. * @param string $code
  3162. * @return unknown
  3163. */
  3164. function url_clean_domain($code=''){
  3165. static $domain = null;
  3166. if($domain === null){
  3167. $domain = request()->domain() ;
  3168. }
  3169. return str_replace($domain.PUBLIC_URL, '', $code);
  3170. }
  3171. }
  3172. if (!function_exists('get_qrcode')) {
  3173. /**
  3174. * 获取某个网址的二维码
  3175. * @param string $url 要生成的真实二维码网址
  3176. * @param string $logo 小LOGO地址
  3177. * @param string $is_wxapp 是否为小程序码
  3178. * @return string
  3179. */
  3180. function get_qrcode($url='',$logo='',$is_wxapp=false){
  3181. static $domain = '';
  3182. if($domain === ''){
  3183. $domain = request()->domain();
  3184. }
  3185. if (!is_numeric($url)) {
  3186. if ($url) {
  3187. $url = preg_match('/:\/\//', $url) ? $url : $domain.$url;
  3188. }else{
  3189. $url = request()->url(true);
  3190. }
  3191. }
  3192. return iurl($is_wxapp?'index/qrcode/wxapp':'index/qrcode/index') . '?url=' . urlencode($url).($logo?'&logo='.urlencode($logo):'');
  3193. }
  3194. }
  3195. if (!function_exists('weixin_share')) {
  3196. /**
  3197. * 微信JS接口
  3198. * @param string $key
  3199. * @return void|string|number|NULL
  3200. */
  3201. function weixin_share($type=''){
  3202. if (!defined('LOAD_SHARE')) {
  3203. define('LOAD_SHARE', TRUE); //方便插件调用判断是否已加载过
  3204. }
  3205. if(config('webdb.weixin_type')<2 || config('webdb.weixin_appid')=='' || config('webdb.weixin_appsecret')==''){
  3206. return ;
  3207. }
  3208. if(!in_weixin()){
  3209. return ;
  3210. }
  3211. static $array = [];
  3212. if(empty($array)){
  3213. $jssdk = new \app\common\util\Weixin_share(config('webdb.weixin_appid'),config('webdb.weixin_appsecret'));
  3214. $array = $jssdk->GetSignPackage();
  3215. }
  3216. if($type){
  3217. return $array[$type];
  3218. }else{
  3219. return $array;
  3220. }
  3221. }
  3222. }
  3223. if (!function_exists('weixin_login')) {
  3224. /**
  3225. * 强制微信登录
  3226. * @param string $url 登录成功后,返回的地址
  3227. * @param string $jump 默认是立即跳转,可以设置为false 只获取跳转地址,
  3228. */
  3229. function weixin_login($url='',$jump=true){
  3230. $url = $url=='' ? request()->url(true) : $url;
  3231. if( config('webdb.autologin_in_weixin')==1 && (
  3232. (in_weixin()&&config('webdb.weixin_type')==3) //在微信端并且是认证服务号的情况下
  3233. || (in_wxapp()&&config('webdb.wxapp_appid')&&config('webdb.wxapp_appsecret')) //在小程序中
  3234. )){
  3235. $url = purl('weixin/login/index',[],'index') . '?fromurl=' . urlencode($url);
  3236. }else{
  3237. $url = iurl('index/login/index').'?fromurl='.urlencode($url);
  3238. }
  3239. if ($jump===true) {
  3240. header("location:$url");
  3241. exit;
  3242. }else{
  3243. return $url;
  3244. }
  3245. }
  3246. }
  3247. if (!function_exists('makepath')) {
  3248. /**
  3249. * 自动创建多级目录
  3250. * @param unknown $path
  3251. * @return string|mixed
  3252. */
  3253. function makepath($path){
  3254. //这个\没考虑
  3255. $path=str_replace("\\","/",$path);
  3256. $ROOT_PATH=str_replace("\\","/",ROOT_PATH);
  3257. $detail=explode("/",$path);
  3258. foreach($detail AS $key=>$value){
  3259. if($value==''&&$key!=0){
  3260. //continue;
  3261. }
  3262. $newpath.="$value/";
  3263. if((preg_match("/^\//",$newpath)||preg_match("/:/",$newpath))&&!strstr($newpath,$ROOT_PATH)){continue;}
  3264. if( !is_dir($newpath) ){
  3265. if(substr($newpath,-1)=='\\'||substr($newpath,-1)=='/')
  3266. {
  3267. $_newpath=substr($newpath,0,-1);
  3268. }
  3269. else
  3270. {
  3271. $_newpath=$newpath;
  3272. }
  3273. if(!is_dir($_newpath)&&!mkdir($_newpath)&&preg_match("/^\//",ROOT_PATH)){
  3274. return false;
  3275. }
  3276. chmod($newpath,0777);
  3277. }
  3278. }
  3279. return $path;
  3280. }
  3281. }
  3282. if (!function_exists('get_pinyin')) {
  3283. /**
  3284. * 取得汉字的拼音
  3285. * @param string $word 汉字
  3286. * @param string $type all:全拼音|first:首字母|one:仅第一字符首字母
  3287. * @return string|number
  3288. */
  3289. function get_pinyin($word='',$type='all'){
  3290. //$obj = new \pinyin\Py;
  3291. //return $obj->change2pinyin($word,$type);
  3292. return \pinyin\Pinyin::get($word,$type);
  3293. }
  3294. }
  3295. if (!function_exists('get_md5_num')) {
  3296. /**
  3297. * 生成随机字串,主要用在手机或邮箱获取注册码的时候,防止用户中途又换了其它邮箱或手机号
  3298. * @param unknown $str
  3299. * @param number $num
  3300. * @return string
  3301. */
  3302. function get_md5_num($str,$num=6){
  3303. $str .= config('webdb.mymd5');
  3304. return substr(preg_replace('/(1|l|o|0|q|z)/i','',md5($str)),0,$num);
  3305. }
  3306. }
  3307. if (!function_exists('check_bom')) {
  3308. /**
  3309. * 检查文件是否包含UTF8+BOM看不到的三个字符.
  3310. * @param string $filename
  3311. * @param string $onlycheck 为false时返回去除BOM后的内容,为TRUE的话,仅仅做检查文件是否包含BOM
  3312. * @return boolean|string
  3313. */
  3314. function check_bom($filename='',$onlycheck=false){
  3315. $contents = is_file($filename) ? file_get_contents($filename) : $filename;
  3316. $charset[1] = substr($contents, 0, 1);
  3317. $charset[2] = substr($contents, 1, 1);
  3318. $charset[3] = substr($contents, 2, 1);
  3319. if(ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191){
  3320. if($onlycheck==true){
  3321. return true;
  3322. }else{
  3323. $contents = substr($contents, 3);
  3324. }
  3325. }
  3326. if($onlycheck==false){
  3327. return $contents;
  3328. }
  3329. }
  3330. }
  3331. if(!function_exists('get_area')){
  3332. /**
  3333. * 获取地区数据,如果第三项不为0的话,则获取其子栏目的数据,这个时候,前两项设置无效
  3334. * @param number $id 某个地区的ID
  3335. * @param string $field 可以取值为name 名称 或 pid 父ID
  3336. * @param number $pid 指定父ID
  3337. */
  3338. function get_area($id=0,$field='name',$pid=null){
  3339. if($id==0 && $pid===null){
  3340. return ;
  3341. }
  3342. $area_array = cache('area_cache');
  3343. if(empty($area_array)){
  3344. $array= \plugins\area\model\Area::get_all();
  3345. $fup = [];
  3346. foreach ($array AS $rs){
  3347. $fup[$rs['pid']][$rs['id']] = $rs['name'];
  3348. }
  3349. $area_array = [
  3350. 'list'=>$array,
  3351. 'fup'=>$fup
  3352. ];
  3353. cache('area_cache',$area_array);
  3354. }
  3355. if($pid!==null){
  3356. return is_numeric($pid) ? $area_array['fup'][$pid] : reset($area_array['fup']);
  3357. }else{
  3358. return $area_array['list'][$id][$field];
  3359. }
  3360. }
  3361. }
  3362. if(!function_exists('get_status')){
  3363. /**
  3364. * 自定义通用状态助手
  3365. * @access public
  3366. * @param int $state 状态
  3367. * @param array $array 自定义数组
  3368. * @return string
  3369. */
  3370. function get_status($state,$array=['禁用','正常']) {
  3371. if(is_string($array)){
  3372. $array = explode(',',$array);
  3373. }
  3374. return $array[$state];
  3375. }
  3376. }
  3377. if(!function_exists('get_wxappinfo')){
  3378. /**
  3379. * 获取小程序的配置参数
  3380. * @param string $appid
  3381. * @return void|array|NULL[]|unknown
  3382. */
  3383. function get_wxappinfo($appid='') {
  3384. if (!plugins_config('wxopen') || !$appid) {
  3385. return ;
  3386. }
  3387. $info = \plugins\wxopen\model\Info::where('appid',$appid)->find();
  3388. return $info ? getArray($info) : [];
  3389. }
  3390. }
  3391. if (!function_exists('logs')) {
  3392. /**
  3393. * 开发调试日志
  3394. * @param unknown $code
  3395. * @param string $type
  3396. * @param string $filename
  3397. */
  3398. function logs($code,$type=true,$filename='log.txt'){
  3399. is_array($code) && $code = var_export($code,true);
  3400. $code .= $type==true ? "\r\n" : '';
  3401. write_file(ROOT_PATH.$filename,$code ,$type==true?'a':'rb+');
  3402. }
  3403. }
  3404. if(!function_exists('fork_set')){
  3405. /**
  3406. * 设置分支进程,linux才支持
  3407. */
  3408. function fork_set(){
  3409. if(!function_exists('pcntl_fork')){
  3410. define('FORK',-1);
  3411. }else{
  3412. $pid = pcntl_fork();
  3413. define('FORK',$pid);
  3414. }
  3415. }
  3416. }
  3417. if(!function_exists('fork_main')){
  3418. /**
  3419. * 主进程 不执行耗时任务
  3420. * @return boolean
  3421. */
  3422. function fork_main(){
  3423. if(!defined('FORK')|| FORK==-1 || FORK>0){
  3424. return true;
  3425. }
  3426. }
  3427. }
  3428. if(!function_exists('fork_son')){
  3429. /**
  3430. * 子进程 执行耗时任务
  3431. * @return boolean
  3432. */
  3433. function fork_son(){
  3434. if(!defined('FORK') || FORK==-1 || FORK==0){
  3435. return true;
  3436. }
  3437. }
  3438. }
  3439. if(!function_exists('cache2')){
  3440. /**
  3441. * 增强版的cache函数,用法跟cache函数类似
  3442. * 但有几点要注意的是
  3443. * 1、cache2(['a','b','c'],'x') 这种格式代表批量插入一个Redis 列表(List)记录 key就是 x ;这个列可以有几万甚至几十万条记录
  3444. * 2、$value的值为 lpop 或 rpop 的时候,第一项就必须是键名,配合上面的列表使用,代表获取列表记录的其中一个值,lpop正序获取,rpop倒序获取,获取后,那一项记录也会自动踢除
  3445. * 3、另外$key为db的时候,就直接返回Redis的类 ,此时可以直接使用原生 Redis类
  3446. * 4、cache2('ab*',null) 代表把所有ab开头的key那些项目删除,cache2('ab*') 代表列出所有包含ab开头的key,只列出key,不列出值
  3447. * 5、cache2()全部参数为空的话,就可以直接操作Redis的方法,比如 cache2()->get('aa'); cache2()->set('aa',88);
  3448. * 这三个关键点要特别注意,也就是增强功能的体现
  3449. * 更详细的教程 http://help.php168.com/1477144
  3450. * @param string $key
  3451. * @param string $value
  3452. * @param number $time
  3453. */
  3454. function cache2($key='',$value='',$time=0){
  3455. if (config('cache.prefix')!='' && $key!=='') {
  3456. if (is_array($key)) {
  3457. if($value!=='' && $value!==null && isset($key[0])){ //插入一批数据
  3458. $value = config('cache.prefix').'___'.$value;
  3459. }else{
  3460. foreach ($key AS $k=>$v){
  3461. $k = config('cache.prefix').'___'.$k;
  3462. $key[$k] = $v;
  3463. }
  3464. }
  3465. }else{
  3466. $key = config('cache.prefix').'___'.$key;
  3467. }
  3468. }
  3469. if (is_array($key)) {
  3470. Cache2::set($key,$value,$time);
  3471. }elseif ($value===null) {
  3472. Cache2::set($key,null);
  3473. }elseif($value===''){
  3474. if ($key==='') {
  3475. return Cache2::db();
  3476. }else{
  3477. return Cache2::get($key);
  3478. }
  3479. }elseif($value==='lpop'||$value==='rpop'){
  3480. return Cache2::get($key,$value);
  3481. }else{
  3482. Cache2::set($key,$value,$time);
  3483. }
  3484. }
  3485. }
  3486. if(!function_exists('val')){
  3487. /**
  3488. * 函数内外之间传递变量
  3489. * @param array|string $array 变量或字符串
  3490. * @param string $k 标志符,默认是label不设置的话,也可以,但会被最后的替换
  3491. * @return unknown
  3492. */
  3493. function val($array='',$k='label'){
  3494. static $data = [];
  3495. static $input = null;
  3496. if (is_array($array)) {
  3497. if($input === null){
  3498. $input = input();
  3499. }
  3500. if($k=='template'){
  3501. $str_match = '/("|\')/is';
  3502. foreach($array AS $key=>$rs){
  3503. if(is_string($rs) && $input[$key] && (preg_match($str_match, $input[$key])||preg_match('/<.+>/is', $input[$key]))){
  3504. showerr("URL中有禁止的变量字符".filtrate($key));
  3505. }elseif(is_array($rs)){
  3506. foreach($rs AS $ke=>$vs){
  3507. if(is_string($vs) && $input[$ke] && (preg_match($str_match, $input[$ke])||preg_match('/<.+>/is', $input[$ke]))){
  3508. showerr("URL中有禁止的变量字符:".filtrate($ke));
  3509. }
  3510. }
  3511. }
  3512. }
  3513. }
  3514. $data[$k] = $array;
  3515. }elseif(is_string($array) && $array!=''){
  3516. return $data[$k]?$data[$k][$array]:'';
  3517. }else{
  3518. return $data[$k];
  3519. }
  3520. }
  3521. }
  3522. if(!function_exists('showerr')){
  3523. function showerr($msg = '', $url = null, $data = '', $wait = 60, array $header = [],$code = 1){
  3524. $obj = new Base;
  3525. $obj->showerr($msg , $url , $data , $wait , $header,$code);
  3526. }
  3527. }
  3528. if(!function_exists('check_tncode')){
  3529. /**
  3530. * 校验行为验证码
  3531. * @return boolean
  3532. */
  3533. function check_tncode(){
  3534. if ( !cache('tn_code'.get_cookie('user_sid')) && !cache('tn_code'.input('post.tnCode')) ) {
  3535. return false;
  3536. }
  3537. cache('tn_code'.get_cookie('user_sid'),null);
  3538. cache('tn_code'.input('post.tnCode'),null);
  3539. return true;
  3540. }
  3541. }
  3542. if (!function_exists('run_label')) {
  3543. //下面这些标签用到的函数将弃用. 改用 fun 函数
  3544. function comment_api($type='',$aid=0,$sysid=0,$cfg=[]){return fun('label@comment_api',$type,$aid,$sysid,$cfg);}
  3545. function reply_api($type='',$aid=0,$cfg=[]){return fun('label@reply_api',$type,$aid,$cfg);}
  3546. function run_label($tag_name,$cfg){fun('label@run_label',$tag_name,$cfg);}
  3547. function label_ajax_url($tag_name='',$dirname){fun('label@label_ajax_url',$tag_name,$dirname);}
  3548. function run_form_label($tag_name,$cfg){fun('label@run_form_label',$tag_name,$cfg);}
  3549. function run_listpage_label($tag_name,$cfg){return fun('label@run_listpage_label',$tag_name,$cfg);}
  3550. function run_showpage_label($tag_name,$info,$cfg){return fun('label@run_showpage_label',$tag_name,$info,$cfg);}
  3551. function label_listpage_ajax_url($tag_name=''){fun('label@label_listpage_ajax_url',$tag_name);}
  3552. function run_comment_label($tag_name,$info,$cfg){fun('label@run_comment_label',$tag_name,$info,$cfg);}
  3553. function reply_label($tag_name,$info,$cfg){fun('label@reply_label',$tag_name,$info,$cfg);}
  3554. }
  3555. //下面这些用到的函数将弃用. 改用 fun 函数
  3556. if (!function_exists('get_app_upgrade_edition')) {
  3557. function get_app_upgrade_edition(){return fun('upgrade@local_edition');}
  3558. }
  3559. if(!function_exists('make_area_url')){
  3560. function make_filter_url($type='zone_id'){return fun('field@make_filter_url',$type);}
  3561. }
  3562. if(!function_exists('format_field')){
  3563. function format_field($info=[],$field='',$pagetype='list',$sysname=''){return fun('field@format',$info,$field,$pagetype,$sysname);}
  3564. }
  3565. if(!function_exists('get_filter_fields')){
  3566. function get_filter_fields($mid=0){return fun('field@list_filter',$mid);}
  3567. }
  3568. if(!function_exists('set_date')){
  3569. function set_date($time,$format='Y-m-d H:i:s'){return $time ? date($format,$time) : '';}
  3570. }
  3571. if(!function_exists('refreshto')){
  3572. function refreshto($url,$msg,$time=1){header("location:$url");exit;}
  3573. }
  3574. if(!function_exists('jump')){
  3575. function jump($msg,$url,$time=1){header("location:$url");exit;}
  3576. }
  3577. if(!function_exists('showmsg')){
  3578. function showmsg($msg){die($msg);}
  3579. }
  3580. if (!function_exists('get_file_path')) {
  3581. function get_file_path($id=0){return fun('zbuilder@get_file_path',$id);}
  3582. }
  3583. if (!function_exists('get_thumb')) {
  3584. function get_thumb($id=0){return fun('zbuilder@get_thumb',$id);}
  3585. }
  3586. if (!function_exists('get_web_menu')) {
  3587. function get_web_menu($type=''){return fun('page@get_web_menu',$type);}
  3588. }
  3589. if (!function_exists('getNavigation')) {
  3590. function getNavigation($link_name='',$link_url='',$fid=0){return fun('page@getNavigation',$link_name,$link_url,$fid);}
  3591. }
  3592. if (!function_exists('label_format_where')) {
  3593. function label_format_where($code=''){return fun('label@where',$code);}
  3594. }