Index: php_apc.c =================================================================== --- php_apc.c (revision 289897) +++ php_apc.c (working copy) @@ -79,9 +79,12 @@ /* True globals */ apc_cache_t* apc_cache = NULL; apc_cache_t* apc_user_cache = NULL; +zval apc_zval_file_get_cont; static void php_apc_init_globals(zend_apc_globals* apc_globals TSRMLS_DC) { + const char* file_get_cont_func_name = "apc_file_get_contents"; + int len = strlen(file_get_cont_func_name); apc_globals->filters = NULL; apc_globals->compiled_filters = NULL; apc_globals->initialized = 0; @@ -106,6 +109,11 @@ apc_globals->use_request_time = 1; apc_globals->lazy_class_table = NULL; apc_globals->lazy_function_table = NULL; + + INIT_ZVAL(apc_zval_file_get_cont); + Z_TYPE(apc_zval_file_get_cont) = IS_STRING; + Z_STRVAL(apc_zval_file_get_cont) = (char*) file_get_cont_func_name; + Z_STRLEN(apc_zval_file_get_cont) = len; } static void php_apc_shutdown_globals(zend_apc_globals* apc_globals TSRMLS_DC) @@ -257,6 +265,7 @@ STD_PHP_INI_BOOLEAN("apc.write_lock", "1", PHP_INI_SYSTEM, OnUpdateBool, write_lock, zend_apc_globals, apc_globals) STD_PHP_INI_BOOLEAN("apc.slam_defense", "1", PHP_INI_SYSTEM, OnUpdateBool, slam_defense, zend_apc_globals, apc_globals) STD_PHP_INI_BOOLEAN("apc.report_autofilter", "0", PHP_INI_SYSTEM, OnUpdateBool, report_autofilter,zend_apc_globals, apc_globals) +STD_PHP_INI_BOOLEAN("apc.cache_static_content", "0", PHP_INI_ALL, OnUpdateBool, cache_static_content, zend_apc_globals, apc_globals) #ifdef MULTIPART_EVENT_FORMDATA STD_PHP_INI_BOOLEAN("apc.rfc1867", "0", PHP_INI_SYSTEM, OnUpdateBool, rfc1867, zend_apc_globals, apc_globals) STD_PHP_INI_ENTRY("apc.rfc1867_prefix", "upload_", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_prefix, zend_apc_globals, apc_globals) @@ -1359,6 +1368,70 @@ } /* }}} */ +/* {{{ proto mixed apc_file_get_contents(string $filename [, int $flags = 0 [, resource $context [, int $offset = -1 [, int $maxlen = -1 ]]]]) + */ +PHP_FUNCTION(apc_file_get_contents) +{ + char *filename; + int filename_len; + char *contents; + zend_bool use_include_path = 0; + php_stream *stream; + int len, newlen; + long offset = -1; + long maxlen = (long) PHP_STREAM_COPY_ALL; + zval *zcontext = NULL; + php_stream_context *context = NULL; + apc_cache_entry_t* entry; + struct stat statbuf; + time_t cur_time; + + if ((!APCG(cache_static_content)) || ZEND_NUM_ARGS() > 1) { + PHP_FN(file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + return; + } + /* Parse arguments */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", + &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) { + return; + } + + if (!(filename && IS_ABSOLUTE_PATH(filename, filename_len))) { + PHP_FN(file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + return; + } + +#if PHP_API_VERSION < 20041225 +#if HAVE_APACHE && defined(APC_PHP4_STAT) + cur_time = ((request_rec *)SG(server_context))->request_time; +#else + cur_time = time(0); +#endif +#else + cur_time = sapi_get_request_time(TSRMLS_C); +#endif + + /* If entry is older than cur_time + user_ttl then apc_cache_user_find will + * return NULL */ + entry = apc_cache_user_find(apc_user_cache, filename, filename_len + 1, + cur_time); + if(entry && (Z_TYPE_P(entry->data.user.val) == IS_STRING)) { + /* Unfortunately we have to make a copy. Because we are never + sure if php script is going to modify it or not. */ + RETVAL_STRINGL(Z_STRVAL_P(entry->data.user.val), + Z_STRLEN_P(entry->data.user.val), 1); + apc_cache_release(apc_cache, entry); + return; + } + PHP_FN(file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (return_value && (Z_TYPE_P(return_value) == IS_STRING)) { + _apc_store(filename, filename_len, return_value, APCG(user_ttl), 0 TSRMLS_CC); + } + return; +} +/* }}} */ + + /* {{{ proto mixed apc_bin_dump([array files [, array user_vars]]) Returns a binary dump of the given files and user variables from the APC cache. A NULL for files or user_vars signals a dump of every entry, while array() will dump nothing. @@ -1655,6 +1728,15 @@ ZEND_ARG_INFO(0, context) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() + +PHP_APC_ARGINFO +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_file_get_contents, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, maxlen) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ apc_functions[] */ @@ -1677,6 +1759,7 @@ PHP_FE(apc_bin_load, arginfo_apc_bin_load) PHP_FE(apc_bin_dumpfile, arginfo_apc_bin_dumpfile) PHP_FE(apc_bin_loadfile, arginfo_apc_bin_loadfile) + PHP_FE(apc_file_get_contents, arginfo_apc_file_get_contents) {NULL, NULL, NULL} }; /* }}} */ Index: apc_compile.c =================================================================== --- apc_compile.c (revision 289897) +++ apc_compile.c (working copy) @@ -887,6 +887,7 @@ char *fullpath = NULL; apc_opflags_t * flags = NULL; apc_pool* pool = ctxt->pool; + int cache_static_content = APCG(cache_static_content); assert(src != NULL); @@ -1002,6 +1003,20 @@ } } break; + case ZEND_DO_FCALL: + if (cache_static_content) { + zval* zf = &zo->op1.u.constant; + if ((zo->op1.op_type == IS_CONST) && (Z_TYPE_P(zf) == IS_STRING) + && (strncmp(Z_STRVAL_P(zf), + "file_get_contents", Z_STRLEN_P(zf)) == 0)) { + zo->op1.u.constant = apc_zval_file_get_cont; + Z_STRVAL(zo->op1.u.constant) = + estrndup(Z_STRVAL(apc_zval_file_get_cont), + Z_STRLEN(apc_zval_file_get_cont)); + Z_STRLEN(zo->op1.u.constant) = Z_STRLEN(apc_zval_file_get_cont); + } + } + break; default: if((zo->op1.op_type == IS_CONST && zo->op1.u.constant.type == IS_CONSTANT_ARRAY) || Index: apc_globals.h =================================================================== --- apc_globals.h (revision 289897) +++ apc_globals.h (working copy) @@ -76,6 +76,7 @@ /* module variables */ zend_bool initialized; /* true if module was initialized */ + zend_bool cache_static_content; /* Store the file_get_contents into cache */ apc_stack_t* cache_stack; /* the stack of cached executable code */ zend_bool cache_by_default; /* true if files should be cached unless filtered out */ /* false if files should only be cached if filtered in */ @@ -131,6 +132,7 @@ extern apc_cache_t* apc_cache; /* the global compiler cache */ extern apc_cache_t* apc_user_cache; /* the global user content cache */ extern void* apc_compiled_filters; /* compiled filters */ +extern zval apc_zval_file_get_cont; #endif