Thinkcmf5 七牛云插件上传没有后缀不显示问题解决

最近发现用Thinkcmf开发的程序迁移服务器后,七牛云出了问题,cms后台上传的时候,看着七牛那边存储的文件不带后缀,切前台是带后缀的导致前台图片不显示问题。看了下七牛插件的源码,发现public/plugins/qiniu/Controller/AssetController里面的saveFile方法有些问题         $signingStr    = "/move/{$encodedEntryURISrc}/{$encodedEntryURIDest}";         $authorization = $auth->signRequest($signingStr, '');         $url = 'http://rs.qiniu.com/' . $signingStr;         $response = $client->post($url, null, ['Authorization' => 'QBox ' . $authorization]); 上面是改文件的一部分源码,执行上面程序七牛http返回码会直接301,原因是signingString多了第一个反斜线,去掉反斜线后,七牛返回的错误是bad_token,错误码是401,那就是token生成有误,token生成是   $authorization = $auth->signRequest($signingStr, ''); 具体代码逻辑可以自己点进去看下,我没有找到官网源码token生成的bug,所以这里我修复的方法是不走原来代码的逻辑,直接用bucketmanager替换原来的方式,整个saveFile方法如下:  public function saveFile()     {         $userId = cmf_get_current_admin_id();         $userId = $userId ? $userId : cmf_get_current_user_id();         if (empty($userId)) {             $this->error('error');         }         $validate = new Validate([             'filename' => 'require',             'file_key' => 'require',         ]);         $data = $this->request->param();         $result = $validate->check($data);         if ($result !== true) {             $this->error($validate);         }         $fileKey = $data['file_key'];         $suffix = cmf_get_file_extension($data['filename']);         $config = $this->getPlugin()->getConfig();         $accessKey = $config['accessKey'];         $secretKey = $config['secretKey'];         $auth = new Auth($accessKey, $secretKey);         $qiniuconfig=new Config();         $bk=new BucketManager($auth,$qiniuconfig);         $err=   $bk->rename($config['bucket'],$fileKey,$fileKey.".{$suffix}");         if($err){             $this->error($err);         }         list($fileinfo,$error)=$bk->stat($config['bucket'],$fileKey.".{$suffix}");         if($error){             $this->error($error);         }         $findAsset = Db::name('asset')->where('file_key', $fileKey)->find();         if (empty($findAsset)) {             Db::name('asset')->insert([                 'user_id'     => $userId,                 'file_size'   => $fileinfo['fsize'],                 'filename'    => $data['filename'],                 'create_time' => time(),                 'file_key'    => $fileKey,                 'file_path'   => $fileKey . ".{$suffix}",                 'suffix'      => $suffix             ]);         }         $this->success('success');     } 亲测没有问题

XiunoBBS 七牛上传插件

   这几天抽着闲暇时间搞了一个bbs,刚开始本来想用discuz,无奈界面太丑,漏洞也多,之前在gitee上发现过一个不错对的开源轻论坛框架xiunobbs,就拿它来搞了。二次开发过程中有一个需求,我想把附件传到七牛,不保存在服务器上,这样能节省服务器带宽,xiuno插件市场提供了一个免费插件,但是可能跟版本相关,已经不能用了,所以就自己弄了一个,今天就免费分享给大家。 安装方式是首先把插件adam_qiniu拖放到plugins文件夹下,然后登陆xiuno后台插件,本地插件,安装即可,在设置里面设置上七牛云的ak,sk,附件上传地址,bucket即可。 安装后上传的附件,不会再保存在upload目录下,上传到七牛后,会自动删除本地文件,这里有一个问题,附件下载的时候会寻找本地文件,没有的话会报attach_not_exist错误,然而本地附件已经被删除了,所以这里需要屏蔽到这块逻辑,在route/attach.php文件下大概131行,备注掉如下代码 : //!is_file($attachpath)AND message(-1, lang('attach_not_exists')); 在model/attach.func.php文件插入  // hook attach_assoc_post_middle.php 源码上下文这样: // 插入后,进行关联 $aid = attach_create($arr);          // hook attach_assoc_post_middle.php $post['message'] = str_replace($file['url'], $desturl, $post['message']); $post['message_fmt'] = str_replace($file['url'], $desturl, $post['message_fmt']); 本来想用hook方式解决这个问题,但是由于本人对框架还不是很熟悉,没有找到好的hook方式。 总结一下安装和配置步骤: 安装adam_qiniu 配置ak,sk,上传url,bucket 备注掉 route/attach.php 131行代码  model/attach.func.php 234行插入  // hook attach_assoc_post_middle.php  如果想恢复本地存储,卸载插件,然后取消上面备注掉的代码即可 下载地址: https://github.com/adamin1990/adam_qiniu https://gitee.com/adamin/adam_qiniu PS:关于安装插件后无法卸载问题,取消备注 view/js/bbs.js第124行   //window.location = jthis.attr('href');

PDO实现mysql数据库数据库备份

$db_hostname="localhost"; $db_database="数据库名"; $db_username="root"; $db_password="xxx"; $DBH = new PDO("mysql:host=$db_hostname;dbname=$db_database; charset=utf8", $db_username, $db_password); //put table names you want backed up in this array. //leave empty to do all //要备份的表 //全备份置空 $tables = array(); backup_tables($DBH, $tables); function backup_tables($DBH, $tables) {     $DBH->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL ); //Script Variables     $compression = false;     $BACKUP_PATH = "/data/www/backup/";     $nowtimename = time(); //create/open files  创建开启文件     if ($compression) {         $zp = gzopen($BACKUP_PATH.$nowtimename.'.sql.gz', "a9");     } else {         $handle = fopen($BACKUP_PATH.$nowtimename.'.sql','a+');     } //array of all database field types which just take numbers     $numtypes=array('tinyint','smallint','mediumint','int','bigint','float','double','decimal','real'); //get all of the tables     if(empty($tables)) {         $pstm1 = $DBH->query('SHOW TABLES');         while ($row = $pstm1->fetch(PDO::FETCH_NUM)) {             $tables[] = $row[0];         }     } else {         $tables = is_array($tables) ? $tables : explode(',',$tables);     } //cycle through the table(s)     foreach($tables as $table) {         $result = $DBH->query("SELECT * FROM $table");         $num_fields = $result->columnCount();         $num_rows = $result->rowCount();         $return=""; //uncomment below if you want 'DROP TABLE IF EXISTS' displayed //$return.= 'DROP TABLE IF EXISTS `'.$table.'`;'; //table structure         $pstm2 = $DBH->query("SHOW CREATE TABLE $table");         $row2 = $pstm2->fetch(PDO::FETCH_NUM);         $ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);         $return.= "nn".$ifnotexists.";nn";         if ($compression) {             gzwrite($zp, $return);         } else {             fwrite($handle,$return);         }         $return = ""; //insert values         if ($num_rows){ … Read more

PHP gzdeflate+str_to13+pack的一种加密解密代码方式

首先我们要加密的明文是: $test=<<<'EVE' echo '<script>alert("nihao")</script>';die; EVE; 字符串转16进制,16进制还原的方法 function String2Hex($string){     $hex='';     for ($i=0; $i < strlen($string); $i++){         $hex .= dechex(ord($string[$i]));     }     return $hex; } function Hex2String($hex){     $string='';     for ($i=0; $i < strlen($hex)-1; $i+=2){         $string .= chr(hexdec($hex[$i].$hex[$i+1]));     }     return $string; } 加密: $test1= gzdeflate($test);  #压缩 $test1=base64_encode($test1);  #base64编码 $adam=String2Hex(str_rot13($test1));  #选rot13转换 在转换成16进制 加密后的字符串: 463033426c537144676c794259666266585953596d527867586753446c66695a465a6b4b30654745756a64654a367178637962514e4e3d3d 解密: $ev=str_rot13(pack("H*",$adam));  #16进制还原,再rot13转换 $decoded=gzinflate(base64_decode($ev)); #base64解码,再gzinflate解压还原 这种方式可能用户部分代码混淆,留网站后门等。

PHP gzdeflate+str_to13+pack的一种加密解密代码方式

首先我们要加密的明文是: $test=<<<'EVE' echo '<script>alert("nihao")</script>';die; EVE; 字符串转16进制,16进制还原的方法 function String2Hex($string){     $hex='';     for ($i=0; $i < strlen($string); $i++){         $hex .= dechex(ord($string[$i]));     }     return $hex; } function Hex2String($hex){     $string='';     for ($i=0; $i < strlen($hex)-1; $i+=2){         $string .= chr(hexdec($hex[$i].$hex[$i+1]));     }     return $string; } 加密: $test1= gzdeflate($test);   #压缩$test1=base64_encode($test1); #转码$adam=String2Hex(str_rot13($test1)); #rot13+16进制转换 加密后的字符串: 463033426c537144676c794259666266585953596d527867586753446c66695a465a6b4b30654745756a64654a367178637962514e4e3d3d 解密: $ev=str_rot13(pack("H*",$adam)); $decoded=gzinflate(base64_decode($ev));

TP5.0和TP5.1 rce远程代码执行漏洞

上午同事发现官网被挂马了,title keywords和description都被改了,网站一句tp5开发的,前几天正好看到TP官方发布了一个安全补丁,阿里云也在提示,就看了下,大概是对controller没有严格过滤导致,影响的有TP,thinkcmf,DolphinPHP等 攻击例子: index.php?s=portal/thinkapp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=/home/wwwroot/demo/public/adam1.txt&vars[1][1]=aaaa 会在public目录下创建adam1.txt文件并写入内容,网上也发布了很多分析漏洞的文章。 https://www.kingkk.com/2018/12/ThinkPHP5-x-%E5%89%8D%E5%8F%B0getshell%E5%88%86%E6%9E%90/ http://www.lsablog.com/networksec/penetration/thinkphp5-rce-analysis/ 这个漏洞影响太大了,得赶紧修复,不能忽略。。 修复方式参考tp官方:https://blog.thinkphp.cn/869075

PHP利用反射获取class method 和function的源码

反射获取function源码  继承ReflectionFunction,扩展getSource方法: <?php /*     ___        __                   _        ____   ____     /   |  ____/ /____ _ ____ ___   (_)____  / __  / __    / /| | / __  // __ `// __ `__  / // __ / /_/ // / / /  / ___ |/ /_/ // /_/ // / / / / // // / / /__, // /_/ /  /_/  |_|__,_/ __,_//_/ /_/ /_//_//_/ /_//____/ ____/                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  做一款产品       愉悦自己                 ****************Powered by Adamin90******************** * @email: 14846869@qq.com * Date: 2018/12/27 * Time: 20:00 * @link: https://www.lixiaopeng.top ******************************************************* */ namespace appcommonlogic; class FunctionExtract  extends ReflectionFunction {     /**      * @return bool|string      * @author Adam      * Time: 2018/12/27 20:30      * Description:获取function源码       */     public function  getSource(){         if(!file_exists($this->getFileName())){             return false;         }         $startoffset=$this->getStartLine()-1;         $endoffset=$this->getEndLine()-$this->getStartLine()+1;         //   return $this->getFileName();         return join('',array_slice(file($this->getFileName()),$startoffset,$endoffset));     }     public function index(){         echo $this->getSource('id_decode');     } } 使用方法: 实例化 FunctionExtract类,构造器传入funtion名称即可 $fc = new FunctionExtract("get_avatar"); echo $fc->getSource(); 输出结果: function get_avatar($uid) { $avatar = Db::name('user')->where('id', $uid)->value('avatar'); if (!empty($avatar)) { $path = get_file_path($avatar); if($path !== false) { return $path; } } //默认头像地址 return '/static/mobile/images/avatar.jpg'; } 反射获取Method源码  继承ReflectionMethod,自定义getSource方法 class MethodExtract  extends ReflectionMethod {     /**      * @return bool|string      * @author Adam … Read more

PHP面试基础–网络

TCP的三次握手四次挥手: 三次握手(Three-way handshake)(SYN,SYN-ACK,ACK)建立连接流程: Host A 发送一个请求(SYNchronize packet)给Host B Host B 接受A的SYN,接着发送一个确同步SYNchronize-ACKnowledgement给Host A Host A 接受B的SYN-ACK同步确认,发送确认接受请求ACK Host B 接口ACK  此后tcp socket connection进入ESTABLISHED状态  四次挥手,终止连接流程: 客户端发送FIN请求终止连接,同时client进入FIN-WAIT-1状态,此时客户端仍然能够接受服务端数据,但是已经无法访问本地数据发送给服务端 Server接受客户端发送的FIN信号,同时发送一个ACK确认信号,服务端进入CLOSE-WAIT状态 客户端接受ACK,等待服务器FIN信号,此时客户端进入FIN-WAIT-2状态 服务端等待程序执行完后发送FIN信号,服务端进入LAST-ACK状态 客户端接受FIN,返回ACK确认信号,客户端进入TIME-WAIT状态 TCP和UDP的区别和应用: TCP(Transmission controll protocol)传输控制协议,是互联网最普遍的协议,他的建立需要三次握手 UDP(User datagram protocol)用户报文协议,他的联系不需要服务端等待确认信息,会一直发送传输速率比TCP要快 TCP应用web浏览器,ssh等非常普遍,UDP应用于广播,游戏等场景 OSI七层架构和TCP/IP五层架构: OSI:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层 TCP/IP:应用层,传输层,网络层,数据链路层,物理层

PHP面试基础之Array Functions

array_change_key_case:      把数组中所有键名称修改小写或大写,默认小写    2.array_chunk(array $array,int $size [, bool $preserve_keys=false])     把一个数组拆分成多个,第三个参数为true表示保留原来的键名    3.array_column(array $input,mixed $column_key [,$index_key=null)     返回数组中的单列,$column_key指返回哪列,$index_key如果设置了返回数组以其对应的值为返回数组的键    4.array_combile(array $keys,array $values)         数组结合    5.array_count_values(array $array)     计算数组内每个值的次数    6.array_diff_assoc ( array $array1 , array $array2 [, array $… ] ) 带索引计算数组的差集,返回$array1中有而$array2后面数组中没有的内容  7. array_diff_key ( array $array1 , array $array2 [, array $… ] ) 用键计算数组差集,返回一个数组,其key在$array1中存在,而在其他参数数组中不存在 8.array_diff_uassoc ( array $array1 , array $array2 [, array $… ], callable$key_compare_func ) 用用户提供的回调函数带索引计算数组的差集 9. array_diff_ukey ( array $array1 , array $array2 [, array $… ], callable$key_compare_func ) 用回调函数对键比较计算数组差集  10 array_diff ( array $array1 , array $array2 [, array $… ] ) 计算数组差集,返回在$array1中出现而在其他数组中不出现的数组,与array_diff_assoc区别在于不考虑索引 11.array array_fill_keys ( array $keys , mixed $value ) 用$keys的值作为key,$value的值作为值返回新数组,如果$value是关联数组,则全部返回作为值 12.array array_fill ( int $start_index , int $num , mixed $value ) 用$value的值填充长度为$num的数组,index从$start_index开始,如果$start_index是负数,则第一个键是$start_index,后面从0开始 13.array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) 用回调函数迭代过滤数组中的元素,如果不提供callback那么$array中值为false的都将被移除。flag默认是0表示只传递值比较,如果flag是ARRAY_FILTER_USE_KEY,那么只传递key给callback,如果是ARRAY_FILTER_USE_BOTH,那么key和value都传递

TP3.1迁移PHP7.2问题及解决办法

tp3.1程序放到php7.2环境下跑会直接报functions.php下112行未找到模块的错误,原因是preg_replace函数pattern中带/e在php7之后已经被移除不再支持 解决办法是用preg_replace_callback函数代替  其中涉及到的类有  ThinkTemplate.class.php  Dispatcher.class.php  common.php  下面贴出完整代码。 ThinkTemplate.class.php: <?php // +———————————————————————- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +———————————————————————- // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. // +———————————————————————- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +———————————————————————- // | Author: liu21st <liu21st@gmail.com> // +———————————————————————- /**  * ThinkPHP内置模板引擎类  * 支持XML标签和普通标签的模板解析  * 编译型模板引擎 支持动态缓存  * @category   Think  * @package  Think  * @subpackage  Template  * @author liu21st <liu21st@gmail.com>  */ class  ThinkTemplate {     // 模板页面中引入的标签库列表     protected   $tagLib          =   array();     // 当前模板文件     protected   $templateFile    =   '';     // 模板变量     public      $tVar            =   array();     public      $config          =   array();     private     $literal         =   array();     private     $block           =   array();     /**      * 架构函数      * @access public      */     public function __construct(){         $this->config['cache_path']         =   C('CACHE_PATH');         $this->config['template_suffix']    =   C('TMPL_TEMPLATE_SUFFIX');         $this->config['cache_suffix']       =   C('TMPL_CACHFILE_SUFFIX');         $this->config['tmpl_cache']         =   C('TMPL_CACHE_ON');         $this->config['cache_time']         =   C('TMPL_CACHE_TIME');         $this->config['taglib_begin']       =   $this->stripPreg(C('TAGLIB_BEGIN'));         $this->config['taglib_end']         =   $this->stripPreg(C('TAGLIB_END'));         $this->config['tmpl_begin']         =   $this->stripPreg(C('TMPL_L_DELIM'));         $this->config['tmpl_end']           =   $this->stripPreg(C('TMPL_R_DELIM'));         $this->config['default_tmpl']       =   C('TEMPLATE_NAME');         $this->config['layout_item']        =   C('TMPL_LAYOUT_ITEM');     }     private function stripPreg($str) { … Read more