Extract zip to server and upload the files to the node? 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-&gt;filename;
$original = file_unmanaged_copy($file-&gt;uri, 'public://work', FILE_EXISTS_REPLACE);
file_unmanaged_delete($file-&gt;uri);
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-&gt;uri);


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

    $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote('png gif jpg jpeg tif tiff html')) . ')$/i';
    if (preg_match($regex, $xt) and ($list[$i]['size'] &lt; 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-&gt;filename = $f_name.".".$xt;
            $file-&gt;uri = $f_name.".".$xt;
            echo "Yes: ".$f_name.".".$xt;
            $preview = true;
        }
    }

    if(is_null($error))
    {
            $to_extract = $GLOBALS['_SERVER']['DOCUMENT_ROOT'] . '/' . drupal_get_path('module', 'some') . '/testing/';
            $ar = $zip-&gt;extract(PCLZIP_OPT_PATH, $to_extract);
            $file-&gt;filename = $ar-&gt;filename;
            $file-&gt;uri = $ar-&gt;filename;

        }
}
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' =&gt; $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-&gt;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)) {
    file_unmanaged_delete_recursive($extract_location);
  }

  $archiver-&gt;extract($directory);


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.