零艺江湖 - 行到水穷处,坐看云起时 | 个人生活记录 | 零艺客 - PHP
type: channel
link: https://www.lykep.com/index.php/category/php/
description: PHP案例代码记录
items: 【笔记】file_get_contents请求传参
items: 【分享】燃鹅解密PHP版，可做接口
items: 【笔记】PHP封装的不错的一个Curl方法
items: 【笔记】PHP一键打包文件夹内文件实现
items: 【笔记】PHP自定义下载地址实现
items: 【原创】懒人收作业源码
items: 【笔记】PHP错误代码500 快速定位方法
items: 【笔记】ThinkPHP5.1+ 安装使用Swagger-Ui
items: 【笔记】PHP原生实现JWT示例
items: 【笔记】Nginx反向代理

【笔记】file_get_contents请求传参
type: item
date: 2022-07-11T09:48:00+08:00
description: <?php $data = array ( "name" => 'test_name' , "content" => 'test_con' ); $data = http_build_query( $data ); $opts = array ( 'http' => array ( 'method' => "POST" , 'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-length:" . strlen ( $data ). "\r\n" . "Cookie: foo=bar\r\n" . "\r\n" , 'content' => $data , ) ); $cxContext = stream_context_create( $opts ); $sFile = file_get_contents ( "http://127.0.0.1/reponse.php" , false, $cxContext ); echo $sFile ; ?> // 结果 string(132) "array(2) { ["content"]=> string(8) "test_con" ["name"]=> string(9) "test_name" } array(1) { ["foo"]=> string(3) "bar" } "

【分享】燃鹅解密PHP版，可做接口
type: item
date: 2021-02-25T21:46:00+08:00
description: 序[scode type="share"]没什么好说的，蹭个热度，燃鹅解密，直接上代码。[/scode]PHP版<?php /* * @Author: ZeroArt * @Date: 2021-02-25 21:41:02 * @Link: http://lykep.com * @LastEditors: ZeroArt * @LastEditTime: 2021-02-25 21:41:30 * @Description: */ class rane { // utf8编码 function decodeUtf8($bytes) { $encoded = ""; for ($i = 0; $i < count($bytes); $i++) { $encoded .= '%' . dechex($bytes[$i]); } return urldecode($encoded); } // 数组转字符串 function dec($t) { if (is_string($t)) { return $t; } else { $n = []; for ($i = 0; $i < count($t); $i++) { $n[] = $t[$i]; } } return $this->decodeUtf8($n); } // hex字符串转数组 public function n($t) { $e = 0; $n = strlen($t); if ($n % 2 != 0) { return null; } else { $n /= 2; $o = []; for ($i = 0; $i < $n; $i++) { $r = substr($t, $e, 2); $a = hexdec($r); $o[] = $a; $e += 2; } $os = []; foreach ($o as $key => $value) { $os[] = $value; } return $os; } } // 加解密核心算法 function m($t, $e) { $a = []; $n = ""; $o = count($e); $i = ($t ^ $o) % 255; $r = (($o & $i) + ($t ^ $i)) % 255; $a = []; $s = 0; for ($s = 0; $s < $o; $s++) { $i -= ($r * $o ^ $t) % 255; $t -= $r; $n = 255 & (($n = $e[$s]) ^ ($r = $i % 255)); $a[] = $n; } return $a; } } $rane = new rane(); // 常规模式 if (isset($_GET['t']) && isset($_GET['v'])) { echo ($rane->dec($rane->m($_GET['t'], $rane->n($_GET['v'])))); exit(); } // JOSN格式 if (isset($_GET['json']) || isset($_POST['json'])) { $param = json_decode($_REQUEST['json'], true); echo ($rane->dec($rane->m($param['t'], $rane->n($param['v'])))); exit(); } // 案例 if (isset($_GET['dome'])) { echo ($rane->dec($rane->m('59131814', $rane->n('ad88eff390bd7706d24a93f04727c0d61f886f3f4922680c5cb7f8716073379a625845875d6708477d3014f31e575098b983ce709bd1f7f3f7fa63f6e12eb216ade7a43e314048cc80d73c18d6a8d72cb1f231593b4aa9ef56a170fbf9db23d07048589053d56fa4bafdbbe8b52720d938f6b4f85a2dd0092805fc2c6aa4c8fd3b92a89c7786368eb0e979d96c03831412d23d008a491b68295d893c77251902dba8ee84fe390efbee01d65815254bd9bbe1bd7e12b1fc0542bfc893d0ac83c3b7abafbc6328aa37f89a378fce83e01d49d19ef4ed20893993870501fdef066…

【笔记】PHP封装的不错的一个Curl方法
type: item
date: 2020-12-12T02:22:00+08:00
description: 序个人对于Curl还是蛮常用的，偶然发现一个封装这么完全的，记录下。代码<?php /** * @author 教书先生 * @link https://blog.oioweb.cn * @date 2020年11月12日18:00:30 * @msg PHPCurl封装的方法 */ function teacher_curl($url, $paras = array()) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); if (@$paras['Header']) { $Header = $paras['Header']; } else { $Header[] = "Accept:*/*"; $Header[] = "Accept-Encoding:gzip,deflate,sdch"; $Header[] = "Accept-Language:zh-CN,zh;q=0.8"; $Header[] = "Connection:close"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $Header); if (@$paras['ctime']) { // 连接超时 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $paras['ctime']); } else { curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); } if (@$paras['rtime']) { // 读取超时 curl_setopt($ch, CURLOPT_TIMEOUT, $paras['rtime']); } if (@$paras['post']) { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $paras['post']); } if (@$paras['header']) { curl_setopt($ch, CURLOPT_HEADER, true); } if (@$paras['cookie']) { curl_setopt($ch, CURLOPT_COOKIE, $paras['cookie']); } if (@$paras['refer']) { if ($paras['refer'] == 1) { curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f='); } else { curl_setopt($ch, CURLOPT_REFERER, $paras['refer']); } } if (@$paras['ua']) { curl_setopt($ch, CURLOPT_USERAGENT, $paras['ua']); } else { curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"); } if (@$paras['nobody']) { curl_setopt($ch, CURLOPT_NOBODY, 1); } curl_setopt($ch, CURLOPT_ENCODING, "gzip"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if (@$paras['GetCookie']) { curl_setopt($ch, CURLOPT_HEADER, 1); $result = curl_exec($ch); preg_match_all("/Set-Cookie: (.*?);/m", $result, $matches); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($result, 0, $headerSize); //状态码 $body = substr($result, $headerSize); $ret = [ "Cookie" => $match…

【笔记】PHP一键打包文件夹内文件实现
type: item
date: 2020-11-28T14:28:21+08:00
description: 序[scode type="share"]网站上需要用到打包文件的可以使用，代码已验证，记录下。[/scode]实现代码[scode type="blue"]//在指定路径创建一个空的压缩包 例如 当前路径 创建 pack.zip // 获取压缩文件清单 $fileList = file_list(__DIR__."/temp/img"); // 打包文件名称 $_filename = date('YmdHis') . '.zip'; // 打包文件保存路径 $filename = __DIR__ .'/temp/'. $_filename; // 如果复制空压缩包成功则加入压缩文件 if (copyFile(__DIR__ . '/pack.zip', $filename)) { // 实例化压缩类 $zip = new \ZipArchive(); // 打开压缩包 if ($zip->open($filename, \ZipArchive::CREATE)) { foreach ($fileList as $file) { //向压缩包中添加文件 $zip->addFile($file, basename($file)); } //关闭压缩包 $zip->close(); exit('打包完成'); } else { exit('打包失败'); } } else { exit('压缩包创建失败'); } //自定义方法补充 // 获取所有文件夹 function file_list($path, $complete = true) { //设置空数组 $arr = array(); //判断文件是否存在 if (is_file($path)) { } else { //判断是否是路径 if (is_dir($path)) { //获取目录下所有文件和目录 $data = scandir($path); //判断是否为空 if (!empty($data)) { //循环取出文件 foreach ($data as $value) { //过滤特殊文件 if ($value != '.' && $value != '..') { //判断是返回完整路径还是仅文件名 if ($complete) { $sub_path = $path . "/" . $value; } else { $sub_path = $value; } //判断是否存在二级目录 if (is_dir($sub_path)) { //递归二级目录文件 $temp = file_list($sub_path); $arr = array_merge($temp, $arr); } else { $arr = array_merge([$sub_path], $arr); } } } } } } //返回数据 return $arr; } // 复制文件 function copyFile($filepath, $tofilepath) { //复制文件地址 复制文件到地址 return copy($filepath, $tofilepath); } [/scode]

【笔记】PHP自定义下载地址实现
type: item
date: 2020-11-28T14:07:23+08:00
description: 序[scode type="share"]有时候某些资源不好走直链或者需要设置下载限制的时候可以使用以下方法来达到目的，已实践代码，记录下。[/scode]实现代码[scode type="blue"]//下载的文件名称 $downname = date('Ymd').'.zip'; //需要下载文件所存放的目录 $file_name = __DIR__.'/temp/123.zip'; $fp = fopen($file_name, "r"); //获取文件的字节 $file_size = filesize($file_name); // 下载文件需要设置的协议头 Header("Content-type: application/octet-stream"); Header("Accept-Ranges: bytes"); Header("Accept-Length:" . $file_size); Header("Content-Disposition: attachment; filename=$downname"); //设置一次读取的字节数，每读取一次，就输出数据（即返回给浏览器） $buffer = 1024; $file_count = 0; //读取的总字节数 while (!feof($fp) && $file_count < $file_size) { $file_con = fread($fp, $buffer); $file_count += $buffer; echo $file_con; } fclose($fp); [/scode]

【原创】懒人收作业源码
type: item
date: 2020-11-28T13:48:00+08:00
description: 序[scode type="share"]水友定做的一个收作业管理系统，基于Thinkphp框架编写。程序为私人定制，不做开源仅用于项目展示。[/scode]下载功能[scode type="blue"]后台1.同学管理包含：同学CRUD同学数据导出文件同学数据打印2.学科管理包含：学科CRUD任命课代表3.作业发布包含：作业CRUD以科目为单位，对以添加同学发布作业（可设置作业提交格式、到期时间）4.作业管理包含：当此作业一键打包作业查看作业上交情况上交名单导出文件上交名单数据打印5.网站设置包含：网站基础信息设置6.其他模块包含：资源访问伪装资源打包下载三级操作权限前台1.作业上传[/scode]

【笔记】PHP错误代码500 快速定位方法
type: item
date: 2020-10-12T23:30:12+08:00
description: 序[scode type="share"]隔壁AE站点看到的，代码放在程序最开始，可以快速定位错误文件、行数、原因。预计以后会用到，先记录下吧i[]~(￣▽￣)~*[/scode]代码// 代码 register_shutdown_function(function(){ print_r(error_get_last()); }); // 异常信息 array ( ltype] =>4 [message] =>synt ax error，umnexpected ''site_info'’(T_CONSTANT_ENCAPSED_STRLNG)，expecting ']' [file]=> D:iphpStudyiPHPTutorialiWWidemoltemplateladminisetting.php [line] => 24 )

【笔记】ThinkPHP5.1+ 安装使用Swagger-Ui
type: item
date: 2020-10-12T13:17:00+08:00
description: 序[scode type="share"]最近写的项目基本都基于前后端分离，写完接口还要去编写文档，两边折腾太累了，找了这么个解决方案Swagger-php，能够在写接口的时候通过注解的方式实现自动生成文档，花了不少时间总算折腾出来了，记录下！[/scode]技术点[scode type="yellow"]1.composer//更新指令 composer update 2.swagger-ui//git下载 git clone https://github.com/swagger-api/swagger-ui.git 3.swagger-php[/scode]安装步骤[scode type="blue"]1.安装swagger-php后端进入你的tp5框架找到根目录下,打开composer.json找到require项，添加一行(注意，每行用逗号分隔)。"zircote/swagger-php": "*" 使用更新命令composer update 使用安装指令（这里安装以下这个版本，测试时安装了N个版本，唯独这个成功了( ╯□╰ )）composer require "zircote/swagger-php:2.0.13" 2.生成swagger.json文件(这里需要先建立存放swagger.json的文件夹swagger-docs，这个文件夹名称随意，存放位置也随意 )//第1个路径是你安装成功后组件的路径； //第2个路径是你想要生成这个目录下所有用swagger方式注释的php文件，把所有注释生成api文档； //第3个路径是你存放生成swagger.json的路径。 php ./vendor/zircote/swagger-php/bin/swagger ./vendor/zircote/swagger-php/Examples -o ./swagger-docs/swagger.json 3.swagger-ui加载生成的json文件<?php namespace app\index\controller; use think\Controller; use Swagger\Annotations as SWG; class Index extends Controller { public function index(){ // APP_PATH tp框架5.1不再提供常量，自己定义根目录 // 测试dome在vendor/zircote/swagger-php/Examples/dynamic-reference 自行复制测试 $path = APP_PATH.'/application/dynamic-reference'; //你想要哪个文件夹下面的注释生成对应的API文档 $swagger = \Swagger\scan($path); $swagger_json_path = APP_PATH.'/swagger-docs/swagger.json'; // 检测模板目录 $dir = dirname($swagger_json_path); if (!is_dir($dir)) { mkdir($dir, 0755, true); } // 更新文档 $myfile = fopen($swagger_json_path, "w") or die("Unable to open file!"); $swagger=json_encode($swagger, true); fwrite($myfile, $swagger); fclose($myfile); // 跳转到文档页面 $this->redirect('/swagger-ui/index.html'); } } 5.下载swagger-ui执行下面命令git clone https://github.com/swagger-api/swagger-ui.git 克隆下来后将dist文件夹内的文件 复制到例如public目录下新建文件夹Swagger-Ui中，修改Swagger-Ui中的index.html文件 在控制器中新建方法，使上方文档能读取到json数据 public function swagger() { echo file_get_contents(APP_PATH . '/swagger-docs/swagger.json'); } [/scode]

【笔记】PHP原生实现JWT示例
type: item
date: 2020-07-16T18:48:00+08:00
description: 序[scode type="share"]基于Laravel框架写的程序需要跟其他端进行交互，需要使用到jwt令牌，试了框架的第三方包感觉好麻烦，网上找了好久终于找到了(●ˇ∀ˇ●)，困扰许久的问题就这么解决了，记录一下。[/scode]代码<?php //框架中使用解除下面命名空间 //namespace App\Http\Controllers\User; /** * PHP实现jwt */ class JwtControler { //头部 private static $header = array( 'alg' => 'HS256', //生成signature的算法 'Type' => 'Jwt' //类型 ); //使用HMAC生成信息摘要时所使用的密钥 private static $key = 'crow'; /** * 获取jwt token * @param array $payload jwt载荷 格式如下非必须 * [ * 'iss'=>'jwt_admin', //该JWT的签发者 * 'iat'=>time(), //签发时间 * 'exp'=>time()+7200, //过期时间 * 'nbf'=>time()+60, //该时间之前不接收处理该Token * 'sub'=>'www.admin.com', //面向的用户 * 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识 * ] * @return bool|string */ public static function getToken(array $payload) { if (is_array($payload)) { $base64header = self::base64UrlEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE)); $base64payload = self::base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE)); $token = $base64header . '.' . $base64payload . '.' . self::signature($base64header . '.' . $base64payload, self::$key, self::$header['alg']); return $token; } else { return false; } } /** * 验证token是否有效,默认验证exp,nbf,iat时间 * @param string $Token 需要验证的token * @return bool|string */ public static function verifyToken(string $Token) { $tokens = explode('.', $Token); if (count($tokens) != 3) return false; list($base64header, $base64payload, $sign) = $tokens; //获取jwt算法 $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY); if (empty($base64decodeheader['alg'])) return false; //签名验证 if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign) return false; $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY); //签发时间大于当前服务器时间验证失败 if (isset($payload['iat']) && $payload['iat'] > time()) return false; //过期时间小宇当前服务器时间验证失败 if (isset($payload['exp']) && $payload['exp'] < time()) return false; //该nbf时间之前不接收处理该Token if (isset($payload['nbf']) && $payload['nbf'] > t…

【笔记】Nginx反向代理
type: item
date: 2020-03-26T22:59:50+08:00
description: 序[scode type="share"]对于网站某些链接或者某些站点不方便公示出地址的，利用Nginx反向代理可以很好的解决，花了点时间测试得到以下结果。[/scode]代码#不跳转源站 location / { #rewrite ^/(.*)$1 break; proxy_pass http://tv.lessh.cn/; } #跳转部分格式下的源站 location / { proxy_pass http://tv.lessh.cn; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; } #不跳转源站 location /{ proxy_pass http://tv.lessh.cn; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; } #类型过滤 location ~ .*\.(php|php5)?$ { } #类型缓存 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; }