2012-04-13 60 views
24

我正在創建實體(實體 - 視圖 - 控制器)(換句話說,模型的MVC)類理論上匹配數據庫表我有。有沒有一種工具讀取mysql表並創建模型類代碼? (不是在執行時,需要代碼輸出) 我希望像PHP實體類生成器

class{ 
public $columnname1; 
public $columnname2; 
public $columnname3; 
public $columnname4; 
public $columnname5; 
public $columnname6; 
function __construct(&$columnname1, &$columnname2){...} 
function insert(&$columnname1, &$columnname2){} 
function delete(&$columnname1){} 
... 
} 

一個工具,它也將創建插入,更新和ID刪除功能將幫助我很多的輸出。

該工具可以免費或付費。

+0

還有一些其他的方法,結帳[RedBeanPHP](http://www.redbeanphp.com/)。 [Doctrine ORM](http://www.doctrine-project.org/projects/orm.html)也是類似的,然而[propel](http://www.propelorm.org/documentation/) 02-buildtime.html),這可能是你正在尋找的:[Existing Databases](http://www.propelorm.org/cookbook/working-with-existing-databases)。 – hakre 2012-04-13 23:00:19

+0

這可能很有趣:http://php.net/manual/en/pdostatement.getcolumnmeta.php。但功能仍然是實驗性的。 – MarcDefiant 2013-02-14 12:00:03

+0

@mogria我期望輸出的文本文件(php或其他)作爲輸出 – 2013-02-14 12:27:59

回答

17

PDO可以fetch results into an object

設計一個與您的數據庫/查詢結構相匹配的類,並使用PDO::FETCH_INTO將結果集提取到已經實例化的對象中。錯誤的問題,我的壞。


爲了從數據庫結構類本身,有幾個項目(我沒有測試過,但這次來到了一個非常簡單的搜索)。

+1

我正在尋找一種能夠自動完成的解決方案,因爲它可以自動完成。我知道如何去做所有這些,比如認識數學和購買計算器 – 2012-04-13 22:49:18

+0

等等,你想從表中生成類? – 2012-04-13 22:50:20

+0

是的,就像問題 – 2012-04-13 22:53:56

3
symfony

什麼?它完全符合你的說法,並且你會得到一個非常好的框架。

symfony根據您提供的數據模型爲您編譯類。它將確保編譯的類和MySQL數據庫結構是同步的。

這種方法比基於Reflection的方法有利,因爲它太簡單了。

1

是的,原則是你所需要的。

  1. 運行命令,你會得到所有的表的元數據以XML或YML格式(選擇是你的)

    $ PHP應用程序/控制檯學說:映射:轉換XML ./src/ Bundle/Resources/config/doctrine/metadata/orm --from-database --force

  2. 一旦你生成元數據,命令Doctrine導入架構來構建你需要的相關實體類。你會發現所有的GET和SET功能(閱讀選擇,更新INSERT)裏面。

    1 $的PHP應用程序/控制檯學說:映射:進口包註釋

    2. $ PHP應用程序/控制檯學說:生成:實體捆綁

    Read details with Example here

+0

「在」doctrine:mapping「命名空間中沒有定義任何命令。」 – Scott 2016-11-21 18:02:33

1

Fat free framework讓你使用以下代碼與現有表一起工作:

$user=new DB\SQL\Mapper($db,'users'); 
// or $user=new DB\Mongo\Mapper($db,'users'); 
// or $user=new DB\Jig\Mapper($db,'users'); 
$user->userID='jane'; 
$user->password=md5('secret'); 
$user->visits=0; 
$user->save(); 

上面的代碼創建新記錄用戶

8

下面的代碼是我用了很長時間來創建MySQL和DB2表的PHP模型。我有MSSQL,PGSQL和SQLite的存根,但從來沒有需要完成它們。

下面的代碼生成器類:

<?php 
/** 
* @license http://opensource.org/licenses/MIT The MIT License 
* @version 1.0.0_20130220000000 
*/ 

/** 
* This class will generate PHP source code for a "model" that interfaces with 
* a database table. 
* 
* @license http://opensource.org/licenses/MIT The MIT License 
* @version 1.0.0_20130220000000 
*/ 
class db_code_generator{ 
    private $closing_tag; 
    private $columns; 
    private $database; 
    private $host; 
    private $password; 
    private $port; 
    private $table; 
    private $type; 
    private $username; 

    /** 
    * Constructor. By default we will try to connect to a MySQL database on 
    * localhost. 
    * 
    * @param string $database The name of the database the user wants to connect 
    * to. 
    * 
    * @param string $table The name of the table to generate code for. 
    * 
    * @param string $username The username we should use to connect to the 
    * database. 
    * 
    * @param string $password The password we need to connect to the database. 
    * 
    * @param string $host The host or server we will try to connect to. If the 
    * user doesn't give us a host we default to localhost. 
    * 
    * @param string $port The port we should try to connect to. Typically this 
    * will not be passed so we default to NULL. 
    * 
    * @param string $type The type of database we are connecting to. Valid 
    * values are: db2, mssql, mysql, pgsql, sqlite. 
    */ 
    public function __construct($database = NULL, 
             $table = NULL, 
             $username = NULL, 
             $password = NULL, 
             $host = 'localhost', 
             $type = 'mysql', 
             $port = NULL, 
             $closing_tag = TRUE){ 
     $this->database = $database; 
     $this->table = $table; 
     $this->username = $username; 
     $this->password = $password; 
     $this->host = $host; 
     $this->port = $port; 
     $this->type = $type; 
     $this->closing_tag = $closing_tag; 
    } 

    /** 
    * Generate the code for a model that represents a record in a table. 
    * 
    * @return string The PHP code generated for this model. 
    */ 
    public function get_code(){ 
     $this->get_data_definition(); 
     $code = $this->get_file_head(); 
     $code .= $this->get_properties(); 
     $code .= $this->get_ctor(); 
     $code .= $this->get_dtor(); 
     $code .= $this->get_method_stubs(); 
     $code .= $this->get_file_foot(); 
     return $code; 
    } 

    /** 
    * Create the code needed for the __construct function. 
    * 
    * @return string The PHP code for the __construct function. 
    */ 
    private function get_ctor(){ 
     $code = "\t/**\n"; 
     $code .= "\t * Constructor.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @param mixed \$id The unique id for a record in this table. Defaults to NULL\n"; 
     if ('db2' === $this->type){ 
      $code .= "\n\t * @param string \$library The library where the physical file resides. Defaults to LIBRARY\n"; 
     } 
     $code .= "\t *\n"; 
     $code .= "\t * @see base_$this->type::__construct\n"; 
     $code .= "\t */\n"; 
     if ('db2' === $this->type){ 
      $code .= "\tpublic function __construct(\$id = NULL, \$library = 'LIBRARY'){\n"; 
      $code .= "\t\tparent::__construct(\$id, \$library);\n"; 
     }else{ 
      $code .= "\tpublic function __construct(\$id = NULL){\n"; 
      $code .= "\t\tparent::__construct(\$id);\n"; 
     } 
     $code .= "\t}\n\n"; 
     return $code; 
    } 

    /** 
    * Connect to the requested database and get the data definition for the 
    * requested table. 
    */ 
    private function get_data_definition(){ 
     try{ 
      switch ($this->type){ 
       case 'db2': 
        $this->get_data_definition_db2(); 
        break; 
       case 'mssql': 
        $this->get_data_definition_mssql(); 
        break; 
       case 'mysql': 
        $this->get_data_definition_mysql(); 
        break; 
       case 'pgsql': 
        $this->get_data_definition_pgsql(); 
        break; 
       case 'sqlite': 
        $this->get_data_definition_sqlite(); 
        break; 
      } 
     }catch(PDOException $e){ 
     } 
    } 

    /** 
    * Get data definition information for a DB2 table. 
    */ 
    private function get_data_definition_db2(){ 
     $con = new PDO("odbc:DRIVER={iSeries Access ODBC Driver};SYSTEM=$this->host;PROTOCOL=TCPIP", $this->username, $this->password); 
     $sql = "SELECT COLUMN_NAME, COLUMN_SIZE, COLUMN_TEXT, DECIMAL_DIGITS, ORDINAL_POSITION, TYPE_NAME FROM SYSIBM.SQLCOLUMNS WHERE TABLE_SCHEM = '". strtoupper($this->database) ."' AND TABLE_NAME = '". strtoupper($this->table) ."'"; 
     $statement = $con->prepare($sql); 
     if ($statement->execute()){ 
      while ($row = $statement->fetch()){ 
       if (NULL !== $row['DECIMAL_DIGITS']){ 
        $decimal = $row['DECIMAL_DIGITS']; 
       }else{ 
        $decimal = NULL; 
       } 
       if ('DECIMAL' === $row['TYPE_NAME'] && NULL !== $row['DECIMAL_DIGITS'] && '0' !== $row['DECIMAL_DIGITS']){ 
        $type = 'float'; 
       }else if ('DECIMAL' === $row['TYPE_NAME']){ 
        $type = 'integer'; 
       }else{ 
        $type = strtolower($row['TYPE_NAME']); 
       } 
       if ('1' === $row['ORDINAL_POSITION']){ 
        $key = 'PRI'; 
       }else{ 
        $key = NULL; 
       } 
       $this->columns[$row['COLUMN_NAME']] = array('allow_null' => TRUE, 
                      'decimal' => $decimal, 
                      'default' => NULL, 
                      'extra' => NULL, 
                      'key' => $key, 
                      'length' => $row['COLUMN_SIZE'], 
                      'name' => $row['COLUMN_NAME'], 
                      'text' => $row['COLUMN_TEXT'], 
                      'type' => $type); 
      } 
      ksort($this->columns); 
     } 
    } 

    /** 
    * Get data definition information for a MS SQL table. 
    */ 
    private function get_data_definition_mssql(){ 
     return "The code for generating MS SQL models is not yet implemented.\n"; 
    } 

    /** 
    * Get data definition information for a MySQL table. 
    */ 
    private function get_data_definition_mysql(){ 
     $dsn = "mysql:host=$this->host;"; 
     if (NULL !== $this->port){ 
      $dsn .= "port=$this->port;"; 
     } 
     $dsn .= "dbname=$this->database"; 
     $con = new PDO($dsn, $this->username, $this->password); 
     $sql = "SHOW COLUMNS FROM $this->table"; 
     $statement = $con->prepare($sql); 
     if ($statement->execute()){ 
      while ($row = $statement->fetch()){ 
       $this->columns[$row['Field']] = array('allow_null' => $row['Null'], 
                    'decimal' => NULL, 
                    'default' => $row['Default'], 
                    'extra' => $row['Extra'], 
                    'key' => $row['Key'], 
                    'length' => NULL, 
                    'name' => $row['Field'], 
                    'text' => NULL, 
                    'type' => $row['Type']); 
      } 
      ksort($this->columns); 
     } 
    } 

    /** 
    * Get data definition information for a PostgreSQL table. 
    */ 
    private function get_data_definition_pgsql(){ 
     return "The code for generating PostgreSQL models is not yet implemented.\n"; 
    } 

    /** 
    * Get data definition information for a SQLite table. 
    */ 
    private function get_data_definition_sqlite(){ 
     return "The code for generating SQLite models is not yet implemented.\n"; 
    } 

    /** 
    * Create the code needed for the __destruct function. 
    * 
    * @return string The PHP code for the __destruct function. 
    */ 
    private function get_dtor(){ 
     $code = "\t/**\n"; 
     $code .= "\t * Destructor.\n"; 
     $code .= "\t */\n"; 
     $code .= "\tpublic function __destruct(){\n"; 
     $code .= "\t\tparent::__destruct();\n"; 
     $code .= "\t}\n\n"; 
     return $code; 
    } 

    /** 
    * Generate the code found at the end of the file - the closing brace, the 
    * ending PHP tag and a new line. Some PHP programmers prefer to not have a 
    * closing PHP tag while others want the closing tag and trailing newline - 
    * it probably just depends on their programming background. Regardless it's 
    * best to let everyone have things the way they want. 
    */ 
    private function get_file_foot(){ 
     $code = ''; 
     if ($this->closing_tag){ 
      $code .= "}\n?>\n"; 
     }else{ 
      $code .= '}'; 
     } 
     return $code; 
    } 

    /** 
    * Generate the code found at the beginning of the file - the PHPDocumentor 
    * doc block, the require_once for the correct base class and the class name. 
    * 
    * @return string The code generated for the beginning of the file. 
    */ 
    private function get_file_head(){ 
     $code = "<?php\n"; 
     $code .= "/**\n"; 
     $code .= " * Please enter a description of this class.\n"; 
     $code .= " *\n"; 
     $code .= " * @author XXX <[email protected]>\n"; 
     $code .= " * @copyright Copyright (c) ". date('Y') ."\n"; 
     $code .= " * @license http://www.gnu.org/licenses/gpl-3.0.html GPLv3\n"; 
     $code .= " * @version ". date('Ymd') ."\n"; 
     $code .= " */\n\n"; 
     $code .= "require_once('base_$this->type.php');\n\n"; 
     $code .= "class ". strtolower($this->table) ." extends base_$this->type{\n"; 
     return $code; 
    } 

    /** 
    * Generate the code for a delete method stub. 
    * 
    * @return string The PHP code for the method stub. 
    */ 
    private function get_method_stub_delete(){ 
     $code = "\t/**\n"; 
     $code .= "\t * Override the delete method found in the base class.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @param mixed \$id The unique record ID to be deleted.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @return bool TRUE if a record was successfully deleted from the table, FALSE otherwise.\n"; 
     $code .= "\t */\n"; 
     $code .= "\tpublic function delete(\$id){\n"; 
     $code .= "\t\treturn parent::delete(\$id);\n"; 
     $code .= "\t}\n\n"; 
     return $code; 
    } 

    /** 
    * Generate the code for an insert method stub. 
    * 
    * @return string The PHP code for the method stub. 
    */ 
    private function get_method_stub_insert(){ 
     $code = "\t/**\n"; 
     $code .= "\t * Override the insert method found in the base class.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @param array \$parms An array of data, probably the \$_POST array.\n"; 
     $code .= "\t * @param bool \$get_insert_id A flag indicating if we should get the autoincrement value of the record just created.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @return bool TRUE if a record was successfully inserted into the table, FALSE otherwise.\n"; 
     $code .= "\t */\n"; 
     $code .= "\tpublic function insert(\$parms, \$get_insert_id = FALSE){\n"; 
     $code .= "\t\treturn parent::insert(\$parms, \$get_insert_id);\n"; 
     $code .= "\t}\n\n"; 
     return $code; 
    } 

    /** 
    * Generate the code for an update method stub. 
    * 
    * @return string The PHP code for the method stub. 
    */ 
    private function get_method_stub_update(){ 
     $code = "\t/**\n"; 
     $code .= "\t * Override the update method found in the base class.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @param array &\$parms An array of key=>value pairs - most likely the \$_POST array.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @param integer \$limit The number of records to update. Defaults to NULL.\n"; 
     $code .= "\t *\n"; 
     $code .= "\t * @return bool TRUE if a record was successfully updated, FALSE otherwise.\n"; 
     $code .= "\t */\n"; 
     $code .= "\tpublic function update(\$parms, \$limit = NULL){\n"; 
     $code .= "\t\treturn parent::update(\$parms, \$limit);\n"; 
     $code .= "\t}\n\n"; 
     return $code; 
    } 

    /** 
    * Create method stubs for create, delete and update. 
    * 
    * @return string The PHP code for these stubs. 
    */ 
    private function get_method_stubs(){ 
     $code = $this->get_method_stub_delete(); 
     $code .= $this->get_method_stub_insert(); 
     $code .= $this->get_method_stub_update(); 
     return $code; 
    } 

    private function get_properties(){ 
     $code = ''; 
     if (count($this->columns)){ 
      foreach ($this->columns AS $index => $col){ 
       $code .= "\t/**\n"; 
       if (NULL !== $col['text']){ 
        $code .= "\t * $col[text]\n"; 
       }else{ 
        $code .= "\t * Description\n"; 
       } 
       $code .= "\t * @var ". $col['type']; 
       if (NULL !== $col['length']){ 
        $code .= " ($col[length]"; 
        if (NULL !== $col['decimal']){ 
         $code .= ",$col[decimal]"; 
        } 
        $code .= ")"; 
       } 
       $code .= "\n\t */\n"; 
       $temp_name = str_replace('#', '_', $col['name']); 
       $code .= "\tpublic \$$temp_name;\n\n"; 
      } 
     } 
     return $code; 
    } 
} 
?> 

,這裏是一個簡單的頁面使用它:

<?php 
/** 
* @license GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html) 
* @version 1.0.0_20130220000000 
*/ 

require_once('db_code_generator.php'); 

$table_type = array(); 
$table_type['db2'] = 'DB2/400 (db2)'; 
$table_type['mssql'] = 'Microsoft SQL Server (mssql)'; 
$table_type['mysql'] = 'MySQL (mysql)'; 
$table_type['pgsql'] = 'PostGRESQL (pgsql)'; 
$table_type['sqlite'] = 'SQLite (sqlite)'; 

$database = (isset($_POST['database'])) ? $_POST['database'] : 'my_database'; 
$host = (isset($_POST['host'])) ? $_POST['host'] : 'localhost'; 
$username = (isset($_POST['username'])) ? $_POST['username'] : 'root'; 
$password = (isset($_POST['password'])) ? $_POST['password'] : ''; 
$table = (isset($_POST['table'])) ? $_POST['table'] : ''; 
$type = (isset($_POST['type'])) ? $_POST['type'] : 'mysql'; 

$library = (isset($_POST['library'])) ? $_POST['library'] : 'LIBRARY'; 
$file = (isset($_POST['file'])) ? $_POST['file'] : 'STATES'; 
//--------------------------------------------------------------------------- 
?> 
<div class="data_input"> 
    <form action="" method="post"> 
     <fieldset class="top"> 
      <legend>Code Generator</legend> 
      <label for="host">Hostname or IP: 
      <input id="host" maxlength="32" name="host" tabindex="<?php echo $tabindex++; ?>" title="Enter the database host name" type="text" value="<?php echo $host; ?>" /> 
      </label> 
      <br /> 

      <label for="username">Username: 
      <input id="username" maxlength="32" name="username" tabindex="<?php echo $tabindex++; ?>" title="Enter the database username" type="text" value="<?php echo $username; ?>" /> 
      </label> 
      <br /> 

      <label for="password">Password: 
      <input id="password" maxlength="32" name="password" tabindex="<?php echo $tabindex++; ?>" title="Enter the database password" type="password" value="<?php echo $password; ?>" /> 
      </label> 
      <br /> 

      <label for="type">Type: 
      <select id="type" name="type" tabindex="<?php echo $tabindex++; ?>"> 
       <?php 
       foreach ($table_type AS $key=>$value){ 
        echo('<option '); 
        if ($key == $type){ 
         echo 'selected="selected" '; 
        } 
        echo 'value="'. $key .'">'. $value .'</option>'; 
       } 
       ?> 
      </select> 
      </label> 
      <br /> 

     </fieldset> 

     <fieldset class="top"> 
      <legend>PostGRESQL/MSSQL/MySQL Parameters</legend> 

      <label for="database">Database: 
      <input id="database" maxlength="100" name="database" tabindex="<?php echo $tabindex++; ?>" title="Enter the database name" type="text" value="<?php echo $database; ?>" /> 
      </label> 
      <br /> 

      <label for="table">Table: 
      <input id="table" maxlength="100" name="table" tabindex="<?php echo $tabindex++; ?>" title="Enter the table name" type="text" value="<?php echo $table; ?>" /> 
      </label> 
      <br /> 

     </fieldset> 
     <fieldset class="top"> 
      <legend>DB2 Parameters</legend> 

      <label for="library">Library: 
      <input id="library" maxlength="10" name="library" tabindex="<?php echo $tabindex++; ?>" title="Enter the library name" type="text" value="<?php echo $library; ?>" /> 
      </label> 
      <br /> 

      <label for="file">Physical File: 
      <input id="file" maxlength="10" name="file" tabindex="<?php echo $tabindex++; ?>" title="Enter the file name" type="text" value="<?php echo $file; ?>" /> 
      </label> 
      <br /> 

     </fieldset> 
     <fieldset class="bottom"> 
      <button tabindex="<?php echo $tabindex++; ?>" type="submit">Generate!</button> 
     </fieldset> 
    </form> 
</div> 
<?php 

if (isset($_POST['host'])){ 
    if ('db2' == $_POST['type']){ 
     $_POST['database'] = strtoupper($_POST['library']); // Library 
     $_POST['table'] = strtoupper($_POST['file']); // Physical file 
     $_POST['host'] = 'db2_host'; 
     $_POST['username'] = 'db2_username'; 
     $_POST['password'] = 'db2_password'; 
    } 
    $object = new db_code_generator($_POST['database'], $_POST['table'], $_POST['username'], $_POST['password'], $_POST['host'], $_POST['type']); 
    echo('<textarea rows="75" style="margin-left : 50px; width : 90%;" onfocus="select()">'. $object->get_code() .'</textarea>'); 
} 
?> 
+0

織布涼爽。你還可以分享base_mysql類嗎? – Grynn 2013-12-04 21:08:35

+0

@Grynn - 「base_mysql」類的長度超過700行,它的父類('base')大約長650行。我很樂意通過電子郵件將它們發送給您或其他東西。 – 2013-12-04 21:26:23

+0

電子郵件會很棒([email protected]),或者你可以將它粘貼到gist.github.com。我會很高興做一個github或者你的代碼中的任何項目(當然歸因於你) - 所以它是可維護的... – Grynn 2013-12-04 22:15:53

2

對於它的價值,Rafael Rocha股票代碼here

儘管如此,我強烈推薦使用ORM的。將MySQL結構轉換回數據庫抽象層是一件不錯的事情...

-1

我認爲你應該讓它變成你的。我認爲每個項目和模型代碼的要求是不同的。兩個mysql查詢會讓你放心。

  1. SHOW TABLES FROM db_NAME //this gives the table listing, so its Master Looper
  2. DESC tbl_name //detail query that fetches column information of given table

DESC tbl_name會給字段中,鍵入,空,重點,默認和額外的列。

例如在管道(|)中分開的值:

Id | int(11)| NO | PRI | NULL | auto_increment |

我遵循這些規則來製作支持Codeigniter 2中的CRUD操作的Model,控制器和查看器文件。它工作得很好。

+0

我寧願自動生成基本知識並操作 – 2013-02-21 09:29:49

+0

是的,如果您已經建立了標準,那麼完全基本的CRUD總是相似的。我想我的代碼不清楚,但問題是,這兩個查詢會給你表格列信息,這可以用來生成MVC類和文件。 – 2013-02-21 09:50:23

0

我已經寫了一個PHP代碼,它會自動檢測MYSQL數據庫中的所有數據庫,在選擇任何數據庫時,它的所有相關表都被加載。您可以選擇所有表格或任何相應的表格來生成模態類別。

以下是鏈接到我的倉庫

https://github.com/channaveer/EntityGenerator

這會自動創建實體目錄和轉儲所有的實體類到該文件夾​​。

注 - 目前僅支持MYSQL

希望它有幫助。快樂編碼!