数据库操作:取一条记录并返回

我想从数据库里面取一条状态为0的记录,然后更新state字段为1,最后返回该条记录:

 $old_article = $article = Finance::where('state', 0)
                            ->orderBy('id', 'asc')
                            ->first();

        if($article){
            $article->state = 1;
            $article->save();
        }

        return $old_article;

上面代码更新成功了,也返回了记录,但是返回记录里面的state已经是1了。

state的值原来是0,我更新后数据库里面变成了1,但我想返回的记录里面state是更新前的0

新手第一次提问。谢谢大家。

附言 1  ·  4年前

已解决:```php
$article = Finance::where('state', 0)
->orderBy('id', 'asc')->select('id', 'state', 'author')
->first();

    $old_article = $article->toArray();

    if($article){
        $article->state = 1;
        $article->author = 'elesos'';
        $article->save();
    }

    return $old_article;
elesos
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

只能这样吧,,,

// ...
$oldState = $article->state;
// ...
$article->state = $oldState;

return $article;

或者,,,

$oldArticle = new Finance($article->toArray());
//...
return $oldArticle;

但是没什么必要,,

4年前 评论
elesos (楼主) 4年前
largezhou (作者) 4年前
讨论数量: 7
ccccccccccc
$article = Finance::where('state', 0)
 ->orderBy('id', 'asc')
 ->first();
 // 最好判断是否有搜索结果再进行赋值,不然$article->state = 1会报错
 if ($article) {
    $test = $article->state;
    $article->state = 1; // 在这行代码赋值之前打印或者新建一个变量存储即可。
    $article->save();
    echo $test;          // 变量test存储的就是之前的值
}
4年前 评论
elesos (楼主) 4年前

如果我的理解能力没有问题的话,你修改过后就无法直接在 $article 实例中获取修改之前的值了,因为数据库里面的数据已经被修改了。你可以在修改前设置一个变量赋值修改前的值,供之后使用

4年前 评论

$article = Finance::where('state', 0)->orderBy('id', 'asc')->first();

    if($article){
        $article->state = 1;
        $article->save();

$article->refresh();
}

    return $article;
4年前 评论
elesos (楼主) 4年前

只能这样吧,,,

// ...
$oldState = $article->state;
// ...
$article->state = $oldState;

return $article;

或者,,,

$oldArticle = new Finance($article->toArray());
//...
return $oldArticle;

但是没什么必要,,

4年前 评论
elesos (楼主) 4年前
largezhou (作者) 4年前
elesos

已解决:

  $article = Finance::where('state', 0)
                            ->orderBy('id', 'asc')->select('id', 'state', 'author')
                            ->first();

        $old_article = $article->toArray();

        if($article){
            $article->state = 1;
            $article->author = 'elesos'';
            $article->save();
        }

        return $old_article;
4年前 评论

其实这个问题涉及到

当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。此行为和给函数传递入实例时一样。可以用克隆给一个已创建的对象建立一个新实例。

从编程角度来看,第一行代码

<?
 $old_article = $article = Finance::where('state', 0)
                            ->orderBy('id', 'asc')
                            ->first();

old_articlearticle 都是指向同一块内存(或者说同一个对象实例。从 C 语言的角度理解,可以类比为他们都是保存指向同一个对象的 内存地址,即指针),那么对于 article 的修改自然也会反应到 old_article 上。(猜测)不符合提问者编写的意图。

以下代码或许可以实现(准备略复杂,并未有时间实践。需要 Eloquent Model 类支持 __clone() 魔术方法),使用时注意内存消耗

<?php
$article = Finance::where('state', 0)
                            ->orderBy('id', 'asc')
                            ->first();
// 关键:复制 article 实例到 old_article。
// 若支持,此时 old_article 指向的实例与 article 不一致
$old_article = clone $article;

$article->state = 1;
$article->save();
// 如果证实可以,此处 old_article state 应为 0
echo $old_article->state;

参考:
[中文]PHP: 基本概念 - Manual
[中文]PHP: 对象复制 - Manual

4年前 评论
elesos (楼主) 4年前
Tsukasa_Kanzaki (作者) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!