tp6 模型replace未生效

浏览:4060 发布日期:2019/06/15 分类:ThinkPHP6专区 关键字: tp6 bug反馈
测试代码:        public function test()
    {
        $model = new Customer();
        $data  = [
            'phone' => '11012010086'
        ];
        $model->replace(true)->save($data);
        return $model->getLastSql();
    }
问题描述:
此处的replace(true)是不生效的,最终生成的sql依然是insert into 而不是预期的replace into

在源码中think/db/Connection类中 951行/**
     * 插入记录
     * @access public
     * @param Query   $query        查询对象
     * @param boolean $getLastInsID 返回自增主键
     * @return mixed
     */
    public function insert(Query $query, bool $getLastInsID = false)
    {
        // 分析查询表达式
        $options = $query->parseOptions();
        
        // 生成SQL语句
        $sql = $this->builder->insert($query);
    
        
此处的代码根据builder走向不同的类, 测试代码中的模型操作在这里指向了
think/db/Mysql类,源码如下: /**
     * 生成Insert SQL
     * @access public
     * @param  Query     $query   查询对象
     * @param  bool      $replace 是否replace
     * @return string
     */
    public function insert(Query $query, bool $replace = false): string
    {
        $options = $query->getOptions();
        
        // 分析并处理数据
        $data = $this->parseData($query, $options['data']);
        if (empty($data)) {
            return '';
        }

        $set = [];
        foreach ($data as $key => $val) {
            $set[] = $key . ' = ' . $val;
        }

        return str_replace(
            ['%INSERT%', '%EXTRA%', '%TABLE%', '%PARTITION%', '%SET%', '%DUPLICATE%', '%COMMENT%'],
            [
                $replace ? 'REPLACE' : 'INSERT',
                $this->parseExtra($query, $options['extra']),
                $this->parseTable($query, $options['table']),
                $this->parsePartition($query, $options['partition']),
                implode(' , ', $set),
                $this->parseDuplicate($query, $options['duplicate']),
                $this->parseComment($query, $options['comment']),
            ],
            $this->insertSql);
    }
可以看到源码中此处的$replace是作为方法的参数单独存在的,而测试代码中replace()的设置在$options数组中,因此导致replace()未生效
因其没有在Connection中显示传递,也没有获取$options中的replace来判断

此处可以修改$replace ? 'REPLACE' : 'INSERT',为与think/db/Builder中的一致!empty($options['replace']) ? 'REPLACE' : 'INSERT',来修复该问题,但暂不清楚$replace作为单独参数存在的意义,希望@ThinkPHP 流年能解惑。
最佳答案
评论( 相关
后面还有条评论,点击查看>>