为 YII2 GridView 的 ActionColumn 添加自定义链接

Yii2 的 GridView 可以解决后台展示绝大多数问题,其中的 ActionColumn 定制性也很强,官方文档没有说明如何操作,下面的代码可以做个参考。

以下代码为 ActionColumn 添加了 lock 的链接,并使用 glyhpicon-lock 作为图标

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        'username',
        [
            'class' => 'yii\grid\ActionColumn',
            'template' => '{view} {update} {lock}', 
            'buttons' => [
                // The new action
                'lock' => function ($url, $model, $key) {
                    // Creates glyphicon, optional
                    $icon = Html::tag('span', '', ['class' => "glyphicon glyphicon-lock"]);
                    // Creates URL
                    $url = Url::to(['/admin/user/lock', 'id' => $model->id]);

                    return Html::a($icon, $url);
                }
            ],
        ],
    ],
]);

Linux恢复文件目录权限

文件和目录的权限被更改之后可以通过备份目录进行恢复。在Debian下,先安装acl工具。

apt-get install acl

然后使用getfacl命令,从备份目录获取权限列表

getfacl -R /backup/dir/ > dir.facl

再回到想要修改的目录下,通过权限列表恢复

cd /target/dir
setfacl --restore=/backup/dir/dir.facl

大功告成~

Yii2 自定义 RESTful API 返回格式

Yii 2 framework 提供了一套 REST API ,通过简单配置即可对外提供服务,支持 JSON、XML 多种格式选择输出;支持 HTTP Basic auth、OAuth 2 等认证方式,用起来确实很爽。

在定义 API 的时候,最常见的就是自定义返回格式,我找到 4 种方式,纪录如下:

第一种:来自官方文档,通过修改 config 文件

return [
    // ...
    'components' => [
        'response' => [
            'class' => 'yii\web\Response',
            'on beforeSend' => function ($event) {
                $response = $event->sender;
                if ($response->data !== null && Yii::$app->request->get('suppress_response_code')) {
                    $response->data = [
                        'success' => $response->isSuccessful,
                        'data' => $response->data,
                    ];
                    $response->statusCode = 200;
                }
            },
        ],
    ],
];

第二种:使用 controller 中的 afterAction 方法,在响应完 action 之后,对数据格式化

use Yii;
class MobileController extends yii\rest\Controller
{
    public function afterAction($action, $result)
    {
        $rs = parent::afterAction($action, $result);
        // 也可以再定义 response
        // $response = Yii::$app->response;
        // $response->statusCode = 200;
        // $response->data = ['message' => 'hello world'];
        return ['data' => $rs, 'error' => '0'];
    }
}

第三种:自定义 Error handler ,来自 github

public function init()
{
    parent::init();

    $handler = new \app\components\ApiErrorHandler;
    \Yii::$app->set('errorHandler', $handler);
    $handler->register();
}

第四种:与第一种类似,在 controller 中绑定 response 的 beforeSend 事件,不同是它不是 global ,更灵活

public function init()
{
    parent::init();

    Event::on(Response::className(), Response::EVENT_BEFORE_SEND, [$this, 'formatDataBeforeSend']);
}

public function formatDataBeforeSend($event)
{
    $response = $event->sender;
    // do something
}

That’s all.
Fin.

在Debian 8 Jessie安装MySQL Server 5.7

在Debian 8 Jessie安装MySQL Server 5.7,其实不只是Debian 8 Jessie,支持的版本还有6和7。安装过程如下

安装APT配置工具,MySQL官方提供

wget http://dev.mysql.com/get/mysql-apt-config_0.7.3-1_all.deb

最新的版本可以从这里获取:https://dev.mysql.com/downloads/repo/apt/

安装配置包,可以选择MySQL的版本5.6 OR 5.7,及是否安装工具包

dpkg -i mysql-apt-config_0.7.3-1_all.deb

更新APT源

apt-get update

安装

apt-get install mysql-community-server

阿里云安装Deiban 8

UPDATE

  • 昨天看aliyun已经支持Debian 8 Jessie的镜像,不用自己升级……
  • 自己升级的系统可以生成快照,但是快照无法回滚,服务器会一直显示“启动中”,无法使用

阿里云提供可安装的OS实在是太有限了,而且更新也非常慢,像Debian 8是15年发布的,到今天已过去了一年,还没有提供安装,很多国外的VPS连Ubuntu 16都已提供尝鲜,更别说Debian 8了。不过,也没关系,我们可以自己手动升级,仅需简单几步:

升级:

1、替换 apt 源配置,将“wheezy”替换为“jessie”

sed -i 's/wheezy/jessie/' /etc/apt/sources.list

2、升级 apt list 索引

apt-get update

3、升级软件包

apt-get upgrade

4、升级系统

apt-get dist-upgrade

5、升级完成!重启后,验证结果:

cat /etc/issue

显示

Debian GNU/Linux 8

再看看uname

uname -a

显示

Linux Machine-id 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux

善后:

1、清理缓存

apt-get clean

2、清理无用文件

apt-get autoremove

3、老的内核也不需要了,删除
查询已安装的内核

dpkg --list|grep linux-image

删除老的

apt-get remove linux-image-3.2.0-4-amd64

显示

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  linux-image-3.2.0-4-amd64
0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
After this operation, 106 MB disk space will be freed.

哈哈,可以节省106MB

记录:

在安装Debian 7的时候,阿里云对系统配置作了一些优化,可以继续使用,在 /etc/sysctl.conf 最后加入

vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time=120
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.all.arp_announce=2
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv4.conf.lo.arp_announce=2

composer升级后不能用,更新fxp插件后修复

今天把composer升级到 d401f6e95cca835d165c61648327fc1fa062ba31 版本之后,再安装其他包的时候,出现错误提示

[ReflectionException]
Class Fxp\Composer\AssetPlugin\Repository\NpmRepository does not exist

[ErrorException]
Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRepository::whatProvides() should be compatible with Composer\Repository\ComposerRepository::whatProvides(Composer\DependencyResolver\Pool $pool, $name, $bypassFilters = false)

显然是FXP包又出问题了,上次也出现过一次,也是这个插件的问题…… 单独把这个包升级一下吧,执行

composer global update fxp/composer-asset-plugin --no-plugins

OK,已经没问题了。

查了一下,果然是fxp的bug:https://github.com/composer/composer/issues/2661

composer果然是越用越喜欢,人都变懒了……

纪念一下shadowsocks

纪念shadowsocks的阵亡,灵魂依然在,历史会记下你的足迹:

https://github.com/shadowsocks/shadowsocks/tree/5b450acfaa15cd6c2d3e8ab99f9297542df74025

感谢作者:Clowwindy

Debian下查看硬盘温度

原理还是通过S.M.A.R.T.来读取硬盘参数,装个名为“hddtemp”的工具就很容易看到。

Debian和Ubuntu下用apt安装即可

sudo apt-get install hddtemp

通过一个简单的命令

hddtemp /dev/sda

就会显示结果

/dev/sda: TOSHIBA DT01ABA300V: 41°C

不支持SMART的硬盘,或者使用USB连接的硬盘盒会显示错误:

/dev/sdb: Hitachi HTS545032B9A302: S.M.A.R.T. not available

关闭root用户的SSH密码登陆

一台自用的服务器,开放SSH服务,看日志发现总会有人扫弱口令,为了安全干脆关闭密码登陆,只允许密钥登陆。但是这台服务器上还有其他账号,必须使用口令验证。查阅了SSHD的手册,发现这也不难,配置文件支持对特定用户进行特殊配置:只要使用“match”关键字进行配置。

对于root用户关闭密码验证登陆,可以在配置文件/etc/ssh/sshd_config的最后加入:

Match User root
PasswordAuthentication no

重启sshd服务器:

service sshd restart

这样,其他用户可以继续使用密码登陆,root用户就不可以了。

几处值得注意的地方:

  • “match”关键字除了可以配合“User”使用之外,还可以配合Group、Host、和 Address 进行配置。
  • “match”关键字首次出现之后,其后出现的配置,都将针对这User(或Group、Host和Address),直至下个match再次出现。这是要把这个配置放到配置文件最后的原因。
  • “match”支持配置的参数还有如下:AllowAgentForwarding, AllowTcpForwarding, Banner, ChrootDirectory, ForceCommand, GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, KbdInteractiveAuthentication, KerberosAuthentication, KerberosUseKuserok, MaxAuthTries, MaxSessions, PubkeyAuthentication, AuthorizedKeysCommand, AuthorizedKeysCommandRunAs, PasswordAuthentication, PermitEmptyPasswords, PermitOpen, PermitRootLogin, RequiredAuthentications1, RequiredAuthentications2, RhostsRSAAuthentication, RSAAuthentication, X11DisplayOffset, X11Forwarding and X11UseLocalHost.

更多配置参看sshd的手册:http://linux.die.net/man/5/sshd_config

添加用户到_www组解决权限问题

一些开发框架需要下载扩展包到其所在目录,但下载回来的文件所属的用户和组为_www,这就使得以当前登陆用户对扩展包进行编辑时非常麻烦,需要经常变更目录权限。如果把当前登陆用户,添加到_www组就可用很方便的解决这一问题。

在Mac下的添加方式与Linux系统不同,须使用如下命令:

sudo dseditgroup -o edit -a username -t user _www

username为当前登陆的用户名
如果不知道登录名,可用通过如下命令查询:

whoami

更多dseditgroup的使用方法,可参考Apple的官方手册