generateProperties($table); * file_put_contents('entity/'. $table . '.php', $class); * * $fields = $entity->generateField('\entity\'. $table); * print_r($fields); * * entity 生成规则: * 首字母、下划线+字母 -> 大写字母 */ class Entity { /** * @var bool $ucFirst 首字母是否大写 */ public $ucFirst = true; public $namespace = "entity"; public function __construct(){ } public function db() { return _loadClass('\Qii\Driver\Model'); } /** * 设置 entity 的名字空间 * @param string $namespace 名字空间 * @return void */ public function setNamespace($namespace) { $this->namespace = $namespace; } /** * 通过 Entity 获取数据表的字段 * * @param $class * @return array * @throws \ReflectionException */ public function generateField($class) { if(!$class) { throw new \Exception('Class is null'); } if(class_exists($class, false)) { throw new \Exception('Class '. $class .' does not exist'); } $method = new \ReflectionClass($class); $properties = $method->getProperties(); $fields = []; foreach($properties as $property) { if($property->isPublic()) { $fields[] = $this->convertToField($property->getName()); } } return $fields; } /** * 将数据表生成entity * * @param string $table 表名 * @return string * @throws \Exception */ public function generateProperties($table, $className = '') { $db = $this->db(); $tableInfo = $db->getTableInfo($table); if($db->isError()) { throw new \Exception($db->getError()); } if(!$tableInfo || empty($tableInfo['fields'])) { throw new \Exception($table . ' does not have any field'); } $properties = []; $docs = []; $defaults = []; foreach ($tableInfo['fields'] as $field) { $comment = $tableInfo['comment'][$field] ?? ''; $convertField = $this->convertToProperty($field); $comment = strlen($comment) > 0 ? " ". $comment : ""; $doc = []; if(($tableInfo['rules']['int'] && isset($tableInfo['rules']['int'][$field])) || ($tableInfo['rules']['number'] && isset($tableInfo['rules']['number'][$field])) ) { $doc[] = "\t/**"; $doc[] = "\t * @var int ". $convertField . $comment; $doc[] = "\t */"; } else if (($tableInfo['rules']['maxlength'] && isset($tableInfo['rules']['maxlength'][$field])) || ($tableInfo['rules']['text'] && in_array($field, $tableInfo['rules']['text'])) ) { $doc[] = "\t/**"; $doc[] = "\t * @var string ". $convertField . $comment; $doc[] = "\t */"; } else if ($tableInfo['rules']['timestamp'] && in_array($field, $tableInfo['rules']['timestamp'])) { $doc[] = "\t/**"; $doc[] = "\t * @var datetime ". $convertField . $comment; $doc[] = "\t */"; } else if($tableInfo['rules']['float'] && isset($tableInfo['rules']['float'][$field])) { $doc[] = "\t/**"; $doc[] = "\t * @var float ". $convertField . $comment; $doc[] = "\t */"; }else if($tableInfo['rules']['decimal'] && isset($tableInfo['rules']['decimal'][$field])) { $doc[] = "\t/**"; $doc[] = "\t * @var decimal ". $convertField . $comment; $doc[] = "\t */"; } if($tableInfo['rules']['default'] && isset($tableInfo['rules']['default'][$field])) { $default = $tableInfo['rules']['default'][$field]; $defaults[$convertField] = $default; } if(count($doc) > 0) { $docs[$convertField] = join("\n", $doc); } $properties[] = $convertField; } $class = $className != '' ? $this->convertToProperty($className) : $this->convertToProperty($table); $classAndProperty = []; $classAndProperty[] = "namespace . ";"; $classAndProperty[] = "\n"; $classAndProperty[] = "use Qii\Driver\Entity\Inf;"; $classAndProperty[] = "use Qii\Driver\Entity\Base;"; $classAndProperty[] = "use Qii\Driver\Response;"; $classAndProperty[] = "\n"; $classAndProperty[] = << $dynamic) { if($dynamic == 'CURRENT_TIMESTAMP') { $classAndProperty[] = "\t\t" . '$defaultValue[\''. $property ."'] = date('Y-m-d H:i:s');"; }else{ $classAndProperty[] = "\t\t" . '$defaultValue[\''. $property ."'] = '". str_replace("'", "\\'", $dynamic)."';"; } } $classAndProperty[] = "\t\treturn \$defaultValue;"; $classAndProperty[] = "\t}"; } $classAndProperty[] = <<generateRules($tableInfo); $classAndProperty[] = '}'; return join("\n", $classAndProperty); } public function generateRules($tableInfo){ $constantJoin[] = <<generateRequired($currentRules, $comments); break; case 'int': $join = $this->generateInt($currentRules, $comments); break; case 'decimal': $join = $this->generateDecimal($currentRules, $comments); break; case 'minlength': $join = $this->generateMinLength($currentRules, $comments); break; case 'maxlength': $join = $this->generateMaxLength($currentRules, $comments); break; case 'timestamp': case 'datetime': $join = $this->generateDatetime($currentRules, $comments); } if(!empty($join)) { $constantJoin = array_merge($constantJoin, $join); } return $carry($tableInfo, $constantJoin); }; }, function($tableInfo, $constantJoin){ return $constantJoin; })($tableInfo, $constantJoin); $next[] = "\t\treturn ". '$rules;'; $next[] = "\t". '}'; //主键自动添加 $primaryKey = array(); if(isset($tableInfo['rules']['pri'])) { $primaryKey = $tableInfo['rules']['pri']; } //保存验证的时候使用 required 并去掉pri和default里边的内容 $defaults = array(); if(isset($tableInfo['rules']['default'])) { $defaults = array_keys($tableInfo['rules']['default']); } $validForSave = array(); if(isset($tableInfo['rules']) && isset($tableInfo['rules']['required'])) { foreach ($tableInfo['rules']['required'] as $field) { if(!in_array($field, $primaryKey) && !in_array($field, $defaults)) { $validForSave[] = $this->convertToProperty($field); } } } $uniKey = array(); if(isset($tableInfo['rules']) && isset($tableInfo['rules']['uniq'])) { foreach ($tableInfo['rules']['uniq'] as $uniq) { $uniKey[] = $this->convertToProperties($uniq); } } $next[] = << 0) { $uniq = array(); foreach ($uniKey as $val) { $uniq[] = "array('". join("','", $val). "')"; } $next[] = "\t\treturn array(". join(", ", $uniq). ");"; }else{ $next[] = <<convertToProperties($primaryKey)). "');"; $exclude = "\t\treturn array('". join("','", $this->convertToProperties($primaryKey)). "');"; }else{ $next[] = << 0) { $next[] = "\t\$fields = array('". join("', '", $validForSave)."');"; }else{ $next[] = "\t\$fields = array();"; } $next[] = <<valid(\$fields); } /** * 更新时验证的字段,自行添加 */ public function validFieldsForUpdate() { \$fields = array(); return \$this->valid(\$fields); } DOC; return join("\n", $next); } /** * required * @param array $rules 规则 * @param array $comments field comment * @return array */ public function generateRequired($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $constantJoin[] = "\t\t". '$rules["required"] = ['; $join = []; foreach($rules as $key => $value) { $comment = ''; if(isset($comments[$value]) && $comments[$value] != "") { $comment = $comments[$value]; } $message = ($comment != '' ? $comment : $value) . "不能为空"; $join[] = <<convertToProperty($value)}", "{$message}"] DOC; } $constantJoin[] = join(",\n", $join); $constantJoin[] = "\t\t];"; return $constantJoin; } public function generateMaxLength($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $constantJoin[] = "\t\t". '$rules["maxLength"] = ['; $join = []; foreach($rules as $key => $value) { $comment = ''; if(isset($comments[$value]) && $comments[$value] != "") { $comment = $comments[$value]; } $message = ($comment != '' ? $comment : $key) . "不能超过 ". $value ."个字符"; $join[] = <<convertToProperty($key)}", "{$message}", {$value}] DOC; } $constantJoin[] = join(",\n", $join); $constantJoin[] = "\t\t];"; return $constantJoin; } public function generateMinLength($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $constantJoin[] = "\t\t". '$rules["minLength"] = ['; $join = []; foreach($rules as $key => $value) { $comment = ''; if(isset($comments[$value]) && $comments[$value] != "") { $comment = $comments[$value]; } $message = ($comment != '' ? $comment : $key) . "不能少于 ". $value ."个字符"; $join[] = <<convertToProperty($key)}", "{$message}", {$value}] DOC; } $constantJoin[] = join(",\n", $join); $constantJoin[] = "\t\t];"; return $constantJoin; } /** * datetime 类型 * @param array $rules * @param $comments * @return array */ public function generateDatetime($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $constantJoin[] = "\t\t". '$rules["date"] = ['; $join = []; foreach($rules as $key => $value) { $comment = ''; if(isset($comments[$value]) && $comments[$value] != "") { $comment = $comments[$value]; } $message = $comment . "格式不正确"; $join[] = <<convertToProperty($value)}", "{$message}"] DOC; } $constantJoin[] = join(",\n", $join); $constantJoin[] = "\t\t];"; return $constantJoin; } /** * int 类型数据 * @param $rules * @param $comments * @return array */ public function generateInt($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $intProperty['min'][] = "\t\t". '$rules["minNumber"] = ['; $intProperty['max'][] = "\t\t". '$rules["maxNumber"] = ['; $intProperty['number'][] = "\t\t". '$rules["number"] = ['; $joinMin = []; $joinMax = []; $joinNumber = []; foreach ($rules as $key => $val) { $message = isset($comments[$key]) && $comments[$key] != "" ? $comments[$key] : $key; $min = $message . '不能小于'. $val[0]; $max = $message . '不能大于'. $val[1]; $number = $message . '必须是数字'; $joinMin[] = <<convertToProperty($key)}", "{$min}", {$val[0]}] DOC; $joinMax[] = <<convertToProperty($key)}", "{$max}", {$val[1]}] DOC; $joinNumber[] = <<convertToProperty($key)}", "{$number}"] DOC; } $intProperty['min'][] = join(",\n", $joinMin); $intProperty['min'][] = "\t\t];"; $intProperty['max'][] = join(",\n", $joinMax); $intProperty['max'][] = "\t\t];"; $intProperty['number'][] = join(",\n", $joinNumber); $intProperty['number'][] = "\t\t];"; return array_merge($constantJoin, $intProperty['min'], $intProperty['max'], $intProperty['number']); } public function generateDecimal($rules, $comments = array()) { $constantJoin = []; if(!$rules || !is_array($rules)) { return $constantJoin; } $constantJoin = []; $constantJoin[] = "\t\t". '$rules["decimal"] = ['; $joinProperty = []; foreach ($rules as $key => $val) { $comment = ''; if(isset($comments[$key]) && $comments[$key] != "") { $comment = $comments[$key]; } $message = ($comment != '' ? $comment : $key) . "格式示例: ". str_repeat(6, min(1, (int)$val[0] - (int)$val[1])) . ".". str_repeat(6, (int)$val[1]); $joinProperty[] = <<convertToProperty($key)}", "{$message}", "{$val[0]},{$val[1]}"] DOC; } $constantJoin[] = join(",\n", $joinProperty); $constantJoin[] = "\t\t];"; return $constantJoin; } /** * 转换为属性,属性会将下划线+小写/大写 转换成大写 * * @param $field * @return array|string|string[]|null */ public function convertToProperty($field) { $field = $this->ucFirst ? ucfirst($field) : $field; return preg_replace_callback("/\_([a-z]|[A-Z]|[0-9])/", function($match){ return ucfirst($match[1]); }, $field); } /** * 批量转 property 名称 * * @param $fields * @return array|string|string[]|null */ public function convertToProperties($fields) { if(!is_array($fields)) { return $this->convertToProperty($fields); } $map = []; foreach ($fields as $val) { $map[] = $this->convertToProperty($val); } return $map; } /** * 将属性转换成字段,属性中的大写会转换成成下划线+小写 * * @param $field * @return array|string|string[]|null */ public function convertToField($field) { $field = $this->ucFirst ? lcfirst($field) : $field; return preg_replace_callback("/[A-Z]/", function($match){ return "_". lcfirst($match[0]); }, $field); } /** * 批量转 field * @param array|string $fields * @return array|string|string[]|null */ public function convertToFields($fields) { if(!is_array($fields)) { return $this->convertToField($fields); } $map = []; foreach ($fields as $val) { $map[] = $this->convertToField($val); } return $map; } }