亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2814 | 回復(fù): 3
打印 上一主題 下一主題

[pear 數(shù)據(jù)庫]PEAR::MDB2模塊調(diào)用機制 [復(fù)制鏈接]

論壇徽章:
1
榮譽版主
日期:2011-11-23 16:44:17
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2006-07-12 01:42 |只看該作者 |倒序瀏覽
從使用PEAR以來,使用得最多的是PEAR::DB,但是這么幾年來,PEAR::DB一直沒有什么新的變化。在最新的一個項目里,我開始嘗試使用 PEAR::MDB2,這個包現(xiàn)在已經(jīng)替代了PEAR::DB,而且提供了豐富的特性,從它的結(jié)構(gòu)上來看,也提供了更多的擴展可能。
可能是作者忙于開發(fā)或者這個包太新,相關(guān)的文檔沒有跟上,所以只能自己閱讀代碼來搞清楚它提供的各種方法。
如何使用最基本的連接、查詢等,在PEAR手冊中(http://pear.php.net/manual/en/package.database.mdb2.php)已經(jīng)提供了簡單的說明,在此我只討論MDB2如何調(diào)用各種模塊的機制。
除了基本的sql查詢功能外,MDB2還提供了幾個擴展模塊,比如Manager(操縱數(shù)據(jù)庫對象),這個模塊可以添加、刪除數(shù)據(jù)庫,添加、修改、刪除表。要使用這個模塊提供的方法有三種方式:
$mdb->loadModule('Manager');
$mdb->manager->createTable($name, $fields);   // PHP4
或者
$mdb->loadModule('Manager');
$mdb->create($name, $fields);                 // PHP5
或者
$mdb->mgCreateTable($name, $fields);          // PHP5
前兩種方式必須事先用loadModule('Manager')載入模塊,否則無法調(diào)用。
先來研究一下loadModule()

  1. function &loadModule($module, $property = null, $phptype_specific = null)
  2. {
  3.     if (!$property) {
  4.         $property = strtolower($module);
  5.     }

  6.     if (!isset($this->{$property})) {
  7.         $version = $phptype_specific;
  8.         if ($phptype_specific !== false) {
  9.             $version = true;
  10.             $class_name = 'MDB2_Driver_'.$module.'_'.$this->phptype;
  11.             $file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name).'.php';
  12.         }
  13.         if ($phptype_specific === false
  14.             || (!MDB2::classExists($class_name) && !MDB2::fileExists($file_name))
  15.         ) {
  16.             $version = false;
  17.             $class_name = 'MDB2_'.$module;
  18.             $file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name).'.php';
  19.         }

  20.         $err = MDB2::loadClass($class_name, $this->getOption('debug'));
  21.         if (PEAR::isError($err)) {
  22.             return $err;
  23.         }

  24.         // load modul in a specific version
  25.         if ($version) {
  26.             if (method_exists($class_name, 'getClassName')) {
  27.                 $class_name_new = call_user_func(array($class_name, 'getClassName'), $this->db_index);
  28.                 if ($class_name != $class_name_new) {
  29.                     $class_name = $class_name_new;
  30.                     $err = MDB2::loadClass($class_name, $this->getOption('debug'));
  31.                     if (PEAR::isError($err)) {
  32.                         return $err;
  33.                     }
  34.                 }
  35.             }
  36.         }

  37.         if (!class_exists($class_name)) {
  38.             $err =& $this->raiseError(MDB2_ERROR_LOADMODULE, null, null,
  39.                 "unable to load module '$module' into property '$property'");
  40.             return $err;
  41.         }
  42.         $this->{$property} =& new $class_name($this->db_index);
  43.         $this->modules[$module] =& $this->{$property};
  44.         if ($version) {
  45.             // this will be used in the connect method to determine if the module
  46.             // needs to be loaded with a different version if the server
  47.             // version changed in between connects
  48.             $this->loaded_version_modules[] = $property;
  49.         }
  50.     }

  51.     return $this->{$property};
  52. }
復(fù)制代碼

前邊一部分是根據(jù)模塊的名字載入對應(yīng)的文件,并且檢查文件中是否包含了正確的類,稍微有點點攪,不過熟悉目錄結(jié)構(gòu)之后就可以看懂。(看不明白也無所謂,只要不自己寫模塊)

關(guān)鍵在于實例化的部分:
$this->{$property} =& new $class_name($this->db_index);
$this->modules[$module] =& $this->{$property};
在實例化了Manager模塊包含的類之后,把這個實例作為當(dāng)前MDB2實例的同名屬性,另外再添加為modules屬性數(shù)組的元素。

所以在PHP4下,可以用$mdb->manager->createTable($name, $fields);調(diào)用模塊的方法。
調(diào)用的時候注意用模塊名字的小寫,因為$property = strtolower($module);

如果是PHP5的話,就可以使用另外兩種更加方便的調(diào)用方式,原因是PHP5的新特性__call()方法。

  1. function __call($method, $params)
  2. {
  3.     $module = null;
  4.     if (preg_match('/^([a-z]+)([A-Z])(.*)$/', $method, $match)
  5.         && isset($this->options['modules'][$match[1]])
  6.     ) {
  7.         $module = $this->options['modules'][$match[1]];
  8.         $method = strtolower($match[2]).$match[3];
  9.         if (!isset($this->modules[$module]) || !is_object($this->modules[$module])) {
  10.             $result =& $this->loadModule($module);
  11.             if (PEAR::isError($result)) {
  12.                 return $result;
  13.             }
  14.         }
  15.     } else {
  16.         foreach ($this->modules as $key => $foo) {
  17.             if (is_object($this->modules[$key])
  18.                 && method_exists($this->modules[$key], $method)
  19.             ) {
  20.                 $module = $key;
  21.                 break;
  22.             }
  23.         }
  24.     }
  25.     if (!is_null($module)) {
  26.         return call_user_func_array(array(&$this->modules[$module], $method), $params);
  27.     }
  28.     trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $method), E_USER_ERROR);
  29. }
復(fù)制代碼

當(dāng)調(diào)用不存在的mgCreateTable()和createTable()方法時,__call()方法會被調(diào)用。

preg_match('/^([a-z]+)([A-Z])(.*)$/', $method, $match)
試圖把調(diào)用的方法名拆分成為"mg C reateTable"(mgCreateTable)三段
所以使用這種方法要注意大小寫,不然無法正確的拆分

isset($this->options['modules'][$match[1]])
第一段是模塊名的縮寫,把這個縮寫拿到$mdb->options屬性中去比較

默認(rèn)的,options屬性的內(nèi)容是

  1. $mdb->options['modules'] = array(
  2.     'ex' => 'Extended',
  3.     'dt' => 'Datatype',
  4.     'mg' => 'Manager',
  5.     'rv' => 'Reverse',
  6.     'na' => 'Native',
  7.     'fc' => 'Function',
  8. );
復(fù)制代碼

$module = $this->options['modules'][$match[1]];
當(dāng)?shù)谝欢蔚膬?nèi)容是mg時,對應(yīng)的模塊就是Manager了

$method = strtolower($match[2]).$match[3];
那么方法就是createTable了

if (!isset($this->modules[$module]) || !is_object($this->modules[$module]))
$result =& $this->loadModule($module);
在modules屬性中查看是否已經(jīng)有被調(diào)用模塊的實例,modules屬性是用來存放模塊實例的數(shù)組,剛才在loadModule()部分已經(jīng)有說明
如果沒有對應(yīng)的實例則loadModule()來創(chuàng)建實例,所以這種調(diào)用方式不用事先loadModule()

foreach ($this->modules as $key => $foo)
當(dāng)三段法無效的時候,遍歷當(dāng)前所有的模塊實例

if (is_object($this->modules[$key]) && method_exists($this->modules[$key], $method)
使用method_exists()函數(shù)尋找每個實例是否有被調(diào)用的方法

return call_user_func_array(array(&$this->modules[$module], $method), $params);
最后調(diào)用找到的模塊實例的對應(yīng)方法

從以上分析可以看出MDB2對它的擴展模塊的調(diào)用方式,只要遵守這些約定,我們也可以自行擴展出自己的模塊。
不過$mdb->createTable()這種調(diào)用方式有個問題,如果兩個模塊都具有相同的方法就可能出問題,寫自己的模塊需要注意這一點。

暫時先寫到這里,以后再繼續(xù)討論幾個內(nèi)置模塊的具體使用。

[ 本帖最后由 夜貓子 于 2006-7-12 02:00 編輯 ]

論壇徽章:
1
榮譽版主
日期:2011-11-23 16:44:17
2 [報告]
發(fā)表于 2006-07-12 01:44 |只看該作者

用PEAR::MDB2 Manager模塊控制表

PEAR::MDB2除了提供PEAR::DB已有的sql處理功能之外,還提供了一個非常強大的擴展功能:添加/刪除/修改數(shù)據(jù)庫對象
可以控制的數(shù)據(jù)庫對象有:

    * 庫
    * 表
    * 索引(普通索引、主鍵、唯一索引)

調(diào)用Manager模塊
$mdb->loadModule('Manager');
或者直接用魔法調(diào)用方式
$mdb->mgCreateTable();
$mdb->mgAlterTable();
模塊調(diào)用機制參看《PEAR::MDB2模塊調(diào)用機制》

創(chuàng)建數(shù)據(jù)庫
$mdb->createDatabase($dbname);
建立數(shù)據(jù)庫很簡單,只要指定數(shù)據(jù)庫名字就好,可惜的是,創(chuàng)建新數(shù)據(jù)庫時不能指定更多的參數(shù),比如postgresql建立數(shù)據(jù)庫時還可以指定encoding、owner等等。

定義字段
MDB2把字段的數(shù)據(jù)類型抽象為:

    * text   字符類型
    * clob   大對象(文本)
    * blob   大對象(二進制)
    * integer    整數(shù)
    * boolean    布爾類型
    * date       日期類型(YY-MM-DD)
    * time       時間類型(HH:MM:SS)
    * timestamp  日期加時間(YYYY-MM-DD HH:MM:SS)
    * float      浮點數(shù)類型
    * decimal    任意精度數(shù)值類型

字段的參數(shù)有:

    * length    長度
    * type      數(shù)據(jù)類型
    * default   默認(rèn)值
    * unsigned  無符號
    * notnull   不允許空值
    * fixed     字符類型是否用空格填充不足的長度

例如我想要,創(chuàng)建一個user_info表,包含三個字段:id(編號 整數(shù))、user_name(用戶名)、password(MD5密碼),字段的描述就是

  1. $fields = array(
  2.     'id' => array(
  3.         'type'      => 'integer',
  4.         'notnull'   => 1
  5.     ),
  6.     'username' => array(
  7.         'type'      => 'text',
  8.         'length'    => 20,
  9.         'notnull'   => 1
  10.     ),
  11.     'password' => array(
  12.         'type'      => 'text',
  13.         'length'    => 32,
  14.         'notnull'   => 1
  15.     )
  16. );
復(fù)制代碼

如果給text類型指定length,字段會使用varchar或者char,如果fixed為真則為char,fixed為假則為varchar,fixed默認(rèn)為false
如果沒有給text指定length,使用text類型
某些DBMS可以把默認(rèn)值設(shè)置為函數(shù),比如now(),但是在這里無法設(shè)置默認(rèn)值為函數(shù),如果指定函數(shù)默認(rèn)值,默認(rèn)值實際上設(shè)置成函數(shù)運行后的值

創(chuàng)建表
創(chuàng)建名字叫user_info的用戶信息表
$mdb->createTable('user_info', $fields);

修改表
表的修改使用alterTable()方法,可以對表進行的操作有

    * name    重命名表名
    * add     添加字段
    * remove  刪除字段
    * change  修改字段
    * rename  字段重命名

添加字段
給user_info表添加三個字段,realname(真實姓名)、reg_date(注冊時間)、login_time(最后一次登錄時間)

  1. $change = array(
  2.     'add' => array(
  3.         'realname'  => array(
  4.             'type'      => 'text',
  5.             'length'    => 20
  6.         ),
  7.         'reg_date'  => array(
  8.             'type'      => 'timestamp',
  9.             'notnull'   => 1
  10.         ),
  11.         'login_time' => array(
  12.             'type'      => 'timestamp'
  13.         )
  14.     )
  15. );
  16. $mdb->alterTable('user_info', $change);
復(fù)制代碼

修改字段
把reg_date字段從timestamp類型改變?yōu)閐ate類型,realname不允許為空

  1. $change = array(
  2.     'change' => array(
  3.         'reg_date' => array(
  4.             'type'  => 'timestamp',
  5.             'definition' => array(
  6.                 'type'  => 'date'
  7.             )
  8.         ),
  9.         'realname' => array(
  10.             'notnull' => 1
  11.         )
  12.     )
  13. );
  14. $mdb->alterTable('user_info', $change);
復(fù)制代碼

刪除字段
刪除login_time字段

  1. $change = array(
  2.     'remove' => array(
  3.         'login_time' => array()
  4.     )
  5. );
  6. $mdb->alterTable('user_info', $change);
復(fù)制代碼

字段重命名
重命名realname為real_name

  1. $change = array(
  2.     'rename' => array(
  3.         'realname' => array(
  4.             'name' => 'real_name'
  5.         )
  6.     )
  7. );
  8. $mdb->alterTable('user_info', $change);
復(fù)制代碼

重命名表
把user_info表重命名為userinfo

  1. $change = array(
  2.     'name' => 'userinfo'
  3. );
  4. $mdb->alterTable('user_info', $change);
復(fù)制代碼

創(chuàng)建索引
在id字段上創(chuàng)建主鍵

  1. $con_define = array(        // 主鍵定義
  2.     'fields' => array('id' => array()),
  3.     'primary' => 1
  4. );
  5. $con_name = 'pk_user_info_id';  // 主鍵名
  6. $mdb->createConstraint('user_info', $con_name, $con_define);
復(fù)制代碼

在username字段上創(chuàng)建唯一索引

  1. $con_define = array(        // 唯一索引定義
  2.     'fields' => array('username' => array()),
  3.     'unique' => 1
  4. );
  5. $con_name = 'uk_user_info_username';    // 唯一索引名
  6. $mdb->createConstraint('user_info', $con_name, $con_define);
復(fù)制代碼

刪除剛才建立的約束
$mdb->dropConstraint('user_info', 'pk_user_info_id');
$mdb->dropConstraint('user_info', 'uk_user_info_username');

在username、password上建立雙字段索引

  1. $idx_define = array(
  2.     'fields' => array(
  3.         'username' => array(),
  4.         'password' => array()
  5.     )
  6. );
  7. $idx_name = 'idx_user_info_auth';
  8. $mdb->createIndex('user_info', $idx_name, $idx_define);
復(fù)制代碼

刪除idx_user_info_auth索引
$mdb->dropIndex('user_info', 'idx_user_info_auth');

Manager模塊對一些通常的操作進行了封裝,可以滿足大部分常見的需求,但是如果你需要是更加精細(xì)的控制,Manager就無法做到了,比如:
// PostgreSQL
CREATE INDEX code_idx ON films(code) TABLESPACE indexspace

最后建議有疑惑的時候看還是看看相關(guān)的代碼,代碼就是最好的文檔

[ 本帖最后由 夜貓子 于 2006-7-12 01:49 編輯 ]

論壇徽章:
1
榮譽版主
日期:2011-11-23 16:44:17
3 [報告]
發(fā)表于 2006-07-12 01:55 |只看該作者
pear安裝方法,參見:http://www.72891.cn/viewthread.php?tid=22107
pear安裝好之后,PHP安裝目錄下會有一個pear.bat文件,可以在命令行下執(zhí)行


pear list                 // 顯示已經(jīng)安裝的pear包
pear install  packagename    // 安裝指定的包,比如 pear install mdb2
pear uninstall packagename // 卸載指定的包
pear list-upgrades      // 顯示安裝的包里可以升級的包
pear upgrade-all   // 升級所有可以升級的包
pear help         // 顯示幫助

[ 本帖最后由 夜貓子 于 2006-7-12 01:58 編輯 ]

論壇徽章:
0
4 [報告]
發(fā)表于 2006-07-12 09:35 |只看該作者
好文章,我轉(zhuǎn)到pearchina那去了,應(yīng)該沒有問題八
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP