These  are not copies of the current StreamtInterface implementation 
returned $this->request->getBody()

I am trying to create a class/method that works with any third-party 
RequestInterface implementation.

I do not know the architecture of StreamtInterface implementation used in 
the RequestInterface implementation.

class Stream implements StreamtInterface
{
    protected $handler;
   
    public function __construct()
    {
        $this->handler = tmpfile();
    }
   
    public function write($str)
    {
        fwrite($this->handler, $str);
    }
}

class FilteredStream extends Stream
{
    protected $filter;
   
    public function __construct(callable $filter)
    {
        parent::__construct();
        $this->filter = $filter;
    }
   
    public function write($str)
    {
        parent::write(($this->filter)($str));
    }
}

$request->withBody(new Stream());
$myAbstractObject->setRequest($request);
// in other case
$request->withBody(new FilteredStream('myFilterFunct'));
$myAbstractObject->setRequest($request);



I think need add "truncate" or/and "withContents" methods to the 
StreamInterface:

interface StreamInterface
{
   /**
    * Truncates a stream data to a given length.
    *
    * @see https://www.php.net/manual/en/function.ftruncate.php
    *
    * @param int $size The size to truncate to.
    * @throws \InvalidArgumentException Size not integer or less zero.
    * @throws \RuntimeException Not seekable.
    */
    public function truncate($size);

    /**
     * Returns new instance with the specified contents.
     *
     * @param string $str New contents.
     * @return static New instance.
     * @throws \RuntimeException On failure.
     */
    public function withContents($str);
}

class Stream implements StreamInterface
{
    public function truncate($size)
    {
        if (intval($size) != $size || $size < 0) {
            throw new \InvalidArgumentException('Size must be not negative 
integer');
        }
        if (! $this->isSeekable()) {
            throw new \RuntimeException('Stream not seekable');
        }
        ftruncate($this->handle, $size);
        if ($this->tell() > $size) {
            // Fix cursor position
            $this->seek(0, SEEK_END);
        }
    }
   
    public function withContents($str)
    {
        $clone = clone $this;
        $clone->rewind();
        $clone->write($str);
        ftruncate($this->handle, strlen($str));
        // or $this->truncate(strlen($str));
        return $clone;
    }
}



суббота, 12 октября 2019 г., 2:42:32 UTC+3 пользователь Matthew Weier 
O'Phinney написал:
>
>
>
> On Thu, Oct 10, 2019, 6:42 PM Anton Fedonjuk <[email protected] 
> <javascript:>> wrote:
>
>> Class contains method setRequest(RequestInterface $request), his abstact 
>> code:
>> Request body already sets: $request->getBody()->write('...');
>> I want send this request with other body content, but dont know how:
>> 1. StreamInterface don't have methods as PHP ftruncate()
>> 2. Constructor not defined in StreamInterface: can't use 
>> $request->withBody() because dont know how create clone of that Steam 
>> object without contents.
>>
>
> To provide new contents, you provide a new body to the request, which 
> means using a new StreamInterface instance. 
>
> To get a new StreamInterface instance, you either instantiate I've 
> directly, per the PSR-7 *implementation* you have installed, or you use a 
> PSR-17 StreamFactoryInterface instance to create it. This is something you 
> would compose into your class as a constructor dependency. 
>
> In each case, you need an *implementation* of one or both of the specs 
> installed, which is already likely the case. 
>
> In the first case, if using Diactoros, your code might look like this:
>
>     $request = $this->getRequest()
>         ->withBody(new \Zend\Diactoros\Stream('php://temp', 'wb+'));
>
> In the second, it would look like this:
>
>     $request = $this->getRequest()
>         ->withBody($this->streamFactory->createStream());
>
> From there, you can call on the stream's write() method. Alternately, if 
> using the factory, create the entire stream *with contents* to save 
> yourself the step. 
>
> Regarding your point that there is no StreamInterface constructor,
> the constructor is not defined in any of the interfaces because:
>
> - We did not want to restrict how implementations wrote constructors.
> - PHP ALWAYS allows classes implementing interfaces to override the 
> signature of a constructor. 
>
> As such, you always have to look at how the *implementation* to determine 
> the signature of constructors. 
>
> This is one large reason PSR-17 exists - to standardize how instances of 
> psr-7 interfaces are created. 
>
> Regardless, each of the above examples give you an instance with an empty 
> body. 
>

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/d6b75c0c-cf63-49e5-9608-1a89e486c678%40googlegroups.com.

Reply via email to