【问题标题】:setTable not working as expected with a legacy database in CakePHP 3.x对于 CakePHP 3.x 中的旧数据库,setTable 无法按预期工作
【发布时间】:2018-05-09 10:34:43
【问题描述】:

我在 CakePHP 3.5.13 应用程序上有一个旧的(未写入 Cake 命名约定的)数据库。

其中一个数据库表名为article_95

当我尝试烘焙应用程序时,它会将实体名称显示为Article95。然后它会产生大量错误消息:

 Table 'article95' doesn't exist

所以我阅读了CakePHP error: cake bake is using the wrong table nameHow to use table name different then in database in cake php 3 并决定使用setTable() 手动完成。

所以我创建了src/Model/Table/Article95Table.php,其中包含以下代码:

namespace App\Model\Table;

use Cake\ORM\Table;

class Article95Table extends Table
{
    public function initialize(array $config)
    {
        $this->setTable('article_95');
    }
}

但它似乎不会承认这一点。在控制器中,我创建了一个测试方法并执行了以下操作:

    Cache::clear(false);
    $Article95 = TableRegistry::get('Article95');
    debug($Article95->find()->list());

但它提出了:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'article95' doesn't exist

好像不是在读取setTable()方法。

我使用了Cache::clear(false) 来确保它没有被缓存,并检查了tmp/cache 目录中是否有任何可疑文件 - 里面没有任何相关内容。

有什么想法吗?

同样,如果我将 debug() 语句更改为 debug($Article95),我会得到以下内容,但表名错误:

object(Cake\ORM\Table) {

    'registryAlias' => 'Article95',
    'table' => 'article95',
    'alias' => 'Article95',
    'entityClass' => '\Cake\ORM\Entity',
    'associations' => [],
    'behaviors' => [],
    'defaultConnection' => 'default',
    'connectionName' => 'default'

}

顺便说一句,如果我在 TableRegistry::get() 中放入一个不存在的类/实体名称 - 例如 TableRegistry::get('dsfdsfdsfsd'); 它不会产生错误消息,但会显示上面的对象以及不存在的表名.这肯定也是错的吧?

【问题讨论】:

  • 您在此处显示的内容可能不是您实际使用的内容。您拥有的对象是所谓的"generic table" or "auto table",这是一个从\Cake\ORM\Table 创建的表对象,因为找不到具体的表类Article95Tabledsfdsfdsfsd 也会发生同样的事情。
  • 具体表类怎么找不到?在相应的目录中有一个文件Article95Table.php!它适用于我创建的其他模型,但bake 似乎很乐意使用他们的命名方案。
  • 从这里我真的无法判断,您所显示的内容看起来是正确的,但正如我所说,也许这不是您实际使用的内容?也许路径或命名空间中有错字,也许是权限问题,也许是缓存问题,以防您使用操作码缓存等...

标签: cakephp cakephp-3.0


【解决方案1】:

我已经成功地完成了这项工作,所以想分享我的解决方案。

经过一些试验和错误后,似乎在类名后附加一个“s”(大概是为了让 Cake 认为它是复数?)。

于是我将Table类重命名为Article95sTable.php,然后在里面使用了如下代码:

class Article95sTable extends Table
{

    public function initialize(array $config)
    {
        $this->setTable('article_95'); 
    }
}

现在,当我调用以下命令时,它会正确拿起桌子:

$foo = TableRegistry::get('Article95s');
debug($foo);

如果我在 setTable() 方法中重命名表,为了确认这是否有效,输出将相应更改。

【讨论】:

  • 您的表类应该被称为 Articles 或 OldArticles 并且其中没有 95 :)。这样注册表才能真正找到并使用它。
  • 阅读原帖 - 我正在使用一个遗留数据库,其中表名尚未写入 Cake 约定。以上工作。
  • 我知道。问题是表类name not 是否必须与 actual 数据库名称相关。你可以保留遗留的数据库表,但你仍然可以为你的表类使用蛋糕命名约定。因此,如果您使用$this->setTable,则无需在类名中包含“95”。我知道你写的东西是有效的,但如果你一开始就为表类命名,你就会省去麻烦。这就是我要说的。
猜你喜欢
  • 1970-01-01
  • 2014-09-22
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
  • 2019-01-05
相关资源
最近更新 更多