返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >【Thinkphp6】tp6 hasOneThrough 远程一对一关联查询 数据查询出现null的异常问题分析
  • 634
分享到

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

php开发语言 2023-09-14 14:09:17 634人浏览 薄情痞子
摘要

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

问题描述

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

--结束END--

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

本文链接: https://lsjlt.com/news/407312.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作