使用 PHP 框架時,常常會用到 ORM 模型查詢數據庫,有沒有疑問:爲啥有些 ORM 中的靜態查詢方法,不能經過函數追蹤下去呢,頗有可能就是使用了 __callStatic 魔術方法的小技巧php
這裏貼一個 簡單的 ORM 模型數據庫
一、先抽象一個基本操做demo類框架
二、數據表對應的模型配置: 對應數據表 和 數據表中的字段dom
三、最後直接使用:函數
demo代碼以下:this
<?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);
固然還可以作一些方法的封裝,好比:spa
<?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);