`
chennanfei
  • 浏览: 41672 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

根据表结构自动生成一个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 FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)

    PHP for MySQL 代码生成助手是一种实用工具,它能够根据MySQL数据库中的表结构自动生成相应的PHP类文件,从而简化数据库操作的编码工作。这个工具对于初学者或者希望提高开发效率的PHP开发者来说,是一个非常有价值...

    一个php mysql的自动文件生成器

    一个"PHP MySQL的自动文件生成器"是开发者用来提高效率的工具,它能自动生成PHP代码和数据库交互所需的文件,从而减少手动编写这些常见任务的时间。 1. **自动文件生成的原理**: 这种工具通常基于用户提供的...

    自动生成Php后台

    【标题】"自动生成PHP后台"涉及的主要知识点是自动化构建PHP Web应用程序的工具和技术。在Web开发中,尤其是PHP环境中,快速生成后端代码能够大大提高开发效率,减少重复工作,让开发者更专注于业务逻辑和创新功能。...

    phpexcelreader读取excel自动生成表和字段

    "phpexcelreader"是一个PHP库,专门用于读取Excel文件,它允许开发者在PHP环境中解析Excel数据,进而自动生成数据库表和字段。这个工具在Web开发中十分实用,尤其在数据迁移、数据分析或自动化报告生成等场景下。 ...

    thinkphp5.1.20代码自动生成

    模型是数据访问层的重要组成部分,ThinkPHP5.1.20的代码生成工具可以创建与数据库表结构相对应的模型类,包括基本的增删改查方法。这使得开发者能够快速地进行数据库操作,而无需关心具体的SQL语句,极大地提高了...

    Mysql数据库表结构差异性对比工具

    总的来说,"Mysql数据库表结构差异性对比工具"是一个实用的开发辅助工具,它简化了数据库同步的过程,提高了开发效率,同时也降低了因数据库结构不匹配带来的风险。对于任何涉及MySQL数据库管理和维护的人来说,理解...

    听棠的spl持久化框架实体类自动生成器

    实体类自动生成器能够根据数据库表结构自动创建对应的Java类,减少了手动编写这些类的工作量。 首先,了解"听棠的spl持久化框架"。这是一个面向对象的数据库访问框架,旨在提供一种简洁、高效的编程方式来处理...

    php自动生成数据字典

    在IT行业中,数据字典是数据库管理中的一个重要工具,它提供了关于数据库中表、字段、数据类型等元数据的详细信息。在这个场景中,我们关注的是如何使用PHP和PDO(PHP Data Objects)扩展来实现自动化的数据字典生成...

    EasyModels 测试版2(读数据库自动生成C#和JAVA类文件)

    它通过连接到指定的数据库,解析表结构,然后根据这些信息自动生成对应的C#或Java类文件。这个过程极大地提升了开发效率,避免了手动编写类文件的繁琐工作,同时也减少了由于人工操作可能引入的错误。对于大型项目,...

    PHP七夕在线表白自动生成阿狸版v1.0

    【PHP七夕在线表白自动生成阿狸版v1.0】是一个基于PHP编程语言的源码项目,设计用于2014年的七夕节,帮助用户创建个性化的情侣表白页面。这个程序允许用户通过修改代码中的文本内容,自定义表白页面上的文字,以阿狸...

    ASP/PHP代码生成器

    2. 表结构映射:允许用户选择数据库中的表,自动生成对应的模型类,包括字段定义、验证规则等。 3. CRUD操作:自动创建CRUD(Create、Read、Update、Delete)功能的代码,用于基本的数据增删改查。 4. 表单生成:...

    帝国cms+php+mysql实现成语接龙的sql语句和表结构

    在这个项目中,“帝国CMS+PHP+MySQL实现成语接龙”的设计,结合了这三个关键元素,旨在创建一个互动的在线游戏平台,用户可以在上面进行成语接龙游戏。下面我们将深入探讨这个项目涉及到的知识点。 首先,让我们...

    PHP 代码生成器适合新手练习

    2. **模板**:预定义的代码结构,可以根据数据模型自动生成代码。 3. **生成逻辑**:基于数据模型和模板,生成符合特定需求的PHP代码。 **使用代码生成器的优点** 1. **提高生产力**:自动化的代码生成可以减少...

    Thinkphp代码生成器

    1. **数据库模型生成**:工具会分析数据库中的表结构,自动生成对应的Model类,这些类包含了对数据库表操作的基本方法,如增删改查。 2. **控制器生成**:根据表的字段信息,生成Controller类,预定义了基本的CRUD...

    PHP表文件 生成器

    这个工具可能是通过读取MySQL数据库中的表结构,自动生成PHP代码,这些代码可能包含以下部分: - **连接函数**:建立到已配置ODBC别名的连接,通常使用`odbc_connect()`函数。 - **查询函数**:根据需要生成查询...

    PHP简易代码生成工具

    2. **数据库交互**:能够根据数据库表结构自动生成数据模型和CRUD(创建、读取、更新、删除)操作代码,大大简化了与数据库交互的步骤。 3. **自动命名约定**:遵循一定的命名规则,例如PSR(PHP Standard ...

    PHP+Mysql自动生成表单.docx

    以下是一个简单的PHP示例,演示如何遍历MySQL表并生成对应的HTML表单: ```php &lt;?php $host = 'localhost'; $db = 'pim_20110227'; $user = 'root'; $pass = 'root'; $conn = mysqli_connect($host, $user, $pass,...

    自动生成数据库字典php版

    本项目“自动生成数据库字典php版”着重于使用PHP语言来创建这样一个自动化工具,使得数据库的描述、关系和规则能够以结构化的形式呈现,便于开发人员和DBA进行维护和协作。 首先,我们要理解“数据库字典”的概念...

    数据库课程设计 试卷自动生成系统,内含代码,设计报告

    数据库课程设计中的试卷自动生成系统是一项实用且技术含量较高的任务,它涉及到数据库管理、软件工程、算法设计等多个方面的知识。在此项目中,我们将探讨以下几个关键点: 1. **数据库设计**:首先,我们需要一个...

    mybatis自动生成工具

    "mybatis自动生成工具"则是MyBatis生态系统中的一个重要辅助工具,它能帮助开发者自动生成SQL映射文件、实体类、DAO接口以及对应的实现类,极大地提高了开发效率。 在MyBatis中,SQL映射文件通常包含了与数据库交互...

Global site tag (gtag.js) - Google Analytics