'PHP Slim Framework request using withAttribute error

I am just try to pass username from middileware auth function

$request->withAttribute('username','XXXXXX');
return $next($request, $response);

But i cannot access this username using

$request->getAttribute('username');

I found a solution that its working only when i add like this

 return $next($request->withAttribute('username','XXXXXX'), $response);

What is the reason? Please help me. I need to pass multiple arguments pass. What should i do?



Solution 1:[1]

withAttributes does not change the state of this object.

Excerpt from relevant source code

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

For testing purposes, in your slim fork, change above code as this.

/* 
* Slim/Http/Request.php 
*/
public function withAttribute($name, $value)
{

    $this->attributes->set($name, $value);
    return $this;
}

Then return $next($request, $response); will work as you expected.

Demo code for inspection

<?php 
 /* code taken from - https://www.tutorialspoint.com/php/php_object_oriented.htm*/
 class Book {

      var $price;
      var $title;
      

      function setPrice($par){
         $this->price = $par;
      }
      
      function getPrice(){
         return $this->price;
      }
      
      function setTitle($par){
         $this->title = $par;
      }
      
      function getTitle(){
         return $this->title;
      }
   }
   
    class CopyBook {

      var $price;
      var $title;
      
      function setPrice($par){
         $clone = clone $this;
         $clone->price = $par;
      }
      
      function getPrice(){
         return $this->price;
      }
      
      function setTitle($par){
         $clone = clone $this;
         $clone->title = $par;
      }
      
      function getTitle(){
         return $this->title;
      }
   }
   
   $pp = new Book;
   $pp->setTitle('Perter Pan');
   $pp->setPrice(25);
   
   $cpp = new CopyBook;
   
   $cpp->setTitle('Peter Pan');
   $cpp->setPrice(25);
     
   var_dump($pp);
   var_dump($cpp);
   
   ?>

Result:

 object(Book)#1 (2) {
  ["price"]=>
  int(25)
  ["title"]=>
  string(10) "Peter Pan"
}
object(CopyBook)#2 (2) {
  ["price"]=>
  NULL
  ["title"]=>
  NULL
}

Solution 2:[2]

Request and Response objects are immutable. This means withAttribute() will return a new copy of the $request object. You need to return the new object not the original one.

$request = $request->withAttribute('username','XXXXXX');
return $next($request, $response);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Glorfindel
Solution 2