exploring include_path options for pecl/phar
| From: | Gregory Beaver | Date: | Tue, 04 Mar 2008 05:08:56 +0000 |
| Subject: | exploring include_path options for pecl/phar | ||
| Groups: | php.pecl.dev | ||
| Request: | Send a blank email to pecl-dev+get-5155@lists.php.net to get a copy of this message | ||
Hi,
I've been musing and coding a lot of solutions to include_path issues
that exist in a pharred application, and while driving today I think I
may have found a much better solution to the problems. However, it's
complex enough I would like to run it by you folks to make sure I'm
really thinking of all the angles.
First, a description of the problem:
Most PHP applications assume 2 things:
1) current working directory is the directory of the calling script, and
can be used to include files relative to cwd
2) include_path can be used to include junk
Without special changes, both of these assumptions break down inside a
stream wrapper. The cwd is actually the path to the phar archive, and
not to the executing script inside the phar archive. Because stream
wrappers contain ":" they can't be used on unix inside include_path.
The current CVS of pecl/phar has some simple magic for resolving the cwd
problem, we simply store the current "working directory" of the entry
path into the phar archive and use it when called for in an include or
file-related statement, and fall through to the operating system if not
found. The include_path problem is much harder to solve. I had
designed a complex auto-mounting system, the details I won't go into,
but the magic is too black for my tastes.
As an example of the kind of application that needs to work as a pharred
application, Stas has crafted a simple Zend Framework-based app that
contains the minimal stuff you need to run a "Hello World" of sorts.
The phar does *not* contain Zend Framework, only the application files.
As such, the way this app works is it sets include_path to several paths
relative to cwd. The phar archive then makes a call out to the ZF code
outside the phar archive, which attempts to locate code using
include_path. Phar's magic is currently only executed while inside the
phar archive. Unfortunately, this breaks down when external code tries
to locate code inside a phar.
There are a number of ways of solving this:
1) always intercept calls to cwd if the code originated inside a phar
archive
This will only work if the first executed script is the phar archive,
and not if the phar contains library code, so I quickly threw this
option out.
2) allow adding phar archives to include_path and explicitly search for
code using this.
This option is the one I explored in my drive. The catch here is that
there needs to be a way to specify a stream wrapper path inside
include_path. There are a couple of ways of doing this:
2a) allow putting the full path to phar archives in include_path
as suggested by Markus Fischer, this would make pecl/phar search inside
the phar archive for files. However, this won't solve the problem in
the sample ZF app, as it actually adds 3 separate paths inside the phar
to look for files. A possible solution would be to specify a search
path inside the phar archive that is searched, but this results in 2
separate include_paths and quickly becomes unmaintainable.
2b) design a more intelligent include_path parser that recognizes phar
stream wrappers
this would almost completely solve the problem, as it would then allow
putting full phar:// stream paths inside include_path. No changes would
need to be made to the PHP code, as interception of include_path-related
stuff would happen inside pecl/phar.
Can anyone think of a problem with 2b? I can't think of any and it is
really ridiculously simple, but my intuition is nagging me that I am
missing something that is a problem with this approach.
Thanks for any feedback on this one, it's a hugely important problem to
solve, and once I find the correct magic bullet, it will make phar much
more versatile, as it will allow seamless interaction between phar-based
apps and library code or regular apps and phar-based libraries simply by
setting include_path or something equally intuitive.
Greg