Re: Silenced include(_once) calls
| From: | Justin Patrin | Date: | Fri, 03 Mar 2006 17:38:01 +0000 |
| Subject: | Re: Silenced include(_once) calls | ||
| References: | 1 2 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-41622@lists.php.net to get a copy of this message | ||
On 3/3/06, Lukas Smith <lsmith@php.net> wrote:
> Justin Patrin wrote:
>
> We have talked about this on multiple occations. My opinion is that you
> can silence errors as long as you handle them accordingly.
>
> > There are several alternatives to silencing include:
> > 1) Leave it as-is but without @. This will cause PHP to display errors
> > when files can't be found, but this is in general something that the
> > developer wanted to see anyway. Remember that production websites
> > should normally have error_reporting turned off and output to a file
> > so that the user doesn't see it.
>
> Sure but what if the include is expected to fail under certain
> conditions? Like with optional modules. So this is not a 1 size fits all
> solution. So lets look at the next solutions.
>
Obviously, which is why I included the other 2.
> > 2) Split the include_path and check file_exists and is_readable for
> > the file for each path. This is a solution which adds some extra
> > cycles to the include process but allows the application to gracefully
> > return an error when a file is not includable without a PHP error
> > getting triggered.
>
> Aside from race conditions, which I consider to be irrelevant,
> file_exists cannot check the include path. This is why I have introduced
> a custom fileExists() into MDB2 and LiveUser. A patch provided to
> internals to extend file_exists() was dismissed.
>
Well, yes, which is why I said you have to loop over the include_path.
> file_exists() also does not play well with safe_mode apparently
> (http://pear.php.net/bugs/bug.php?id=6226) so I tried to work around
> optional includes as much as possible by letting users explicitly tell
> me if they have a given optional dependency installed.
>
Actually, that user said that the problem was PHP's function
is_readable() which is used in your implementation of file_exists.
Perhaps if you simply removed the is_readable check it would work with
safe_mode?
> > 3) Use @fopen($file, 'r', true). This is faster than #2 and still
> > checks the include_path. This also does a check for readability in one
> > call. This does use @, but in this case it has no horrible
> > side-effects, such as the script dying. There are a few side-effects
> > in that a registered PHP error handler will catch errors from this,
> > but that is not likely to hurt an application in any way. This
> > solution also allows an application to gracefully return an error
> > without PHP errors being displayed.
>
> fopen() is not a good idea. I talked to Wez about this several years
> back. It creates locking issues or something like that. I do not
> remember the details.
Ok. I'd never heard of fopen's include_path parameter before a few
days ago and I was very surprised to find that it had one. If it's not
for this type of thing....that what the heck is it for?? Could you
find your e-mails about the locking? The code I would propose in this
case is basically:
$fp = @fopen($file, 'r', true);
if ($fp === false) {
return PEAR::raiseError('Could not find file '.$file.' in include_path');
}
fclose($fp);
include_once($file);
If that causes locking issues then I suspect a bug in PHP... I know
that others are using this code in their own projects with no problems
(such as Paul M Jones' Solar).
>
> So to conclude:
> Internals has decided to totally ignore the idea of dynamic includes.
> Which makes the existance of include[_once] so laughable. Whenever
> anyone has brought up the limitations they were laughed at. Even
> solutions already implemented in C were ignored. Pisses me off whenever
> I think about it.
Yep. PHP *should* support this intrinsically. However it seemed to me
that this is what the include_path option for fopen is for....
>
> So the solution I have taken is:
> - use file_exists() and iterate over the include path setting
> - let users explicitly specify if they match an optional dependency
> - do not silence includes when the debug option is set
>
> Have a look at MDB2.php if you want to see how I did things.
>
Despite all that I still think that silencing include_once is bad idea
for all of the reasons that I listed. Having it not silenced if debug
is set to true is nice...but if you don't need to see these warnings
and such you should have error_reporting set not to display anything
anyway (in which case silencing does essentially nothing).
--
Justin Patrin