summaryrefslogtreecommitdiff
path: root/zend/file.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-11 00:08:41 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-11 00:08:41 +0100
commit1efade1a7667e4e1a34265fb3cf310faf8c80bb6 (patch)
treebd311ac3de5500daae633fbfdb585faf737607ba /zend/file.cpp
parent825049026dd2b2e906cdb46279faa39580d931d1 (diff)
refactored script class to have a seperate opcodes class, added file class that uses this same opcodes class
Diffstat (limited to 'zend/file.cpp')
-rw-r--r--zend/file.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/zend/file.cpp b/zend/file.cpp
new file mode 100644
index 0000000..3ba53c9
--- /dev/null
+++ b/zend/file.cpp
@@ -0,0 +1,114 @@
+/**
+ * File.cpp
+ *
+ * Implementation file for the File class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+
+/**
+ * Dependencies
+ */
+#include "includes.h"
+
+/**
+ * Namespace
+ */
+namespace Php {
+
+/**
+ * Constructor
+ *
+ * The constructor receives a filename as parameter. It uses the normal
+ * PHP include path resolve algorithms to find the location of the file.
+ *
+ * @param name the filename
+ * @param size length of the filename
+ */
+File::File(const char *name, size_t size)
+{
+ // we need the tsrm_ls variable
+ TSRMLS_FETCH();
+
+ // resolve the path
+ _path = zend_resolve_path(name, size TSRMLS_CC);
+}
+
+/**
+ * Destructor
+ */
+File::~File()
+{
+ // clean up path name
+ if (_path) efree(_path);
+
+ // clean up opcodes
+ if (_opcodes) delete _opcodes;
+}
+
+/**
+ * Execute the file
+ * @return Value
+ */
+Value File::execute()
+{
+ // do we already have the opcodes?
+ if (_opcodes) return _opcodes->execute();
+
+ // skip if there is no valid path
+ if (!_path) return nullptr;
+
+ // we are going to open the file
+ zend_file_handle fileHandle;
+
+ // open the file
+ if (zend_stream_open(_path, &fileHandle TSRMLS_CC) == FAILURE) return nullptr;
+
+ // make sure the path name is stored in the handle
+ if (!fileHandle.opened_path) fileHandle.opened_path = estrdup(_path);
+
+ // we need temporary compiler options
+ CompilerOptions options(ZEND_COMPILE_DEFAULT);
+
+ // we need the tsrm_ls variable
+ TSRMLS_FETCH();
+
+ // create the opcodes
+ _opcodes = new Opcodes(zend_compile_file(&fileHandle, ZEND_INCLUDE TSRMLS_CC));
+
+ // close the file handle
+ zend_file_handle_dtor(&fileHandle TSRMLS_CC);
+
+ // execute the opcodes
+ return _opcodes->execute();
+}
+
+/**
+ * Execute a file only once
+ * @return Value
+ */
+Value File::once()
+{
+ // skip if the opcodes are already known (then we know for sure that the
+ // file was already executed)
+ if (_opcodes) return nullptr;
+
+ // also leap out if the filename was not even valid
+ if (!_path) return nullptr;
+
+ // check if this file was already included
+ if (zend_hash_exists(&EG(included_files), _path, ::strlen(_path) + 1)) return nullptr;
+
+ // add the entry to the list of included files
+ if (zend_hash_add_empty_element(&EG(included_files), _path, ::strlen(_path) + 1) == FAILURE) return nullptr;
+
+ // execute the file
+ return execute();
+}
+
+/**
+ * End of namespace
+ */
+}
+