<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                各DBMS間,最明顯、最常見的差異就在于所支持、實現的數據類型不同。Yii的一個重要任務,就是消 除這些區別,提供一個統一的開發界面供開發者使用。所以,我們先來看看Yii是怎么克服這一攔路虎 ,實現天下的大一統的。 ## 抽象數據類型[](http://www.digpage.com/db_datatype.html#id2 "Permalink to this headline") 在使用Yii進行數據庫開發時,涉及到2個方面的數據類型:PHP自身的數據類型,DBMS的數據類型。 其中,PHP數據類型比較好整,反正就那么幾個,跟平臺、環境的關系也比較清楚。 復雜的地方在于DBMS的數據類型,龍生九子,各有不同。 因此,Yii不但需要搞定各DBMS間數據類型的差異,還需要搞定PHP與DBMS間數據類 類型的差異。因此,Yii引入了一個邏輯層面的數據類型,來統一PHP與DBMS,以及各DBMS之間數據類型 的差異。這里我們把這個邏輯層面的數據類型稱為抽象類型,在?yii\db\Schema?中進行定義: ~~~ abstract class Schema extends Object { // 預定義16種抽象字段類型 const TYPE_PK = 'pk'; const TYPE_BIGPK = 'bigpk'; const TYPE_STRING = 'string'; const TYPE_TEXT = 'text'; const TYPE_SMALLINT = 'smallint'; const TYPE_INTEGER = 'integer'; const TYPE_BIGINT = 'bigint'; const TYPE_FLOAT = 'float'; const TYPE_DECIMAL = 'decimal'; const TYPE_DATETIME = 'datetime'; const TYPE_TIMESTAMP = 'timestamp'; const TYPE_TIME = 'time'; const TYPE_DATE = 'date'; const TYPE_BINARY = 'binary'; const TYPE_BOOLEAN = 'boolean'; const TYPE_MONEY = 'money'; // ... ... } ~~~ yii\db\Schema?一上來就先針對各DBMS間差異最明顯的字段數據類型進行統一,提供了16種抽象的 字段類型。這16種類型與DBMS無關,在具體到特定的DBMS時,Yii會自動轉換成合適的數據庫字段類型 。我們在編程中,若需要指定字段類型,比如創建數據庫之類,就使用這16種抽象類型。這樣的話, 就不用考慮使用的類型具體的DBMS是否支持的問題了,可以使我們更加專注于開發。 這16種類型看著就知道是什么意思,我們就不展開講了。只是有一點,這個數據類型是抽象的,也就是 說,只是一個邏輯意義上的數據類型,不涉及到具體實現。比如上面的?Schema::TYPE_BIGINT?所 要表示的是一個大數,但具體實現上,可能是用一個字符串來表示。 ## 數據類型轉換[](http://www.digpage.com/db_datatype.html#id3 "Permalink to this headline") 既然Yii使用抽象數據類型來一統江山,那么無可避免的,涉及到PHP數據類型和DBMS數據類型與抽象類 型的轉換問題。 ### 抽象類型轉數據庫類型[](http://www.digpage.com/db_datatype.html#id4 "Permalink to this headline") 前面提到過,在Yii開發中,我們使用16種抽象數據類型,而不使用具體的DBMS的數據類型。那么,在 我們要創建一個數據庫時,Yii是怎么為我們所定義的字段指定合適的數據類型的呢? 首先來看看一個基類?yii\db\QueryBuilder ~~~ class QueryBuilder extends \yii\base\Object { // $typeMap用于定義抽象數據類型到DBMS數據類型的映射關系, // 具體由各QueryBuilder子類實現。 public $typeMap = []; // 將抽象數據類型轉換成合適的DBMS數據類型 public function getColumnType($type) { // 映射表中已經有的,直接使用映射的類型 if (isset($this->typeMap[$type])) { return $this->typeMap[$type]; // 映射表中沒有的類型,看看是不是形如 "Schema::TYPE_INT(11) DEFAULT 0" 之類的 } elseif (preg_match('/^(\w+)\((.+?)\)(.*)$/', $type, $matches)) { if (isset($this->typeMap[$matches[1]])) { return preg_replace('/\(.+\)/', '(' . $matches[2] . ')', $this->typeMap[$matches[1]]) . $matches[3]; } // 看看是不是形如 "Schema::TYPE_INT NOT NULL" 之類的, // 注意這一分支在第二分支之后 } elseif (preg_match('/^(\w+)\s+/', $type, $matches)) { if (isset($this->typeMap[$matches[1]])) { return preg_replace('/^\w+/', $this->typeMap[$matches[1]], $type); } } // 實在匹配不上映射表中的類型,那就原封不動返回吧 return $type; } // ... ... } ~~~ 上面的代碼只列出了?yii\db\QueryBuilder?的部分內容。特別是其中的?$typeMap[]?是由子 類來具體實現的。比如,對于MySQL數據庫,?yii\db\mysql\QueryBuilder?中: ~~~ namespace yii\db\mysql; class QueryBuilder extends \yii\db\QueryBuilder { public $typeMap = [ Schema::TYPE_PK => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY', Schema::TYPE_BIGPK => 'bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY', Schema::TYPE_STRING => 'varchar(255)', Schema::TYPE_TEXT => 'text', Schema::TYPE_SMALLINT => 'smallint(6)', Schema::TYPE_INTEGER => 'int(11)', Schema::TYPE_BIGINT => 'bigint(20)', Schema::TYPE_FLOAT => 'float', Schema::TYPE_DECIMAL => 'decimal(10,0)', Schema::TYPE_DATETIME => 'datetime', Schema::TYPE_TIMESTAMP => 'timestamp', Schema::TYPE_TIME => 'time', Schema::TYPE_DATE => 'date', Schema::TYPE_BINARY => 'blob', Schema::TYPE_BOOLEAN => 'tinyint(1)', Schema::TYPE_MONEY => 'decimal(19,4)', ]; // ... ... } ~~~ 因此,對于16種抽象數據類型而言,都可以轉換成MySQL的特定數據類型。這里我們看到,TYPE_MONEY?本來是MySQL所沒有的數據類型,但通過將其映射成了?decimal(19,4)?,使得 MySQL也可以支持?TYPE_MONEY?類型了。 同樣的,在?yii\db\pgsql\QueryBuilder?yii\db\mssql\QueryBuilder?等QueryBuilder子類 中,也有相同的數據類型映射表?$typeMap[]?,以實現從抽象數據類型到具體數據庫數據類型的映 射。 對于抽象數據類型的具體定義,我們選一個自己比較熟悉的DBMS的Schema進行記憶就可以了。如果實在 吃不準,比如?TYPE_STRING?是定長還是變長,保留不保留空格等,可以看看Schema中的定義。建 議讀者朋友們還是熟記這16個基本類型,起碼仔細過一遍,在具體開發時,能省時不少。 yii\db\QueryBuilder::getColumnType()?實現了抽象數據類型到具體DBMS數據類型的轉換。 在具體的轉換過程中,如果指定一個字段為?Schema::TYPE_STRING?之類的,那么就會被轉換成?varchar(255)?。有的讀者朋友可能會問,那要是想指定成?varchar(64)?該怎么做呢? 那就直接使用?Schema::TYPE_STRING(64)?。?yii\db\QueryBuilder::getColumnType()?會識 別出來Schema::TYPE_STRING?,并將原來的?varchar(255)?轉換成?varchar(64)?。 這點適用于其他數據類型。當然,其本身要支持。指定一個?Schema::TYPE_BOOLEAN(2)?又有什么 意義呢? 我們還可以在16種抽象類型后面使用?NOT?NULL?,?DEFAULT?等。yii\db\QueryBuilder::getColumnType()?也是能夠識別出來并加以處理的。 ### 數據庫類型轉抽象類型[](http://www.digpage.com/db_datatype.html#id5 "Permalink to this headline") 所謂來而不往非禮也,說完了抽象類型轉DBMS數據類型,就該說說反過來數據庫的數據類型, 怎么轉換成抽象數據類型了。仍然以MySQL數據庫為例,具體代碼在?yii\db\mysql\Schema?中: ~~~ class Schema extends \yii\db\Schema { // 定義從數據庫數據類型到16個抽象數據類型間的映射關系 public $typeMap = [ 'tinyint' => self::TYPE_SMALLINT, 'bit' => self::TYPE_INTEGER, 'smallint' => self::TYPE_SMALLINT, 'mediumint' => self::TYPE_INTEGER, 'int' => self::TYPE_INTEGER, 'integer' => self::TYPE_INTEGER, 'bigint' => self::TYPE_BIGINT, 'float' => self::TYPE_FLOAT, 'double' => self::TYPE_FLOAT, 'real' => self::TYPE_FLOAT, 'decimal' => self::TYPE_DECIMAL, 'numeric' => self::TYPE_DECIMAL, 'tinytext' => self::TYPE_TEXT, 'mediumtext' => self::TYPE_TEXT, 'longtext' => self::TYPE_TEXT, 'longblob' => self::TYPE_BINARY, 'blob' => self::TYPE_BINARY, 'text' => self::TYPE_TEXT, 'varchar' => self::TYPE_STRING, 'string' => self::TYPE_STRING, 'char' => self::TYPE_STRING, 'datetime' => self::TYPE_DATETIME, 'year' => self::TYPE_DATE, 'date' => self::TYPE_DATE, 'time' => self::TYPE_TIME, 'timestamp' => self::TYPE_TIMESTAMP, 'enum' => self::TYPE_STRING, ]; // ... ... } ~~~ 在?yii\db\mysql\Schema::$typeMap?中,定義了MySQL數據類型與16種抽象數據類型的映射關系。 當然,由于抽象數據類型只有16種,所以,有一些MySQL數據類型被映射成同一種抽象類型。比如year?date?都被映射成了?self::TYPE_DATE?了。 同樣的,你可以在?yii\db\mssql\Schema?和?yii\db\pgsql\Schema?中找到類似的映射代碼。 在各Schema子類中,Yii針對不同的DBMS,實現了數據庫數據類型到抽象數據類型間的映射關系。 從數據庫類型到抽象類型的映射關系,只要掌握前面16種抽象類型與數據庫數據類型的映射關系, 那么,其逆向映射就幾乎不用刻意去記憶了。額外的,凡是沒有合適的抽象類型的,就用?TYPE_STRING來表示。 上面只是一個映射表,具體轉換過程在生成字段信息?yii\db\ColumnSchema?時進行。yii\db\ColumnSchema?保存了一個字段的各種相關信息,包括字段類型等。 字段信息的獲取和填充,又發生在?yii\db\Schema::loadTableSchema()?中。 該函數用于加載數據表信息?yii\db\TableSchema?,這是一個抽象函數,具體由各子類實現。 字段信息和表信息我們后面再講,這里大致知道就是用于保存字段和數據表的各種信息就可以了。而且 在獲取表信息時,必然會調用到獲取字段信息的相關代碼。字段信息和表信息的獲取,都由Schema子類 來具體實現。 對于MySQL數據庫而言,字段信息的獲取在?yii\db\mysql\Schema::loadColumnSchema()?中,也是 他實現了從數據庫類型到抽象類型的轉換: ~~~ // $info數組 由 SQL 語句 "SHOW FULL COLUMNS FROM ..." 而來,形式如下: // Field: id // Type: int(11) // Collation: NULL // Null: NO // Key: PRI // Default: NULL // Extra: auto_increment // Privileges: select,insert,update,references // Comment: protected function loadColumnSchema($info) { $column = $this->createColumnSchema(); // 字段名 $column->name = $info['Field']; // 是否允許為NULL $column->allowNull = $info['Null'] === 'YES'; // 是否是主鍵 $column->isPrimaryKey = strpos($info['Key'], 'PRI') !== false; // 是否 auto_increment $column->autoIncrement = stripos($info['Extra'], 'auto_increment') !== false; // 獲取字段注釋 $column->comment = $info['Comment']; // 重點是這里,獲取數據庫字段類型,如上面的 int(11) $column->dbType = $info['Type']; // 是否是 unsigned $column->unsigned = stripos($column->dbType, 'unsigned') !== false; // 以下將把數據庫類型,轉換成對應的抽象類型,默認為 TYPE_STRING $column->type = self::TYPE_STRING; if (preg_match('/^(\w+)(?:\(([^\)]+)\))?/', $column->dbType, $matches)) { // 獲取 int(11) 的 "int" 部分 $type = strtolower($matches[1]); // 如果映射表里有,那就直接映射成抽象類型 if (isset($this->typeMap[$type])) { $column->type = $this->typeMap[$type]; } // 形如int(11) 的括號中的內容 if (!empty($matches[2])) { // 枚舉類型,還需要將所有枚舉值寫入 $column->enumValues if ($type === 'enum') { $values = explode(',', $matches[2]); foreach ($values as $i => $value) { $values[$i] = trim($value, "'"); } $column->enumValues = $values; // 如果不是枚舉類型,那么括號中的內容就是精度了,如 decimal(19,4) } else { $values = explode(',', $matches[2]); $column->size = $column->precision = (int) $values[0]; if (isset($values[1])) { $column->scale = (int) $values[1]; } // bit(1) 類型的,轉換成 boolean if ($column->size === 1 && $type === 'bit') { $column->type = 'boolean'; } elseif ($type === 'bit') { // 由于bit最多64位,如果超過 32 位,那么用一個 bigint 足以。 if ($column->size > 32) { $column->type = 'bigint'; // 如果正好32位,那么用一個 interger 來表示。 } elseif ($column->size === 32) { $column->type = 'integer'; } } } } } // 獲取PHP數據類型 $column->phpType = $this->getColumnPhpType($column); // 處理默認值 if (!$column->isPrimaryKey) { // timestamp 的話,要實際獲取當前時間戳,而不能是字符串 'CURRENT_TIMESTAMP' if ($column->type === 'timestamp' && $info['Default'] === 'CURRENT_TIMESTAMP') { $column->defaultValue = new Expression('CURRENT_TIMESTAMP'); // bit 的話,要截取對應的內容,并進行進制轉換 } elseif (isset($type) && $type === 'bit') { $column->defaultValue = bindec(trim($info['Default'],'b\'')); // 其余類型的,直接轉換成PHP類型的值 } else { $column->defaultValue = $column->phpTypecast($info['Default']); } } return $column; } ~~~ 上面的代碼是完整獲取字段信息的過程,這里重點要看的,是獲取數據類型部分的代碼。結合映射表和 上面的代碼,我們能夠得出: * 通過?SHOW?FULL?COLUMNS?FROM?SQL語句獲取字段信息,并存儲在?$info?數組中。 * 根據?$info['Type']?獲取字段類型信息。 * 如果映射表里已經有映射關系的,直接通過映射表,獲取相應的抽象類型。 * 如果映射表沒有的,默認地視字段的抽象類型為?TYPE_STRING?。 * 對于枚舉類型,除了轉換成?TYPE_STRING?外,還要獲取其枚舉值,否則,類型信息不完整 。 * 對于bit類型,在32位及32位以下時,使用?TYPE_INTEGER?抽象類型,在32位以上(bit最大為64 位)時,使用?TYPE_BIGINT?類型。 至于其他字段信息的獲取,如是否允許為 NULL 之類,上面的代碼中注釋已經交待清楚了,大家這么聰 明,相信難不倒你們。需要稍稍注意的,就是默認值的處理,特別是?timestamp?類型默認值的處 理。 ### 抽象類型轉PHP類型[](http://www.digpage.com/db_datatype.html#php "Permalink to this headline") 前面講數據庫類型轉抽象類型時,在?yii\db\mysql\Schema::loadColumnSchema()?中,有一個語 句$column->phpType?=?$this->getColumnPhpType($column);?我們只是簡單地說是轉換成 PHP 類型,就一筆帶來了。其實,他就是把抽像類型轉換成PHP類型的關鍵,讓我們來看看這個yii\db\Schema::getColumnPhpType() ~~~ protected function getColumnPhpType($column) { // 定義從抽象類型到PHP類型的映射 static $typeMap = [ 'smallint' => 'integer', 'integer' => 'integer', 'bigint' => 'integer', 'boolean' => 'boolean', 'float' => 'double', 'binary' => 'resource', ]; // 除了上面的映射關系外,還有幾個特殊情況: // 1\. bigint字段,在64位環境下,且為singed時,使用integer來表示,否則string // 2\. integer字段,在32位環境下,且為unsinged時,使用string表示,否則integer // 3\. 映射中不存在的字段類型均使用string if (isset($typeMap[$column->type])) { if ($column->type === 'bigint') { return PHP_INT_SIZE == 8 && !$column->unsigned ? 'integer' : 'string'; } elseif ($column->type === 'integer') { return PHP_INT_SIZE == 4 && $column->unsigned ? 'string' : 'integer'; } else { return $typeMap[$column->type]; } } else { return 'string'; } } ~~~ 首先不要驚訝于為什么這個方法不像數據庫類與抽象類型轉換時,放在MySQL子類Schema中實現。這是 由于我們現在討論的是抽象類型到PHP類型的轉換。我們說過,抽象類型是與數據庫無關的,PHP類型更 是與數據庫沒有半毛錢關系,所以,放在基類?yii\db\Schema?中是合理的。這也是我們在平時在 編程時經常采用的劃分基類與子類的一個常用準則。 雖然,我們說抽象數據類型有16種,但是到了PHP范疇,有的類型是沒有意義的。在PHP中,數據庫的字 段類型,都可以歸結了?integer?boolean?double?resourece?string?5種。 * TYPE_PK?和?TYPE_BIGPK?表示主鍵,Yii使用?yii\db\ColumnSchema::isPrimaryKey?屬性來表示,不存在將其轉換成何種數據類型的問題。 * TYPE_SMALLINT?TYPE_INTEGER?TYPE_BIGINT?等字段一般都轉換成PHP的?integer?類型。特別是TYPE_SMALLINT?,PHP的?integer?完全可以滿足要求。 * TYPE_BIGINT?字段,如果是在64位環境下,且該字段并非為?unsigned?時,PHP的?integer?足夠存儲。但是,在32位環境下,PHP的?integer?只有4個字節,不夠存儲8個字節的TYPE_BIGINT?。而如果字段是?unsigned?的,由于PHP并沒有?unsigned?一說,就算是 64位環境,也少了1 bit。在不夠存儲時,就只能選用PHP的?string?類型了。 * TYPE_INTEGER?字段,在32位環境下,如果是?unsigned?的,那也會少1 bit來存儲。而如 果是64位環境,或者并非是?unsigned?的,PHP的?integer?都是夠用的。同樣,不夠存儲時 ,就使用字符串類型了。 * TYPE_FLOAT?字段,注意是轉換成PHP的?double?而非?float?,?float?精度不夠。 * TYPE_BOOLEAN?字段,順理成章對應PHP的?boolean?類型。 * TYPE_BINARY?字段,理所當然對應PHP的?resource?類型。 * TYPE_STRING?和?TYPE_TEXT?字段,顯而易見對應 PHP的?string?類型。 * TYPE_DECIMAL?和?TYPE_MONEY?字段由于PHP的數值類型精度都不夠,所以, 只能使用?string類型來表示。 * 對于日期、時間等字段,盡管PHP提供了豐富的日期、時間函數,但事實上,PHP中并沒有專門的表示 日期、時間的數據類型。因此,對于這類字段,又只能求助于萬能的?string?類型了。 ### 字段內容轉PHP變量[](http://www.digpage.com/db_datatype.html#id6 "Permalink to this headline") 前面我們有了數據庫類型轉抽象類型,抽象類型轉PHP類型,那么,我們就可以完成數據庫類型到PHP類 型的轉換,也就是說,能夠將數據庫中的內容讀取到PHP中供我們編程時使用啦。 假設有如下的MySQL數據表: ~~~ CREATE TABLE `tbl_news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(10) unsigned NOT NULL DEFAULT '0', `status` enum('Draft','Publish','Archive','Unpublish') NOT NULL DEFAULT 'Draft', `title` varchar(256) NOT NULL DEFAULT '', `tags` varchar(256) NOT NULL DEFAULT '', `createtime` int(10) unsigned NOT NULL DEFAULT '0', `publishtime` int(10) unsigned NOT NULL DEFAULT '0', `abstract` varchar(512) NOT NULL DEFAULT '', `content` text, `lastupdate` int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ~~~ 那么,通過PDO獲取其中一個記錄,DUMP出來后,各字段的類型為: ~~~ array(10) { ["id"]=> string(1) "7" ["userid"]=> string(1) "1" ["status"]=> string(5) "Draft" ["title"]=> string(6) "teste2" ["tags"]=> string(4) "test" ["createtime"]=> string(10) "1382152003" ["publishtime"]=> string(10) "1381161600" ["abstract"]=> string(3) "abs" ["content"]=> string(12) "<p>cont</p>" ["lastupdate"]=> string(10) "1382152003" } ~~~ 你能看到,所有的字段通過PDO讀取后,再DUMP出來都是以?string?保存的。這就需要Yii根據 ColumnSchema中字段信息,去把各字段以合適的PHP類型表現出來。而這個過程, 就是yii\db\ColumnSchema::phpTypeCast() ~~~ // 該方法用于把 $value 轉換成 php 變量,其中 $value 是PDO從數據庫中讀取的內容 // 主要參考的是字段的抽象類型 $type 和 PHP類型 $phpType public function phpTypecast($value) { // 內容為空時,若不是字符串或二進制抽象類型,則是NULL的意思。 if ($value === '' && $this->type !== Schema::TYPE_TEXT && $this->type !== Schema::TYPE_STRING && $this->type !== Schema::TYPE_BINARY) { return null; } // 內容為null,或者 $value 的類型與PHP類型一致,或者 $value 是一個數據庫表達式, // 那么可以直接返回 if ($value === null || gettype($value) === $this->phpType || $value instanceof Expression) { return $value; } // 否則,需要根據PHP類型來完成類型轉換 switch ($this->phpType) { case 'resource': case 'string': return is_resource($value) ? $value : (string) $value; case 'integer': return (int) $value; case 'boolean': return (bool) $value; case 'double': return (double) $value; } return $value; } ~~~ 在上面的轉換過程中,PHP類型信息已經在上一步的?yii\db\Schema::getColumnPhpType()?中獲 取了。這里就是把從數據庫中得到的數據,轉換成?phpType?所指定的PHP變量類型。 前面我們講過,16種抽象類型最終對應于PHP的5種數據類型。但是,從上面的?phpTypeCast()?來 看,還要多出2種類型來: * 一是?null?,對于既不是文本類型,又不是二進制類型的字段,如果其內容為空,那么他的意思 其實是?NULL?。 * 二是?yii\db\Expression?數據庫表達式類型。如前面我們提到的?timestamp?的默認值是CURRENT_TIMESTAMP?時,就用到了一個?new?Expression('CURRENT_TIMESTAMP')?。 ### PHP類型轉PDO類型[](http://www.digpage.com/db_datatype.html#phppdo "Permalink to this headline") 前面,我們已經實現了創建數據庫時,使用抽象類型來指定字段類型,也實現了從數據庫讀取數據到 PHP(數據庫類型-抽象類型-PHP類型)的轉換過程。 還有一個情景我們沒有涉及到,那就是PHP類型轉數據庫類型的問題。由于Yii通過PDO操作數據庫,因 此,這個問題就成為了PHP類型怎么轉換成PDO數據類型的問題,至于PDO轉數據庫字段類型,由PDO自己 實現,我們就不用操心了。 這里,比如說的SQL查詢參數綁定,?PDO::bindParam()?要求提供參數類型。Yii是能過PHP類型, 直接就轉換成PDO的類型了,具體的代碼在?yii\db\Schema::getPdoType() ~~~ // 將一個PHP數據類型轉換成PDO數據類型 public function getPdoType($data) { // 定義一個PHP類型到PDO類型的映射表 static $typeMap = [ 'boolean' => \PDO::PARAM_BOOL, 'integer' => \PDO::PARAM_INT, 'string' => \PDO::PARAM_STR, 'resource' => \PDO::PARAM_LOB, 'NULL' => \PDO::PARAM_NULL, ]; $type = gettype($data); // 在匹配不上映射表時,采用字符串類型 return isset($typeMap[$type]) ? $typeMap[$type] : \PDO::PARAM_STR; } ~~~ 前面我們一直在說,16種抽象數據類型,可以用來表示各種DBMS的各種字段類型。而這16種抽象類型, 具體到PHP數據類型時,逃不過?integer?boolean?resource?string?和?double?5種,再加上特殊的?null?一共是6種。 而在上面的?getPdoType()?中,與6種PHP數據類型對應的,PDO提供了5種,其中?double?類型 用PDO::PARAM_STR?來表示。 至此,PHP、Yii、DBMS、PDO間的數據類型轉換問題就完全解決了。 如果覺得《深入理解Yii2.0》對您有所幫助,也請[幫助《深入理解Yii2.0》](http://www.digpage.com/donate.html#donate)。 謝謝!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看