为什么要在oop中返回一个对象的克隆?

I recently had to use Slim\Http\Message and Slim\Http\Request to get the users posted data.

I noticed something in the method withBody() where it was returning a clone of the object instead of $this.

This caused me some trouble as I couldn't get my application to work until I assigned $request->withBody(...) to a variable ($request) and then carried on using that new variable in my script.

I have a mock example to explain (see comments in the code);

class Request {
    protected $body;

    public function addBody($body) {
        $clone = clone $this;
        $clone->body = $body;
        return $clone;
    }

    public function getBody() {
        return $this->body;
    }
}

$request = new Request;

// this will return NULL
$request->addBody([
    'name' => 'john',
    'email' => 'john@example.com',
]);

var_dump($request->getBody());

// -----------------------

// but this will return the "body" that was passed in above.
$request = $request->addBody([
    'name' => 'john',
    'email' => 'john@example.com',
]);

var_dump($request->getBody());

I see what is happening here. But I don't understand why a class would be implemented like this.

What are the benefits? Why restrict a developer in this way?

Slim uses the PSR-7 HTTP Messaging Interface standard, which describes itself as follows:

<?php
namespace Psr\Http\Message;

/**
 * HTTP messages consist of requests from a client to a server and responses
 * from a server to a client. This interface defines the methods common to
 * each.
 *
 * Messages are considered immutable; all methods that might change state MUST
 * be implemented such that they retain the internal state of the current
 * message and return an instance that contains the changed state.
 *
 * @see http://www.ietf.org/rfc/rfc7230.txt
 * @see http://www.ietf.org/rfc/rfc7231.txt
 */
interface MessageInterface
{
    //etc
}

"Messages are considered immutable". They are considered Value objects, which must never change state, and if you do want to change state, a new instance is returned.

Here's a link explaining Value Objects http://deviq.com/value-object/

And a little extract from the page I linked:

A Value Object is an immutable type that is distinguishable only by the state of its properties. That is, unlike an Entity, which has a unique identifier and remains distinct even if its properties are otherwise identical, two Value Objects with the exact same properties can be considered equal. Value Objects are a pattern first described in Evans’ Domain-Driven Design book, and further explained in Smith and Lerman’s Domain-Driven Design Fundamentals course.

Hopefully this will help you understand why!

Finally, have a wee look at the actual PSR-7 Standard here http://www.php-fig.org/psr/psr-7/