Benjamin Schulz wrote:
Hi,
i just read the phar examples in the manual and found things like this:

$p = new Phar('coollibrary.phar');
if (Phar::canWrite()) {
    $fp = fopen('hugefile.dat', 'rb');
    $p['data/hugefile.dat'] = $fp;
    if (Phar::canCompress()) {
        $p['data/hugefile.dat']->setCompressedGZ();
    }
    $p['images/wow.jpg'] = file_get_contents('images/wow.jpg');
    $p['images/wow.jpg']->setMetaData(array('mime-type' => 'image/jpeg'));
    $p['index.php'] = file_get_contents('index.php');
}

First thing: yes i fully understand what the code is doing but i still think that it doesn't need to be so "hackish". One thing is that i think there is no point in using ArrayAccess here, in my oppinion ArrayAccess is great to hack stuff but it doesn't belong in such (maybe soon?) core functionality. The second thing that looks weird to me is that the setter (offsetSet) sets the file content but the getter (offsetGet) retrieves a file object. What about changing this into something more OO like this (just a proposal):

$p = new Phar('coollibrary.phar');

/* What about creating a non-static pendant to canWrite()?
Maybe there is an archive file that has only read permissions on the filesystem or phar will be able to generate readonly-archives later? (Might be interesting for companies that want to provide readonly and signed archives for the customers)

<snip example>

Some notes:

1) if you want to know writability without Phar::canWrite(), you can also use is_writeable('phar:///path/to/archive.phar/index.php') just like you can with any other file 2) ArrayAccess is a very natural way of viewing an archive - archives are a collection of files that can be accessed randomly, just like an associative array. As such, it can be viewed abstractly as an array of objects with attributes and methods (files with properties like compression, checksum, size, metadata, contents and operations to modify the file or query the contents). 3) Phar extends DirectoryIterator. As such, one needs to think of Phar as an enhanced DirectoryIterator. This comes with the benefits of DirectoryIterator (easy iteration, ability to iterate over a CSV file quite easily, ability to iterate over lines of the file easily) and its disadvantages (not designed for easy modification of the files or access to their contents). Fortunately, Marcus is a lead maintainer of both Phar and SPL, and so he has already fixed some of the missing pieces in SPL. 4) Phar does not force one-true-way of building the archive. The stream wrapper is fully enabled with write capabilities as well.

Let's take a look at the ways you can populate the contents of a phar archive:

1) file_put_contents('phar:///path/to/archive.phar/index.php', 'file contents'); 2) $phar = new Phar('/path/to/archive.phar'); $phar->buildFromIterator(new DirectoryIterator('/some/path'), '/some/path'); 3) $phar = new Phar('/path/to/archive.phar'); $phar['index.php'] = file_get_contents('/some/path/index.php');

There's plenty of flexibility here, and no need to be scared of the arrayaccess option.

I do agree that although I am perfectly comfortable with the current API, it may seem inconsistent to others who think the way you do to directly set contents that way when offsetGet() does not return the contents. However, the solution is quite simple, which is to make even clearer what operation we are doing:

$contents = $phar['index.php']->contents;
$phar['index.php']->contents = 'something';

This way, it is even clearer that the archive is an "array" of PharFileInfo objects. This would be very easy to implement and would not require removing the existing functionality.

I see no problem in adding an alias to offsetSet() called addFile() and another for addFromString() and a method for addEmptyDir(). In case it isn't obvious, I will not do this change unless it adheres to the existing ext/zip API to allow easy mental migration for developers between the two extensions, so don't even think about suggesting other possibilities, thank you :).

Also, as an important note, the only up-to-date manual is at http://docs.php.net/manual/en/book.phar.php and furthermore the manual is not yet completely updated to the 2.0 API, which is one of the reasons I marked phar alpha on release. None of the code you quoted, however, is out of date. Code that is out of date in the manual is in compressAllFiles*() and some of the coding examples use the old syntax. The changes missing from the manual are as follows:

1) compressAllFilesGZ() and compressAllFilesBZIP2() do nothing for tar-based archives, as there is no way to individually compress files in a tar archive. To compress an entire archive, use the new compress() method. Formerly, compressAllFilesGZ() changed a .tar to a .tar.gz. 2) convertToTar/convertToZip/convertToPhar() all return a Phar or a PharData object, allowing fluent interface niceness such as :

$phar = $phar->convertToTar()->compress(Phar::GZ);

Thanks for checking out phar.

Greg

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

Reply via email to