Opened 7 years ago

Last modified 3 years ago

#296 new defect

Multiple instances of the same software causes PHP "cannot redeclare class" errors when xcache enabled

Reported by: specky_rum Owned by: dschnepper
Priority: major Milestone: 3.0.2
Component: cacher Version: 3.0.0
Keywords: Cc: dschnepper@…
Application: PHP Version: 5.4.x
Other Exts: SAPI: Irrelevant
Probability: Blocked By:


PHP 5.4.3
Apache 2.2.22 64bit.
Win 2008 64bit
xcache 2.0.1

We have several instance of the Drupal CMS installed on our server which means several copies of the same files and file structure, just in different base directories. We do this so we can break a development version and not affect live, however, they run through one Apache instance and therefore one PHP and xcache instance.

It appears that when xcache is enabled we get frequent but intermittent and apparently fairly random "cannot redeclare class" errors in the PHP error log. These are fatal errors so the page completely fails when this happens. Disabling xcache completely eliminates the problem.

Since these errors are usually caused by either loading the same file twice (include instead of include_once) or by loading two files which have the same class declared in them I wonder if xcache is not using the entire filepath to identify cached files? After all, we have several instances of the same file, each of which has the same size etc.

Evidence for this comes from the error stack which shows the source of the error itself from instance A where all the other entries in the stack are in instance B. This should never happen and as stated, when xcache is disabled, it doesn't.

Attachments (2)

ticket-296-2.0.1.patch (2.7 KB) - added by dschnepper 7 years ago.
Patch for 2.0.1
0001-ticket-296-3.0.1.patch (2.8 KB) - added by dschnepper 7 years ago.
Patch for 3.0.1

Download all attachments as: .zip

Change History (34)

comment:1 follow-up: Changed 7 years ago by moo

IIRC, this is fixed in 3.0.0. can you please try 3.0.0 (or 3.0.1-dev)

comment:2 Changed 7 years ago by specky_rum

Thanks very much for your quick response. I think the only reason we're not already using 3.0.1 is because I couldn't find a 64bit version and there isn't one at that link. Does that matter? If so, do you happen to know where I might get a 64bit Windows compile of it? Cheers.

comment:3 Changed 7 years ago by specky_rum

Note that we're using 64 bit Apache and it regularly exceeds 2GB of memory usage!

comment:4 Changed 7 years ago by moo

where did you get 64 bit version of PHP prebuilt for windows?

comment:5 Changed 7 years ago by specky_rum


All very unofficial but we had concerns over memory usage and crashes and these versions have helped resolve that. From this page the additional extensions (link at bottom) include xcache but only up to version 2.0.1, which is the version we were using.

comment:6 Changed 7 years ago by moo

updated XCache build. you may want to get 5.4.8 (or 5.4.9) because PHP older than 5.4.7 (5.4.x) may not compatible with XCache that is build with newer PHP

comment:7 Changed 7 years ago by specky_rum

  • PHP Version changed from 5.4.3 to 5.4.8
  • Version changed from 2.0.1 to 3.0.0

updated to:
Apache 2.2.23 64bit
PHP 5.4.8 ts 64bit
xcache 3.0.1dev ts 64bit

The same problem occurs. When I disable xcache it stops the problem occurring.

If there's anything I can do to help diagnose this problem please let me know. Is there an ini setting that helps perhaps?

comment:8 Changed 7 years ago by moo

need a short reproduce-able script/steps

comment:9 Changed 7 years ago by dschnepper

  • Owner changed from moo to dschnepper

comment:10 Changed 7 years ago by dschnepper

  • Status changed from new to assigned

comment:11 Changed 7 years ago by dschnepper

We also ran into this problem when we upgraded from XCache 1.3.x to 2.0.1.

The root of the problem is the assumption that files-with-identical-source will results in identical opcodes. For PHP source files that contain the compile-time constants DIR or FILE, this assumption is not true.

I don't fully understand the use-case that lead to de-duplicating cached Opcode sets based on identical source files. While I understand the intent was to save on cache space - the use case that lead to this xcache feature doesn't apply on our site.

In our case, we have "revision X" and "revision X+1" active on the site at the same time, and phase an increasing percentage of traffic from one release to the next over a short time interval (1 hour). Many files are identical between the two releases, but files that make use of DIR or FILE are functionally different as release X and X+1 are stored in different directory trees.

comment:12 in reply to: ↑ 1 Changed 7 years ago by dschnepper

Replying to moo:

IIRC, this is fixed in 3.0.0. can you please try 3.0.0 (or 3.0.1-dev)

We duplicated that the problem also exists in 3.0.0, 3.0.1, and 3.1.0-dev. (as well as 2.0.1)

comment:13 Changed 7 years ago by dschnepper

  • Cc dschnepper@… added

Changed 7 years ago by dschnepper

Patch for 2.0.1

Changed 7 years ago by dschnepper

Patch for 3.0.1

comment:14 Changed 7 years ago by rluecke

I've been working with dschnepper on this issue. In order to easily reproduce the error, I've built two virtual machine images: one is a fresh Ubuntu installation, and the other is that same fresh VM but with Apache 2, PHP 5.4, and XCache 2.0.1, which allows you to easily to reproduce the PHP errors via an ApacheBench? test. Please see this link for the steps involved, and the VM images:

comment:15 Changed 7 years ago by moo

The patch attached may remove the problem but also remove the feature of md5 dedup.

Simply disable md5 dedup would be a easier to avoid this bug before we can fix this unstable feature.

comment:16 Changed 7 years ago by specky_rum

Following my initial report on this I spent some time creating a test case for you using a few very simple classes that called each other from different files. I copied them to different folders and then ran it from the different folders alternately and could never get it to fail!

Since then I have installed xcache on a multi Drupal install and seen it working and the only major difference I can see is that the one that works is 32 bit and the one that didn't was 64 bit. This may well be a red herring but I thought it worth mentioning just in case.

If you would like the test case I created that I couldn't actually get to fail let me know and I'll post it up, it just didn't seem much use since it needs to fail to prove anything!

Thanks for continuing to look into this. In our case we are now running separate Apache instances on our live server and using xcache on each so it is not an urgent issue but if I can help further I will.

comment:17 Changed 7 years ago by moo

Thanks for the info. I'm making time to the test case env mention on the google group.

comment:18 Changed 7 years ago by moo

Thanks to the test case, it can now be reported under my dev env. To reproduce:

  • xcache.readonnly_protection=off (not reproduced: xcache.readonnly_protection=on and xcache.mmap_path=/tmp/xcache (not /dev/zero))
  • concurrent request to the server

comment:19 Changed 7 years ago by moo

  • PHP Version changed from 5.4.8 to 5.4.x

comment:20 Changed 7 years ago by moo

fixed in [1238] for trunk (3.1.x). please confirm it and make a harder test before it is back port to 3.0.x

comment:21 Changed 7 years ago by moo

  • Resolution set to fixed
  • Status changed from assigned to closed

comment:22 Changed 7 years ago by moo

confirmed fixed by dschnepper

backport as [1239] for branch 3.0.x

comment:23 Changed 7 years ago by moo

  • Milestone changed from undecided to 3.0.2

comment:24 Changed 7 years ago by gacek

This problem occurs also in PHP 5.2. I know, this version supported has been stopped by, but i.e. 5.1 is still being supported by RedHat?/CentOS.

Is it possible to fix this bug also for ver <=5.2 ?
Simplest test case for this bug below. I know, this is dumb, but such construct is used by Zend Framework...

if (true) {

class My_Exception extends Exception {}

} else {

class My_Exception extends Exception {}


comment:25 Changed 7 years ago by moo


comment:26 Changed 6 years ago by specky_rum

Could you possibly provide an x64 Windows binary for the 3.1.0 release with this fix please? Specifically for PHP 5.4 thread safe. I'd like to give it another go. Cheers.

comment:27 Changed 6 years ago by moo

done, thanks for notifying me about missing x64 build

comment:28 Changed 6 years ago by specky_rum

This appears to be working beautifully now. Thanks very much!

comment:29 Changed 4 years ago by StrangeWill

Odd I appear to still be having this problem using mpm-itk and xcache:

 require_once(): Failed opening required
'/mnt/www/data/vhosts/[Web Site 1]/wp-content/plugins/wp-security-audit-log/classes/Connector/ConnectorFactory.php' 
(include_path='.:/usr/share/php:/usr/share/pear') in
/mnt/www/data/vhosts/[Web Site 2]/wp-content/plugins/wp-security-audit-log/classes/Models/ActiveRecord.php on line 2

The includes are mixed, the order reverses depending on which site ends up in xcache first.

#dpkg -s php5-xcache
Package: php5-xcache
Status: install ok installed
Priority: optional
Section: php
Installed-Size: 439
Maintainer: Debian PHP PECL Maintainers <>
Architecture: amd64
Source: xcache
Version: 3.2.0-1
Replaces: php5-user-cache
Provides: php5-user-cache

Xcache 3.2.0, should be fixed as of 3.0.2.

Last edited 4 years ago by StrangeWill (previous) (diff)

comment:30 Changed 3 years ago by laurent

This bug is still there in some form, I just experienced it.
I have also twice the same site on my PC, and when I open site1/index.php, it's cached. When I open site2/index.php, it's thinking it's at the same as site1/index.php with the same path, thus all the requires of site2/ are done in site1/

My requires are using require_once(__DIR__.'/lib.php'); for example.
So the pb is that site2/index.php got a wrong __DIR__ (and __FILE__)

If the pb is too simple, this doesn't happen! I just created a a.php with just echo __FILE__; in it, and copied it on the 2 sites, and they displayed their good path!

My conf:
PHP 5.5.9-1ubuntu4.11 (cli) (built: Jul 2 2015 15:23:08)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

with XCache v3.1.0, Copyright (c) 2005-2013, by mOo
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with XCache Optimizer v3.1.0, Copyright (c) 2005-2013, by mOo
with XCache Cacher v3.1.0, Copyright (c) 2005-2013, by mOo
with XCache Coverager v3.1.0, Copyright (c) 2005-2013, by mOo

comment:31 Changed 3 years ago by laurent

  • Resolution fixed deleted
  • Status changed from closed to new

comment:32 Changed 3 years ago by moo

what if you change code to

$dir = __DIR__;
require_once($dir . '/lib.php');
Note: See TracTickets for help on using tickets.