kphp icon indicating copy to clipboard operation
kphp copied to clipboard

Missing streams - Cannot read from STDIN ???

Open henrywood opened this issue 1 year ago • 3 comments

The php streams:

php://memory php://temp php://input php://output

are all missing !

I tried to compile this simple script:

<?php

$input = fopen('php://input', 'rb');
$output = fopen('php://output', 'wb');
$temp = fopen('php://temp', 'wb');

echo "OUTPUT:".PHP_EOL;
fwrite($output, 'HELLO');

$contents = '';

while(! feof($input)) {
        $contents.= fread($input, 8192);
}

echo "Input: ".$contents.PHP_EOL;

I compiles fine with:

kphp test2.php --mode cli --composer-root $(pwd) -o ./test2

But when run output is:

henrik@HSLAPTOP-ASUS:/tmp/sreq2$ ./test2
[1779467][2024-08-14 19:21:12.592479 limits.cpp  124] failed to set rlimit for core dump size.
[1723656072] [1779467] Warning: php://input should be opened in read mode
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x6660e4]
(1) ./test2 : f$fopen(string const&, string const&)+0x98 [0x6936e8]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x50 [0x521720]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e22f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f00347c5130]
-------------------------------

[1723656072] [1779467] Warning: Stream php://output not found
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x6660e4]
(1) ./test2 : f$fopen(string const&, string const&)+0x98 [0x6936e8]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0xac [0x52177c]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e22f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f00347c5130]
-------------------------------

[1723656072] [1779467] Warning: Stream php://temp not found
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x6660e4]
(1) ./test2 : f$fopen(string const&, string const&)+0x98 [0x6936e8]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x101 [0x5217d1]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e22f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f00347c5130]
-------------------------------

OUTPUT:
[1723656072] [1779467] Warning: Can't find appropriate wrapper for ""
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x6660e4]
(1) ./test2 : f$fwrite(mixed const&, string const&)+0x89 [0x690519]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x171 [0x521841]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e22f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f00347c5130]
-------------------------------

[1723656072] [1779467] Warning: Can't find appropriate wrapper for ""
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x6660e4]
(1) ./test2 : f$feof(mixed const&)+0x1d0 [0x68ed30]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x24c [0x52191c]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e22f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f00347c5130]
-------------------------------

Input:

Also:

stream_copy_to_stream() is missing stream_get_meta_data() is missing stream_get_contents() is missing

Can the missing streams ('php://temp', 'php://memory', 'php://input' and 'php://output') be added soon ?

I just spent a couple of days making a PSR-7 HTTP Message implementation to use with KPHP and it compiles fine but does not work due to the missing streams ???

Please prioritize this !

henrywood avatar Aug 14 '24 17:08 henrywood

Now I tried this:

<?php

$input = fopen('php://stdin', 'r');
$output = fopen('php://stdout', 'w');

stream_set_blocking($input, false);

echo "OUTPUT:".PHP_EOL;
fwrite($output, 'HELLO');

$contents = '';

// Use stream_select to check for input availability
$read = [$input];
$write = null;
$except = null;
$timeout = 1;
//$ready = stream_select($read, $write, $except, $timeout);  // This line is uncompilable ????
$ready = 1;

if ($ready > 0) {
 // Input is available, read it
 while (!feof($input)) {
  $line = fgets($input);
  if ($line === false) {
   break;
  }
  $contents.= $line;
 }
} else {
 echo "No input available.\n";
}

echo "Input: ".$contents.PHP_EOL;

According to the funtions file, php://stdin and php://stdout are defined but while the code above compiles the output is:

henrik@HSLAPTOP-ASUS:/tmp/sreq2$ echo "HELLO" | ./test2
[1786882][2024-08-14 19:54:50.117989 limits.cpp  124] failed to set rlimit for core dump size.
[1723658090] [1786882] Warning: Stream php://stdin not found
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x666504]
(1) ./test2 : f$fopen(string const&, string const&)+0x98 [0x693b08]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x57 [0x521727]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e64f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f4abc38e130]
-------------------------------

[1723658090] [1786882] Warning: Can't find appropriate wrapper for ""
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x666504]
(1) ./test2 : f$stream_set_blocking(mixed const&, bool)+0x1d0 [0x692980]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x108 [0x5217d8]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e64f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f4abc38e130]
-------------------------------

OUTPUT:
HELLO[1723658090] [1786882] Warning: Can't find appropriate wrapper for ""
------- Stack Backtrace -------
(0) ./test2 : php_warning(char const*, ...)+0xa4 [0x666504]
(1) ./test2 : f$feof(mixed const&)+0x1d0 [0x68f150]
(2) ./test2 : f$src_test2e0546a04c0b99c86()+0x2d3 [0x5219a3]
(3) ./test2 : f$src_test2e0546a04c0b99c86$run()+0xd [0x52150d]
(4) ./test2 : PhpScript::run()+0xef [0x71e64f]
(5) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f4abc38e130]
-------------------------------

Input:

So how do you read from php://stdin and write to php://stdout using KPHP ?

Please help !

henrywood avatar Aug 14 '24 17:08 henrywood

Now I refactored my KPHPRequestBody class to this:

<?php
/**
 * Created by PhpStorm.
 * User: inhere
 * Date: 2017-08-28
 * Time: 14:31
 */

namespace PhpPkg\Http\Message\Request;

use Psr\Http\Message\StreamInterface;
use RuntimeException;

/**
 * Class RequestBody
 *   Provides a PSR-7 implementation of a reusable raw request body
 * @package PhpPkg\Http\Message\Request
 */
class KPHPRequestBody implements StreamInterface {

        private string $data;
        private int $position;

        public function __construct(string $content = null)
        {
                $stdinContent = '';
                $fp = fopen('php://stdin', 'r'); // This line produces a warning ?

                while(!feof($fp)) {

                        $line = fgets($fp, 8192);
                        $stdinContent.=$line;
                }

                $this->data = $stdinContent;
                $this->position = 0;

                if ($content !== null) {
                        $this->write($content);
                }
        }

        public function __toString() : string
        {
                return $this->data;
        }

        public function close()
        {
                $this->data = '';
                $this->position = 0;
        }

        public function detach()
        {
                $this->close();
                return null;  // No underlying resource to return
        }

        public function getSize() : ?int
        {
                return strlen($this->data);
        }

        public function tell() : int
        {
                return $this->position;
        }

        public function eof() : bool
        {
                return $this->position >= strlen($this->data);
        }

        public function isSeekable() : bool
        {
                return true;
        }

        public function seek($offset, $whence = SEEK_SET)
        {
                $length = strlen($this->data);

                switch ($whence) {
                case SEEK_SET:
                        $this->position = $offset;
                        break;
                case SEEK_CUR:
                        $this->position += $offset;
                        break;
                case SEEK_END:
                        $this->position = $length + $offset;
                        break;
                default:
                        throw new RuntimeException('Invalid whence value');
                }

                if ($this->position < 0 || $this->position > $length) {
                        throw new RuntimeException('Invalid seek position');
                }
        }

        public function rewind()
        {
                $this->position = 0;
        }

        public function isWritable() : bool
        {
                return true;
        }

        public function write($string) : int
        {
                $length = strlen($string);

                // Replace data at the current position with new data
                $this->data = substr_replace($this->data, $string, $this->position, $length);
                $this->position += $length;

                return $length;
        }

        public function isReadable() : bool
        {
                return true;
        }

        public function read($length) : string
        {
                $result = substr($this->data, $this->position, $length);
                $this->position += strlen($result);
                return $result;
        }

        public function getContents() : string
        {
                $result = substr($this->data, $this->position);
                $this->position = strlen($this->data);  // Move to end
                return $result;
        }

        public function getMetadata(?string $key = null): ?array
        {
                // No metadata for an in-memory stream
                return null;
        }
}

test.php:

<?php
require_once('vendor/autoload.php');

use PhpPkg\Http\Message\HttpFactory;

$request = HttpFactory::createServerRequestFromArray($_SERVER);
//$request = HttpFactory::createServerRequest('GET', 'http://www.abc.com/home?first=henrik&last=skov');
//
$code = 200;

var_dump($request->get('first'));

$response = HttpFactory::createResponse($code);

$response->write('HELLO');
$response->end();

It compiles fine using:

# kphp test.php --composer-root $(pwd) --mode cli -o ./test

However, when run like this:

# echo "FOO" | ./test

the output is this:

[56569][2024-08-15 10:38:16.377521 limits.cpp  124] failed to set rlimit for core dump size.
[1723711096] [56569] Warning: Stream php://stdin not found
------- Stack Backtrace -------
(0) ./test : php_warning(char const*, ...)+0xa4 [0x6b54a4]
(1) ./test : f$fopen(string const&, string const&)+0x98 [0x6e0cc8]
(2) ./test : f$PhpPkg$Http$Message$Request$KPHPRequestBody$$__construct(class_instance<C$PhpPkg$Http$Message$Request$KPHPRequestBody> const&, Optional<string> const&)+0xa0 [0x552ff0]
(3) ./test : f$PhpPkg$Http$Message$HttpFactory$$createServerRequestFromArray(mixed const&, Optional<string> const&)+0x551 [0x557bb1]
(4) ./test : f$src_testa2eaf1d201790ddf()+0x80 [0x56fc70]
(5) ./test : f$src_testa2eaf1d201790ddf$run()+0xd [0x53866d]
(6) ./test : PhpScript::run()+0xef [0x76b80f]
(7) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f2d9c079130]
-------------------------------

[1723711096] [56569] Warning: Can't find appropriate wrapper for ""
------- Stack Backtrace -------
(0) ./test : php_warning(char const*, ...)+0xa4 [0x6b54a4]
(1) ./test : f$feof(mixed const&)+0x1d0 [0x6dc310]
(2) ./test : f$PhpPkg$Http$Message$Request$KPHPRequestBody$$__construct(class_instance<C$PhpPkg$Http$Message$Request$KPHPRequestBody> const&, Optional<string> const&)+0x156 [0x5530a6]
(3) ./test : f$PhpPkg$Http$Message$HttpFactory$$createServerRequestFromArray(mixed const&, Optional<string> const&)+0x551 [0x557bb1]
(4) ./test : f$src_testa2eaf1d201790ddf()+0x80 [0x56fc70]
(5) ./test : f$src_testa2eaf1d201790ddf$run()+0xd [0x53866d]
(6) ./test : PhpScript::run()+0xef [0x76b80f]
(7) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7f2d9c079130]
-------------------------------

NULL
HELLO

So how exactly do you read from STDIN using KPHP ?

I checked the C++ source and php://stdin is defined as a Stream ?

Please help !

henrywood avatar Aug 15 '24 08:08 henrywood

Next I tried using php://input

The output was then

# echo "FOO" | ./test

the output is:

[60444][2024-08-15 10:58:36.405808 limits.cpp  124] failed to set rlimit for core dump size.
[1723712316] [60444] Warning: Can't use feof with stream php://input
------- Stack Backtrace -------
(0) ./test : php_warning(char const*, ...)+0xa4 [0x6b54a4]
(1) ./test : f$feof(mixed const&)+0x5f [0x6dc19f]
(2) ./test : f$PhpPkg$Http$Message$Request$KPHPRequestBody$$__construct(class_instance<C$PhpPkg$Http$Message$Request$KPHPRequestBody> const&, Optional<string> const&)+0x156 [0x5530a6]
(3) ./test : f$PhpPkg$Http$Message$HttpFactory$$createServerRequestFromArray(mixed const&, Optional<string> const&)+0x551 [0x557bb1]
(4) ./test : f$src_testa2eaf1d201790ddf()+0x80 [0x56fc70]
(5) ./test : f$src_testa2eaf1d201790ddf$run()+0xd [0x53866d]
(6) ./test : PhpScript::run()+0xef [0x76b80f]
(7) /lib/x86_64-linux-gnu/libc.so.6 : +0x5a130 [0x7fbdf15fb130]
-------------------------------

NULL
HELLO

henrywood avatar Aug 15 '24 09:08 henrywood