Skip to main content
Home
GrN.dk

Main navigation

  • Articles
  • Cases
  • Services
  • Your Digital Project Manager
  • About Greg Nowak
  • Image Gallery
  • Contact
User account menu
  • Log in

Join my community / free newsletter — sign up here

Breadcrumb

  1. Home

Unzip with PHP on Shared Hosting: A Safer Way to Extract ZIP Files

Illustrated infographic summarizing: Unzip with PHP on Shared Hosting: A Safer Way to Extract ZIP Files

By Greg Nowak. Updated 5 August 2026.

Uploading one ZIP archive can be much faster than transferring thousands of small files over FTP. On shared hosting without SSH or a reliable file manager, extracting that archive with PHP may be the most practical deployment option.

It should still be treated as a controlled maintenance operation. A ZIP can contain unsafe paths, consume far more disk space than its compressed size suggests, or overwrite files if you extract it directly over the live site. The safer pattern is to inspect the archive, impose limits, extract into a new release directory and remove every temporary tool afterwards.

Use ZipArchive as the default

PHP’s ZipArchive class is preferable to a general-purpose browser unzipper. It comes from PHP’s ZIP extension, has a small API and lets you inspect every entry before extraction.

The example below adds three controls often missing from quick snippets: consistency checking, validation of stored paths and limits on the number and uncompressed size of entries. Adjust the limits for your release, but do not simply remove them.

<?php
$archive = __DIR__ . '/site-release.zip';
$target = __DIR__ . '/releases/2026-08-05';
$maxFiles = 2000;
$maxBytes = 200 * 1024 * 1024; // 200 MB after extraction

if (!class_exists('ZipArchive')) {
    exit('ZIP support is not enabled on this host.');
}

if (!is_file($archive)) {
    exit('Archive not found.');
}

if (file_exists($target)) {
    exit('Target already exists. Use a new release directory.');
}

$zip = new ZipArchive();
$result = $zip->open(
    $archive,
    ZipArchive::RDONLY | ZipArchive::CHECKCONS
);

if ($result !== true) {
    exit('Could not open ZIP archive. Error code: ' . $result);
}

if ($zip->numFiles > $maxFiles) {
    $zip->close();
    exit('Archive contains too many entries.');
}

$totalBytes = 0;

for ($i = 0; $i < $zip->numFiles; $i++) {
    $stat = $zip->statIndex($i);

    if ($stat === false) {
        $zip->close();
        exit('Could not inspect an archive entry.');
    }

    $path = str_replace('\\', '/', $stat['name']);
    $unsafe = $path === ''
        || strpos($path, "\0") !== false
        || $path[0] === '/'
        || preg_match('#(^|/)\.\.(/|$)#', $path)
        || preg_match('#^[A-Za-z]:/#', $path);

    if ($unsafe) {
        $zip->close();
        exit('Unsafe path found in archive.');
    }

    $totalBytes += (int) $stat['size'];

    if ($totalBytes > $maxBytes) {
        $zip->close();
        exit('Archive exceeds the extraction size limit.');
    }
}

if (!mkdir($target, 0755, true)) {
    $zip->close();
    exit('Could not create the release directory.');
}

$oldUmask = umask(0022);
$extracted = $zip->extractTo($target);
umask($oldUmask);
$zip->close();

if (!$extracted) {
    exit('Extraction failed. Remove the partial release before retrying.');
}

echo 'Archive extracted into the new release directory.';

The path test rejects parent-directory references, absolute paths and Windows drive paths. The size calculation uses metadata returned by statIndex(), so a highly compressed archive cannot quietly expand without meeting the configured limit. These checks reduce risk; they do not make an untrusted upload safe. Only deploy archives produced or reviewed by your team.

Check the hosting environment first

With command-line access, confirm that the extension is loaded:

php -m | grep -i zip

Without SSH, use the hosting panel’s PHP-extension screen or temporarily run var_dump(class_exists('ZipArchive'));. Delete that diagnostic file as soon as you have the answer.

PHP’s current documentation says Linux builds require ZIP support and Windows installations from PHP 8.2 onward must enable php_zip.dll in php.ini. As of August 2026, PHP 8.2 through 8.5 remain supported, although 8.2 receives security fixes only and reaches end of life on 31 December 2026. An older PHP version is a platform problem, not a reason to find an older unzip script.

Hosting situation Recommended approach Main control
File manager can extract ZIPs Use the hosting panel Extract into a new release folder
PHP works, but there is no SSH Use a temporary ZipArchive helper Password-protect the maintenance URL
ZIP extension is unavailable Ask the host to enable it or extract for you Do not install an unknown fallback script
Deployments are frequent or business-critical Introduce a repeatable release process Document validation, activation and rollback
A decision matrix for ZIP extraction on constrained shared hosting.

Protect the browser endpoint

If PHP must be triggered through a browser, an unusual filename is not access control. Protect the maintenance directory using the hosting panel’s password feature or an IP restriction. If the host offers neither, ask support to perform the extraction or use its file manager rather than leaving a public deployment endpoint online.

A third-party browser unzipper may look convenient, but it usually exposes more functions and input choices than this job requires. If one is unavoidable, review its current code and maintenance status, protect access, use it once and delete it immediately. Do not leave it installed “for next time.”

Extract beside the live site, not over it

Package the release locally and inspect its top-level structure before upload. A common mistake is adding an unnecessary parent folder, producing release/site-release/index.php instead of release/index.php.

After server-side extraction, check the expected entry point, configuration strategy and writable directories. Keep uploads, generated files, secrets and environment-specific configuration outside the replaceable package wherever possible. Then activate the new release using the safest mechanism the host supports.

Before switching, retain the previous working release. After switching, test the homepage, one important user journey, forms or checkout where applicable, and the error log. If validation fails, restore the previous release rather than repairing a half-deployed site in place.

Finish with cleanup

Delete the ZIP archive, extraction script and any partially extracted directory. Remove temporary password rules if they are no longer needed, but keep a short deployment note recording the package, destination and checks performed.

If ZIP uploads have become a regular operational ritual, the real improvement is a modest release workflow with named owners, pre-flight checks and a rehearsed rollback. Greg can help shape that process around the limits of your hosting without turning a small website into an infrastructure project.

Related on GrN.dk

  • Debugging WordPress on a Live Site: A Safer Workflow
  • WP-CLI for Faster, Safer WordPress Operations
  • Before Your Website AI Bot Goes Live: Prompt-Injection Controls for Chat and Lead Capture

Need help with this kind of work?

Discuss a safer website deployment workflow Get in touch with Greg.

Sources

  • PHP Manual: ZipArchive::open
  • PHP Manual: ZipArchive::extractTo
  • PHP Manual: ZipArchive::statIndex
  • PHP Manual: ZIP Extension Installation
  • PHP Supported Versions
Last modified
2026-08-05

Tags

  • php
  • ZIP Archives
  • Shared Hosting
  • FTP Deployment
  • Website Operations
  • Log in to post comments

Review Greg on Google

Greg Nowak Google Reviews

 

Written recommendations from Trafik og Veje, Aarhus Municipality (2011) and AgroTech (2010) — read them on LinkedIn.

Illustrated infographic summarizing: What Are Customers Asking? Let AI Find the Patterns in Support Tickets
What Are Customers Asking? Let AI Find the Patterns in Support Tickets
2026-09-04

AI-based ticket analysis can uncover recurring complaints, product defects and gaps in documentation—without the company needing yet another chatbot.

Illustrated infographic summarizing: OpenAI Has Machine Identity Now. Which Jobs Should Lose API Keys?
OpenAI Has Machine Identity Now. Which Jobs Should Lose API Keys?
2026-09-03

OpenAI’s X.509 workload identity can replace API keys for the right workloads. This practical framework helps teams decide where to start safely.

Illustrated infographic summarizing: WordPress 7.1 Exposes AI-Ready Actions. Who Gets to Run Them?
WordPress 7.1 Exposes AI-Ready Actions. Who Gets to Run Them?
2026-09-02

WordPress 7.1 helps AI agents discover and invoke site abilities. Here is how to keep exposure, authentication and permission firmly separate.

Illustrated infographic summarizing: From Sales Meeting to CRM: Automate Follow-Up Without Compromising Data Quality
From Sales Meeting to CRM: Automate Follow-Up Without Compromising Data Quality
2026-09-01

How to use AI for meeting notes and follow-up while fixed rules protect CRM data, customer matching and the sales pipeline from errors and premature changes.

Illustrated infographic summarizing: Your AI Gateway Can Name the User. Decide What That Log Is For
Your AI Gateway Can Name the User. Decide What That Log Is For
2026-08-31

Identity-aware AI Gateway logs can sharpen security and cost control, but only when attribution, access, retention, guardrails, and response are clearly defined.

Illustrated infographic summarizing: Zero Data Retention Is a Workflow Audit, Not a Checkbox
Zero Data Retention Is a Workflow Audit, Not a Checkbox
2026-08-30

Zero Data Retention covers the provider, not every copy in your stack. See how to audit endpoints, logs, storage, deletion and project-level controls.

Illustrated infographic summarizing: MCP 2026-07-28 Is an Auth Migration, Not a Version Bump
MCP 2026-07-28 Is an Auth Migration, Not a Version Bump
2026-08-29

MCP’s July 2026 release removes protocol sessions and tightens OAuth. Here’s a practical plan for migrating clients, servers and enterprise access safely.

Illustrated infographic summarizing: Turn a Technician’s Voice Note into a Work Order—Not Raw Audio
Turn a Technician’s Voice Note into a Work Order—Not Raw Audio
2026-08-28

Voice input can reduce the technician’s documentation burden when hours, materials and status are validated before the information is saved in the work order system.

Illustrated infographic summarizing: ChatGPT Disabled Personal Knowledge Sync. What Broke on Your Team?
ChatGPT Disabled Personal Knowledge Sync. What Broke on Your Team?
2026-08-27

ChatGPT retired personal sync connections for Enterprise and Edu. Here is how to find affected workflows, migrate access, and test permissions.

Illustrated infographic summarizing: Cloudflare’s September Bot Defaults Could Quietly Cut AI Visibility
Cloudflare’s September Bot Defaults Could Quietly Cut AI Visibility
2026-08-26

Cloudflare’s September bot defaults give publishers more control, but one training block could also cut search crawling and AI-driven discovery.

More articles

Built by AI — available for your business. The daily articles on this site are researched, written and illustrated by an autonomous AI pipeline. At nowa.dk I install the same kind of AI automation in businesses at fixed prices — site in Danish, English version here, and web/marketing agencies have a dedicated page.

RSS feed

Footer

  • All articles
  • Contact

GrN.dk — AI automation, web platforms, web optimization, data handling and logistics.

© 2026 GrN.dk · LinkedIn · Contact · AI automation in Danish: nowa.dk

Behind GrN.dk: Individual Entrepreneur Codecrafter · Tax ID 305669096 · Bakhtrioni St. 22, 0194 Tbilisi, Georgia · official business register