I allow users to upload zip files I extract, and look into them to see if they contain a .jpg file. I use that file to create a new node. The differences between the .jpg and the .zip file uploaded are that the first came as an object, while I don't know how I can take the second as an object.

I'm using the PclZip library.

This is part of the code I use when the uploaded file is a JPEG.

$file = $form_state['values']['file'];

$original_filename = $file->filename;
$original = file_unmanaged_copy($file->uri, 'public://work', FILE_EXISTS_REPLACE);
list($file, $tfile) = some_fileprep($original_filename);

This is the code I use when the file is a .zip file.

include $pclzip_lib.'pclzip.lib.php';
$zip = new PclZip($file->uri);

for ($i=0; $i<$total_files; $i++) {
    $file_name = $list[$i]['filename'];
    list($f_name,$xt) = explode('.', $file_name);

    $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote('png gif jpg jpeg tif tiff html')) . ')$/i';
    if (preg_match($regex, $xt) and ($list[$i]['size'] < 10000000)) {
        $error[] = "File with conflict: ".$file_name;
        if((($xt == 'png') or ($xt == 'gif') or ($xt == 'jpg') or ($xt == 'jpeg') or ($xt == 'tif') or ($xt == 'tiff')) and ($f_name == 'preview')){
            $file->filename = $f_name.".".$xt;
            $file->uri = $f_name.".".$xt;
            echo "Yes: ".$f_name.".".$xt;
            $preview = true;

            $to_extract = $GLOBALS['_SERVER']['DOCUMENT_ROOT'] . '/' . drupal_get_path('module', 'some') . '/testing/';
            $ar = $zip->extract(PCLZIP_OPT_PATH, $to_extract);
            $file->filename = $ar->filename;
            $file->uri = $ar->filename;

  • 1
    I'm not sure if I understand the problem and/or question here?
    – mpdonadio
    Jul 2, 2012 at 16:30
  • when you upload a jpg or a file, drupal take it as an object, so, I'm uploading a zip and I need to extract it, I put the files into the server and need to take one of this files like if it was uploaded by normal mode (as an object), how can I do that? (I'm from Argentina and my english isn't good, sry about the grammar) Jul 2, 2012 at 17:44
  • You should show some_fileprep()'s code.
    – apaderno
    Jul 2, 2012 at 18:16

2 Answers 2


When you successfully unzip a file you have the code:

        $to_extract = $GLOBALS['_SERVER']['DOCUMENT_ROOT'] . '/' . drupal_get_path('module', 'some') . '/testing/';
        $ar = $zip->extract(PCLZIP_OPT_PATH, $to_extract);
        $file->filename = $ar->filename;
        $file->uri = $ar->filename;

Once you've extracted the zip you have a $file object ... just save it using the drupal API such as:

$original = file_unmanaged_copy($file->uri, 'public://work', FILE_EXISTS_REPLACE);

  • Hi tenken, thanks for the answer, but when I make a var_dump($file->filename) or var_dump($file->uri) or var_dump($ar->filename) I get nulls, but the file was extracted, how can take it as an object? Jul 2, 2012 at 19:19

You can simply use file_unmanaged_save_data(), as in the following code, where $data is the content of the .jpeg file contained the .zip file.

file_unmanaged_save_data($data, 'public://work', FILE_EXISTS_REPLACE);

As side note, Drupal includes the ArchiverZip class, which should probably be used instead of the PclZip class. You don't normally deal with the class directly, but you use code similar to the following one, used by update_manager_archive_extract().

  $archiver = archiver_get_archiver($file);
  if (!$archiver) {
    throw new Exception(t('Cannot extract %file, not a valid archive.', array('%file' => $file)));

  // Remove the directory if it exists, otherwise it might contain a mixture of
  // old files mixed with the new files (e.g. in cases where files were removed
  // from a later release).
  $files = $archiver->listContents();

  // Unfortunately, we can only use the directory name to determine the project
  // name. Some archivers list the first file as the directory (i.e., MODULE/)
  // and others list an actual file (i.e., MODULE/README.TXT).
  $project = strtok($files[0], '/\\');

  $extract_location = $directory . '/' . $project;
  if (file_exists($extract_location)) {


archiver_get_archiver() uses drupal_realpath(); this means it is able to get the realpath of a file when its filename is using stream wrappers, such as public://archive.zip.

  • Hi kiamlaluno, Thanks for the answer, When I started with this, the first thing i tried to use was the ArchiverZip class, but unfortunately, I can't understand it at all, because when I read the documentation, this says something about edit the php.ini and I have no access to that file (Production server), so, the ArchiverZip was discarded immediately, but, I'll to make a new read about it, thanks. Jul 2, 2012 at 19:26
  • I don't have access to the php.ini file in my web server, but update_manager_archive_extract() works fine; in fact, I am updating the modules using the update manager, and it works. As far as I know, the Zip extension is normally enabled, in PHP 5.
    – apaderno
    Jul 2, 2012 at 20:07
  • Hello Again kiamlaluno, I'm trying to use ArchverZip as you says, but I'm getting an exception, this is the code (for now): $zip = new ArchiverZip($file->uri); Where $file->uri is the URI of the zipped file, and this is the exception I'm getting Exception: Cannot open <em class="placeholder">temporary://ahi_va_preview.zip</em> in ArchiverZip->__construct() (line 91 of /var/www/html/modules/system/system.archiver.inc). Some ideas about what I'm doing wrong? Jul 3, 2012 at 17:22
  • Check the process running PHP has the right file permissions on the directory used as directory for temporary files.
    – apaderno
    Jul 4, 2012 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.