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

Globalfix #385

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions Examples/GlobalBug/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# The name of the project, which is also how the .cpp and .php files are called,
# and how the resulting .so and .ini file will be called.
NAME = globalbug

# Where to find PHP-CPP relative to this directory
PHPCPPROOT = ../..

# Where the resulting files will be stored
LIBRARY_DIR = $(shell ${PHP_CONFIG} --extension-dir)
PHP_CONFIG_DIR = /etc/php5/cli/conf.d


# The compiler and its flags
CXX = g++
CXX_FLAGS = -c -I. -I ${PHPCPPROOT} -Og -g -std=c++11 \
-Wall -Wextra -Wno-unused-parameter -Wno-format

# The linker and its flags
LINKER = g++
LINKER_FLAGS = -Wall -shared -O2 -L ${PHPCPPROOT}

# In case the programs aren't on the default location, change these variables
RM = rm -rf
CP = cp -f

# Get all files that have to be compiled
SOURCES = $(wildcard *.cpp)
HEADERS = $(wildcard *.h)
OBJECTS = $(SOURCES:%.cpp=%.o)

# Targets that don't create files with the same name
.PHONY: all clean run install

all: ${NAME}.so

${NAME}.so: ${OBJECTS}
${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} -lphpcpp

${OBJECTS}: %.o: %.cpp ${HEADERS}
${CXX} ${CXX_FLAGS} -fpic -o $@ $<


clean:
${RM} *.obj *~* "${OBJECTS}" "${NAME}.so"

# Since the phpcpp.so file is (during development) in an unusual directory,
# we have to specify where we can find it.
run: export LD_LIBRARY_PATH = ${PHPCPPROOT}
run: ${NAME}.so
@# -n: ignore global php.ini file
@php -n -d extension="${NAME}.so" -d extension_dir=. "${NAME}.php"

install:
${CP} ${NAME}.so ${LIBRARY_DIR}
echo "extension=${NAME}.so" > ${PHP_CONFIG_DIR}/30-${NAME}.ini
52 changes: 52 additions & 0 deletions Examples/GlobalBug/globalbug.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* globalbug.cpp
* @author Charlie Bouthoorn <[email protected]>
*
* An example file which shows a former bug in globals
*/

#define NAME "globalbug"
#define VERSION "1.0"

#include <iostream>
#include <phpcpp.h>

/**
* process_globals()
*
* This function reads and modifies global variables
*/
void process_globals()
{
// Create a global array
Php::GLOBALS["array"] = Php::Array();

// Get this global back
Php::Global array = Php::GLOBALS["array"];

// Store a value in a member field
// NOTE: This is where the bug was. Changing this value didn't
// result in the global being updated.
array["member"] = 123;

// For comparison: These two answers should be the same
std::cout << array["member"] << std::endl;
std::cout << Php::GLOBALS["array"]["member"] << std::endl;
}

// 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(NAME, VERSION);

// add function to extension
extension.add<process_globals>("process_globals");


return extension.module();
}
}
5 changes: 5 additions & 0 deletions Examples/GlobalBug/globalbug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php
process_globals();

var_dump($array);
var_dump($array['member']);
12 changes: 12 additions & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ class PHPCPP_EXPORT Global : public Value

// call base
Value::set(index, value);

// force update current object
force_update();
}

/**
Expand All @@ -131,6 +134,9 @@ class PHPCPP_EXPORT Global : public Value

// call base
Value::set(key, size, value);

// force update current object
force_update();
}


Expand All @@ -141,6 +147,12 @@ class PHPCPP_EXPORT Global : public Value
*/
Global &update();

/**
* Update the underlying value forcefully
* @return Value
*/
Global &force_update();

private:
/**
* Constructor for non-existing var
Expand Down
24 changes: 23 additions & 1 deletion zend/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,29 @@ Global &Global::update()
}

/**
* End of namespace
* Update the underlying value forcefully
* @return Value
*/
Global &Global::force_update()
{
// make sure the global already exists
if (! _exists) return update();

// remove the old value
zend_symtable_del_ind(&EG(symbol_table), _name);

// add one extra reference because the variable now is a global var too
Z_TRY_ADDREF_P(_val);

// update the internal symtable
zend_symtable_update_ind(&EG(symbol_table), _name, _val);

_exists = true;

return *this;
}

/**
* End of namespace
*/
}