Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing streams - Cannot read from STDIN ??? #1065

Open
henrywood opened this issue Aug 14, 2024 · 3 comments
Open

Missing streams - Cannot read from STDIN ??? #1065

henrywood opened this issue Aug 14, 2024 · 3 comments

Comments

@henrywood
Copy link

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
Copy link
Author

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
Copy link
Author

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 henrywood changed the title Missing streams Missing streams - Cannot read from STDIN ??? Aug 15, 2024
@henrywood
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant