Lars Strojny wrote:
Hi Greg,

Am Freitag, den 28.03.2008, 17:13 -0500 schrieb Greg Beaver:
[...]
In addition, this would mean that offsetGet() would have to create a directory. Why?

$phar['full']['path']['to']['file'] = 'hi' calls offsetGet() with 'full', 'path', and 'to', and offsetSet() only with 'file'.

I know that and I discussed that with Marcus beforehand. I don't think
that implicitly creating the directory is much an issue. If somebody
does not want that, he can just use isset() before.

Hi Lars,

If one uses file_put_contents('/path/to/this/file', 'hi') and '/path/to/this' does not exist, there is an error. The same is true of fopen, regardless of mode. mkdir() even fails unless the recursive parameter is explicitly specified. I do not think that this behavior should be different in ext/phar, especially because all that is needed is to create 1 directory (full/path/to/) and add the file.

Incidentally, you cut out the portion of my objections that related to the creation of many unnecessary entries in the phar archive. It is important to understand that every unnecessary entry in a phar archive causes phar to do extra processing on loadup, which ultimately increases the latency (this will be true until we implement caching of phar manifests, which will be relatively easy to do, I think). In addition, the performance of:

$phar['long/path/to/subdir/file'] = 'hi';

compared to:

$phar['long']['path']['to']['subdir']['file'] = 'hi';

is significantly slower. Each [] results in a call to offsetGet and instantiation of a new PharFileInfo object plus the final offsetSet call.

In other words, the proposed change is much more complex, introduces magic and counterintuitive behavior inside the extension. For instance, let's say we have this code:

<?php
$a = $phar['dir'];
$b = $phar['dri']; // typo
?>

if phar.readonly=1, the second line would throw an exception for attempting to create the directory "dri"

Wouldn't the second line throw an exeception anyway because the index is
not defined? And: can't offsetGet() check weither Phar::canWrite() is
true?

Yes, but if you're attempting to access the "dir" directory, an intuitive exception would be "dri not found" instead of "write access is disabled, cannot create dri directory." If I got the write access error, I would report a bug, since I was not trying to write anything.

What about this?

<?php
unset($phar['dri']); // dri doesn't exist
?>

The above code would first create the dri directory, and then erase it.

No, it would not. Please take a look at
http://lars.schokokeks.org/php/phar.phps and
http://lars.schokokeks.org/php/phar.php

You're right, chock this up to jet lag on my part. :)

In other words, the proposed syntax is not a good idea.

Two of three assumptions were not correct or at least arguable, so I
can't agree that easily.

Only 1 was incorrect, but my objection still holds on a fundamental level: offsetGet() should not attempt to write anything.

However, let's examine the feature from another perspective - I think it could be useful as a read access method, for several reasons:

1) foreach($phar as $name => $file)

This construct does not iterate over every file in the phar archive, but instead iterates over only those files in the top-most directory. If a directory returned implemented ArrayAccess and Iterator, one could treat it like a phar object. Currently this isn't possible. This means ultimately one should be able to do:

foreach($phar['subdir'] as $name => $file)

or

foreach($phar['subdir/anothersubdir'] as $name => $file)

or

foreach($phar['subdir']['anothersubdir'] as $name => $file)

2) Some might find it easier to do something like:

$phar['subdir/with/really/long/path/file1.txt'] = 'a';
$subdir = $phar['subdir/with/really/long/path'];
$subdir['file2.txt'] = 'a';
$subdir['file3.txt'] = 'a';

Incidentally, if you want to know a *real* hack in the implementation of ArrayAccess, you can make a directory now with this code:

$phar['subdir/with/really/long/path/'] = 0;

Needless to say, that probably should be removed as an option :).

Could you live with $phar['this']['thing'] as a read access API (offsetGet only)?

2) Names must be very carefully considered in relation to existing APIs and the pre-existing methods.

Phar::create(), for instance, should be named buildFromDirectory() to match buildFromIterator().

I agree, that this name is much better.

what benefit is there in adding complexity of remembering the Phar::GZ constant over setCompressedGZ()? We have to think hard about changes like this.

setCompressedGZ() is just not the way object oriented APIs should
behave, as it taints the API with concrete implementation details
("there can be gzip compression and every compression algorithm is
exposed" opposed to "there can be compression, one variant is gzip").
Phar::compress() indicates that "the archive can be compressed" with the
concrete algorithm as a parameter. What about in 5 years when a new,
free compression algorithm rises, which fixes the problems of bzip2.
Would you like to add another setCompressedFooBar() or just add the
algorithm and the class constant and be fine?
If you insist on setCompressedFoo(), I would at least propose to not
implement that as a setter but to describe the attached behaviour, which
would be Phar::compressWithGzip() or something like that. Nevertheless,
please seriously consider to do it with a single compress()-method.

As I was trying to say in the portion you quoted below, Phar::compress() is already used to compress the entire archive, and should not be overloaded. I would be happy with these method names:

Phar::compressArchive() /* Steph hated this when I originally proposed it, perhaps she's changed her mind? */
Phar::compressAllFiles()
Phar::uncompressArchive()
Phar::uncompressAllFiles()

If I need to explain what the two methods do, then we need to choose new names, could you react to these names and let me know what you think they would do?

3) I would like to suggest these changes, and these alone:

* simplify all compression methods, with more consistency of naming that clearly differentiates between compressing files within an archive, and compressing the entire archive. This abstract idea is more important to me than the specific naming, but it should be very easy to do.

What would be your concrete proposal regarding that?
[...]

See above.

Lars, I also think it might help to understand my reaction better that we've been publicly discussing the API of compression and other phar-related issues on pecl-dev for a while, with no feedback. To suddenly see an RFC with major changes without having even been notified was annoying, I hope that in the future you will at least contact the leads of the project you are proposing changes for so that minor disagreements can be worked out in private. I always relish improvements, Steph can attest to both my flaws and my talents in this regard (I believe you witnessed a rough patch on IRC one day...), and also the satisfaction in the ultimate result, so I hope we will find our right working interaction from here forward. :)

Do you want to take a crack at a patch for any of these API features once they are worked out (buildFromDirectory should be an easy one, if you would like to start there)?

Thanks,
Greg

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to