Re: Rethink CS for require_once?

From: Date: Wed, 01 Dec 2004 08:02:32 +0000
Subject: Re: Rethink CS for require_once?
References: 1 2  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-34681@lists.php.net to get a copy of this message
Alan Knowles wrote:
The key reasons are pointed out here - and followed through on various posts. http://marc.theaimsgroup.com/?l=pear-dev&m=103549252630540&w=2 Regards Alan
I'm not proposing what was proposed in these posts. None of the problems that are raised would exist. Why? There would be no change to any user scripts. People would not do require_once dirname(__FILE__) . 'DB.php'; DB.php would be included once. Once the DB.php is included, it includes any native files relative to __FILE__. Users who wish custom drivers would simply use the manual method of including drivers, as I said, that Log or PEAR_Command uses. Having automatic inclusion of files that were not distributed with a package can only lead to difficult bugs. Let's look at specific examples: include_path is ".:/path1/pear:/path2/pear" /path1/pear/DB is version 1.6.0 /path2/pear/DB is version 1.6.8 let's say the user wishes to use features of DB 1.6.8 that did not exist in 1.6.0. if the user runs require_once 'DB.php'; $blah = &DB::factory('cooldb'); the current implementation tries to include 'DB/cooldb.php' - which succeeds. However, the internals of DB have changed to fix some bugs, and cooldb relies on this. Meanwhile, the user is experiencing bewildering bugs and even Dan is stumped. Now, with the new format, this code does not work at all. factory correctly returns a PEAR_Error, and the user has no ambiguity about where the problem is - there is no cooldb driver. There is no chance of accidental double inclusion as long as all internal files are included through the single global object. In other words, any helper classes must be included through factory or singleton methods for this to work. Also, if there is any chance that the user might want to directly include the file without the parent file, then it can no longer be included using the dirname(__FILE__) because it is no longer internal. In fact, because DB recommends doing either DB::factory or instantiating with require_once 'DB/mysql.php', for instance, it would not be eligible to make this switch unless the API changed. Packages like PEAR_PackageFileManager, however, would be perfect candidates, because the users are expected to never directly include internal classes for retrieving file information, but can specify a custom path for including files. However, the PEAR_Common class, which is used by PEAR_PackageFileManager, would still be included as 'PEAR/Common.php', and inside PEAR itself it would be included like that because it exposes a public interface for reuse. Most importantly, Stig's example of two years ago doesn't apply to what I'm talking about - only private, internal files can use the dirname(__FILE__) approach in my proposal. By definition, they cannot be included more than once as the parent class will be doing the inclusion, and it is fettered by a relative inclusion (require_once 'DB.php' will never be overridden). if class Foo can be included and instantiated without any helper classes, then it is by definition a class of type (2) and must be included with require_once 'relative/path.php'; In any case, it's worth consideration, because it will mean that packages that expose a single class/file and distribute many other private files as drivers to split up functionality can include them in a much more robust and efficient manner. Again, there are a number of places where dirname(__FILE__) is already used in PEAR packages, and has been for years, I'm just attempting to codify when this is OK. Greg

« previous php.pear.dev (#34681) next »