ویژگی تصویر

آموزش تابع media_handle_sideload() در وردپرس و کاربرد آن

  /  وردپرس   /  تابع media_handle_sideload در وردپرس
بنر تبلیغاتی الف
wp - wordpress - وردپرس

در توسعه افزونه‌ها یا قالب‌های وردپرس گاهی لازم است فایل‌هایی (مثلاً تصویر) را از منابع خارجی دانلود و به کتابخانه رسانه Media Library اضافه کنیم. تابع media_handle_sideload() یکی از توابع داخلی وردپرس است که این کار را ساده و استاندارد انجام می‌دهد: فایل موقت را به مسیر آپلودهای وردپرس منتقل می‌کند، متادیتای تصویر را تولید می‌کند و به‌عنوان یک پیوست (attachment) ثبت می‌نماید.

پیش‌نیازها و نکات اولیه

  • باید فایل موقت (tmp file) داشته باشید؛ معمولاً از تابع download_url() برای دانلود استفاده می‌شود.
  • پیش از فراخوانی تابع باید فایل‌های مورد نیاز را شامل کنید: file.php, media.php, image.php.
  • خروجی تابع می‌تواند شناسه ضمیمه (attachment ID) یا شیء WP_Error باشد؛ بنابراین حتماً خطاها را بررسی کنید.
  • برای امنیت درخواست‌ها، کنترل capability و nonce را در سمت سرور انجام دهید.

پارامترها و مقدار بازگشتی

پارامترتوضیح
file_arrayآرایه‌ای مشابه $_FILES با کلیدهای name و tmp_name
post_idشناسه پستی که ضمیمه باید به آن متصل شود (مقدار 0 برای بدون والد)
post_data (اختیاری)آرایه‌ای برای تنظیم عنوان، توضیح و … هنگام ایجاد پست ضمیمه

مقدار بازگشتی: شناسه ضمیمه (int) یا WP_Error.

مثال پایه: دانلود تصویر و ایجاد ضمیمه

require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );

$image_url = 'https://example.com/image.jpg';
$tmp = download_url( $image_url );

if ( is_wp_error( $tmp ) ) {
    // خطای دانلود
    return;
}

$file = array(
    'name'     => basename( $image_url ),
    'tmp_name' => $tmp
);

$attachment_id = media_handle_sideload( $file, 0 );

if ( is_wp_error( $attachment_id ) ) {
    @unlink( $file['tmp_name'] ); // پاک کردن فایل موقت
    // مدیریت خطا
} else {
    // موفقیت‌آمیز: $attachment_id شناسه پیوست است
}

توضیح: در این کد ابتدا فایل‌های مورد نیاز شامل می‌شوند، سپس با download_url() فایل را موقتاً دانلود می‌کنیم. آرایه‌ای شبیه $_FILES ساخته و به media_handle_sideload() ارسال می‌کنیم. در صورت خطا باید حتماً فایل موقتی که ایجاد شده پاک شود تا فضای دیسک اشغال نگردد.

مثال عملی: قرار دادن تصویر دانلود شده به‌عنوان تصویر شاخص

// شامل فایل‌های ضروری
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );

function my_set_remote_featured_image( $post_id, $image_url ) {
    $tmp = download_url( $image_url );

    if ( is_wp_error( $tmp ) ) {
        return $tmp;
    }

    $file_array = array(
        'name'     => basename( $image_url ),
        'tmp_name' => $tmp
    );

    $attachment_id = media_handle_sideload( $file_array, $post_id );

    if ( is_wp_error( $attachment_id ) ) {
        @unlink( $file_array['tmp_name'] );
        return $attachment_id;
    }

    // تنظیم متن جایگزین (alt)
    update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( 'Alt text example' ) );

    // تنظیم به‌عنوان تصویر شاخص
    set_post_thumbnail( $post_id, $attachment_id );

    return $attachment_id;
}

توضیح: این تابع تصویری را از یک URL خارجی می‌گیرد، آن را به‌عنوان پیوست ذخیره کرده و سپس شناسه را به عنوان تصویر شاخص پست تعیین می‌کند. توجه کنید که متن alt با sanitize_text_field پاکسازی شده است.

چند نکته کاربردی و بهینه‌سازی

  • همیشه خطاها را با is_wp_error() چک کنید و در صورت خطا فایل موقت را حذف کنید.
  • برای چند فایل، این روند را داخل حلقه اجرا کنید و از throttling یا queue برای جلوگیری از فشار بر سرور استفاده کنید.
  • اگر فایل‌های بزرگ دانلود می‌کنید، زمان اجرای اسکریپت و محدودیت‌های حافظه را مد نظر داشته باشید.
  • در محیط‌هایی با محدودیت PHP-FPM یا CGI، بهتر است دانلود را به یک فرآیند پس‌زمینه انتقال دهید.

امنیت و مجوزها

ورود URL توسط کاربران باید اعتبارسنجی شود. از روش‌های زیر استفاده کنید:

  • فقط اجازه دهید کاربران با capability مناسب (مثل edit_posts) این عمل را انجام دهند.
  • درخواست‌ها را با nonce بررسی کنید تا CSRF جلوگیری شود.
  • از wp_check_filetype_and_ext() یا دیگر توابع وردپرس برای بررسی نوع فایل استفاده کنید؛ تابع داخلی در مسیر پردازش عمل می‌کند اما بهتر است ورودی‌ها را هم کنترل کنید.
  • محدودسازی دامنه‌ها (مثلاً تنها دامنه‌های خودتان یا لیست سفید) برای جلوگیری از دانلود از منابع خطرناک.

نمونه پیشرفته: اضافه کردن عنوان و کپشن و پاکسازی نام فایل

function download_and_attach( $post_id, $url, $title = '' ) {
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );
    require_once( ABSPATH . 'wp-admin/includes/image.php' );

    $tmp = download_url( $url );
    if ( is_wp_error( $tmp ) ) {
        return $tmp;
    }

    $filename = wp_basename( $url );
    $filename = sanitize_file_name( $filename );

    $file = array(
        'name'     => $filename,
        'tmp_name' => $tmp
    );

    $attachment_id = media_handle_sideload( $file, $post_id, array(
        'post_title' => sanitize_text_field( $title ),
        'post_content' => ''
    ) );

    if ( is_wp_error( $attachment_id ) ) {
        @unlink( $file['tmp_name'] );
        return $attachment_id;
    }

    return $attachment_id;
}

توضیح: در این نسخه اسم فایل پیش از ارسال پاکسازی می‌شود و می‌توان عنوان و محتوای پیوست را نیز تنظیم کرد. استفاده از sanitize_file_name و sanitize_text_field امنیت بهتری فراهم می‌کند.

مقایسه با media_sideload_image()

  • media_handle_sideload() شناسه پیوست را برمی‌گرداند و برای دسترسی به متادیتا و استفاده‌های بعدی مناسب است.
  • media_sideload_image() معمولاً HTML تصویر را برمی‌گرداند یا WP_Error؛ مناسب وقتی تنها می‌خواهید تصویر را داخل محتوا نمایش دهید.

جمع‌بندی و بهترین روش‌ها

  • از توابع داخلی وردپرس برای دانلود و ثبت فایل استفاده کنید تا سازگاری با سیستم مدیریت فایل و تکمیل متادیتا حفظ شود.
  • همیشه خروجی‌ها را بررسی، فایل‌های موقت را پاک و ورودی‌ها را صیقل (sanitize) کنید.
  • برای عملیات در مقیاس بزرگ از صف‌ها یا پردازش پس‌زمینه بهره ببرید تا از زمانی‌بندی و استفاده بیش از حد منابع جلوگیری شود.

با رعایت نکات بالا، media_handle_sideload() ابزاری قدرتمند و امن برای افزودن فایل‌های خارجی به کتابخانه رسانه وردپرس است و استفاده صحیح از آن باعث افزایش انعطاف‌پذیری اپلیکیشن شما می‌شود.

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

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