PHP 小技巧之__callStatic魔术方法使用

 

 

使用 PHP 框架时,经常会用到 ORM 模型查询数据库,有没有疑问:为啥有些 ORM 中的静态查询方法,不能通过函数追踪下去呢,很有可能就是使用了 __callStatic 魔术方法的小技巧

 

这里贴一个 简单的 ORM 模型

1、先抽象一个基本操作demo类

 

2、数据表对应的模型配置: 对应数据表 和 数据表中的字段

 

3、最后直接使用:

 

 demo代码如下:

<?php
/**
 * User: szliugx@gmail.com
 * Date: 2018/11/9
 * Time: 上午11:00
 */

abstract class ActiveRecord
{
    protected static $table;
    protected $fieldValues;
    public $select;

    function __get($fieldName)
    {
        return $this->fieldValues[$fieldName];
    }

    static function __callStatic($methodName, $arguments)
    {
        // 正则向后引用提取字段
        $field = preg_replace("/^findBy(\w*)$/", '\\1', $methodName);
        // 条件字段 $field 需要做大小写转换,甚至驼峰法还原字段,这里未做
        $query = "select * from " . self::$table . " where " . $field . " = " . $arguments[0];

        return self::createDomain($query);
    }

    private static function createDomain($query)
    {
        $class = get_called_class();
        $domain = new $class;
        $domain->select = $query;
        $domain->fieldValues = [];
        ////  模拟查询结果
        $result = [];
        // TODO 可以在此步做驼峰法的转换
        foreach ($class::$fields as $index => $field) {
            $domain->fieldValues[$field] = $result[$field] ?? null;
        }

        return $domain;
    }
}

class Customer extends ActiveRecord
{
    protected static $table = 'tb_customer';
    protected static $fields = ['id', 'sex', 'name', 'age'];
}

class Goods extends ActiveRecord
{
    protected static $table = 'tb_customer';
    protected static $fields = ['id', 'title', 'describe'];
}

$customer = Customer::findByName('zhangsan');
$goods = Customer::findById(1);
assert(true);

 

 

当然还能够做一些方法的封装,比如:

 

<?php
/**
 * User: szliugx@gmail.com
 * Date: 2018/11/9
 * Time: 上午10:31
 */

class LianShiDiaoYong
{
    public static function __callStatic($methodName, $arguments)
    {
        switch ($methodName) {
            case 'strlen':
            case 'trim':
                $arg = $arguments[0];
                break;
            case 'array_values':
                $arg = $arguments;
        }
        return call_user_func($methodName, $arg);
    }
}

$res = LianShiDiaoYong::strlen(' hello ');
var_dump($res);

$res = LianShiDiaoYong::trim(' hello ');
var_dump($res);

$res = LianShiDiaoYong::array_values('zhangsan', 'lisi');
var_dump($res);

 

posted @ 2018-11-09 11:58  liugx  阅读(478)  评论(0编辑  收藏  举报