table_exists()方法可能无法正常工作

时间:2012-02-28 09:05:30

标签: php mysql codeigniter

我开始使用codeigniter 2.1.0编写一个简单的Model类。我现在要做的就是创建并删除它所代表的MySQL表。这是代码:

<?php

    class Users_model extends CI_Model {

        public function createTable(){

            if( $this->db->table_exists('users') == FALSE ){

                $query = "CREATE TABLE users(
                        id SERIAL PRIMARY KEY,
                        email  VARCHAR(52) NOT NULL check(email <> ''),
                        UNIQUE (email)
                        )ENGINE = InnoDB;";

                $this->db->query($query);

            }

        }

        public function deleteTable(){

            if( $this->db->table_exists('users') ){

                $query = "DROP TABLE users;";

                $this->db->query($query);

            } else {

                echo "users not found <br />";

                $tables = $this->db->list_tables();
                foreach ($tables as $table)
                {
                    echo $table."<br />";
                }
            }

        }


    }

?>

这是我在主类中执行的代码:

$this->load->model('users_model');
$this->users_model->deleteTable();
$this->users_model->createTable(); 

第一次运行很好,花花公子。表格创建得很好。但是,当我再次运行它时,我得到输出:

users not found
users

经过进一步检查,我发现table_exists()永远不会返回TRUEvar_dump($this->db->table_exists('users'));会返回bool(false)

那么,我做错了吗?这很简单,从documentation复制粘贴。谷歌没有返回任何相关内容,作为一名C程序员,我的心态始终是“如果有一个错误,那就是你的。(理查德斯托曼永远不会错)”......但由于斯托曼先生与此无关,所以一种可能性。

TL; DR

为什么即使table_exists('users')确实返回“用户”,上述代码中的TRUE也永远不会返回list_tables();

6 个答案:

答案 0 :(得分:2)

尝试使用var_dump()代替echo。布尔值不适用于echo

var_dump( $this->db->table_exists('users') );

table_exists的{​​{3}}如下所示:

function table_exists($table_name)
{
    return ( ! in_array($this->_protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables())) ? FALSE : TRUE;
}
来自评论的

更新

如果您查看source code,它会将数据库名称添加到表名中。但应该有一个。在db.table之间。也许你的db配置搞砸了?

答案 1 :(得分:2)

作为codeigniter中问题的解决方案,您可以尝试此功能

function validateTable($tableName)
    {
        $result = $this->db->list_tables();

        foreach( $result as $row ) {
            if( $row == $tableName )    return true;
        }
        return false;
    }

答案 2 :(得分:0)

作为解决方案,您可以使用方法列出所有表(在链接中),将它们存储在数组中

while ($row = mysql_fetch_row($result)) {
echo "Table: {$row[0]}\n";
//search array here
}

您可以按照以下链接中的示例1进行操作:

http://uk.php.net/manual/en/function.mysql-list-tables.php

答案 3 :(得分:0)

我遇到类似的问题。

如果函数table_exists()确定缺少任何必需的表,我正在使用脚本来创建我的站点所需的表。我一直看到一个奇怪的问题,在第一页加载时,似乎没有发生几个数据库插入。我认为我的插入语句有问题,但我找不到一个错误。此外,在第一页加载后,一切似乎都运行正常。事实证明,表创建脚本实际上被多次调用,每次都重新创建一个空表。

我假设多次调用table_exists()返回的结果不会根据调用后的表(第一次)更改。

我也尝试使用Shayan Husaini给出的解决方案。 list_tables();似乎也以同样的方式回应。它不会返回在调用之后创建的新表。

我最终通过跟踪页面加载期间创建的每个表来解决此问题。尽管如此,我觉得这些函数应该能够在这些函数调用一次(或多次)之后找到已添加到数据库中的新表。

答案 4 :(得分:0)

尝试在迁移上下文中使用table_exists()时,与CodeIgniter 3存在相同的问题。 (它似乎在我的代码中的其他点上按预期工作。)

对MySQL来说,这是一个廉价而开朗的替代品:

if(is_null($this->db->query("SHOW TABLES LIKE '{$tableName}'")->row()))
{
    //echo "Table {$tableName} does not exist";
}

虽然令人讨厌的是,这个替代品似乎并不满足于CI的数据库缓存开启。

: - /

好的,所以我只是在代码中钓鱼,虽然它看起来不像是一个bug,但它绝对是值得知道的:

<强> DB_driver.php

  • :: table_exists()取决于:

  • :: list_tables()可以将表名列表拉出自己的&#34;每个实例化&#34;缓存或由以下提供的查询:

  • :: _ list_tables()[在问题中的mysqliOrWhatever_driver.php],对于MySQL来说,它是一个来自theSchemaName&#39; SHOW TABLES FROM theSchemaName&#39;查询

<强> DB_forge.php

以下方法可能会影响&#34;每个实例化&#34; DB_driver.php的缓存:

  • :: create_table()[更新没有!它不会更新缓存的表列表。这是我的怪癖!]
  • :: drop_table()
  • :: rename_table()

(说得对吗?)

答案 5 :(得分:0)

它对我有用

$YOUR_TABLE_NAME="XYZ";
if ($this->db->table_exists($YOUR_TABLE_NAME) )
{
  echo "table exists";
}
else
{
  echo "table does not exist";
}