↓ Archives ↓

Category → php

Two patches for Lithium (li3)

First, added method _toBoolean to Lithium\data\source\database\adapter\MySql:

    protected function _toBoolean($value) {
        return (int) parent::_toBoolean($value);
    }

Now Lithium treat tinyint(1) in MySQL as boolean type, but when you insert/update with a field has been defined as tinyint(1), Lithium will try insert boolean type, then an SQL error will throws.

The second patch is for Lithium\data\source\Database. Try this:

class User extends Lithium\data\Model {}

$user = User::create();
$user->name = 'Leechael';
$user->email = 'blah@blah.blah';
$user->blah = 'Field that NOT exists in schema';
$user->save();

Than you will got an SQL error, said unknown column `blah`. The solution is add a few lines in method Database::create() and Database::update(). First one, go to line 190:

while (list($field, $value) = each($data['fields'])) { // This line is what we looking for!
    // Insert following block!
    if (!isset($schema[$field])) {
        continue;
    }
// other codes ....

Second, go to line line 274 (after previous patched):

while (list($field, $value) = each($data['fields'])) { // You looking for this!
    if (!isset($schema[$field])) {
        continue;
    }
// other codes ....

Done.

Setup a helper for Lithium (a.k.a. li3)

Save your helper class under app/extensions/helper/, like Navigator.php, than calls $this->Navigator in your template.

It’s fucking easy but leaks document. Hope this helps you.

PHP Snippet: ip4_in_range

ip 范围检测函数,老生常谈了,贴一下自己造的轮子:

function ip4_in_range ($ip, $start, $end = null) {
    if (func_num_args() === 2) {
        if (strpos($start, '*') !== false) {
            $end = str_replace('*', '255', $start);
            $start = str_replace('*', 0, $start);
        } elseif (strpos($start, '/') !== false) {
            $ip_dec = ip2long($ip);
            list($range, $netmask) = explode('/', $start);
            $netmask_dec = ~ (pow(2, (32 - intval($netmask))) - 1);
            $range_dec = ip2long($range);
            return (($ip_dec & $netmask_dec) === ($range_dec & $netmask_dec));
        } else {
            trigger_error('ip4_in_range: Parameter $start maybe in invalid format.');
            return false;
        }
    }
    extract(array_map(function ($ip) {
        return (float) sprintf("%u", ip2long($ip));
    }, compact('ip', 'start', 'end')));
    if ($start > $end) {
        list($start, $end) = array($end, $start);
    }
    return ($ip >= $start && $ip <= $end);
}

只简单的做了几个小测试,都通过了。用法:

  • ip4_in_range('10.0.1.13', '10.0.1.0/24');
  • ip4_in_range('10.0.1.13', '10.0.1.*');
  • ip4_in_range('10.0.1.13', '10.0.1.10', '10.0.1.20');

PHP Framework,以及团队

这一次选 Framework 的过程比较简单。Zend Framework 直接忽略,个人感觉它更像一个 toolkits 或者 library。Symfony 的感觉就是 Model 太臃肿,做 ORM 的 Propel 和 Doctrine 实际上都不讨我喜欢,此外通过脚本实现 duplicated 的代码还是放弃罢了。个人感觉写脚本做 script generator 的 framework 就有点过了。考虑 Kohana,但 Singleton 使用过度了,感觉这就不利于做 Unit Test,写 Mock 也会比较困难的感觉;或者可能是自己没有通读 Kohana 源码的关系。暂时用着 Lithium,可能也有不便于测试,或者 Singleton 过多的问题,但目前感觉还是不错的。Lithium 缺少文档,下一步大概就是读一读源码了,不过得看看工作怎么安排是好了。

目前的团队有三个人——忽略“鸡”这个角色。对于实践 Scrum,我并没有底,毕竟自己也是半吊子的水平,对 scrum 的认识仅限于《硝烟中的Scrum和XP》一书。也经过好一段子日子的思考了,打算在接下来的日子,

  1. 先把使用 Google Calendar 和 Gmail 这两个使用习惯培养起来,
  2. 然后实践 Daily Scrum Meeting,先从交流和每人能确定自己的工作目标做起。

由于端午节假期,我与另一位团队成员也得回学校处理毕业相关事宜,所以一口气吃成胖子也是不现实的。或者在接下来做的一个外包单子中实践上述的两点。

《Get Things Done》的重读还没有完成。这个星期奔波在旅途中就去了两天(再次来回肇庆-广州),回广州后的第二天就是病了的感觉,也是有气无力地混了一天多。感觉这一周没完成了点什么,看来对产出物的定义还是需要有的。