我的技术和生活

  • 使用 Satis 搭建私有仓库

    使用 Satis 搭建私有仓库

    题外话

    开始正题之前聊一些题外话。PHP 是个很好的语言,简洁高效,易学强大。但是出身不好,工程学上的高起点反而成为大家轻视它的原因。很多开发者也的确对自己要求不高,只写业务逻辑不考虑语言特性,使得代码难看难改难维护。所以我想多说两句回顾一下 PHP 本身的发展史。(以下以我个人经历为主)

    上古时期

    我们一个页面写一段 PHP,或者一个动作写一个 PHP,收集请求,做出处理,给出回应,完成。

    好处:

    1. 简单,好上手
    2. 逻辑关系清晰,从前端可以直接找到目标程序
    3. 一个地方出错,多半只挂一个功能

    坏处:

    1. 代码复用率低,不好维护
    2. 难以批量修改

    古典社会

    随着工程变大,需要大量的 PHP,分散碎片化的代码实在难以管理和维护。于是我们开始把一些共用代码抽出来,做成一个函数,叫 functions.php,其他所有页面都 include 它,这样公用的代码就不会这里一份那里一份了。

    好处:

    1. 提高了代码复用性,减少开发量,提升效率,降低维护难度

    坏处:

    1. 工程大的话,一个 functions.php 好几千行,可读性也没好到哪儿去
    2. 有时候我们需要对一个函数进行一些小修改,于是不仅函数库会膨胀,函数本身也在膨胀

    中世纪

    PHP 引入类的概念,并且提供了“魔术方法”来实现一些功能。有些程序员也意识到不能所有代码都自己手写,该引用的还得引用,于是从一些开源的库拷来代码开始用。这个时候连 Google Code 都不存在,下载代码多半在网上搜索 + Ctrl C/V,所以代码中各种混用。经常出现,我 include 一个文件,然后就挂了,原来是类被重复定义,或者全局环境下同名函数互相覆盖。开发乱象不断,形如黑暗的中世纪。

    好处:

    1. 不考虑维护的话,开发速度还是可以的……

    坏处:

    1. 越到后来坑越多,项目一大积重难返
    2. 内部执行环境不统一,a.php b.php 的内部环境都不一致,共享代码反而更加困难

    文艺复兴

    PHP 对类的支持已经十分完善了,大家也开始习惯用命名空间划分领域。通过使用设计模式、继承、接口,复写功能和代码管理的情况大大改善。同时,伴随 Google Code 和 GitHub 的出现和发展,大家有了一个托管代码和寻找代码的好地方。我们也开始用 SVN 管理代码,不会再搞出 action.php action.php.bak action_new.php action_new.20160102.php 这样的幺蛾子。开始学习开发规范,开始更多的的用类管理代码。

    好处:

    1. 代码规范
    2. 版本管理后,更好追溯代码的变更记录
    3. 可以下载到新版本的代码

    坏处:

    1. SVN 不方便进行多仓库的管理
    2. 测试还靠人工发掘问题

    近代社会

    Git 开始普及,我们可以更方便的管理代码了。GitHub 发展速度很快,从上面找好代码也很容易,凭借 Git 子仓库的概念,维护依赖也容易很多。MVC 框架开始普及,单入口开始流行,内部执行环境得到统一。开发者意识到测试的重要性,开始使用测试工具进行测试开发,代码的稳定性进一步提升。

    好处:

    1. 内部执行环境统一,全局修改变得容易
    2. 开始写测试了

    坏处:

    1. 学习成本开始增加,新入行的人开始搞不懂,为啥写一个脚本就能干的事,你们要搞这么复杂一套架构出来

    现代社会

    包管理工具成为标配。项目依赖不再通过复制代码或者子仓库来管理,而是直接使用包管理工具 Compposer。并且整合测试、部署脚本,方便我们更容易地完成整套开发流程。另一方面,前端之前已经崛起,PHP 可以更多的考虑后端业务逻辑,输出纯粹的数据接口。

    好处:

    1. 大型项目稳定性可用性大大增加
    2. 专业分工加强,PHP 程序员可以更多考虑后端逻辑

    坏处:

    1. 学习曲线更加陡峭,新人入行更难,甚至连有经验的老人都未必能适应新形态的开发。

    然则历史的车轮不可阻挡,我们势必会走向学习成本更高、学习曲线更陡,但业务量更大、更稳定的未来。


    正文开始

    正如前面所说,现在我们更多使用 Composer 进行依赖管理。和其它语言的包管理工具一样,Composer 使用 GitHub 托管代码,可以根据配置文件管理依赖,也可以建立各种脚本,执行特定任务。总之好处很多。

    实际工作中,我们可以把多个项目公用的逻辑抽出来,作为一个依赖,然后提交到 Packagist,就可以在其它项目中引用它了。但是,与 NPM 这种工具不同的是,PHP 程序多半会部署在服务器上,通过接口接受外部访问,对安全性的要求高很多。前端可以放开给大家随便观摩,后端最好还是放在别人轻易看不到的地方,万一哪个同事把密码、salt 写到代码里提交,被搜出来,结果可能就很危险。

    此时我们就需要一个工具,能够搭建私有源,里面都是私有仓库,对内不对外。

    Satis 就是 Composer 官方提供的建立私有源的工具。它的文档在这里 以及 这里

    整体流程并不复杂,文档里都有,我简单复述一下,只包含我用过的部分,重点穿插我的经验。我假定读者已经了解 Composer 的基础使用,如有问题,请自行翻阅文档。

    1. 建立项目

    使用 Composer 自带的建项目功能,这个相当于 git clone + composer install + 运行 post-install 脚本。

    composer create-project composer/satis my-satis --stability=dev --keep-vcs
    

    2. 建立配置文件

    /path/to/my-satis 目录下建立 satis.json 文件

    {
      "name": "仓库名称",
      "homepage": "http://satis仓库地址",
      "repositories": [
        { "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
        { "type": "vcs", "url": "http://svn.example.org/private/repo" },
        { "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
      ],
      "require-all": true
    }
    

    注意:仓库名称需要和仓库里 composer.jsonname 定义一致,和路径没什么关系,不然就会找不到。我当时被这个卡了好久……

    因为加入私有源的仓库本身可能也有依赖,require-all 会把这些依赖的信息也抓进来。如果不需要的话,可以指定某个仓库,甚至某个版本:

    {
      "name": "仓库名称",
      "homepage": "http://satis仓库地址/",
      "repositories": [
        { "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
        { "type": "vcs", "url": "http://svn.example.org/private/repo" },
        { "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
      ],
      "require": {
        "company/package": "*",
        "company/package2": "*",
        "company/package3": "2.0.0"
      }
    }
    

    3. 生成仓库列表

    执行

    php bin/satis build satis.json ./web
    

    就可以在 path/to/my-satis/web/ 里生成仓库列表了。

    4. 在其它项目中使用私有源

    只需要在项目的 composer.json 文件的根上添加

    {
      "repositories": [
        {
          "type": "composer",
          "url": "http://satis仓库地址/"
        }
      ],
      "require": {
        "company/package": "1.2.0",
        "company/package2": "1.5.2",
        "company/package3": "dev-master"
      }
    }
    

    之后再通过 composer require 或者 composer install 想要的仓库就可以了。

    注意:源里面只有“仓库列表”,并没有真的同步代码仓库过来,所以下载还要走托管代码的机器,比如 GitHub,内部 GitLab 等。所以需要确保相关的 ssh-key 已经添加,或者在配置文件中写上登录信息(不建议这么做)。

    Tips: secure-http

    satis 默认要求使用 https,不过 https 需要证书,不太好搞,比如前司运维就不愿意弄(当然,他们工作很忙,我十分理解)。此时我们可以设置 secure-httpfalse 强制 Composer 接受 http 的源。需要注意,secure-httpconfig 的属性之一,写在根上是没用的。

    {
      "config": {
        "secure-http": false
      }
    }
    

    总结,Satis 私有源的搭建,对于使用 PHP 的开发团队来说是非常必要的。用 Composer 管理依赖效果也非常好,希望所有 PHP 开发者都好好学一学。我现在用的也比较浅,将来有心得继续补充。

  • 日本·九州·由布院

    日本·九州·由布院

    由布院是个好地方,美中不足就是有点贵。

    其实整个日本现在都挺贵的,以现在1:15的汇率来看,没有哪儿便宜。

    由布院尤其贵,毕竟温泉小镇,自然不可能再挤快捷酒店,温泉酒店一晚快3000,由布院两晚的住宿费用比其它所有地方的加起来还高。

    不过由布院还是好耍。火车穿过最后一个长隧道,温泉小镇便一下子跃入眼帘。不超过3层的楼房随意铺陈在山谷中,随处可见温泉冒出的蒸汽。几条小河将镇子切割成数块,上面有小桥相连,河中有白鹭觅食——说起来日本的河里真的很常见水鸟。

    我们运气不好,赶上台风,火车晚点一个小时,到达由布院的时候将近6点,天已经渐渐黑了,路上的店铺几乎都关门了。温泉旅店的标准服务是一泊二食,就是住一晚,含早晚餐。所以大部分游客晚上都会在下榻的酒店吃晚餐,吃完多半就会去泡澡,其它店铺开店实在意义不大。于是我们只好在昏黄的灯光下拖着箱子和孩子奔向酒店。好在那里一切就绪,帮我办好入住,就安排丰盛的晚餐,最后泡完舒服的家庭风吕,大家都恢复了活力。

    我们定在 日之春,Booking 上评分颇高,实际住起来也非常棒。酒店位置很好,离商业街很近,基本上位于车站和金鳞湖连线的中点,往哪边逛都很方便。服务人员态度很好,非常热情,虽然英语一般,但真的很努力在跟我们交流。负责接待我们的似乎叫“松下Erica”(她发音听起来像“Elica”,不是说日本人分不清“L”和“R”,我就认为是 Erica),每天都用很饱满的热情提供服务,后来我们有衣服忘在酒店,更是追出来半条街找到我们。

    在这里了解到“家族風呂”。“風呂”大约是浴室、浴盆的意思;“家族風呂”大约就是可以拱全家人一起洗的大浴室的意思吧。来之前看“XFun吃货俱乐部”,介绍了“一壶天”,非常棒的酒店,由若干独栋别墅构成,每间也都有独立的温泉。美中不足的是,即使最大的房间,温泉也是小小的一个,比澡盆大不多少,实在满足不了我对温泉的幻想。日之春也有带私汤的房间,不过我们没有订——价钱当然是最重要的一点——不过,这丝毫没有影响我们泡汤的体验,因为有三个“家族风吕”(懒得切换简繁体了)+两个公共温泉(分男女)。这边的“家族风吕”是先到先洗,后到排队;每次不要超过40分钟,但可以无限次使用。实际上也泡不到40分钟,我们基本每次20~25分钟就泡好了,再泡久了会不舒服。这家酒店只有11间客房,还有两个带私汤,所以几乎不排队,公共温泉也只有我一个人,跟独享一样的。最令我满意的,就是温泉好大啊,十几平米的大池子都可以游泳了,比一个人躺不直的私汤强太多了。

    不知道有没有私汤都这么大的房间,也不知道价格几何。我觉得这样就非常好。

    由布院是个温泉小镇,出酒店就是商业街,上面有各种卖东西的小店,卖各种东西,我们从金鳞湖一直逛到车站,把所有店都走了个遍,只能说:好贵啊。汇率不行真心买不动,很多东西都想买,但是算算价格还是……不是必要就算了。必须推荐的,是“B-speak”家的“P roll”蛋糕卷,真好吃。实话实说我都震惊了,毕竟蛋糕卷不是啥稀罕物,到处都推荐还能做出花来?没想到吃下去唇齿留香,回味无穷;那个自然醇美,可惜回来再也吃不到了……还有就是“花之道”家的蜂蜜冰淇淋。这家没什么人推荐,至少我看的游记上没人提过,但是普通一个300日元的冰淇淋,却有非常浓郁的蜂蜜香味,令人痴迷,小姆二吃的谁都不给。金鳞湖不大,绕着走一圈也花不太多时间,旁边的咖啡厅味道也蛮好,姆二竟然喝掉半杯咖啡。想当年拜雀巢所赐,我对咖啡几乎毫无兴趣,不过看来姆二很可能会喜欢上。

    按照既定目标,由布院算是中场休息,前后都是密集的火车旅行。事实上,由布院休息的非常好,让我们意犹未尽。马上进入11月,枫叶红了,好想再去住两天。

  • bower.json 指定版本

    为了使用部署脚本部署代码而不是登录到服务器上用命令行,我需要尽量简化部署步骤。

    相对来说,composer 会简单一些,因为只要提交 composer.lock 文件然后 composer install --no-dev 即可。经测试 bower install --production 它是不会自己去更新了安装新依赖的,只会从缓存里安装。所以需要想个办法。

    Value must be a valid semver range, a Git URL, or a URL (inc. tarball and zipball).

    按照官网上的描述,只允许版本号、Git URL 或者安装包 URL。然则我试了一下,写 “#+版本号” 也是可以的,所以我们现在是这样:

    {
      "dependencies": {
        "tiger-prawn": "#68fa36ceb88c1b0e9b9472b6901d957f424e50b7"
      }
    }
    
  • 日本·九州·熊本

    日本·九州·熊本

    懒了两天,今天写几个字。

    这两天都是高强度肉身迁徙模式,每天在各类交通工具上的时间超过4个小时。因为小朋友喜欢火车,爱屋及乌,也喜欢电车之类有轨道的东西,所以我就把乘车当娱乐,到处坐车,各种车。日本的交通相当高效,说几点就是几点,54分都还看不到汽车,55分突然就出现在门口,好像游戏里刷新一样。

    前天的路线:

    1. 酒店出门搭一路电车到长崎站
    2. 坐海鸥高铁到谏早
    3. 谏早坐岛铁巴士到小滨
    4. 小滨泡脚泡澡吃午饭
    5. 13:55 坐岛铁巴士回谏早(真的13:55车就到了)
    6. 谏早坐 JR 回长崎
    7. 长崎站逛街,回酒店吃饭

    昨天的路线:

    1. 酒店出门搭一路电车到长崎站
    2. 坐海鸥高铁到谏早
    3. 坐岛铁小火车到岛原港
    4. 岛原港坐船到熊本港
    5. 熊本港坐巴士到熊本站
    6. 到酒店办理入住放行李
    7. 去部长办公室拜访
    8. 逛街(部长办公室就在鹤屋百货一楼),吃晚餐,回酒店

    今天的路线:

    1. 酒店出门坐 “SL 人吉”去人吉
    2. 吃上村鳗鱼饭(百年老店)
    3. 去猫老师神社拜祭
    4. 买酒和其它土产
    5. 去人吉铁道博物馆闲逛+坐小火车
    6. 搭火车回熊本
    7. 在车站附近吃饭

    这些行程几乎是一两个月前我对照各种时刻表安排的,这几天竟然能成行,而且几乎时间一点不变,简直不可思议。在我看来,整个日本社会达成一种默契,就是人人守规矩,不给别人添麻烦,从而磨合出极高的效率。这种社会潜规则要求大家不要因小失大,不要关注自己的小小得失,把很多成本分摊到全社会,每个人都承担小小的一部分,整个社会成本反而降得很低,而每个人也都能享受到其带来的好处。

    举个例子。日本街道上面很少见到垃圾桶,但几乎看不到垃圾。他们的垃圾分类非常细致,用汪壕的话说就是一个饮料瓶要分成瓶盖、瓶体、塑料纸三个部分分别扔到不同的垃圾桶;牛奶盒子要喝完后剪开洗净晾干然后再作为纸制品回收。我猜正是为避免大家随意处理垃圾才这样做的。然而日本人没有选择找个犄角旮旯把垃圾偷偷丢进去,而是尽自己的责任把垃圾处理好,就是通过将垃圾分类回收这个成本高昂的事情分摊到每个普通人身上,使得它的成本变得没那么高,而每个人又都能享受到其带来的便利和舒适。


    明天去由布院,又是早上10点出门下午5点到酒店的折腾之旅。为了折腾而折腾,这次过了坐火车的瘾了。

  • 日本·九州·长崎

    日本·九州·长崎

    昨天发完牢骚,上床睡觉。酒店房间不大,床品还是阔以,所以睡得不错,早上起来,用完1000円/人的早餐,恢复的元气满满。然后收拾东西,退房,去车站,今天要坐火车到长崎。

    博多站门口不知道在搞什么活动,排了好长的队伍,而且全是女生。好像是 JR 搞活动,请来某个组合,排队的应该都是女粉丝。可惜我们都不感兴趣,直接绕道走了。

    到站里买了排名一二的便当,然后就上站台候车。今天运气不太好,每次都与想搭的车擦肩而过。不过还好,这两趟海鸥特快之间只差20分钟,要是再误就得一个小时了。

    到长崎直奔酒店办入住。酒店比想象中上档次得多,房间也比昨天的大,还送小朋友礼包+浴品,似乎一切都在往好的地方发展。姆二最喜欢收东西,马上就拿着彩色铅笔乱涂乱画起来。

    稍事休息之后开奔诹坊神社。神社正在准备大祭,外面正在搭架子,好像是个有340年历史的大祭,可惜我们做攻略的时候不知道这个消息,所以把长崎安排在前面几天,等开祭的时候又不想过来了……作为另一个遗憾吧,反正每次出来玩都会有诸多遗憾,这也是每次出来玩的动力。神社里面也没多少人,绕着看了看,石头上面爬满了青苔绿藤,非常有感觉,于是蚊子也特别多,我们仨都被咬惨了。最后逃将出来,去买了求健康的绘马祈福。过去一年家里大病小情不断,希望来年有所好转。

    然后准备去传说中的百年便当店“心田庵”吃下午茶,结果费尽力气爬坡上坎终于到了,没开门……我们只好在他们家门口野餐以示抗议。然后坐有轨电车回商业街,逛吃逛吃直到回酒店。


    在我看来,日本之所以在我的朋友圈中受欢迎,多半是因为日本人的认真,不将就。不管房间再小,也要用好的床品,资生堂的洗化,有卫立洗和浴缸;不管地方再偏,也要收拾的干干净净;不管客人再难沟通,也要耐心的接待到最后。所以对于我们这种乍富的小中产,就特别受用。我们确实受不了国内老农民的糙,但是太高大上的服务我们也消费不起或者欣赏不了(比如怀石料理),所以日本这种处处显精致的地方就很对我们的胃口。

    另外,日本人的遵纪守法也帮他们大大降低了社会成本。比如火车,我们这趟火车7节车厢,就司机一个人负责(当然也可能是两个人,不过我只见到一个)。过几站就过来检一下票,然后回去。大家也遵守公德,上厕所尽量收拾干净,东西不乱摆放,等等。如此一来其实大大降低火车的运营成本,乘客就可以以更实惠的价格坐车。其实是双赢的。


    没想到住到花街柳巷……

  • 日本·九州·初印象

    日本·九州·初印象

    盼望已久的日本旅游终于成行!今天早上,我和老婆拉起睡眼惺忪的孩子,赶飞机直奔九州而来。事实证明,起早了,10:35的飞机,我们8:50就开始候机。办登机、安检、出关一切顺利,队伍很短。看来稍微错峰还是有意义的。

    经过两个半小时的飞行,我们终于抵达福冈机场。旅行开始了。

    不过坦白说,日本并没有我想象中的那么好,或者说,不适应的地方还有点多。

    1. 小。机场小,电梯窄,几乎到处都是如此。在国内习惯傻大傻大的,来日本有点不适应。
    2. 用现金多,500以下都是硬币。国内除了停车费过路费,我很少用现金。这边到处都用现金,而且500及以下都是硬币,感觉挺不方便。
    3. 日本人英语不太好,我日语仅限于打招呼,很难和他们用交流。他们也不爱说英语,即使发现对方是外国人也绝不尝试用英语交流。
    4. 贵……随着日元一波又一波走强,按照666的汇率算起来,大部分东西性价比都不高了。比如拉面,1000日元=50人民币,和国内还有一拼,现在66.66,在国内还能加块肉呢。
    5. 约定俗成不一样。比如这次买 SL 人吉车票,选项里有一个是“同时买返程”,我想当然地以为返程也是有座位的,于是就买了。结果今天才知道,返程只能坐自由席,意味着不能原车返回。然后补了差价买指定席。当然他们这样卖也有道理,毕竟是趟有点贵的火车,去的时候享受过了,回的时候随便坐个别的少花点钱……好像是哦,我当时没这么想,觉得设计好坑,现在想想似乎我们往返坐同一趟火车也有点扯……
    6. 好吧,强行加吐一波槽。日本人的效率很高,秩序意识很强,地少人多,所以整个博多 JR 站连个坐的地方都没有,办 JR Pass 和 SL 人吉车票把我们几个站惨了。

    总之,忙碌的一天过去了,我和老婆都累得够呛。姆二今天出来玩也兴奋,很多时候陪我们办事儿也没耍开心,有点作。出游的第一天,大家惯例再找感觉……


    今日开销:

    10000 * 5

  • 使用 Windows Linux Subsystem 配置开发环境

    使用 Windows Linux Subsystem 配置开发环境

    微软前些日子公布了 Windows Subsystem Linux(下简称WSL),当时还只有 Insider Preview 支持安装,作为普通用户的我就没有尝试。这两天不知道伴随哪次更新,标准的专业版也可以安装了,就试着配了一下,发现效果还比较理想,基本可以替代之前的 IIS 或者 VirtualBox 方案。这里简单记录一下。

    (2016-12-02 更新)随着最近一次 1607 更新,家庭版也可以安装了,效果基本一样。
    (2018-01-21 更新)已知 Yarn 在非 ~/ 开头的目录里 install 会出问题

    安装 WSL

    开始 > 设置 > 系统 > 应用和功能 > 拖到最下面“程序和功能”。然后点击“启用或关闭 Windows 功能”,找到“适用于 Linux 的 Windows 子系统(beta)”,启动之。

    启用 Windows Subsystem Linux

    之后系统会要求重启,听它的。

    然后打开命令行(或者 PowerShell,下同),输入 bash,提示需要切换到开发者模式。按照提示切过去,然后再次运行 bash,系统会安装需要的组件。这个过程会比较久,大概源都在国外吧。安装完成后又要重启,之后 WSL 就算安装成功。

    再次打开命令行,输入 bash,就可以进入 Linux 子系统了。

    WSL 其实就是 Ubuntu 14.04.5,所以安装包直接用 apt-get 就可以。嫌慢的话可以换上国内的源,不赶时间就让它慢慢更新。

    sudo apt-get update
    sudo apt-get upgrade

    配置Apache

    【2020-04-06 更新】现在已经没这个问题了,建议直接删掉 apache。

    这次我本来打算用 Nginx,装上之后启动不了,Google 之,似乎是 WSL 对 IP v6 的支持有问题,遂卸掉继续用 Apache。反正本地开发嘛,性能并发不是什么问题。

    Ubuntu 自带 Apache 2.4.7,直接 sudo service apache2 start 启动就好。不过这里遭遇到 vhost 的问题,我配置的虚机怎么都不生效,最后在 stack overflow 上找到解决方案,说是 000-default 和自定义的主机冲突,禁用掉默认配置就好了。

    sudo a2enmod vhost_alias
    sudo a2dissite 000-default
    sudo a2ensite 001-mysite

    然后还需要调整一下模块,比如要进行 WordPress 开发,就要保证重定向生效。

    sudo a2enmod php7.1
    sudo a2enmod rewrite
    

    另外,Apache 2.4 要求配置目录的“访问条件”,不然不能访问(会返回 “403 Forbidden”,改目录权限也没有用),所以要增加一行:

    <Directory "/path/to/my/site">
      ...
      Require all granted # 允许所有来源
      AllowOverride All # 允许重定向,WordPress 必备
      ...
    </Directory>

    全部配置好之后,重启 apache,访问配置的域名,就可以了。

    安装 Nginx

    不知道什么时候 Nginx 可以用了,反正我某天试着配了一下,突然就可以用了。

    sudo apt install nginx

    安装完配置一下即可,不过需要注意,apache 默认启动并占据 80 端口,所以使用 nginx 前必须卸载或者关掉 Apache,避免出现端口冲突。

    安装 PHP

    添加 PHP 源。

    sudo add-apt-repository ppa:ondrej/php

    需要注意,以前那个 ppa:ondrej/php5-5.6 的源已经被移除了,5.5 到 7.1 都用 ondrej/php 这个新源。如果非要用 5.4 的话,还有个 php5-oldstable 的源。

    这里顺便把几个可能用到的组件也装上。

    sudo apt-get install php
    sudo apt-get install php-mysql
    sudo apt-get install php-xdebug
    sudo apt-get install php-apcu
    sudo apt-get install php-xml
    sudo apt-get install php-mcrypt

    配置 Xdebug

    配置好 PHP 之后,开启 Xdebug 并不复杂。以我安装的 PHP7.1为例,安装之后,配置文件都在 /etc/php/7.1/apache2/conf.d/ 这个文件夹里,找到 20-xdebug.ini 并添加以下几行,然后重启 apache,即可。

    xdebug.remote_enable=on
    xdebug.remote_autostart=on
    xdebug.idekey=PHPSTORM

    使用 cmder 替换 PowerShell

    PowerShell 也好,自带的命令行也好,都不好用。要么字体难看得要死,要么中文输入有问题,而且不支持多窗口。这里推荐 cmder,很好用,体验提升明显。

    cmder 支持打开窗口并执行启动脚本,可以一键进入 Linux 控制台,只要按下图进行配置即可。

    配置 cmder 支持 WSL

    然后再修改启动时默认的 tab。

    修改 cmder 启动时默认打开的 tab 类型

    启用 Ruby

    这个版本的 Ubuntu 集成了 rvm,通过 rvm list 可以看到已经安装了 Ruby 2.3.0。但是直接运行 ruby 却提示没有安装,运行 rvm use 2.3.0 提示

    RVM is not a function, selecting rubies with ‘rvm use …’ will not work.
    You need to change your terminal settings to allow shell login.
    Please visit https://rvm.io/workflow/screen/ for example.

    这个很奇怪,以前没有遇见过。通过 Google 得知,这是因为默认的登录方式没有读取 ~/.bash_login 里的配置信息,没有加载到 rvm 需要的方法,所以需要在启动 WSL 的时候增加参数 --login,所以回到上一步,修改启动脚本,问题解决。

    %windir%\system32\bash.exe ~ -cur_console:p --login

    (这里我还去掉了zsh,因为这台电脑似乎没有安装这个包,我不知道是不是默认不安装的问题。)

    安装 MySQL

    【2017-03-25 更新】下面提到的坑跟我用“旧”配置——0.6.0 有关。这个配置参考自 digital ocean 的文章,实际上 Oracle 已经推出了新版本的配置文件,使用新版配置文件安装 MySQL 就不会遇到这个问题。新版配置文件的链接在此。其它步骤相同。

    原以为安装 MySQL 最简单,没想到也有坑……主要是 5.7 的坑。

    我比较喜欢新版本,所以自然就准备上 5.7。Ubuntu 自带的源是 5.5 或者 5.6,所以要先更新一下:

    wget http://dev.mysql.com/get/mysql-apt-config_0.6.0-1_all.deb
    sudo dpkg -i mysql-apt-config_0.6.0-1_all.deb
    sudo apt-get update

    好了,接下来直接安装就好:

    sudo apt-get install mysql-server

    根据提示信息安装 MySQL Server 5.7,设置 root 密码。这个阶段多半不会出问题。安装完成之后,运行 mysql -uroot -p,输入刚才设置的密码,不出意外的话就可以进入 MySQL 控制台了。

    进入 MySQL 控制台

    接下来我们通常要设置开发用户,此时问题也就来了。(这个问题在我的几台机器上,包括 VPS 表现不一,时有时无,所以我不太确定到底什么情况下会发生。)

    CREATE USER 'someone'@'localhost' IDENTIFIED BY 'password';

    执行这句 SQL 将创建一个用户,看起来完全不会有问题,结果却报错了:ERROR 1054 (42S22): Unknown column 'plugin' in 'mysql.user'(报错的列可能不同,但原因是一样的)。Google 之,原来随着 MySQL 版本升级,系统内建表的结构也发生着变化,5.7 需要的字段比起 5.5 甚至 5.4 多了不少。虽然我们直接安装的 5.7,也不耽误它按照老的结构创建表……

    这个时候有两个选择,一是手工把差的列加上,另一个则是运行官方提供的升级脚本 mysql_upgrade。为表达对官方的信任,我选择了后者。退出 MySQL,回到 SSH,执行脚本:

    mysql_upgrade --upgrade-system-tables -u root -p

    升级完成之后,再 mysql -uroot -p,输入密码,登录不进去了!WTF!怎么回事?!

    又是一通 Google,原来 5.7 之后,开发团队移除了 mysql.user 表里的 password 字段,用 authentication_string 取而代之,然而这个字段并没有复制之前 password 的值,所以原来的密码就失效了!这是什么鬼……

    这里我们又有两个选择,一是想办法修改 root 密码,二是卸了重装……因为我当时没找到真正的原因(就是上面这个),所以选择了后者。现在我推荐一个解决方案:

    1. 安装后,进入 MySQL 控制台,输入 DESC mysql.user;
    2. 如果返回 45 rows(行),则不需要升级系统内建表,改干嘛干嘛;如果少于这个数,就要执行 mysql_upgrade
    3. 刚才的窗口不要动,新开一个窗口,执行 mysql_upgrade --upgrade-system-tables -u root -p
    4. 执行完毕回到刚才的窗口,在 MySQL 环境下执行
    UPDATE `mysql`.`user`
    SET `authentication_string`=PASSWORD('password')
    WHERE `user`='root';

    文件互访

    在 WSL 里访问系统中的文件比较容易,使用 /mnt/盘符/路径 即可。

    如果要在 Windows 里访问 WSL 里的文件,它们位于 C:\Users\你的用户名\AppData\Local\lxss\

    有待解决的问题

    有了 WSL,各种依赖 Linux 环境的东西都可以随便跑了,利用 apt-get 安装更新也都很方便。侦听端口要完全没有问题。但其实两个环境是隔绝的,Windows 里不能执行 Ubuntu 的东西,反之亦然。这样一来,诸如 Phpstorm 的 File Watcher 包括测试都无法正常发挥作用。解决方案有待进一步发掘。

    临时解决方案就是通过命令行启动各种 watch,比如

    sass watch

    Yarn

    在非 ~/ 开始的目录里执行 yarn install 有一定机率会产生错误,具体原因不明,暂时无法稳定重现,反复重试之后倒是也能装成功。这个是 WSL 的锅,只能等待 Windows 更新。

    总结

    时代在发展,科技在进步。按照 GitHub 刚刚发布的报告,微软已经是开源贡献第一大公司,Windows 拥抱 Linux 之后我们也可以在 Windows 下进行PHP开发了。世界真美好啊!

    顺便Ubuntu新版本也比老版本容易配置了,当然,也可能是我之前不会。


    参考:

  • 也谈阿里月饼事件

    也谈阿里月饼事件

    终于,阿里开除了月饼事件中的第五人,而且几乎是由最高层在充分复盘下做出的决定。可以认为这件事尘埃落定。本来这是个热闹,是个谈资,于我没啥切身关系。不过我在很多人的表述中,看到了我不希望看到的东西,所以我决定表达下自己的看法。

    后文可能很长,所以先把我的观点列出来:

    1. 阿里开除这五人没有问题。
    2. 不是定量而是定性问题,这五人的行为不涉及到人品和道德问题。
    3. 整件事情是因不了解而产生恐惧,因不了解而产生攻击的结果。施害方是阿里管理层,或者按网络传闻“阿里HR”;受害方是习惯用代码解决问题的程序员。

    下面逐条表述。

    阿里开除这五人没有任何问题

    不仅阿里,任何公司开除任何员工其实都没有任何问题,只要公司愿意承担相应的责任。我不是具体当事人,就不展开了。

    作为打工者,无论身处何位,无论跟公司、跟老板、跟直接领导是什么样的关系,都要时刻做好离开这个公司的准备,也必须随时修正自己的职业规划。不要依附任何人,更不要依附某个公司。个人与公司之间,就是简单的雇佣与被雇佣关系,也应该是简单的雇佣与被雇佣关系。不要掺杂个人情感之类乱七八糟的东西。

    个人觉得公司不合适,可以跳槽;公司判断个人不适合,将其开掉对公司和对个人也都是最好的方式。此次事件中阿里就是这么做的。

    这五人的行为不涉及到人品和道德问题

    首先,我要强调,当时执行的是“秒杀抢月饼”,“秒杀”!不是温情脉脉你谦我让,就是谁先抢到谁就赢!那么每个人动用自己的能力增加自己的秒杀机率就理所应当。

    我们平时抢东西怎么抢?找个网速更快的地方;多准备几台设备;多找几个同事朋友帮忙一起抢。这和写一个脚本自动去点击有什么区别呢?有人会有人不会?我没有朋友怎么办?我没有多台设备怎么办?我只蹭得到时断时续的网怎么办?“抢”这个事儿本身就是不公平的。

    “秒杀”对于当时没时间的人,就是最大的不公平。

    再回到“脚本”这个东西上。阿里官方定性是“有牟利目的”,“利用系统漏洞”,“侵害了其它参与秒杀小二的利益”。这点我完全不同意。就那几盒破月饼,还是自己掏钱买,也没人蹲外面等着高价收,怎么就“有牟利目的”呢?至于“系统漏洞”,一个点击脚本叫个屁的系统漏洞啊!黑到数据库里改数据才叫系统漏洞,点击脚本只是作者为了避免自己正常工作被打扰临时开发出来的“效率工具”而已。只是在不懂技术的人眼里,这东西自己不理解,给它按一个自己理解的名称理所当然,最近炒得火热的“系统漏洞”看起来蛮合适,就它吧。于是一大堆不懂技术或者半桶水的人就给它定了性。

    然而,一线开发人员脑子里,是怎么想的:

    MDZZ,谁都跟你们似的那么闲,上班时间搞秒杀?老子活儿还干不干了。尼玛公司福利还搞花活,随便抽签或者申请下不就完了。哎,没办法,惹不起帮孙子,好吧,写个脚本,随便抢一盒吧。

    就是这样。不需要因为抢的是月饼,就从轻处罚。参与者本身不希望攻击什么,只是利用自身能力帮自己争取一些优势,和找人帮自己抢是一样的。写个脚本只是提高自己本职工作的效率,这只是个效率工具,而已。

    因不了解而产生恐惧,因不了解而产生攻击

    继而,我就得出上面这个结论。

    在很多不懂技术的人看来,程序员就像中世纪的巫师一样,你不知道他在干什么,只知道他鼓捣鼓捣鼓捣,就鼓捣出来一个东西,能干很多事情,很神奇。其实大多数行业,专业和非专业之间都有很高的壁垒,只不过其他行业要么成型已久,比如厨师;要么跟现实比较紧密,比起设计师;要么我们其实不关心,比如科学家。程序员这个行业又新,干的事情又抽象,产出的结果又跟其他人紧密相关,于是大家对我们的误解也就越深。

    比如,我司的后台由我开发。然则我的同事会通过观测得到一些的“客观规律”,然后拿来跟我争辩,坚信他们才是对的……

    所以大家可以容忍代秒,可以容忍多设备秒,可以容忍4G秒,但是不能容忍程序员写个三两行的脚本,走正规途径,秒。因为,“我不会,我不懂”。如果他这样干了,就是“作弊”,就是“利用系统漏洞”。我不管是不是,反正他会我不会,我没法确认他不是,那我姑且用最大的恶意去猜测,那就是“是”!

    因不了解而产生恐惧,因不了解而产生攻击。

    让我拿祖师爷举个例子。图灵(拜三拜),人类历史上最伟大的头脑之一,将二战缩短了两年的男人,因为同性恋,被强制精神治疗,甚至直接导致他的死亡。

    因不了解而产生恐惧,因不了解而产生攻击。

    我在担心什么

    有本科幻小说,讲未来的,说未来不同行业之间术语的差别就跟现在不同语种之间的差别一样巨大。现实正在向这个方向发展。如何去界定不同行业的人的行为?按照自己的经验去推测?用最大恶意去揣摩?按照传统道德来批判?还是,听听专家的意见,做同行评定?

    按照阿里这个做法,甚至还有很多支持的人,“同行评定”可能只是程序员脑中的乌托邦。

    科技越来越发展,开源的工具越来越多,程序员可能涉足的领域、操纵的东西越来越多。有些有明显边界,无须多辩;有些则边缘模糊。比如在饮水机上加监控,水开自动提示,我可以比其他同事享用更多的热水,这是问题么?比如我用摄像头监控领导的办公桌,他一回来我立刻跑过去让他先签我的请假条,这是问题么?有个妹子,领导安排她做报表,我帮她用脚本生成了,于是她成功挤掉了另一个妹子,这是问题么?客户有100个表单,销售报价100人・天,我做了个工具,30天搞完了,净赚70天,这是问题么?

    所有这些,都是在程序员眼里看来理所应当,甚至很酷的事情。但是到大众眼里,可能就不那么好接受。如果放任对程序员的不信任和攻击性增加,那么将来很可能有一天,我也会因为某个我认为理所应当的事情,被公司开掉。


    总结

    阿里开人没问题,但理由实在让同为程序员的我难以接受。从不懂技术的角度出发,他们想当然的认为,今天会写几行点击脚本,明天说不定就把公司数据库拷出去卖了!然而在身为程序员的我看来,这两者有天壤之别,完全不可相提并论。

    希望非程序员能多听听程序员的呼声。程序员们也不要羞涩,该表达就表达。希望以后程序员的环境更加宽容,不要让我们步步惊心。

    祝这五位今后一路走好,该写什么脚本,就写什么脚本。我支持你们。

    我单方面宣布鄙视阿里,不会谋求去阿里工作。


    吐槽

    1. 阿里这种货色,好意思说别人价值观有问题?
    2. 谁tm上班时候有时间去搞秒杀啊,HR 你们自己工作不上心别牵累别人好么?
    3. HR 你们外包给谁做的破程序啊,吃回扣了吧?
    4. 阿里那个伪造离职谈话记录的 HR 怎么样了?
    5. 我司老板竟然支持阿里,你可是技术出身啊!
  • 《岛上书店》读后

    《岛上书店》读后

    《岛上书店》内容简介:岛上书店是间维多利亚风格的小屋,门廊上挂着褪色的招牌,上面写着: 没有谁是一座孤岛,每本书都是一个世界。A.J.费克里,人近中年,在一座与世隔绝的小岛上,经营一家书店。命运从未眷顾过他,爱妻去世,书店危机,就连值钱的宝贝也遭窃。他的人生陷入僵局,他的内心沦为荒岛。就在此时,一个神秘的包袱出现在书店中,意外地拯救了陷于孤独绝境中的A.J.,成为了连接他和妻姐伊斯梅、 警长兰比亚斯、出版社女业务员阿米莉娅之间的纽带,为他的生活带来了转机。小岛上的几个生命紧紧相依,走出了人生的困境,而所有对书和生活的热爱都周而复始,愈加汹涌。


    这是本畅销书,长期位于亚马逊小说类推荐位上,我买它只是为凑单——而且我一度以为作者是东野圭吾(其实是跟《解忧杂货铺》搞混了)。

    不过应该说这是我的幸运,因为《岛上书店》这本书的确非常棒。整本书波澜不惊,朴实无华。里面没有什么伏笔、转折,人物形象既简单又朴实,没有高大上,也不会勾心斗角,就是正常过自己的日子,在生活的种种安排之下,做出自己的选择,无悔的迎接自己的结局。这个故事太过简单,简单到如果我想到这个故事,我可能都不会把它写下来。

    但是作者笔力强劲,塑造出的人物形象生动丰满,文字行云流水自然流畅,读起来全无压力,又快又舒服。书里弥漫着一股温暖的气息,每个人物,在力所能及的范围内,都是善良的。虽然生活不完美:最爱的人可能会离自己而去,仰慕的人可能只想享受偷情的乐趣,甚至疾病也随时可能袭来。但所有人都在努力生活,爱自己,爱别人。所以我更喜欢它的英文原名:“A・J・费克里那传奇的一生”(The Storied Life of A.J.Fikry),略显高大上的书名和简单朴实的内容形成了一种反差,我认为这是作者有意为之,因为她也相信这个道理:

    如果你一生耿直,刚正不阿,没做任何恶心的事情,没有做任何对别人造成伤害的事情,一辈子拼了老命勉强把老婆、孩子、老娘,把身边的这些人照顾好了,没有成名,没有发财,没有成就伟大的事业,一生正直,最后梗着脖子到了七八十岁死掉了,你这一生是不是没有改变世界?你还是改变世界了,你把这个世界变得美好了一点点。

    因为你,这个世界又多了一个好人,听懂了吧?每一个生命来到世间,都注定改变世界。所以将来有一天你心里挣扎,不知道要做一个流氓,过得很滋润,养六个六奶,哦,六个二奶;还是做一个正直的人。你在这个中间彷徨的时候,希望你记得我今天给你讲的这句话,每一个生命都注定改变这个世界。

    语出罗永浩,摘自豆瓣。


    当然,译者表现也很出色。

    购买链接


    传说 T3 又出问题,希望一切顺利。愿老罗成功。

    另外,我认为老罗并没有成为他自己讨厌的那种人。世故圆滑也和坚持他的那些原则没有冲突。


    头图为清水断崖,2014年摄于台湾花莲。