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

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

这里贴一个 简单的 ORM 模型

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

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

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

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

3、最后直接使用:

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

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 小技巧之__callStatic魔术方法使用

<?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);
上一篇:spark 与 Hadoop 融合后启动 slf4j提示Class path contains multiple SLF4J bindings


下一篇:easyui treegrid 动态展开数据(暂记)