依据表结构自动生成一个PHP类

WBOY
發布: 2016-06-13 10:41:22
原創
907 人瀏覽過

根据表结构自动生成一个PHP类

Zend framework提供了一种class和table映射起来的方式,创建一个继承Zend_Db_Table的class。查询时,zend自动将表字段做处理,生成一个对象,对象属性都是动态创建,所以是public的。这有两个大问题,一是class的属性是public,二是class的属性只有代码执行后才确定。于是乎,自己写了一个程序,根据表信息生成对应的class。

?

?

<?php/** * 这个类的作用是从数据库里读出表结构,然后生成一个bean类,并将其属性与类一一映射。 * 具体生成的内容包括: * 1. 私有变量 * 2. 表字段与属性的映射关系 * 3. 表字段的信息,用于server的验证 */class TableClassGenerator {	const DEFAULT_DIR = 'classes';	const DEFAULT_INDENT = 4;	const DEFAULT_MIN = 2;	private $excludedProperties;    private $database;    private $file;    private $givenTables;    private $parentClass;        public function __construct($config) {    	if (!isset($config) || empty($config) || ! is_array($config)) {    		die('Invalid config: '. print_r($config, true));    	}    	    	$this->database = $config['database'];    	$conn = isset($config['password'])        	? mysql_connect($config['host'], $config['user'], $config['password'])    		: mysql_connect($config['host'], $config['user']);    	if (! isset($conn)) {    		die('Failed to connect.' . mysql_error());    	}    	    	$this->givenTables = $config['tables'];    	if (isset($this->givenTables)    			&& (!is_array($this->givenTables)    					|| empty($this->givenTables))) {    		die("Tables($this->givenTables) in config is not an array or it is empty.");    	}    	    	$this->parentClass = $config['parentClass'];    	    	if ($config['excludedProperties']) {    		$this->excludedProperties = $config['excludedProperties'];    		if (!is_array($this->excludedProperties)    				|| empty($this->excludedProperties)) {    			die('excludedProperties should be an array and shoudnot be empty.');    		}    	}    	    	if (! file_exists(self::DEFAULT_DIR)) {    		mkdir(self::DEFAULT_DIR);    	}    }        public function __destroy() {        mysql_close();    }    	public function generateClasses() {		$allTables = $this->getTables();		var_dump($allTables);		$tables = $this->givenTables			? $this->givenTables			: $allTables;    	if (empty($tables)) {    		die("Empty given tables");    	}    	    	foreach ($tables as $table) {    		$index = array_search($table, $allTables);    		if (!is_int($index)) {    			echo "Table($table) not found in database({$this->database}).\n";    			continue;    		}    		    		$this->generateClassForTable($table);    	}    }    	private function generateClassForTable($table) {        $class = ucfirst($this->transform($table));        $fileName = self::DEFAULT_DIR . "/$class.php";        if (file_exists($fileName)) {        	echo "The file($fileName) already exists. You need delete if first.\n";        	//return;        }                $columns = $this->getTableColumns($table);        if (!isset($columns) || empty($columns)) {		  	echo "The table($table) doesn't have columns.\n";        	return;  	        }                $this->file = fopen($fileName, 'w');        if (! isset($this->file)) {        	die("Failed to open file: $fileName");        }                echo "Generating class for table: $table.\n";        $this->writeToFile("<?php");        if ($this->parentClass) {        	$this->writeToFile("class $class extends {$this->parentClass} {");        } else {        	$this->writeToFile("class $class {");        }        $this->generateConst($table);        $this->generateColumnPropMapping($columns);        $this->generateValidateConfig($table, $columns);        $this->generateProperties($columns);        $this->generateGetters($columns);        $this->generateSetters($columns);        $this->writeToFile("}");        $this->writeToFile("?>");        fclose($this->file);        echo "Class($class) was created in the file($fileName).\n\n";    }    	private function generateColumnPropMapping($columns) {		$this->writeToFile('private static $_colPropMapping = array(', 1);				foreach ($columns as $key => $value) {			$prop = $this->transform($key);			$this->writeToFile("'$key' => '$prop',", 2);		}				$this->writeToFile(');', 1);		$this->writeNewLine();    }        private function generateConst($table) {    	$this->writeToFile("const TABLE_NAME = '$table';", 1);    	$this->writeNewLine();    }    	private function generateGetters($columns) {        foreach ($columns as $key => $value) {            $prop = $this->transform($key);        	if ($this->shouldExcludeProp($prop)) {            	continue;            }                        $method = 'get' . ucfirst($prop);            $this->writeToFile("public function $method() {", 1);            $this->writeToFile('return $' . "this->$prop;", 2);            $this->writeToFile("}", 1);            $this->writeNewLine();        }    }        private function generateProperties($columns) {        $keys = array_keys($columns);        foreach ($keys as $key) {            $prop = $this->transform($key);            if ($this->shouldExcludeProp($prop)) {            	continue;            }            $this->writeToFile("private $prop;", 1);        }        $this->writeNewLine();    }        private function generateSetters($columns) {        foreach ($columns as $key => $value) {            $prop = $this->transform($key);        	if ($this->shouldExcludeProp($prop)) {            	continue;            }            $method = 'set' . ucfirst($prop);            $this->writeToFile("public function $method ($$prop) {", 1);            $this->writeToFile('$' . "this->$prop = $" . "$prop;", 2);            $this->writeToFile("}", 1);            $this->writeNewLine();        }    }        private function generateValidateConfig($table, $columns) {    	$this->writeToFile('private static $_validator = array(', 1);		$this->writeToFile("'$table' => array(", 2);		foreach ($columns as $key => $value) {			$this->writeToFile("'$key' => array(", 3);			foreach ($value as $k => $v) {				if (is_string($v)) {					$this->writeToFile("'$k' => '$v',", 4);				} else {					$this->writeToFile("'$k' => $v,", 4);				}			}			$this->writeToFile("),", 3);		}		$this->writeToFile("), // $table", 2);		$this->writeToFile(');', 1);		$this->writeNewLine();    }        private function getMin($max, $type) {    	if (!isset($max)) {    		return null;    	}    	    	$min = self::DEFAULT_MIN;    	if ($type == 'date' || $min > $max) {    		$min = $max;    	}    	return $min;    }        public function getTableColumns($table) {        $fields = mysql_list_fields($this->database, $table);        $count = mysql_num_fields($fields);        if (! isset($fields)) {            die("Failed to get fields" . mysql_error());        }        $columns = array();        for ($i = 0; $i < $count; $i++) {            $flags = mysql_field_flags($fields, $i);            $isRequired = preg_match('/not_null/', $flags);            $col = mysql_field_name($fields, $i);            $max = mysql_field_len($fields, $i);            $type = mysql_field_type($fields, $i);            $min = $this->getMin($max, $type);                        $columns[$col] = array(                'isRequired' => $isRequired,                'max' => $max,            	'min' => $min,                'type' => $type,            );        }                $sortedColumns = array();        $keys = array_keys($columns);        sort($keys);        foreach ($keys as $key) {            $sortedColumns[$key] = $columns[$key];        }        return $sortedColumns;    }        private function getTables() {    	$sql = "SHOW TABLES FROM {$this->database}";    	$result = mysql_query($sql);    	$tables = array();    	for ($i = 0; $i < mysql_num_rows($result); $i++) {    		$tables[] = mysql_tablename($result, $i);    	}    	return $tables;    }        private function shouldExcludeProp($prop) {    	if (! isset($this->excludedProperties)) {    		return false;    	}    	        $index = array_search($prop, $this->excludedProperties);        return is_int($index);    }    	private function transform($name) {        $words = explode('_', $name);        $newName = null;        foreach ($words as $word) {            if ($newName == null) {                $newName = $word;            } else {                $newName .= ucfirst($word);            }        }                return $newName;    }        private function writeNewLine() {    	$this->writeToFile('');    }        private function writeToFile($str, $count = 0) {        $space = null;        $count *= self::DEFAULT_INDENT;        while ($count) {            if ($space == null) {                $space = ' ';            } else {                $space .= ' ';            }            $count--;        }        fwrite($this->file, $space);        fwrite($this->file, "$str\n");    }} // TableClassGenerator$gen = new TableClassGenerator(array(    'excludedProperties' => array('id', 'userId'),    'database' => 'mydb',    'host' => 'localhost',    'parentClass' => 'Base',    'password' => 'pwd',    // 'tables' => array('user'),    'user' => 'userId',));    	$gen->generateClasses();
登入後複製
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板