一、错误原因其实从错误信息里就看出错误原因了:Arrayandstringoffsetaccesssyntaxwithcurlybracesisdeprecated,这是PHP7.4版本的更新,从7.4后,只能使用$value[0]的方式来获取字符串偏移,$value{0}已经被弃用。ThinkPHP报错的原因是在thinkphp\library\think\db\Query.php的568行有一段代码用了$value{0}的方式:$seq=(ord($value{0})%$rule['num'])+1;二、错误解决方法解决方法也很简单,将$value{0}改成$value[0]就行了:$seq=(ord($value[0])%$rule['num'])+1;
为什么网站要防跨域防盗链?随着前后端分离技术的兴起,很多手机端网站、小程序、APP访问后台数据都是调用API接口,很多接口都是内部使用的,而不是对外开放,如果没有做好防护措施,你家的接口很可能被其他人盗用,接口被盗用的的话,一方面会增加系统的负担,另一方面是数据被黑客利用,对企业造成一定的损失。本文着重介绍两种php防跨域防盗链的方法,供大家参考!一、禁止非本站域名访问<?php$refer=$_SERVER['HTTP_REFERER'];if($refer){$url=parse_url($refer);$host=explode('.',$url['host']);$count=count($host);$domainStr=$host[$count-2].'.'.$host[$count-1];if($domainStr!='www.zhansanjie.com'){//www.zhansanjie.com是你的网站域名exit('拒绝访问!');}}二、禁止直接访问本页面<?phpif(isset($_SERVER['HTTP_REFERER'])){$url_array=explode('http://',$_SERVER['HTTP_REFERER']);$url=explode('/',$url_array[1]);if($_SERVER['SERVER_NAME']!=$url[0]){//不是从本站来的exit("AccessDenied");}}else{//禁止直接访问本页面exit('拒绝访问!');}注:如果网址有端口,比如http://www.zhansanjie.com:88,就需要做如下修改:<?phpif(isset($_SERVER['HTTP_REFERER'])){$url_array=explode('http://',$_SERVER['HTTP_REFERER']);$url=explode('/',$url_array[1]);if(strstr($url[0],$_SERVER['SERVER_NAME'])==false){//不是从本站来的exit("AccessDenied");}}else{//禁止直接访问本页面exit('拒绝访问!');}?>
1.POST/***POST请求https接口返回内容*@paramstring$url[请求的URL地址]*@paramstring$post[请求的参数]*@returnstring*/publicfunctionpost_curls($url,$post){$curl=curl_init();//启动一个CURL会话curl_setopt($curl,CURLOPT_URL,$url);//要访问的地址curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);//对认证证书来源的检查curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,1);//从证书中检查SSL加密算法是否存在curl_setopt($curl,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);//模拟用户使用的浏览器curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);//使用自动跳转curl_setopt($curl,CURLOPT_AUTOREFERER,1);//自动设置Referercurl_setopt($curl,CURLOPT_POST,1);//发送一个常规的Post请求curl_setopt($curl,CURLOPT_POSTFIELDS,$post);//Post提交的数据包curl_setopt($curl,CURLOPT_TIMEOUT,30);//设置超时限制防止死循环curl_setopt($curl,CURLOPT_HEADER,0);//显示返回的Header区域内容curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);//获取的信息以文件流的形式返回$res=curl_exec($curl);//执行操作if(curl_errno($curl)){echo'Errno'.curl_error($curl);//捕抓异常}curl_close($curl);//关闭CURL会话return$res;//返回数据,json格式}2.GET/***CURL方式获取**@paramunknown$server*@paramunknown$send_data*@returnmixed*/publicfunctionget_api_alimama($url){$ch=curl_init();//设置选项,包括URLcurl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);//加上这才能获取跳转后的curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);//绕过ssl验证//curl_setopt($curl,CURLOPT_TIMEOUT,5);//超时时间,自行按情况而定curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//执行并获取HTML文档内容$output=curl_exec($ch);//释放curl句柄curl_close($ch);return$output;}
接口访问限制一.在接口中判断访问来源,例如php使用HTTP_REFERER来判断来源,如果是直接访问接口的请求不予处理,如果是从网页调用的请求再做处理。二.通过redis限制用户一分钟内访问次数functionrestrict($uid,$ip,$url){$redis=newRedis();$redis->connect('127.0.0.1',6379);$key='user:1:api_count'.$uid.$ip.$url;//限制次数为10$limit=10;//$check=$redis->exists($key);$check=1;if($check){$redis->incr($key);$count=$redis->get($key);if($count>$limit){exit('yourhavetoomanyrequest');}}else{$redis->incr($key);//限制时间为60秒$redis->expire($key,60);}$count=$redis->get($key);echo'Youhave'.$count.'request';}headers:{‘yl-authorization’:this.token}//设置header信息
foreach加&是用来做什么呢?foreach加&遍历的同时改变原数组即修改数据或者增加数据如果我要改变数组某一个值直接遍历的话原数组是不会变的下面提供两种方法1.最基本的两种方法第一种$aa=array(1,2,3);$newdata=array();foreach($aaas$k=>$v){if($v==1){$v='a';}array_push($newdata,$v);//这样可以得到我们想要的数组}dump($aa);第二种$aa=array(1,2,3);foreach($aaas$k=>$v){if($v==1){$aa[$k]='a';//这样可以得到我们想要的数组}}dump($aa);2.我们可以在遍历的值前面加个&符号这样就可以改变原数组了$aa=array(1,2,3);foreach($aaas$k=>&$v){if($v==1){$v='a';}}dump($aa);
首先来一段官方文档对Guzzle的介绍:Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上。接口简单:构建查询语句、POST请求、分流上传下载大文件、使用HTTPcookies、上传JSON数据等等。发送同步或异步的请求均使用相同的接口。使用PSR-7接口来请求、响应、分流,允许你使用其他兼容的PSR-7类库与Guzzle共同开发。抽象了底层的HTTP传输,允许你改变环境以及其他的代码,如:对cURL与PHP的流或socket并非重度依赖,非阻塞事件循环。中间件系统允许你创建构成客户端行为。执行Composer命令下载Guzzle:Linux环境、Windows都一样composerrequireguzzlehttp/guzzle下载完成后会生成一个vender文件夹:我这边使用的Tp5框架进行开发。因为Guzzle属于PHP的第三方扩展,所以使用前先 use引用 接着实例化*******<?phpnamespaceapp\admin\controller;useapp\admin\controller\BasicAdmin;useapp\admin\service\DataService;useGuzzleHttp\Client;usethink\Db;classNewsextendsBasicAdmin{//企业微信推送消息publicfunctionsend_message(){//实例化GuzzleHttp$client=newClient();//文章id$news_id=input('news_id');//查询文章$news_data=Db::table('wm_news')->where('id',$news_id)->find();//企业微信参数$corpid="*************";$secret="*********";//先通过token获取access_token$access_token=cookie('access_token');//如果access_token为空,则去获取,存储//如果推送的消息没有图片则给一张企业默认图片if(empty($news_data['img_url'])){$news_data['img_url']='https://tcms.living-power.com/static/images/common/lingpa.jpg';}if(empty($access_token)){$url="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".$corpid."&corpsecret=".$secret;$response=$client->request('GET',$url);$body=$response->getBody();//获取相应体$html=$body->getContents();//获取目标页面//解密json字符串$res=json_decode($html,true);//存储access_token$access_token=$res['access_token'];}$agentid="1000002";//推送消息//如果推送的消息没有图片则给一张企业默认图片if(empty($news_data['img_url'])){$news_data['img_url']='http://cms.living-power.com/static/images/common/lingpa.jpg';}$msgUrl="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=".$access_token;$send_msg['touser']='@all';$send_msg['msgtype']='news';$send_msg['agentid']=$agentid;$send_msg['news']['articles'][0]['title']=$news_data['title'];$send_msg['news']['articles'][0]['description']=strip_tags($news_data['content']);$send_msg['news']['articles'][0]['url']='https://tqymobile.living-power.com/index.php/blog/news/detail?id='.$news_id;$send_msg['news']['articles'][0]['picurl']=$news_data['img_url'];$send_msg['safe']=0;//$send_msg=json_encode($send_msg);$response=$client->request('POST',$msgUrl,['json'=>$send_msg]);$body=$response->getBody();//获取相应体$html=$body->getContents();//获取目标页面//解密json字符串$res=json_decode($html,true);//print_r($res);die();}}
//定义编码header('Content-Type:text/html;charset=utf-8');//Atomheader('Content-type:application/atom+xml');//CSSheader('Content-type:text/css');//Javascriptheader('Content-type:text/javascript');//JPEGImageheader('Content-type:image/jpeg');//JSONheader('Content-type:application/json');//PDFheader('Content-type:application/pdf');//RSSheader('Content-Type:application/rss+xml;charset=ISO-8859-1');//Text(Plain)header('Content-type:text/plain');//XMLheader('Content-type:text/xml');//okheader('HTTP/1.1200OK');//设置一个404头:header('HTTP/1.1404NotFound');//设置地址被永久的重定向header('HTTP/1.1301MovedPermanently');//转到一个新地址header('Location:http://www.example.org/');//文件延迟转向:header('Refresh:10;url=http://www.example.org/');print'Youwillberedirectedin10seconds';//当然,也可以使用html语法实现//<metahttp-equiv="refresh"content="10;http://www.example.org//>//overrideX-Powered-By:PHP:header('X-Powered-By:PHP/4.4.0');header('X-Powered-By:Brain/0.6b');//文档语言header('Content-language:en');//告诉浏览器最后一次修改时间$time=time()-60;//orfilemtime($fn),etcheader('Last-Modified:'.gmdate('D,dMYH:i:s',$time).'GMT');//告诉浏览器文档内容没有发生改变header('HTTP/1.1304NotModified');//设置内容长度header('Content-Length:1234');//设置为一个下载类型header('Content-Type:application/octet-stream');header('Content-Disposition:attachment;filename="example.zip"');header('Content-Transfer-Encoding:binary');//loadthefiletosend:readfile('example.zip');//对当前文档禁用缓存header('Cache-Control:no-cache,no-store,max-age=0,must-revalidate');header('Expires:Mon,26Jul199705:00:00GMT');//Dateinthepastheader('Pragma:no-cache');//设置内容类型:header('Content-Type:text/html;charset=iso-8859-1');header('Content-Type:text/html;charset=utf-8');header('Content-Type:text/plain');//纯文本格式header('Content-Type:image/jpeg');//JPG***header('Content-Type:application/zip');//ZIP文件header('Content-Type:application/pdf');//PDF文件header('Content-Type:audio/mpeg');//音频文件header('Content-Type:application/x-shockw**e-flash');//Flash动画//显示登陆对话框header('HTTP/1.1401Unauthorized');header('WWW-Authenticate:Basicrealm="TopSecret"');print'Textthatwillbedisplayediftheuserhitscancelor';print'enterswronglogindata';
函数名称:strstr()用途:已知字符串中的一部分,获取字符串中这一部分的前面或者后面的字符串. 参数:参数1,就是从这个字符串中搜索.(大的字符串).参数2,就是被搜索的字符串.(小的字符串).参数3,bool,默认为false,为true则返回前面的字符串(重点:不包含参数2的字符串),为false返回后面的字符串(重点:包含参数2的字符串)返回值:字符串详解:<?php$str="站三界导航www.zhansanjie.com";$str2="www.zhansanjie.com";$res=strstr($str,$str2);var_dump($res);输出:string(8)"www.zhansanjie.com"说明这个返回的字符串,包含了参数2中的字符串. 加上第三个参数:<?php$str="站三界导航www.zhansanjie.com";$str2="www.zhansanjie.com";$res=strstr($str,$str2,true);var_dump($res);输出:string(6)"站三界导航"说明第三个参数为true时,返回的是前面的字符串,但是不包含被搜索的字符串.
对于限制了ip和来源的网站,使用正常的访问方式是无法访问的。本文将介绍一种方法,使用php的curl类实现模拟ip和来源,访问那些限制了ip和来源的网站。server.php<?php$client_ip=getip();$referer=getreferer();$allow_ip='192.168.1.100';$allow_referer='http://www.zhansanjie.com';if($client_ip==$allow_ip&&strpos($referer,$allow_referer)===0){echo'allowaccess';}else{echo'denyaccess';}//获取访问者ipfunctiongetip(){if(!empty($_SERVER['HTTP_CLIENT_IP'])){$cip=$_SERVER['HTTP_CLIENT_IP'];}elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){$cip=$_SERVER['HTTP_X_FORWARDED_FOR'];}elseif(!empty($_SERVER['REMOTE_ADDR'])){$cip=$_SERVER['REMOTE_ADDR'];}else{$cip='';}return$cip;}//获取访问者来源functiongetreferer(){if(isset($_SERVER['HTTP_REFERER'])){return$_SERVER['HTTP_REFERER'];}return'';}?<2.使用curl正常访问>?phpfunctiondoCurl($url,$data=array(),$header=array(),$timeout=30){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_HTTPHEADER,$header);curl_setopt($ch,CURLOPT_POST,true);curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($data));curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);$response=curl_exec($ch);if($error=curl_error($ch)){die($error);}curl_close($ch);return$response;}//调用$url='http://www.zhansanjie.com/data.php';$response=doCurl($url);echo$response;?<返回denyaccess3.使用curl模拟ip和来源进行访问1.模拟来源curl_setopt($ch,CURLOPT_REFERER,'来源');2.模拟ipcurl_setopt($ch,CURLOPT_HTTPHEADER,array('CLIENT-IP:模拟ip','X-FORWARDED-FOR:模拟ip'));完整代码如下>?phpfunctiondoCurl($url,$data=array(),$header=array(),$referer='',$timeout=30){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_HTTPHEADER,$header);curl_setopt($ch,CURLOPT_POST,true);curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($data));curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);//模拟来源curl_setopt($ch,CURLOPT_REFERER,$referer);$response=curl_exec($ch);if($error=curl_error($ch)){die($error);}curl_close($ch);return$response;}//调用$url='http://xxx.com/server.php';$data=array();//设置IP$header=array('CLIENT-IP:192.168.1.100','X-FORWARDED-FOR:192.168.1.100');//设置来源$referer='http://xxxx.cn/';$response=doCurl($url,$data,$header,$referer,5);echo$response;?<返回allowaccess
最近搞一点东西要用到对称加密,于是在网上找到一个不错的对称加密方法,分享给大家。/***简单对称加密算法之加密*站三界导航www.zhansanjie.com*@paramString$string需要加密的字串*@paramString$skey加密EKY*@returnString*/functionencode($string='',$skey='cxphp'){$strArr=str_split(base64_encode($string));$strCount=count($strArr);foreach(str_split($skey)as$key=>$value)$key<$strCount&&$strArr[$key].=$value;returnstr_replace(array('=','+','/'),array('O0O0O','o000o','oo00o'),join('',$strArr));}/***简单对称加密算法之解密*@paramString$string需要解密的字串*@paramString$skey解密KEY*@authorAnyonZou<zoujingli@qq.com>*@date2013-08-1319:30*@update2014-10-1010:10*@returnString*/functiondecode($string='',$skey='cxphp'){$strArr=str_split(str_replace(array('O0O0O','o000o','oo00o'),array('=','+','/'),$string),2);$strCount=count($strArr);foreach(str_split($skey)as$key=>$value)$key<=$strCount&&isset($strArr[$key])&&$strArr[$key][1]===$value&&$strArr[$key]=$strArr[$key][0];returnbase64_decode(join('',$strArr));}echo'<pre>';echo"encode:".($enstring=encode($str)).'<br/>';echo"decode:".decode($enstring);die();安全URL解码/***安全URL编码*@paramstring$data*@站三界导航www.zhansanjie.com*@returnstring*/functionencode($data){returnstr_replace(array('+','/','='),array('-','_',''),base64_encode(serialize($data)));}functiondecode($string){$data=str_replace(array('-','_'),array('+','/'),$string);$mod4=strlen($data)%4;($mod4)&&$data.=substr('====',$mod4);returnunserialize(base64_decode($data));}UTF8三十六进制/***UTF8字符串加密*@paramstring$string*@站三界导航www.zhansanjie.com*@returnstring*/functionencode($string){$chars='';$len=strlen($string=iconv('utf-8','gbk',$string));for($i=0;$i<$len;$i++){$chars.=str_pad(base_convert(ord($string[$i]),10,36),2,0,0);}returnstrtoupper($chars);}functiondecode($string){$chars='';foreach(str_split($string,2)as$char){$chars.=chr(intval(base_convert($char,36,10)));}returniconv('gbk','utf-8',$chars);}别的方式//字符串加密functionlockString($txt,$key){$chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";$nh=rand(0,64);$ch=$chars[$nh];$mdKey=md5($key.$ch);$mdKey=substr($mdKey,$nh%8,$nh%8+7);$txt=base64_encode($txt);$tmp='';$i=0;$j=0;$k=0;for($i=0;$i<strlen($txt);$i++){$k=$k==strlen($mdKey)?0:$k;$j=($nh+strpos($chars,$txt[$i])+ord($mdKey[$k++]))%64;$tmp.=$chars[$j];}returnurlencode($ch.$tmp);}functionunlockString($txt,$key){$txt=urldecode($txt);$chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";$ch=$txt[0];$nh=strpos($chars,$ch);$mdKey=md5($key.$ch);$mdKey=substr($mdKey,$nh%8,$nh%8+7);$txt=substr($txt,1);$tmp='';$i=0;$j=0;$k=0;for($i=0;$i<strlen($txt);$i++){$k=$k==strlen($mdKey)?0:$k;$j=strpos($chars,$txt[$i])-$nh-ord($mdKey[$k++]);while($j<0)$j+=64;$tmp.=$chars[$j];}returnbase64_decode($tmp);}auth_code优化版/***@paramstring$string加密字符串内容*@paramstring$operation加密或者解密*@paramstring$key私钥*@paramint$expiry过期时间/秒0为永不过期*@returnfalse|string*/functionauth_code(string$string,$operation='DECODE',$key='',$expiry=0){$cakey_length=4;$key=md5($key);$keys=md5(substr($key,0,16));$keytab=md5(substr($key,16,16));if($operation==='DECODE'){$key_str=substr($string,0,$cakey_length);}else{$key_str=substr(md5(microtime()),-$cakey_length);}$keycode=$cakey_length?$key_str:'';$cryptic=$keys.md5($keys.$keycode);$key_length=strlen($cryptic);$string=$operation==='DECODE'?base64_decode(substr($string,$cakey_length)):sprintf('%010d',$expiry?$expiry+time():0).substr(md5($string.$keytab),0,16).$string;$string_length=strlen($string);$result='';$box=range(0,255);$render=array();for($i=0;$i<=255;$i++){$render[$i]=ord($cryptic[$i%$key_length]);}for($j=$i=0;$i<256;$i++){$j=($j+$box[$i]+$render[$i])%256;$tmp=$box[$i];$box[$i]=$box[$j];$box[$j]=$tmp;}for($a=$j=$i=0;$i<$string_length;$i++){$a=($a+1)%256;$j=($j+$box[$a])%256;$tmp=$box[$a];$box[$a]=$box[$j];$box[$j]=$tmp;$result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));}if($operation==='DECODE'){if((strpos($result,0)===0||substr($result,0,10)-time()>0)&&strpos(md5(substr($result,26).$keytab),substr($result,10,16))===0){returnsubstr($result,26);}return'';}return$keycode.str_replace('=','',base64_encode($result));}