php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59493 APC fails to include files with relative paths and apc.stat=0
Submitted: 2010-11-04 00:56 UTC Modified: 2013-01-02 04:00 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:2 (50.0%)
From: pierre at archlinux dot de Assigned: gopalv (profile)
Status: Closed Package: APC (PECL)
PHP Version: 5.4 OS: Arch Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: pierre at archlinux dot de
New email:
PHP Version: OS:

 

 [2010-11-04 00:56 UTC] pierre at archlinux dot de
Description:
------------
I am using PHP 5.3.3 (cannot be chosen in the bug tracker menu btw.) and APC 3.1.5 on Arch Linux x86_64.

My local APC config is:
apc.shm_size=128M
apc.stat=0

After updating from 3.1.4 to 3.1.5 my php error log is filled with entries like:

[04-Nov-2010 06:42:41] PHP Warning:  include(): apc failed to locate ./lib/include2.php - bailing in /home/pierre/public_html/apc-test/lib/include.php on line 5

This only happens with stat=0 and if the file to include has been given a relative path to the initial called script.

I have seen this with using FluxBB btw.. If this is just a new warning which wasn't simply shown in previous apc versions I'll report a bug there to use absolute path for including files.

Reproduce code:
---------------
Here is some example code with the following files:

apc-test
├── lib
│?? ├── include2.php
│?? └── include.php
└── test.php

test.php:
<?php

define('l', './lib/');

echo 4;

if (file_exists(l.'include.php')) {
        include(l.'include.php');
}

?>

include.php:
<?php

echo 2;

include(l.'include2.php');

?>

include2.php:
<?php

echo '!';

?>

Actual result:
--------------
Although the code is executed as expected PHP logs the warning mentioned above.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-11-04 03:40 UTC] pierre dot php at gmail dot com
That can happen if you use stat=0, enable this setting again and the error will disappear.

The problem is that using stat=0, apc won't verify the file path full path with relative include_path.

Can you confirm that the warning went away with stat=1?
 [2010-11-04 05:19 UTC] pierre at archlinux dot de
Yes, it does not happen with stat=1 as I said before. My point is that it also wont happen with the previous APC versions.

So, am I right that if I want to use stat=0 all includes have to be absolute and the way to fix this issue is change the PHP-Script to use absolute paths?
 [2010-11-04 07:33 UTC] gopalv82 at yahoo dot com
That's really a bug, not a feature.

So initially, apc.stat=0 was supposed to work only if every path was a full path.

In apc-3.1.4, an include "./lib/include.php" would trigger a stat on every directory in the include_path while it gropes about looking for that file.

Assuming your include_path said "/usr/share/pear;/var/www/html/includes:."

it would stat 3 times with

stat("/usr/share/pear/./lib/include2.php")
stat("/var/www/html/includes/./lib/include2.php")
stat("././lib/include2.php")

Now, the last one succeeds. But this is obviously broken badly w.r.to performance.

So I made it look for only in the __DIR__ of the file
that was including it.

So here, it's looking for it in 

/home/pierre/public_html/apc-test/lib/lib/include2.php

which obviously doesn't exist.

So, if you do care about performance, I'd like to break
this bit of code, just to squeeze that much more extra
from the code.

All it needs to be fixed is a

define('l', __DIR__.'/lib/');

And you're going to get rid of any extra stats.
 [2010-11-08 12:00 UTC] marcus at deglos dot com
These messages should probably be changed from apc_warning to apc_debug.  Many other similar messages do not generate warnings.

patch:

Index: apc_cache.c
===================================================================
--- apc_cache.c	(revision 305202)
+++ apc_cache.c	(working copy)
@@ -859,12 +859,12 @@
             fileinfo = apc_php_malloc(sizeof(apc_fileinfo_t) TSRMLS_CC);
 
             if (apc_search_paths(filename, include_path, fileinfo TSRMLS_CC) != 0) {
-                apc_warning("apc failed to locate %s - bailing" TSRMLS_CC, filename);
+                apc_debug("apc failed to locate %s - bailing" TSRMLS_CC, filename);
                 goto cleanup;
             }
 
             if(!realpath(fileinfo->fullpath, APCG(canon_path))) {
-                apc_warning("realpath failed to canonicalize %s - bailing" TSRMLS_CC, filename);
+                apc_debug("realpath failed to canonicalize %s - bailing" TSRMLS_CC, filename);
                 goto cleanup;
             }
 [2010-11-29 03:00 UTC] webmaster_apc at colnect dot com
This APC "feature" is also breaking phpBB which uses relative paths. As I understand, when stat="0" it means APC doesn't try to check file existence again so the performance gain from this "feature" is completely irrelevant and it being not backward compatible makes it a BUG. 
Is it going to be fixed any time soon? I see it's open for nearly a month.
 [2010-12-01 04:30 UTC] gopalv@php.net
apc.stat = 0 doesn't work with relative paths.

If it is a relative path, it does a stat().

It used to do a stat() for every path in the include_path, which was destroying the purpose of using no-stat in the first place.

for reference 

include_once("foo.php");

with include_path = /usr/share/php:/usr/lib/php/:.

does

lstat("/usr/share/php/foo.php"); // if that fails
lstat("/usr/lib/php/foo.php"); // if that fails
getcwd();
lstat("/var/www/html/foo.php");
lstat("/var");
lstat("/var/www");
lstat("/var/www/html");
open("/var/www/html/foo.php");

It no longer does any of the stat calls (or a realpath()), to look for a file. And that's not a bug.

Remember, it *never* used to work right. Now it throws a warning about it not working, so that you can go fix the code.
 [2010-12-19 07:24 UTC] webmaster_apc at colnect dot com
While I understand your answer it's still BREAKING backward comparability. Previously, if some paths were relative and some absolute, using apc.stat=0 would mean it'll work great for the files with absolute paths. For relative paths, as you say, it still did stat. Altogether, the system responded well and it did LESS stat calls where it could.

As some PHP code CANNOT BE CHANGED (third party and such - see my http://www.phpbb.com/community/viewtopic.php?f=46&t=2112260&p=12919262#p12919262 ), the result of this change is that I'm forced to use apc.stat=1 even though previously most relevant files enjoyed my use of apc.stat=0

I suggest to add another mode apc.stat=2 which will react the way you've changed to. You can make it the default in apc.ini
However, currently, you were simply BREAKING compatibility and hurting overall system performance.

Thanks
 [2010-12-26 11:18 UTC] john at feurix dot com
Please reconsider the previous suggestion to keep supporting a lazy stat (even if this was not initially intended and is considered a bug today):

If apc.stat=2 (or call it apc.lazy_stat), then skip stat for absolute paths, and _try_ to skip stat for relative paths. If the latter fails, fall back to stat.

Educating the world to use absolute paths all the time is kind of ignorant. It isn't going to happen. Thank you!
 [2010-12-26 13:18 UTC] gopalv@php.net
Actually, that's exactly what it does right now.

apc.stat=0 is not intended to work for all cases, it's designed to be fast for the people who do write code for it.
 [2011-01-16 04:33 UTC] webmaster_apc2 at colnect dot com
While I can easily adjust my code, it becomes much harder to do that for third party code such as the aforementioned phpBB. Not being backward compatible is something that always has to be considered seriously. In this case, there's no need not to be backward compatible as you can add the "fix" in a way that doesn't damage existing code. PLEASE fix it.
 [2011-01-21 11:59 UTC] aaron dot cicali at gmail dot com
I use a 3rd party PHP framework and using stat=0 breaks all 
over.  I would also like to add my request for a third state 
of this parameter for backwards compatibility.  Thanks.
 [2011-02-28 19:01 UTC] passby at gmail dot com
After upgraded PHP to 5.2, I have the same relative path issue of APC.

Then I ran across another thread about this and people mentioning to set apc.canonicalize=1. From what I observed the speed did increase a lot and the issue seems to be resolved.
 [2011-11-16 01:24 UTC] webmaster_apc at colnect dot com
This is stuck on wontfix but seems that I can now do stat="0" again. Currently with v3.1.7 of APC and all seems to be responding well.
 [2012-06-22 21:06 UTC] denis_truffaut at hotmail dot com
Same bug with PHP 5.4 and APC 3.1.9
 [2012-09-28 00:30 UTC] stas@php.net
it definitely looks like a bug. aps.stat worked with relative paths before, and whatever was the 
secret intent behind it, the usage pattern clearly indicates that people are using it with relative 
paths and apc.stat=0 in a lot of cases. It also doesn't make sense to have option that makes code 
work in plain PHP and fail in APC just because option saying "don't stat files each time" gets 
turned on. This makes this option effectively useless since it will break a lot of apps.

Moreover, I see no particular reason to do this since PHP has realpath cache, that can be used to 
store and cache path resolutions. But even if PHP did not, it should be different option or 
different value of an option. 

BC is a very important principle in PHP. Please seriously consider following BC and making new APC 
versions not break applications.
 [2012-09-28 00:30 UTC] stas@php.net
-Status: Wont fix +Status: Open -PHP Version: Irrelevant +PHP Version: 5.4
 [2012-09-28 00:39 UTC] stas@php.net
-Assigned To: +Assigned To: gopalv
 [2012-09-28 05:56 UTC] pajoye@php.net
Pls try a snapshot or latest release, afair something was done in this area.
 [2012-09-28 05:56 UTC] pajoye@php.net
-Status: Assigned +Status: Feedback
 [2013-01-02 04:00 UTC] stas@php.net
-Status: Feedback +Status: Closed
 [2013-01-02 04:00 UTC] stas@php.net
APC 3.1.14-dev displays 42! for me with given code, no errors. So unless there are 
any news about it, I think this can be closed.
 [2013-01-24 16:11 UTC] 661645 at gmail dot com
I am using apc 3.1.14.
When I call php from cli I'm receiving Warning.

# php -v
PHP 5.3.2-1ubuntu4.11 with Suhosin-Patch (cli)

# php
PHP Warning:  Unknown: apc failed to locate - - bailing in Unknown on line 0

Is this bug? How can i fix it?
 [2013-01-25 09:36 UTC] pierre at archlinux dot de
This might indeed be fixed; at least I no longer see a warning. I am using PHP 5.4.11 (not patched) and APC 3.1.14.I tested with FPM and the internal server on Arch Linux x86_64.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 10:01:28 2024 UTC