Heim  >  Artikel  >  php教程  >  pdo数据库驱动存在一个Bug,影响3.1.3及以下版本[严重]

pdo数据库驱动存在一个Bug,影响3.1.3及以下版本[严重]

WBOY
WBOYOriginal
2016-06-07 11:44:191250Durchsuche

pdo数据库驱动存在一个无法获取数据表主键的Bug,导致此Bug的原因并非逻辑缺陷,而是TP开发人员的粗心大意
ThinkPHP pdo数据库驱动存在一个无法获取数据表主键的Bug,此Bug会导致所有与数据表主键有关的操作发生错乱、失败甚至无法预料的结果(数据表主键为id或者Model里自定义pk则不受影响).如果你的数据表主键不是"id",对数据库进行一系列依赖主键的操作会发生错误.

Bug影响版本:3.1.3及以下

Bug位置:Extend/Driver/Db/DbPdo.class.php或:Lib/Driver/Db/DbPdo.class.php代码位置:定位到函数getFieldspublic function getFields($tableName) {<br>         $this->initConnect(true);<br>         if(C('DB_DESCRIBE_TABLE_SQL')) {<br>             // 定义特殊的字段查询SQL<br>             $sql   = str_replace('%table%',$tableName,C('DB_DESCRIBE_TABLE_SQL'));<br>         }else{<br>             switch($this->dbType) {<br>                 case 'MSSQL':<br>                 case 'SQLSRV':<br>                     $sql   = "SELECT   column_name as 'Name',   data_type as 'Type',   column_default as 'Default',   is_nullable as 'Null'<br>         FROM    information_schema.tables AS t<br>         JOIN    information_schema.columns AS c<br>         ON  t.table_catalog = c.table_catalog<br>         AND t.table_schema  = c.table_schema<br>         AND t.table_name    = c.table_name<br>         WHERE   t.table_name = '$tableName'";<br>                     break;<br>                 case 'SQLITE':<br>                     $sql   = 'PRAGMA table_info ('.$tableName.') ';<br>                     break;<br>                 case 'ORACLE':<br>                 case 'OCI':<br>                     $sql   = "SELECT a.column_name \"Name\",data_type \"Type\",decode(nullable,'Y',0,1) notnull,data_default \"Default\",decode(a.column_name,b.column_name,1,0) \"pk\" "<br>                       ."FROM user_tab_columns a,(SELECT column_name FROM user_constraints c,user_cons_columns col "<br>                       ."WHERE c.constraint_name=col.constraint_name AND c.constraint_type='P' and c.table_name='".strtoupper($tableName)<br>                       ."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)";<br>                     break;<br>                 case 'PGSQL':<br>                     $sql   = 'select fields_name as "Name",fields_type as "Type",fields_not_null as "Null",fields_key_name as "Key",fields_default as "Default",fields_default as "Extra" from table_msg('.$tableName.');';<br>                     break;<br>                 case 'IBASE':<br>                     break;<br>                 case 'MYSQL':<br>                 default:<br>                     $sql   = 'DESCRIBE '.$tableName;//备注: 驱动类不只针对mysql,不能加``<br>             }<br>         }<br>         $result = $this->query($sql);<br>         $info   =   array();<br>         if($result) {<br>             foreach ($result as $key => $val) {<br>                 $val            =   array_change_key_case($val);<br>                 $val['name']    =   isset($val['name'])?$val['name']:"";<br>                 $val['type']    =   isset($val['type'])?$val['type']:"";<br>                 $name           =   isset($val['field'])?$val['field']:$val['name'];<br>                 $info[$name]    =   array(<br>                     'name'    => $name ,<br>                     'type'    => $val['type'],<br>                     'notnull' => (bool)(((isset($val['null'])) && ($val['null'] === '')) || ((isset($val['notnull'])) && ($val['notnull'] === ''))), // not null is empty, null is yes<br>                     'default' => isset($val['default'])? $val['default'] :(isset($val['dflt_value'])?$val['dflt_value']:""),<br>                     'primary' => isset($val['dey'])?strtolower($val['dey']) == 'pri':(isset($val['pk'])?$val['pk']:false),<br>                     'autoinc' => isset($val['extra'])?strtolower($val['extra']) == 'auto_increment':(isset($val['key'])?$val['key']:false),<br>                 );<br>             }<br>         }<br>         return $info;<br>     }定位到此行:'primary' => isset($val['dey'])?strtolower($val['dey']) == 'pri':(isset($val['pk'])?$val['pk']:false),你会看到原本为"key"的数组键名被错输为"dey",没错,导致此Bug的问题就出现在此行代码.

解决办法:将dey修改为key,修改后代码为:'primary' => isset($val['key'])?strtolower($val['key']) == 'pri':(isset($val['pk'])?$val['pk']:false),

AD:真正免费,域名+虚机+企业邮箱=0元

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn