关于PHP链式操作问题

问题遇到的现象和发生背景

例如数据库操作时:

$res = $db->add(['name'=>'王富贵','age'=>23])
echo $res;

添加数据时返回了新插入的ID,那么我想再用链式操作,直接返回新插入的整条数据


$res = $db->add(['name'=>'王富贵','age'=>23])->select()
echo $res;

由于add返回的是新插入的ID,并不是$this
所以有什么方法可以在执行add的时候就判断出后面是否还有需要继续操作的方法。
判断后面还有,就返回$this,没有就返回ID?

select()方法不用传入id吗,那它怎么知道应该查什么

可以在add方法里面添加一个返回值判断,如果后面还有需要继续操作的方法,就返回$this,否就返回新插入的ID:

class DB {
    public function add($data) {
        // 数据库操作,插入数据
        $new_id = ...
        if (debug_backtrace()[1]['function'] != '__destruct') {
            return $this;
        }
        return $new_id;
    }
    public function select() {
        // 数据库操作,查询数据
    }
}

或者把后面的操作存下来,返回新插入的ID,执行完后再执行之前存下来的操作。

class DB {
    private $operations = [];
    public function add($data) {
        $this->operations[] = ['method' => 'add', 'data' => $data];
        return $this;
    }
    public function select() {
        $this->operations[] = ['method' => 'select'];
        return $this;
    }
    public function execute() {
        $result = null;
        foreach ($this->operations as $operation) {
            $method = $operation['method'];
            $data = $operation['data'] ?? null;
            if ($method === 'add') {
                $new_id = ...
                $result = $new_id;
            } elseif ($method === 'select') {
                // 数据库操作,查询数据
                $result = ...
            }
        }
        $this->operations = [];
        return $result;
    }
}

这样使用:

$db = new DB();
$res = $db->add(['name'=>'王富贵','age'=>23])->select()->execute();
echo $res;

这样就可以在执行add的时候就判断出后面是否还有需要继续操作的方法。
仅供参考,望采纳,谢谢。

可以通过在add方法中返回一个新的类实例来实现。

  1. 在add方法中插入数据并获取新插入的ID。
  2. 在add方法中返回一个新的实例,并将新插入的ID作为属性存储在该实例中。
  3. 在其他需要继续操作的方法中,检查返回值是否为新实例,如果是,则继续使用该实例进行操作,如果不是,则返回新插入的ID。

示例代码如下:

class DB {
    public function add($data) {
        // 插入数据并获取新插入的ID
        $new_id = $db->insert($data);
        // 返回一个新的实例
        $new_instance = new self();
        $new_instance->new_id = $new_id;
        return $new_instance;
    }
    public function select() {
        // 判断是否有new_id属性,如果有,则返回整条数据,如果没有,则返回new_id
        if (isset($this->new_id)) {
            return $db->where("id", $this->new_id)->get();
        } else {
            return $this->new_id;
        }
    }
}

在 PHP 中实现链式操作,需要在类中的方法返回 $this 来实现。

在你的例子中,可以在add方法中进行判断,如果后面还有需要继续操作的方法,就返回$this,没有就返回新插入的ID。

class Db {
    public function add($data) {
        // 执行 add 操作
        $id = // 新插入的 ID
        return $this;
    }

    public function select() {
        // 执行 select 操作
    }

    public function __call($name, $arguments)
    {
        //判断后面还有没有需要继续操作的方法,如果有返回$this,否则返回插入的ID
    }
}

$res = $db->add(['name'=>'王富贵','age'=>23])->select();
echo $res;


上面的代码是一个简单的例子,它演示了如何在 PHP中实现链式操作。需要注意的是,在__call函数中可以利用debug_backtrace()来判断是否还有其他方法需要继续操作。

还有一个实现方式是在类中设置一个状态变量,在执行 add 方法时将状态变量设置为 true,并在后面的方法中判断状态变量的值来确定是否返回 $this 还是新插入的 ID。

这只是其中一种实现方式,根据你的需求,还有其他方法可以实现链式操作。

你可以在你的数据库操作类中重新定义 add 方法来实现链式操作。具体的实现可以是在 add 方法执行完成后,返回一个新的对象,该对象包含了新插入的数据,并且它还有其他的方法可以继续进行链式操作。

可以这样更改:

class DB {
    // other methods
    public function add($data) {
        // insert data into database
        $insertedId = // get the id of the newly inserted data
        $this->insertedData = $this->select($insertedId);
        return $this;
    }

    public function select($id = null) {
        if ($id) {
            // select data with id
        } else {
            // select all data
        }
        return $this;
    }
    public function end() {
        return $this->insertedData;
    }
}


然后你可以这样使用:

$res = $db->add(['name'=>'王富贵','age'=>23])->end();


这样就可以在结束链式操作后返回新插入的整条数据了。

注意,本示例仅用来描述思路,不能直接使用在项目中,需要根据你的具体业务逻辑来实现.

希望对你有帮助,望采纳。

可以在add方法中返回一个包含了新插入ID和链式操作能力的对象,然后在对象的select方法中判断是否还有其他链式操作,如果没有就返回新插入的整条数据,如果有就返回$this,类似于这样:

class DB {
  public function add($data) {
    $id = // 执行插入操作
    $this->new_id = $id;
    return $this;
  }

  public function select() {
    if (isset($this->new_id)) {
      $data = // 查询新插入的数据
      unset($this->new_id);
      return $data;
    }
    return $this;
  }
}

这样就可以实现链式操作和返回新插入的整条数据了。
望采纳。