使用PHP反射機(jī)制來構(gòu)造"CREATE TABLE"的sql語句
反射是指在PHP運(yùn)行狀態(tài)中,擴(kuò)展分析PHP程序,導(dǎo)出或提取出關(guān)于類、方法、屬性、參數(shù)等的詳細(xì)信息,包括注釋。這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為反射API。反射是操縱面向?qū)ο蠓缎椭性P偷腁PI,其功能十分強(qiáng)大,可幫助我們構(gòu)建復(fù)雜,可擴(kuò)展的應(yīng)用。
其用途如:自動(dòng)加載插件,自動(dòng)生成文檔,甚至可用來擴(kuò)充PHP語言。
php反射api由若干類組成,可幫助我們用來訪問程序的元數(shù)據(jù)或者同相關(guān)的注釋交互。借助反射我們可以獲取諸如類實(shí)現(xiàn)了那些方法,創(chuàng)建一個(gè)類的實(shí)例(不同于用new創(chuàng)建),調(diào)用一個(gè)方法(也不同于常規(guī)調(diào)用),傳遞參數(shù),動(dòng)態(tài)調(diào)用類的靜態(tài)方法。
反射api是php內(nèi)建的oop技術(shù)擴(kuò)展,包括一些類,異常和接口,綜合使用他們可用來幫助我們分析其它類,接口,方法,屬性,方法和擴(kuò)展。這些oop擴(kuò)展被稱為反射。
下面的程序使用Reflection來構(gòu)造"CREATE TABLE"的sql語句。如果你不是很熟悉反射機(jī)制,可以從這個(gè)程序中看看反射的魅力與作用。
<?php /** * Creates an SQL 'Create Table' based upon an entity * @author Chris Tankersley <chris@ctankersley.com> * @copyright 2010 Chris Tankersley * @package PhpORM_Cli */ class PhpORM_Cli_GenerateSql { /** * Use a MySQL database */ const MYSQL = 'mysql'; /** * Use a SQLite database */ const SQLITE = 'sqlite'; /** * Types that are allowed to have a length * @var array */ protected $_hasLength = array('integer', 'varchar'); /** * Regexes needed to pull out the different comments * @var array */ protected $_regexes = array( 'type' => '/ type=([a-z_]*) /', 'length' => '/ length=([0-9]*) /', 'default' => '/ default="(.*)" /', 'null' => '/ null /', ); /** * Types that we support * @var array */ protected $_validTypes = array( 'boolean' => 'BOOL', 'date' => 'DATE', 'integer' => 'INT', 'primary_autoincrement' => 'INT AUTO_INCREMENT PRIMARY KEY', 'text' => 'TEXT', 'timestamp' => 'TIMESTAMP', 'varchar' => 'VARCHAR', ); /** * Name of the class we will interperet * @var string */ protected $_className; /** * Name of the table we are generating * @var string */ protected $_tableName; /** * The type of database we are generating * @var string */ protected $_type; /** * Sets the name of the class we are working with * @param string $class * @param string $table_name * @param string $type */ public function __construct($class, $table_name, $type = self::MYSQL) { $this->_className = $class; $this->_tableName = $table_name; $this->_type = $type; } /** * Builds an SQL Line for a property * @param ReflectionProperty $property * @return string */ protected function _getDefinition($property) { $type = ''; $length = ''; $null = ''; preg_match($this->_regexes['type'], $property->getDocComment(), $matches); if(count($matches) == 2) { if(array_key_exists($matches[1], $this->_validTypes)) { $type = $this->_validTypes[$matches[1]]; if(in_array($matches[1], $this->_hasLength)) { $length = $this->_getLength($property); } if($matches[1] != 'primary_autoincrement') { $null = $this->_getNull($property); } $sql = '`'.$property->getName().'` '.$type.' '.$length.' '.$null; return $sql; } else { throw new Exception('Type "'.$matches[1].'" is not a supported SQL type'); } } else { throw new Exception('Found '.count($matches).' when checking Type for property '.$property->getName()); } } /** * Extracts the Length from a property * @param ReflectionProperty $property * @return string */ protected function _getLength($property) { preg_match($this->_regexes['length'], $property->getDocComment(), $matches); if(count($matches) == 2) { return '('.$matches[1].')'; } else { return ''; } } /** * Determines if a Property is allowed to be null * @param ReflectionProperty $property * @return string */ protected function _getNull($property) { preg_match($this->_regexes['null'], $property->getDocComment(), $matches); if(count($matches) == 1) { return 'NULL'; } else { return 'NOT NULL'; } } /** * Generates a block of SQL to create a table from an Entity * @return string */ public function getSql() { $class = new ReflectionClass($this->_className); $definitions = array(); foreach($class->getProperties() as $property) { if(strpos($property->getName(), '_') === false) { $definitions[] = $this->_getDefinition($property); } } $columns = implode(",n", $definitions); $sql = "CREATE TABLE ".$this->_tableName." (".$columns.")"; if($this->_type == self::MYSQL) { $sql .= " ENGINE=MYISAM"; } return $sql.";"; } }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
- 深入解析PHP底層機(jī)制及相關(guān)原理
- PHP中的異常處理機(jī)制深入講解
- PHP底層運(yùn)行機(jī)制與工作原理詳解
- php7 錯(cuò)誤處理機(jī)制修改實(shí)例分析
- PHP的Trait機(jī)制原理與用法分析
- PHP命名空間與自動(dòng)加載機(jī)制的基礎(chǔ)介紹
- PHP session垃圾回收機(jī)制實(shí)例分析
- PHP進(jìn)階學(xué)習(xí)之類的自動(dòng)加載機(jī)制原理分析
- PHP進(jìn)階學(xué)習(xí)之垃圾回收機(jī)制詳解
- PHP簡單驗(yàn)證碼功能機(jī)制實(shí)例詳解
- PHP SESSION機(jī)制的理解與實(shí)例
- PHP析構(gòu)函數(shù)destruct與垃圾回收機(jī)制的講解
- 詳解PHP的執(zhí)行原理和流程
相關(guān)文章
PHP無限分類代碼,支持?jǐn)?shù)組格式化、直接輸出菜單兩種方式
一朋友寫的PHP無限分類代碼,分享給大家,支持?jǐn)?shù)組格式化、直接輸出菜單兩種方式2011-05-05PHP數(shù)組編碼gbk與utf8互相轉(zhuǎn)換的兩種方法
這篇文章給大家分享了兩種轉(zhuǎn)換的方法,都可以實(shí)現(xiàn)PHP數(shù)組的編碼進(jìn)行相互轉(zhuǎn)換。大家可以參考自己的實(shí)際情況進(jìn)行選擇哪一種方法,下面來一起看看吧。2016-09-09PHP實(shí)現(xiàn)網(wǎng)頁內(nèi)容html標(biāo)簽補(bǔ)全和過濾的方法小結(jié)【2種方法】
這篇文章主要介紹了PHP實(shí)現(xiàn)網(wǎng)頁內(nèi)容html標(biāo)簽補(bǔ)全和過濾的方法,結(jié)合實(shí)例形式分析了php常見的標(biāo)簽檢查、補(bǔ)全、閉合、過濾等相關(guān)操作技巧,需要的朋友可以參考下2017-04-04PHP中運(yùn)用jQuery的Ajax跨域調(diào)用實(shí)現(xiàn)代碼
PHP中運(yùn)用jQuery的Ajax跨域調(diào)用實(shí)現(xiàn)代碼,需要的朋友可以參考下2012-02-02php 微信開發(fā)獲取用戶信息如何實(shí)現(xiàn)
這篇文章主要介紹了php 微信開發(fā)獲取用戶信息如何實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-12-12