ویژگی تصویر

تابع zip_entry_name() در PHP

  /  PHP   /  تابع zip_entry_name() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع zip_entry_name() یکی از توابع پروسیژوال مرتبط با کار با فایل‌های فشرده ZIP در PHP است. این تابع نام (مسیر داخلی) یک ورودی داخل آرشیو ZIP را برمی‌گرداند. این مجموعه توابع (مثل zip_open, zip_read, zip_entry_read) گاهی در کدهای قدیمی دیده می‌شوند، اما در عمل توصیه می‌شود از کلاس ZipArchive استفاده شود که مدرن‌تر و قابل اعتمادتر است.

کاربرد اصلی

  • دریافت نام فایل/پوشه داخل آرشیو ZIP
  • استفاده در حلقه برای لیست کردن محتویات آرشیو
  • ترکیب با توابع دیگر برای خواندن یا استخراج فایل‌ها

مشخصات تابع

آرگوماننوعتوضیح
zip_entryresourceریسورس ورودی که از zip_read() دریافت می‌شود
مقدار بازگشتیstring | false
نام فایل (مسیر داخلی) یا false در صورت بروز خطا

نکات مهم

  • این توابع پروسیژوال مربوط به یک API قدیمی هستند؛ در پروژه‌های جدید ZipArchive توصیه می‌شود.
  • ممکن است در برخی نگارش‌های PHP تغییر وضعیت (deprecated یا removed) داشته باشند؛ بهتر است نسخه PHP سرور را بررسی کنید.
  • نام بازگردانده‌شده ممکن است شامل مسیر پوشه‌ها (مثلاً “folder/file.txt”) باشد؛ برای تشخیص پوشه می‌توان نامی که با / تمام می‌شود را بررسی کرد یا از zip_entry_filesize() کمک گرفت.

مثال عملی با توابع قدیمی (zip_open, zip_read, zip_entry_name)

// Example: List files inside a ZIP using older zip_* functions
$zipPath = '/path/to/archive.zip';
if (($zip = zip_open($zipPath)) === FALSE) {
    die('Could not open ZIP file');
}

while ($entry = zip_read($zip)) {
    $name = zip_entry_name($entry);
    if ($name !== FALSE) {
        echo $name . PHP_EOL;
    }
}

zip_close($zip);

توضیح: این قطعه کد آرشیو ZIP را با zip_open باز می‌کند، سپس با zip_read به ترتیب هر ورودی را می‌گیرد و با zip_entry_name() نام آن را چاپ می‌کند. در صورت خطا، مقدار false برگردانده می‌شود که با شرط کنترل شده است. این روش ساده است اما برای محیط‌های تولیدی بهتر است از مدیریت خطا و اعتبارسنجی مسیر استفاده شود.

اشکالات و بهبودها

  • این API قدیمی است و روی نسخه‌های جدید PHP ممکن است پشتیبانی یا رفتار متفاوتی داشته باشد.
  • در صورت نیاز به استخراج یا پردازش دقیق‌تر، استفاده از ZipArchive بهتر است.

معادل بهتر: استفاده از ZipArchive

// Example: List files using ZipArchive (recommended)
$zipPath = '/path/to/archive.zip';
$zip = new ZipArchive();
if ($zip->open($zipPath) === TRUE) {
    for ($i = 0; $i numFiles; $i++) {
        $stat = $zip->statIndex($i);
        echo $stat['name'] . PHP_EOL;
    }
    $zip->close();
} else {
    die('Could not open ZIP file');
}

توضیح: این نسخه از کلاس ZipArchive استفاده می‌کند که مدرن، پایدار و دارای متدهای مفیدتری مانند statIndex و متدهای مستقیم استخراج است. شما می‌توانید به‌راحتی نام فایل‌ها را از آرایه $stat['name'] بخوانید، اندازه‌ها، تاریخ و جزئیات دیگر را هم دریافت کنید.

مزایا نسبت به zip_entry_name()

  • بهتر بودن نگهداری و خوانایی کد
  • پشتیبانی بهتر از استخراج مستقیم با extractTo()
  • خطایابی و مدیریت استثناها آسان‌تر

موارد عملی و نکات پیشرفته

  • برای تشخیص پوشه‌ها: نام‌هایی که با / خاتمه می‌یابند معمولاً نمایانگر پوشه در داخل ZIP هستند.
  • ملاحظات رمزنگاری: اگر آرشیو رمز داشته باشد، هنگام خواندن یا استخراج باید رمز را در متدهای مرتبط فراهم کنید (ZipArchive از متدهایی برای رمزنگاری پشتیبانی دارد).
  • مسائل مربوط به encoding: نام فایل‌ها ممکن است با encoding متفاوت (مثل CP866 یا UTF-8) ذخیره شده باشند—در این صورت نیاز به تبدیل رشته دارید تا نام‌ها به درستی نمایش داده شوند.
  • امنیت: هرگز مسیرهای آرشیو (مسیر نام‌ها) را بدون اعتبارسنجی برای استخراج به دایرکتوری‌های حساس استفاده نکنید—ممکن است مسیرهایی شامل “../” باشند که باعث خروج از دایرکتوری هدف شوند.

مثال: بررسی مسیری که مانع بیرون‌زدن از پوشه می‌شود (ZipArchive)

// Secure extract using ZipArchive: prevent directory traversal
$zipPath = '/path/to/archive.zip';
$extractTo = '/var/www/uploads/unpack/';
$zip = new ZipArchive();
if ($zip->open($zipPath) === TRUE) {
    for ($i = 0; $i numFiles; $i++) {
        $name = $zip->getNameIndex($i);
        $target = $extractTo . $name;
        // Normalize path and prevent ../
        $realTarget = realpath(dirname($target));
        if ($realTarget === FALSE || strpos($realTarget, realpath($extractTo)) !== 0) {
            // suspicious path, skip
            continue;
        }
        // Optionally extract single file
        copy("zip://{$zipPath}#{$name}", $target);
    }
    $zip->close();
}

توضیح: این کد با ZipArchive نام هر فایل را می‌گیرد و قبل از استخراج مسیر نهایی را بررسی می‌کند تا از حملات directory traversal جلوگیری شود. استفاده از realpath و اعتبارسنجی مسیر ضروری است. توجه داشته باشید که برای فایل‌های بزرگ یا تعداد زیاد باید مدیریت حافظه و I/O را لحاظ کنید.

جمع‌بندی

تابع zip_entry_name() برای دریافت نام ورودی‌های یک آرشیو ZIP مفید است اما جزئی از API قدیمی PHP محسوب می‌شود. در پروژه‌های جدید حتما از ZipArchive استفاده کنید که قابلیت‌ها، امنیت و پشتیبانی بهتری ارائه می‌دهد. در هر دو حالت مراقب encoding، مسیرها و حملات احتمالی باشید و از اعتبارسنجی و مدیریت خطا غافل نشوید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: