為什麼 PSR-7 規範中 RequestInterface 中用 withX 而不是 setX

來源:互聯網
上載者:User
關鍵字 psr-7 php
比如 SlimPHP 中的 Request 實現。

public function withAttribute($name, $value){    $clone = clone $this;    $clone->attributes->set($name, $value);    return $clone;}

with 的實現都涉及到 clone $object,clone 就會申請新的變數空間。為什麼不用 set 呢?一個請求過來一個 Request 對象就可以了吧。

public function setAttribute($name, $value){    $this->attributes->set($name, $value);    return $this;}

回複內容:

比如 SlimPHP 中的 Request 實現。

public function withAttribute($name, $value){    $clone = clone $this;    $clone->attributes->set($name, $value);    return $clone;}

with 的實現都涉及到 clone $object,clone 就會申請新的變數空間。為什麼不用 set 呢?一個請求過來一個 Request 對象就可以了吧。

public function setAttribute($name, $value){    $this->attributes->set($name, $value);    return $this;}

好問題!

因為PSR-7規定,HTTP Message和URI都是值對象(value object),值對象的一個特徵是它的值決定了它的唯一性,也就是說如果兩個值對象的所有值都是一樣的,那它們也應該是同一個對象;反過來說,如果兩個值對象有至少一個值不一樣,那它們就應該算兩個不同的對象。正因為這個原因,當遵循PSR-7而你要改變Request一個屬性時,你應該建立另一個對象,而不能在原來的對象上做修改,所以要用clone而不能簡單地賦值。所以,值對象是一種不可變(immutable)的對象。

那麼,PSR-7為什麼要選用不可變的值對象來規範HTTP Message呢?原因有以下幾點:

  1. 因為HTTP Message本身就因該是一個不可變的狀態。當一個使用者給你的程式發送請求,發送完成後請求的內容就已經固定,不會再變,只會有下一個相同或不同的請求。

  2. 值對象可以儲存原始請求的一切狀態,任何其他的程式都可以獲得這種原始狀態。

官方FIG提供了一段示範值對象好處的代碼:

$uri = new Uri('http://api.example.com');$baseRequest = new Request($uri, null, [    'Authorization' => 'Bearer ' . $token,    'Accept'        => 'application/json',]);;//上面構造基礎 Request$request = $baseRequest->withUri($uri->withPath('/user'))->withMethod('GET');$response = $client->send($request);//基於上述基礎Request構造一個GET請求,獲得user的ID$body = new StringStream(json_encode(['tasks' => [    'Code',    'Coffee',]]));;$request = $baseRequest    ->withUri($uri->withPath('/tasks/user/' . $userId))    ->withMethod('POST')    ->withHeader('Content-Type', 'application/json')    ->withBody($body);$response = $client->send($request)//基於基礎Request構造另一個POST請求,用剛才拿到的user ID添加task//如果不是使用值物件模型,我們將要重新從頭開始構建這個Request$request = $baseRequest->withUri($uri->withPath('/tasks'))->withMethod('GET');$response = $client->send($request);//依然是基於基礎Request構建其他請求

其實這些在PSR-7的Meta Document中都有說明
http://www.php-fig.org/psr/psr-7/meta/

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.