-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
Option to store output of php_execute_script #9330
Comments
Something like that? #include <sapi/embed/php_embed.h>
static size_t embed_ub_write(const char *str, size_t str_length){
printf("Data (%lu bytes): [%s]\n", str_length, str);
return str_length;
}
int main(int argc, char **argv)
{
php_embed_module.ub_write = embed_ub_write;
PHP_EMBED_START_BLOCK(argc, argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, "example.php");
if (php_execute_script(&file_handle) == FAILURE) {
php_printf("Failed to execute PHP script.\n");
}
PHP_EMBED_END_BLOCK()
} <?php
echo 'Hello world!' . PHP_EOL;
|
Well, sort of... #include <sapi/embed/php_embed.h>
char *string[999] = {NULL};
int i = 0;
static size_t embed_ub_write(const char *str, size_t str_length){
string[i] = (char *) str; i++;
return str_length;
}
int main(int argc, char **argv)
{
php_embed_module.ub_write = embed_ub_write;
PHP_EMBED_START_BLOCK(argc, argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, "example.php");
if (php_execute_script(&file_handle) == FAILURE) {
php_printf("Failed to execute PHP script.\n");
}
for (i = 0; string[i] != NULL; i++) {
printf("%s", string[i]);
}
PHP_EMBED_END_BLOCK()
} Where did you learn that, anyways? Is there some documentation or something I can't find or... Does that mean this feature already exists? |
Embed is poorly documented, you need to look into source, especially ‘stdout‘ goes directly to filedescriptor, I think there was a way to override said descriptor, but I didn't dive into this. |
Another POC, probably not the cleanest way: #include <sapi/embed/php_embed.h>
#include <fcntl.h> // O_NONBLOCK
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
int cstdout = STDOUT_FILENO;
// `ub_write` disabled for this example
static size_t embed_ub_write(const char *str, size_t str_length){
// own stdout to display data
dprintf(cstdout , "Data (%lu bytes): [%s]\n", str_length, str);
return str_length;
}
int main(int argc, char **argv)
{
int pipefd[2];
// pipe to buffer php stdout
if (pipe2(pipefd, O_NONBLOCK) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// copy stdout before overriding
cstdout = dup(STDOUT_FILENO);
// override stdout with pipe
if(dup2(pipefd[1], STDOUT_FILENO) == -1){
perror("dup2");
exit(EXIT_FAILURE);
}
// // can be skipped if all should go to stdout
// php_embed_module.ub_write = embed_ub_write;
PHP_EMBED_START_BLOCK(argc, argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, "example.php");
if (php_execute_script(&file_handle) == FAILURE) {
php_printf("Failed to execute PHP script.\n");
}
PHP_EMBED_END_BLOCK()
// restore stdout and close pipe input
if(dup2(cstdout, STDOUT_FILENO) == -1){
perror("dup2 restore");
exit(EXIT_FAILURE);
}
printf("Script ended\n");
char buf[2048];
int bytes;
while ((bytes = read(pipefd[0], &buf, 2048)) != -1)
{
// strings are *not* null terminated here
printf( "Stdout (%u bytes): [%.*s]\n", bytes, bytes, (char*)&buf);
}
// close pipe output
close(pipefd[0]);
} <?php
echo 'Hello world!' . PHP_EOL;
file_put_contents("php://stdout", "Hello stdout!" . PHP_EOL);
If you create pipe with
Pipe has also limit to how much data can take, in my case it was |
Oh, I thought it used some sort of other method of output (stupid expectation, really) and that was why it wasn't working. (For those who didn't understand the code, you need to I'll keep this open to see what they have to say about it, perhaps they can make this a built-in feature or something, IDK if it's useful or not though (as I thought this wasn't even possible when I opened this issue). |
I can't speak for maintainers, but I don't think so, and
As I mentioned documentation is lacking, but I'm not sure if embedding is popular enough to improve it. |
Makes sense. Closing.
Yeah, I thought I was the only one who thought that way. |
Description
I'm embedding PHP and I need to store the output of
php_execute_script
using the API. Can we have this feature?The text was updated successfully, but these errors were encountered: