Skip to content

Instantly share code, notes, and snippets.

@kdstarter
Created December 5, 2019 06:51
Show Gist options
  • Save kdstarter/df1ab6a79538d97a98b684160d97196b to your computer and use it in GitHub Desktop.
Save kdstarter/df1ab6a79538d97a98b684160d97196b to your computer and use it in GitHub Desktop.
BaseModel ORM prototype for php
<?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();
@kdstarter
Copy link
Author

输出结果:
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}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment