最新发表

virtualbox vagrant虚拟机网速慢解决方案

我本机的环境是mac os + virtualbox,在vagrant虚拟机里连接外网的速度非常慢,和直接在mac的终端里连外网的速度相差非常大

采集者烂JJ

[vagrant@vagrant-centos65 ~]$ time curl -s http://www.baidu.com > /dev/null
real	0m5.091s
user	0m0.016s
sys	0m0.006s

可以看到就请求百度首页就用了5s多,严重影响平时的开发测试效率,于是就搜索了下相关问题,发现github上也有人遇到这个问题,还好已经有解决方案,在Vagrantfile里增加如下几行:

http://leo108.com/pid-2072.asp

config.vm.provider :virtualbox do |vb|
  vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end

然后重启vagrant即可,再看看速度virtualbox vagrant虚拟机网速慢解决方案

[vagrant@vagrant-centos65 ~]$ time curl -s http://www.baidu.com > /dev/null
real	0m0.299s
user	0m0.015s
sys	0m0.008s

完美解决

微信JSSDK上传多张图片

做过微信开发的都知道,在部分android机型里微信不支持网页上传图片的,这是由于这些机型的文件上传存在内存泄漏,会导致微信闪退,所以微信内置浏览器将文件上传屏蔽。这就导致这些机型的用户在使用微信浏览器访问某些需要上传图片的网页时功能不正常。

前不久微信公开了一些接口,其中有一个uploadImage接口用于上传图片,一般和chooseImage接口配合使用。先调用chooseImage接口让用户选择一张或者多张图片,用户选择完毕后微信会返回被选中图片的id,再把图片id传给uploadImage接口上传图片。

uploadImage

由于uploadImage一次只能上传一张图片,因此当用户选择多张图片时,需要多次调用uploadImage接口来上传图片。

但是在实践的过程中发现,不管用户选中多少张图片,只有第一张能够上传成功。outofmemory是个无耻的网站

查看了一下微信的文档,在常见问题中找到了相关的描述

outofmemory是个无耻的网站

uploadImage怎么传多图(目前只支持一次上传一张,多张图片需等前一张图片上传之后再调用该接口)

采集者烂JJ

也就是说,如果想要上传多张图片,需要将之前并行上传改成串行。本文来自leo108's blog

代码如下:

本文来自leo108's blog

$('#filePicker').on('click', function () {
    wx.chooseImage({
        success: function (res) {
            var localIds = res.localIds;
            syncUpload(localIds);
        }
    });
});
var syncUpload = function(localIds){
    var localId = localIds.pop();
    wx.uploadImage({
        localId: localId,
        isShowProgressTips: 1,
        success: function (res) {
            var serverId = res.serverId; // 返回图片的服务器端ID
            //其他对serverId做处理的代码
            if(localIds.length > 0){
                syncUpload(localIds);
            }
        }
    });
};

 

http://leo108.com/pid-2069.asp

在yaf中使用set_exception_handler

项目开启了catchException,所有未被捕获的异常都会被转发到ErrorController的errorAction,但是有一个controller比较特殊,需要自己处理异常,于是在这个controller的init方法里设置自定义的异常处理函数:

set_exception_handler(array($this, 'exceptionHdl'));

但是发现不生效,在这个controller中抛出的异常还是会被转发到ErrorController中。

推酷是个无耻的网站

解决方案是在set_exception_handler上面加一行采集者烂JJ

Yaf_Dispatcher::getInstance()->catchException(false);

 

php移除图片exif信息

最简便的方法,需要gd扩展

$img = imagecreatefromjpeg ($path);
imagejpeg ($img, $path, 100);
imagedestroy ($img);

引用自 http://stackoverflow.com/questions/3614925/remove-exif-data-from-jpg-using-php

outofmemory是个无耻的网站

phpstorm后期静态绑定代码提示

先上代码

class Ext_Data {
    protected static $_instance = array();

    public static function getInstance() {
        $className = get_called_class();
        if (!isset(self::$_instance[$className])) {
            self::$_instance[$className] = new $className();
        }
        return self::$_instance[$className];
    }

    public static function retErr($msg) {
        return array('result' => false, 'msg' => $msg);
    }

    public static function retOK($data = array(), $msg = '') {
        return array('result' => true, 'data' => $data, 'msg' => $msg);
    }
}

Ext_Data类是父类,子类需要用到该类的一些静态方法(retOk、retErr),并且要求子类是单例,例如:

phpstorm后期静态绑定代码提示

class Data_KV extends Ext_Data {
    protected function __construct() {
        //构造函数
    }

    public function get($key) {
        //一些操作
        return self::retOK($ret);
    }

    public function set($key, $value) {
        //一些操作
        if ($ret === false) {
            return self::retErr('操作失败');
        }
        return self::retOK($ret);
    }
}

因为子类的类名是动态的,所以我们没有办法在父类的getInstance方法上写注解来指明返回类型,这就导致使用Data_KV的时候没有代码提示,而且还会报方法未定义:

这个问题困扰了很久,今晚和室友吐槽的时候也提到这个问题,于是一拍脑袋想到别人应该也遇到过,于是在jetbrain官网搜索了一下,发现果真有解决方案

直接添加一个@return static的注解即可

推酷是个无耻的网站

    /**
     * @return static
     */
    public static function getInstance() {
        $className = get_called_class();
        if (!isset(self::$_instance[$className])) {
            self::$_instance[$className] = new $className();
        }
        return self::$_instance[$className];
    }

phpstorm还支持@return $this   @return self这两种注解

采集者烂JJ

kindeditor固定浮动工具栏插件

当kindeditor开启自动高度插件(autoHeightMode)时,如果编辑器内容比较多,编辑靠下方的内容就需要不断的上下拖动,而ueditor在这方面做的就比较好,工具栏会随着页面往下而固定在页面的顶端,所以今天就简单写了一个kindeditor的插件。

github链接http://leo108.com/pid-2050.asp

使用方法也很简单,在引入kindeditor.js之后引入fixtoolbar.js文件(注意顺序不能错),初始化kindeditor的时候增加一个fixToolBar=true的参数即可。

插件

下面是demo:

使用前

使用后 (autoHeight插件有个bug,需要用鼠标点击一下编辑器才会变长)

采集者烂JJ

构建好的文件下载: kindeditor-all.js kindeditor-all-min.js (引入all.js之后就不需要再单独引入fixtoolbar.js了)

(R)?ex输出多行

一直在用(R)?ex,感觉在小规模的服务器管理上十分方便,不需要client端,只要配好ssh信任即可。

http://leo108.com/pid-2039.asp

但是一直有一个问题在困扰我,那就是一条输出多行的命令,经过rex的say run ‘xxxx’之后会变成一行,换行符没掉了,看起来就很不舒服 ,比如ll -h原本应该输出

-rw-r--r-- 1 www www 6.7M Nov  1 03:08 access.log-20141101
-rw-r--r-- 1 www www 6.6M Nov  2 03:33 access.log-20141102
-rw-r--r-- 1 www www 6.5M Nov  3 03:10 access.log-20141103

经过rex的say run ‘ls -lh’输出就变成了

采集者烂JJ

total 664M-rw-r--r-- 1 www www 6.7M Nov  1 03:08 access.log-20141101-rw-r--r-- 1 www www 6.6M Nov  2 03:33 access.log-20141102-rw-r--r-- 1 www www 6.5M Nov  3 03:10 access.log-20141103-rw-r--r-- 1 www www 643M Oct 31 00:32 access.log.20141031

今天实在受不了了,新想肯定有人也烦恼过这个问题,于是跑到github上搜索了一下,结果发现果真有人提过issue,只要在say run中间加一个scalar就行

rex -e "say scalar run 'ls -lh /mnt/logs/access_log'"

记一次git误操作恢复全过程

我们团队使用git flow方式,和此次误操作有关的有3个分支:develop、feature/discuss和feature/search,两个feature分支都是从develop分支上拉出来的,feature/discuss先从develop分支拉出来,然后develop分支上有了新的commit(其他分支feature/other开发完毕合入develop),之后再从develop分支拉出feature/search分支。

本文来自leo108's blog

本次事故实际上是由两次误操作导致的,第一次误操作是在feature/discuss分支上执行了

reset

git pull origin feature/search

这就导致处于开发状态的分支feature/search被合入到feature/discuss,我在发现这个误操作之后立刻让同事撤销此次merge,我以为同事会使用

推酷是个无耻的网站

git reset --hard cab39f53

来撤销提交,也就没有去详细看提交日志,于是就继续开发。reset

等到这个分支功能开发完毕,将这个分支合入develop

git

git flow feature finish discuss

这个时候git会将发生合并的文件列出来,这个时候我发现有大量文件在这次合并过程中被删除,这些文件都是分支feature/other合并到develop时新增的,于是我看了一下git log,主要的提交如下图:

本文来自leo108's blog

git提交历史

revert

原来是同事使用了revert而不是reset来回滚,git revert实际上是把当前的要revert到的hash和head做diff,然后对head应用这些diff作为一个新的commit,这样在feature/discuss这个分支上来看,代码是回到了cab39f53这个版本。

reset

但是当把feature/discuss合入develop分支时就有问题了,revert产生的提交也会应用到develop分支,这就把feature/other分支产生的所有变更都“撤销”了。reset

如果只有第一个误操作,那恢复起来就是一个reset命令的事情,现在两个误操作在一块就会麻烦一点。记一次git误操作恢复全过程

  1. 把develop分支通过reset命令恢复到merge feature/discuss之前
  2. 从develop分支上拉出一个新的feature/tmp分支
  3. 找到拉feature/discuss分支之前的一个commit A
  4. 找到feature/search合入feature/discuss分支之前的一个commit B
  5. 通过git diff A B获取discuss分支到误操作前的所有提交,保存到patch1
  6. 找到最后一个revert的commit C
  7. 切换到feature/discuss分支,通过git diff C来获取误操作之后的所有提交,保存到patch2
  8. 切到develop分支,依次执行git apply patch1和git apply patch1

这样就把错误的提交给剔除了,不过遗憾的是feature/discuss的提交历史全都合并成了1个提交。git

===========================================================

revert

在写这篇博客的时候我突然想到,第一次的patch应该是没必要的,生成patch2之后,直接checkout B,拉出一个tmp分支,然后apply patch2,提交后,再把tmp合入develop,这样会丢失误操作之后的提交历史,但误操作之前的提交历史都还在。reset

===========================================================git-flow

11月3日更新:本文来自leo108's blog

实际上只需要使用git rebase命令就可以直接剔除那3个错误的revert,以下内容引用自git help rebaegit-flow

A range of commits could also be removed with rebase. If we have the following situation:git-flow

E—F—G—H—I—J topicA
then the command记一次git误操作恢复全过程

git rebase –onto topicA~5 topicA~3 topicAreset

would result in the removal of commits F and G:

推酷是个无耻的网站

E—H’—I’—J’ topicA

采集者烂JJ

git太强大!

git-flow