Skip to content

Commit

Permalink
fixed the Php::include_once() call for PHP 8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
EmielBruijntjes committed Oct 20, 2024
1 parent 1d878ff commit 009580d
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 15 deletions.
4 changes: 4 additions & 0 deletions Examples/IncludeOnce/30-includeonce.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
; configuration for phpcpp module
; priority=30
extension=includeonce.so

34 changes: 34 additions & 0 deletions Examples/IncludeOnce/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CPP = g++
RM = rm -f
CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
PHP_CONFIG = $(shell which php-config)
LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
PHP_CONFIG_DIR = $(shell ${PHP_CONFIG} --ini-dir)

LD = g++
LD_FLAGS = -Wall -shared -O2
RESULT = includeonce.so

PHPINIFILE = 30-includeonce.ini

SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:%.cpp=%.o)

all: ${OBJECTS} ${RESULT}

${RESULT}: ${OBJECTS}
${LD} ${LD_FLAGS} -o $@ ${OBJECTS} -lphpcpp

clean:
${RM} *.obj *~* ${OBJECTS} ${RESULT}

${OBJECTS}:
${CPP} ${CPP_FLAGS} -fpic -o $@ ${@:%.o=%.cpp}

install:
cp -f ${RESULT} ${LIBRARY_DIR}/
cp -f ${PHPINIFILE} ${PHP_CONFIG_DIR}/

uninstall:
rm ${LIBRARY_DIR}/${RESULT}
rm ${PHP_CONFIG_DIR}/${PHPINIFILE}
21 changes: 21 additions & 0 deletions Examples/IncludeOnce/class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Class.php
*
* Empty class, we just try to double-include this file to run into a
* "class already defined" error
*
* @author Emiel Bruijntjes <[email protected]>
* @copyright 2024 Copernica BV
*/

/**
* Include ourselves (should do nothing)
*/
include_once(__FILE__);
my_include_once(__FILE__);

/**
* Class definition
*/
class SillyClass {}
50 changes: 50 additions & 0 deletions Examples/IncludeOnce/includeonce.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* callphpfunction.cpp
* @author Jasper van Eck<[email protected]>
*
* An example file to show the working of a php function call in C++.
*/

/**
* Libraries used.
*/
#include <iostream>
#include <phpcpp.h>

/**
* Namespace to use
*/
using namespace std;

/**
* Function to test the Php::include_once() call
* @param &params
*/
void my_include_once(Php::Parameters &params)
{
// the string
Php::Value path = params[0];

// do the call
Php::include_once(path.stringValue());
}


// Symbols are exported according to the "C" language
extern "C"
{
// export the "get_module" function that will be called by the Zend engine
PHPCPP_EXPORT void *get_module()
{
// create extension
static Php::Extension extension("include_once","1.0");

// add function to extension
extension.add<my_include_once>("my_include_once", {
Php::ByVal("path", Php::Type::String),
});

// return the extension module
return extension.module();
}
}
18 changes: 18 additions & 0 deletions Examples/IncludeOnce/includeonce.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* include_once.php
*
* An example file to show the working of a php function call in C++.
*/

/**
* Include the file (should include the file only once)
*/
my_include_once(__DIR__."/class.php");
my_include_once(__DIR__."/class.php");
my_include_once(__DIR__."/class.php");

/**
* Construct object
*/
$x = new SillyClass();
34 changes: 19 additions & 15 deletions zend/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,33 +62,37 @@ bool File::compile()
if (_opcodes) return _opcodes->valid();

// we are going to open the file
zend_file_handle fileHandle;
zend_file_handle filehandle;

#if PHP_VERSION_ID < 80100

// open the file
if (zend_stream_open(ZSTR_VAL(_path), &fileHandle) == FAILURE) return false;

#else
/**
* zend_stream_open now only accepts the fileHandle object
* Filename must now be set through the object path.
*/
fileHandle.filename = _path;

// open the file
if (zend_stream_open(&fileHandle) == FAILURE) return false;
// since php 8 (or 8.1? - this has not been checked), zend_stream_open just takes the file-handle, and we must associate it first with a filename
zend_stream_init_filename_ex(&filehandle, _path);

// the stream if supposed to be open by now
if (zend_stream_open(&filehandle) == FAILURE) return false;

#endif

// make sure the path name is stored in the handle (@todo: is this necessary? do we need the copy?)
if (!fileHandle.opened_path) fileHandle.opened_path = zend_string_copy(_path);
// make sure the path name is stored in the handle (@todo: is this necessary? do we need the copy,
// this was copied from zend_execute.c, maybe deals with case when opened_path is not set for
// special types of files that are correctly opened, but that do not expose path-info, while this info
// is still needed by the subsequent zend_compile_file() call for error messages?)
if (!filehandle.opened_path) filehandle.opened_path = zend_string_copy(_path);

// we need temporary compiler options
CompilerOptions options(ZEND_COMPILE_DEFAULT);

// create the opcodes
_opcodes.reset(new Opcodes(zend_compile_file(&fileHandle, ZEND_INCLUDE)));
_opcodes.reset(new Opcodes(zend_compile_file(&filehandle, ZEND_INCLUDE)));

// close the file handle
zend_destroy_file_handle(&fileHandle);
zend_destroy_file_handle(&filehandle);

// done
return _opcodes->valid();
Expand Down Expand Up @@ -133,9 +137,6 @@ Value File::execute()
// try compiling the file
if (!compile()) return nullptr;

// add the entry to the list of included files
zend_hash_add_empty_element(&EG(included_files), _path);

// execute the opcodes
return _opcodes->execute();
}
Expand All @@ -152,6 +153,9 @@ Value File::once()
// check if this file was already included
if (zend_hash_exists(&EG(included_files), _path)) return nullptr;

// add the entry to the list of included files
zend_hash_add_empty_element(&EG(included_files), _path);

// execute the file
return execute();
}
Expand Down

0 comments on commit 009580d

Please sign in to comment.