Re: Rethink CS for require_once?
| From: | Alan Knowles | Date: | Wed, 01 Dec 2004 06:55:13 +0000 |
| Subject: | Re: Rethink CS for require_once? | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-34680@lists.php.net to get a copy of this message | ||
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
Greg Beaver wrote:
Hi, I would like to suggest a simple and compelling change into the CS for require_once in PEAR packages. Currently, all internal inclusion of PEAR files must be done like require_once 'Relative/Package/FilePath.php'; I'd like to revisit this CS and split it into two kinds of includes: 1) inclusion of internal package files 2) inclusion of external package files definitions: 1) internal package files drivers internal extensions (PEAR_Command commands, PEAR_PackageFile_v1 any internal file that must not be changed (can be considered final) 2) external package files *any* file that is not in the package.xml any internal file that can be user-customized So, the new standard would be: for (1) use dirname(__FILE__) for absolute inclusion require_once dirname(__FILE__) . '/Foo/Driver.php'; This means that any supporting files must be included by parents. This hypothetical include from Foo/Driver.php would not be allowed: require_once dirname(dirname(__FILE__)) . '/Foo.php'; and would instead have to be included in the relative manner require_once 'Foo.php'; To be clear: the ONLY new syntax allowed would be including deeper files from Foo.php require_once dirname(__FILE__) . '/Foo/Driver.php'; require_once dirname(__FILE__) . '/Foo_Unserializer.php'; from Foo/Driver.php require_once dirname(__FILE__) . '/Driver/Subhelper.php'; require_once 'Foo_Unserializer.php'; no funny business like require_once dirname(__FILE__) . '../FooUnserializer.php'; would be allowed either. for (2) use the old way require_once 'Relative/Path/To/File.php'; Why? 1) errors caused by include_path go bye-bye phpDocumentor has run into trouble when the include_path has a version installed by PEAR after a version that is downloaded from sourceforge, mainly because of the unnecessary use of relative includes. In addition it enforces better design. If you are extending DB_mysql and putting it in /path/to/home/DB/mysql.php, where PEAR is in /usr/local/pear/DB/mysql.php, and you use include_path ".:/path/to/home/:/usr/local/pear" it can lead to sudden breakage caused by upgrading the server version, and very difficult bugs to trace. In addition, how many times have people suddenly gotten messages like: "undefined function fetchRow()" when they define a file named "DB.php" in the . directory? Anyone who wants to override Foo::factory() can either extend Foo, or Foo could follow the path offered by Log, and attempt to include user-designed drivers from a specific path first, and then from local directories. 2) it opens up unique possibilities with Davey's new package and other yet-uncoded solutions. require_once dirname(__FILE__) . '/DB/mysql.php'; will include 'phar://DB-1.6.8.phar/DB/mysql.php' if DB.php is __FILE__ and it was included with require_once 'phar://DB-1.6.8.phar/DB.php'; 3) performance is notably faster with absolute paths at script startup, although this is a distant third. I'm most concerned with keeping the include_path cleaner for internal files. This also makes include_path less of an issue for packages extracted into a non-PEAR environment which is *always* a good thing. For an example of clean require_once, check out Harry Fueck's Calendar code, which raised some flack when he proposed it. Also, check out the internal driver inclusion of PEAR's own PEAR_Command (uses dirname(__FILE__) unless the user specifies a directory where commands reside). Greg