Created
December 5, 2019 06:51
-
-
Save kdstarter/df1ab6a79538d97a98b684160d97196b to your computer and use it in GitHub Desktop.
BaseModel ORM prototype for php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class BaseModel | |
{ | |
protected $tableName = ''; | |
private $columnNames = []; // ['id' => 'int', ...] | |
private $attrNames = []; | |
// private $attrValues = []; // ['id' => 1, ...] | |
private $attrFuncNames = []; | |
protected function startsWith($haystack, $needle) { | |
return strncmp($haystack, $needle, strlen($needle)) === 0; | |
} | |
public function __call($funcName, $params) { | |
if(in_array($funcName, $this->attrFuncNames)) { | |
$this->invokeGetterSetter($funcName, $params); | |
} else { | |
echo 'Base 未知方法'.$funcName .', params: '.json_encode($params). PHP_EOL; | |
} | |
} | |
public function __construct($attrValues = []) { | |
echo 'Base '.$this->tableName.'初始化' .json_encode($attrValues) . PHP_EOL; | |
$this->defineAttrs(); | |
foreach (array_keys($attrValues) as $key) { | |
// $this->$key = $attrValues[$key]; | |
$this->setAttr($key, $attrValues[$key]); | |
} | |
} | |
protected function setAttr($name, $value) { | |
if(in_array($name, array_keys($this->columnNames))) { | |
// echo 'Base 定义属性方法' . $name . ' '. $attrType . $value . PHP_EOL; | |
array_push($this->attrNames, $name); | |
$attrType = $this->columnNames[$name]; | |
if (isset($value) && ($attrType == 'float')) { | |
$this->{$name} = (float)$value; | |
echo 'Base '.$name.'类型转换为 '.$this->{$name}.' '.$attrType . PHP_EOL; | |
} elseif ($this->columnNames[$name] == 'int') { | |
$this->{$name} = (int)$value; | |
} else { | |
$this->{$name} = $value; | |
} | |
} else { | |
echo 'Skip unknown attr: '.$name.PHP_EOL; | |
} | |
} | |
protected function invokeGetterSetter($funName, $params) | |
{ | |
// $this->$funcName = ( function($params) use($funcName) | |
echo 'Base 调用方法'.$funName.', params: '.json_encode($params) . PHP_EOL; | |
if ($this->startsWith($funName, 'get')) { | |
$columnName = strtolower(preg_replace('/get/', '', $funName)); | |
echo 'Base '.$funName.'(): '.$this->$columnName . PHP_EOL; | |
} else if ($this->startsWith($funName, 'set')) { | |
$columnName = strtolower(preg_replace('/set/', '', $funName)); | |
$this->setAttr($columnName, $params[0]); | |
echo 'Base '.$funName.'(): '.$params[0] . PHP_EOL; | |
} else { | |
echo '未定义方法'.$funName . PHP_EOL; | |
} | |
} | |
public function attrs() { | |
$keyValues = []; | |
foreach (array_keys($this->columnNames) as $key) { | |
$keyValues[$key] = $this->$key; | |
} | |
echo "Base attrs: ".json_encode($keyValues) . PHP_EOL; | |
return $keyValues; | |
} | |
public static function all() { | |
// 从数据表结构查询, for example | |
$cows = [ | |
['id' => 1, 'name' => 'name1', 'price' => '1.1'], | |
['id' => 2, 'name' => 'name2', 'price' => '2.2'] | |
]; | |
$class = get_called_class(); | |
// echo 'get_called_class(): '. $class . PHP_EOL; | |
return [ | |
new $class($cows[0]), new $class($cows[1]), | |
]; | |
} | |
protected function defineAttrs() { | |
if ($this->tableName == 'coupons') { | |
// 从数据表结构查询到的字段为 name, price | |
$this->columnNames = ['id' => 'int', 'name' => 'string', 'price' => 'float']; | |
$this->attrFuncNames = ['getId', 'setId', 'getName', 'setName', 'getPrice', 'setPrice']; | |
foreach (array_keys($this->columnNames) as $key) { | |
$this->setAttr($key, null); | |
} | |
} | |
} | |
} | |
class Coupon extends BaseModel { | |
protected $tableName = 'coupons'; | |
} | |
echo 'New Coupon1-----------'. PHP_EOL; | |
$coupon1 = new Coupon(['name' => 'name1', 'price' => '1.1', 'test' => 'sdf']); | |
echo '$coupons1 get_class: '.get_class($coupon1) . PHP_EOL . PHP_EOL; | |
//echo 'Coupon get_class_vars' . PHP_EOL; | |
//print_r(get_class_vars('Coupon')); | |
//echo 'Coupon get_class_methods' . PHP_EOL; | |
//print_r(get_class_methods('Coupon')); | |
echo 'New Coupon2-----------'. PHP_EOL; | |
$coupon2 = new Coupon(['name' => 'name2', 'price' => '2.2']); | |
echo 'Coupon methods--------'. PHP_EOL . PHP_EOL; | |
$coupon = Coupon::all()[0]; | |
echo '$coupons[0] get_class: '.get_class($coupon) . PHP_EOL . PHP_EOL; | |
$coupon->attrs(); | |
$coupon->setPrice('3.3'); | |
$coupon->attrs(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
输出结果:
New Coupon1-----------
Base coupons初始化{"name":"name1","price":"1.1","test":"sdf"}
Base price类型转换为 1.1 float
Skip unknown attr: test
$coupons1 get_class: Coupon
New Coupon2-----------
Base coupons初始化{"name":"name2","price":"2.2"}
Base price类型转换为 2.2 float
Coupon methods--------
Base coupons初始化{"id":1,"name":"name1","price":"1.1"}
Base price类型转换为 1.1 float
Base coupons初始化{"id":2,"name":"name2","price":"2.2"}
Base price类型转换为 2.2 float
$coupons[0] get_class: Coupon
Base attrs: {"id":1,"name":"name1","price":1.1}
Base 调用方法setPrice, params: ["3.3"]
Base price类型转换为 3.3 float
Base setPrice(): 3.3
Base attrs: {"id":1,"name":"name1","price":3.3}