文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Thinkphp6】tp6 hasOneThrough 远程一对一关联查询 数据查询出现null的异常问题分析

2023-09-14 14:11

关注

问题描述

tp6 的远程一对一关联查询 当要查询的关联数据查询时会出现相同不是为null 的情况。
可能这个用的人比较少的原因,网上对hasOneThrough的相关资料比较少,出现这个问题就记录一下。

原因分析

下面是hasOneThrough的源码

```php    public function hasOneThrough(string $model, string $through, string $foreignKey = '', string $throughKey = '', string $localKey = '', string $throughPk = ''): HasOneThrough    {        // 记录当前关联信息        $model      = $this->parseModel($model);        $through    = $this->parseModel($through);        $localKey   = $localKey ?: $this->getPk();        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);        $throughKey = $throughKey ?: $this->getForeignKey((new $through)->getName());        $throughPk  = $throughPk ?: (new $through)->getPk();        return new HasOneThrough($this, $model, $through, $foreignKey, $throughKey, $localKey, $throughPk);    }

我这里用的是VsCode,按住点击Crtrl 和 鼠标点击"HasOneThrough"源码内容
出现下面,选择右边下面远程一对一的双击,跳转到文件源码"HasOneThrough.php"
跳转示例
也可以直接找这文件,这 HasOneThrough.php 文件的路径为
vendor\topthink\think-orm\src\model\relation\HasOneThrough.php

找到 eagerlyWhere 方法,大概140行,基本是最后那个方法

        protected function eagerlyWhere(array $where, string $key, array $subRelation = [], Closure $closure = null, array $cache = []): array    {        // 预载入关联查询 支持嵌套预载入        $keys = $this->through->where($where)->column($this->throughPk, $this->foreignKey);        if ($closure) {            $closure($this->getClosureType($closure));        }        $list = $this->query            ->where($this->throughKey, 'in', $keys)            ->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)            ->select();        // 组装模型数据        $data = [];        $keys = array_flip($keys);        foreach ($list as $set) {            $data[$keys[$set->{$this->throughKey}]] = $set;        }        return $data;    }

相信细心的已经看到出问题的地方了,
bug处
正是这个array_flip()函数,这个函数的作用是:反转数组中的键名和对应关联的键值
举个简单的例子

原数组:Array ( [1] => 32 [2] => 32 )
array_flip()函数转换后
转换后: Array ( [32] => 2 )

这就是为什么相同的会部分显示为null 的原因了

解决方法

先贴修改后的代码

protected function eagerlyWhere(array $where, string $key, array $subRelation = [], Closure $closure = null, array $cache = []): array    {        // 预载入关联查询 支持嵌套预载入        $keys = $this->through->where($where)->column($this->throughPk, $this->foreignKey);        if ($closure) {            $closure($this->getClosureType($closure));        }        $list = $this->query            ->where($this->throughKey, 'in', $keys)            ->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)            ->select();        // 组装模型数据        $data = [];        // start 原代码        // $keys = array_flip($keys);        // foreach ($list as $set) {        //     $data[$keys[$set->{$this->throughKey}]] = $set;        // }        // end                // start 修改部分        $arr = [];        foreach ($keys as $k => $v) {            if (isset($arr[$v])) {                array_push($arr[$v], $k);            } else {                $arr[$v][] = $k;            }        }        foreach ($list as $set) {            if (is_array($arr[$set->{$this->throughKey}])) {                foreach ($arr[$set->{$this->throughKey}] as $key) {                    $data[$key] = $set;                }            }        }        // end        return $data;    }

修改后: Array ( [32] => Array ( [0] => 1 [1] => 2 ) )
也就是简单的将一维数组,转化为二维数组,之后就可以正常使用了。
这个方法可能还有可以优化的地方,有的话评论告知,相互学习。

来源地址:https://blog.csdn.net/zcc_520/article/details/127202821

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯