Rob Crowell
Rob Crowell

Reputation:

Opcode caching in APC and missing files

We are using APC as an opcode cache. Is there a way to get APC to cache the non-existence of a file? We have set apc.stat = 0 and apc.include_once_override = 1. Is there something more to do to improve the performance of calling include_once on a file that may not be present on the filesystem? If it is present, obviously we want to include it. However, if it is not present, it will never be present and we don't want PHP to call open() on the file on every request to check.

For some background: we have one base site but provide customizations to the site on a customer-by-customer basis. Some customers have a custom login page, others have totally unique pages, etc.

We're using the Zend Framework in a slightly unusual way to allow us to override controllers as necessary. Our site might have a controller called LoginController, defined in a file controllers/LoginController.php. However, our client "Company" might have a requirement for a custom login page, so we will write a new class called Company_LoginController defined in a directory controllers/company/LoginController.php. (This naming convention allows us to be consistent with the Zend Framework notion of "modules".)

When we're dealing with the class, we basically do something like this:

include_once APPLICATION_PATH . '/controllers/company/LoginController.php';
if (class_exists("Company_LoginController")) {
    echo 'customer-specific controller exists';
} else {
    include_once APPLICATION_PATH . '/controllers/LoginController.php';
    echo 'customer-specific controller does not exist; using default';
}

If the file /controllers/company/LoginController.php exists, APC will cache it on the first request and never fetch it from the filesystem again. However, if the file /controllers/company/LoginController.php does not exist, I don't want APC to check for the existence of this file more than once. Any way to make this happen?

Upvotes: 3

Views: 1581

Answers (3)

user336242
user336242

Reputation:

If you are using Zend Framework i would recommend using using the Zend_Loader autoloading magic to make sure the files you need are loaded. By using the autoloader you can strip out nearly all the include_once calls from ZF (except the ones in the Zend_Loader class) Caveat - does depend on your class and filenaming style, but you can rewrite/extend the autoloader to counter this.

This might not be what you are after but i hope its helpful nonetheless..

Upvotes: 0

Frank Farmer
Frank Farmer

Reputation: 39356

jmucchiello's answer gets my vote for simplicity, but if for some reason that's not practical, you could always do things the hard way.

The following is a rough, untested example, but it should communicate the basic idea, which is to manually store the existence of the file in APC yourself

function conditional_include($file) {
  $key = 'file-exists-' . $file;
  //fetch cache key; if it does not exist, then...
  if(($fileExists = apc_fetch($key)) === false) {
    //actually hit the disk to look for the file, and store the result
    apc_store($key, $fileExists = (file_exists($file) ? 1 : 0));
  }

  //only include the file if it exists.
  if($fileExists)
   include_once $file;
}

Upvotes: 2

jmucchiello
jmucchiello

Reputation: 18984

Can you just create empty files in the company directory? Since APC will not load them twice, there's no harm in having some empty files that get "loaded" the first time the server starts.

Upvotes: 3

Related Questions