PHP开发:REST接口 POST方法获取客户端提交的对象

根据REST规范,新增数据用POST方法。如果采用传统的application/x-www-form-urlencoded表单形式提交对象,需要将每个字段的值和value取出来,放到参数里,服务端接收到后,再还原成相应的对象作处理,这对客户端和服务端都是额外的工作。
客户端与服务端之间传输对象,最好的方式是用json或者xml,客户端跟服务端都有相应的工具序列化或反序列化对象。个人更倾向于json,代码更简洁,转换也更方便。
客户端提交请求时,设置Content-Type 为”application/json;charset=UTF-8″,告诉服务端消息主体是json,服务端判断$_SERVER[‘CONTENT_TYPE’],如果是json,则使用file_get_contents(‘php://input’)获取消息主体,取到的就是对象序列化后的json字符串,再作相应处理。

Android开发:LayerDrawable setBounds无效解决方法

设计效果是这样的:
circle
两个圆,底下是蓝色,上面的是白色,用LayerDrawable做,两个ShapeDrawable最合适不过,因为要动态改白圆的大小,所以直接写在xml里就不太合适,用Java代码写.
但是发现在白色的ShapeDrawable上setBounds没有缩进的效果,直接把下面的蓝圆盖掉了。其实这里应该用LayerDrawable的setLayerInset方法:

        OvalShape shape1 = new OvalShape();
        ShapeDrawable drawable1 = new ShapeDrawable(shape1);
        drawable1.getPaint().setColor(colorBlue);
        Drawable[] drawables = new Drawable[2];
        drawables[0] = drawable1;
        OvalShape shape2 = new OvalShape();
        ShapeDrawable drawable2 = new ShapeDrawable(shape2);
        //下面一行无效
//        drawable2.setBounds(10,10,10,10);
        drawable2.getPaint().setColor(Color.WHITE);
        drawables[1] = drawable2;
        LayerDrawable layerDrawable = new LayerDrawable(drawables);
        //需要使用setLayerInset,第一个参数是drawable索引,后面是左上右下
        layerDrawable.setLayerInset(1, 10,10,10,10);
        ViewHelper.setBackgroundForView(viewCircle,layerDrawable);

ThinkPHP 转换数据库查询出的数据到对应类型

默认情况下,Thinkphp查询出的所有字段值类型都是String,如果是开发web,当然没问题,但开发接口,就很麻烦了,总不能让客户端去转类型。
ThinkPHP的Model.class.php时,提供了_parseType方法,可以在查询完以后,做类型转换,但框架没有这么干,需要我们手工调一下。
写一个Model基类:
BaseModel.class.php,因为我用到关联查询,所以继承自RelationModel

use Think\Model;
use Think\Model\RelationModel;

class BaseModel extends RelationModel
{
    //在查询后,转换数据类型
    protected function _after_select(&$resultSet, $options)
    {
        parent::_after_select($resultSet,$options);
        foreach ($resultSet as &$result) {
            $this->_after_find($result, $options);
        }
    }
    protected function _after_find(&$result, $options)
    {
        parent::_after_find($result,$options);
        foreach ($result as $field => $value) {
            $this->_parseType($result, $field);
        }

    }
}

所有的Model类继承自BaseModel.
本来,这样已经搞定了,但发现Model.class.php的_parseType方法里有个低级bug,看图:
thinkphpbug

VPS推荐:BandwagonHost,超高性价比的程序员专用VPS

为啥把它叫做程序员专用VPS呢?主要因为它的后台提供了一键安装openVpn,ShadowSocks的功能,可以帮助我们上Youtube,twitter,github之类的,当然,几乎所有的国外VPS都可以安装类似的工具,但自己折腾起来还是挺麻烦的。如果你只是用于科学上网,买个最低配,256M内存,流量500G,够用,后台一键安装shadowsocks,甚至都不用进ssh。BandwagonHost目前有5个数据中心,感觉卡了自己在后台随便换,不用开工单。256M内存年付19.99刀,合人民币130元左右,支持paypal,支付宝,信用卡支付。我现在3个同事合租,每年每人也就40多块RMB,只要不是同时上youtube之类的视频网站,网速绝对没问题。购买进官方网站Continue reading ‘VPS推荐:BandwagonHost,超高性价比的程序员专用VPS’ »

iOS开发:UIButton设置文本和字体

直接设置titleLabel的text是无效的

extension UIButton {
    ///设置iconfont 但设置字体必须同时设置字体大小
    /// - parameter str:iconfont 字串 如\u{e603}
    /// - parameter fontSize:字体大小
    func icon(str:String,fontSize: CGFloat) {

        self.titleLabel?.font = UIFont(name: "iconfont", size: fontSize)
        //swift使用unicode码
        self.setTitle(str, forState: UIControlState.Normal)
        
    }
}

iOS开发:设置StatusBar前景颜色

在plist里设置或者UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent 只能改变LaunchScreen的StatusBar,一旦进入ViewController,就会变成默认的黑色。
如果需要在显示viewController时,改变StatusBar前景色,需要override UIViewController的 preferredStatusBarStyle方法:

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return UIStatusBarStyle.LightContent
    }

iOS开发:解决右滑返回上一页功能失效

iOS7以后,默认支持右滑返回上一页,但是,当隐藏navigationBar或是自定义返回按钮时,右滑返回就会失效。解决方法,自己实现interactivePopGestureRecognizer的delegate
viewDidLoad:

 navigationController?.interactivePopGestureRecognizer!.delegate =  self ;

实现UIGestureRecognizerDelegate定义的方法:

    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        if (navigationController?.viewControllers.count <= 1 ) {
            return false;
        }
        return true;
    }