CakePHP 3:获取所有表对象的列表

x33g5p2x  于 2022-11-11  发布在  PHP
关注(0)|答案(3)|浏览(137)

我正在寻找一种方法来获得所有可用的table objects的列表。这些是(默认情况下)位于App/Modal/Table下的所有类,并且由TableRegistry处理。如何获得所有这些对象的列表?
我知道可以获取数据库的所有表:

$tables = ConnectionManager::get('default')->schemaCollection()->listTables();

然后使用TableRegistry::get()获取表对象。
但这对我的解决方案来说是不可能的,因为有两种情况下这不起作用:
1.与表对象名称不同的自定义表名称
1.插件表对象
有什么想法吗?

**Edit:**Why?我需要所有使用行为X的表对象。在我的例子中,需要一个自定义的SearchableBehavior,它在保存实体的每个afterSave事件中更新searchindex表。要更新所有表的所有实体的searchindex,我需要知道哪些表正在使用SearchableBehavior,并手动调用它们的update方法。

vvppvyoh

vvppvyoh1#

$tables = glob(APP."Model".DS."Table".DS."*Table.php");
    $tablesNames = [];
    foreach ($tables as $name){
        $item = explode('Table.php', basename($name));
        $tablesNames[] = $item[0];
    }
    pr(tablesNames);
lpwwtiir

lpwwtiir2#

编写一个监听Model.initialize的事件监听器,然后检查主题,如果表具有您的行为,则主题是表对象,然后对该列表执行一些操作。
如果这对你不起作用--你给予了 zero 背景信息--遍历apps Model/Table文件夹和plugin文件夹以及vendor文件夹,搜索Model文件夹,检查*Table.php文件。然后尝试基于path / namespace和filename示例化表对象,并检查模型。但这不是很快,你应该缓存结果列表。

b0zn9rqh

b0zn9rqh3#

我最近有一个类似的用例,需要访问所有的表对象,以便在控制台命令中初始化数据库中的数据。
我首先构建了一个包含Table对象类可以驻留的所有路径的数组,然后遍历所有文件并使用以“Table.php”结尾的文件。注意,根据您的用例,这种方法可能需要稍微修改。

<?php

use Cake\Core\Plugin;
use Cake\ORM\TableRegistry;
use Cake\Filesystem\Folder;

// Building an array of all possible paths. Firstly the src directory:
$tableClassPaths = [
    APP . 'Model' . DS . 'Table' . DS,
];

// Secondly, all loaded plugins:
foreach(Plugin::loaded() as $plugin) {
    $dir = Plugin::classPath($plugin) . 'Model' . DS . 'Table' . DS;
    if(is_dir($dir)) {
        $tableClassPaths[$plugin] = $dir;
    }
}

// Iterating over each file in each folder.
$tableObjects = [];
foreach($tableClassPaths as $plugin => $dir) {
    foreach(new \FilesystemIterator($dir) as $file) {
        // All Files ending in Table.php might be relevant
        if($file instanceof \SplFileInfo && $file->isFile()
            && mb_substr($file->getFilename(), -9) === 'Table.php'
        ) {
            $className = mb_substr($file->getFilename(), 0, -9);
            if(is_string($plugin)) {
                $className = $plugin . '.' . $className;
            }

            $tableObject = TableRegistry::getTableLocator()->get($className);
            // Here you can use / filter the Tables, for example by checking for the presence of a behavior "Indexable":
            if($tableObject->hasBehavior('Indexable')) {
                $tableObjects[] = $tableObject;
            }
        }
    }
}

?>

请记住,这只适用于非常狭窄的环境,因为这完全避开了CakePHP的常规MVC模式。

相关问题