نمایش متن در فرانت، داخل حلقه PHP

  1. خانه
  2. /
  3. PHP
  4. /
  5. نمایش متن در فرانت، داخل حلقه PHP

بالاخره بعد مدتها وقت شد یه پست آموزشی آماده کنم. حتما براتون پیش اومده که یک کاری رو داخل حلقه با php دارید انجام میدید مثلا یک فانکشن خاصی روی تعداد 100 ایتم در یک حلقه اجرا میشه و میخواهید بعد از انجام عملیات روی هر ایتم به کاربر در فرانت اند نشون بدید الان ایتم فلان پراسس شده و اینقدر درصد از کل کار پیش رفته. خب چطوری میشه؟ اگر پیش نیومد براتون هم بخونید پست رو بعدا بدرد تون میخوره.

اول میاییم یک سناریو واقعی رو تعریف میکنیم و بعد برایش راه حل ها رو میگم و در نهایت سورس رو بصورت کامل قرار میدم.

درخواست: میخواهیم یک meta از پست های سایت رو تغییر بدیم، مثلا 1500 تا پست داریم. خب یه راه حل اینه که با wp_localize_script بیاییم لیست پست ها رو که از get_posts گرفتیم رو به فایل جاوا اسکریپت مون بدیم، بعد اون طرف با اجاکس و مثلا متد post ریکوئست بفرستیم پست ها رو یکی یکی داخل لوپ (یا با سینکرونوس) و بعد از اتمام هر ریکوئست نتیجه رو بگیریم نشون بدیم تو فرانت. ولی یکم پیچیده هست برای کار به این سادگی درسته؟ میخواهیم یه متا از پست ها رو تغییر بدیم که کلا با php میشه انجامش داد، دیگه جاوا اسکریپت و اینا چیه دست و پا گیر شده!

راه حل: قرار هست با افزودن یک کوئری به صفحه داشبورد مدیریت سایت، یک صفحه سفید باز بشه و پست ها رو یکی یکی پراسس کنه متا شون رو تغییر بده و همزمان هم درصد پیشرفت رو نشون بده، و کاربر هم بتونه وسط پروسه سیستم رو متوقف کنه. و برای پراگرس بار هم بکگراند بادی رو با گرادینت رنگ میکنیم.

کد زیر رو با توضیحات کامل هست :

/*
Plugin Name: Bulk Update Post meta
Version: 0.1
Plugin URI: https://amirhosseinhpv.ir/news/echo-on-loop-pure-php/
Description:
Author: Amirhosseinhpv
Author URI: https://hpv.im/
*/

/**
 * check if we are receiving request in admin area
 * e.g. https://yoursite.com/wp-admin/?bulk_update_post_meta
 */
if ( is_blog_admin() && isset($_GET["bulk_update_post_meta"])){
  bulk_update_post_meta_proccess();
}

/**
 * Bulk update post meta function
 */
function bulk_update_post_meta_proccess()
{
  // first get all posts ids as array
  $array_posts_ids = get_posts(
    array(
      "post_type" => "post",
      "posts_per_page" => -1,
      "fields" => "ids",
    )
  );

  // declare variables
  $i = 0;
  $success_items = 0;
  $current_progress = 0;
  $total_posts = count($array_posts_ids);

  // we are going to sent js to frontend as we want to update frontend dom elements
  // so what happens here is if we have 12000 item, we will output js for 12000 times,
  // which may cause browser crash, so we output js only for 300 times
  $steps = floor($total_posts / 300);

  // Implicit flushing will result in a flush operation after every output call,
  // so that explicit calls to flush() will no longer be needed
	ob_implicit_flush(true);

  // turn output buffering on
	ob_start();

  // let user know we started process
  echo "<h1>Updating Meta in progress, press ESC to cancel.</h1>";

	foreach( $array_posts_ids as $post) {

    // set current loop item position
    $i++;

    // get post meta
    $views = get_post_meta( $post, "views", true);

    // set post meta
		$update = update_post_meta($post, "views", $views*7 );
    if (true === $update){
      $success_items++;
    }

    // calculate current progress percentage, output be like 48.78%
    $_precent = min(100, 100 * $i / $total_posts);
    $current_precent = sprintf("%'05.2f%%", );

    // now output loop information
    // output be like: 50.00% ~~ 500 / 1000 ~~ Post ID #7896 meta updated!
    printf("<p>%s ~~ %02d / %02d ~~ Post ID #%s meta updated!</p>", $current_precent, $i, $total_posts, $post);

    // we only update progressbar or page title precentage 300 times, no matter how many items are in loop
    if ($i % $steps == 0 ){
      echo "<script>

        /* update page title */
        document.title = 'Updating $current_precent';

        /* make a large progressbar with body background */
        document.querySelector('body').style.backgroundImage = 'linear-gradient(to right, rgba(0, 223, 56, 0.18) {$_precent}%, white {$_precent}%)';

        /* scroll to bottom */
        window.scrollTo(0, document.body.scrollHeight);

      </script>";
    }
    ob_end_flush();
    ob_flush();
    flush();
    ob_start();
	}

  echo "<h1><strong>$success_items</strong> items of total <strong>$total_posts</strong> posts meta updated successfully.</h1>";

	ob_end_flush();
	exit;
}

کد زیر هم بدون کامنت و جمع جور شده است.

/*
Plugin Name: Bulk Update Post meta
Version: 0.1
Plugin URI: https://amirhosseinhpv.ir/news/echo-on-loop-pure-php/
Description:
Author: Amirhosseinhpv
Author URI: https://hpv.im/
*/

/* usage: https://yoursite.com/wp-admin/?bulk_update_post_meta */
if ( is_blog_admin() && isset($_GET["bulk_update_post_meta"])){
  $array_posts_ids = get_posts( array( "post_type" => "post", "posts_per_page" => -1, "fields" => "ids", ) );
  $i = 0; $success_items = 0; $current_progress = 0; $total_posts = count($array_posts_ids);
  $steps = floor($total_posts / 300);
  ob_implicit_flush(true);  ob_start();
  echo "<h1>Updating Meta in progress, press ESC to cancel.</h1>";
  foreach( $array_posts_ids as $post) {
    $i++;
    $views = get_post_meta( $post, "views", true);
    $update = update_post_meta($post, "views", $views*7 );
    if (true === $update){ $success_items++; }
    $_precent = min(100, 100 * $i / $total_posts);
    $current_precent = sprintf("%'05.2f%%", );
    printf("<p>%s ~~ %02d / %02d ~~ Post ID #%s meta updated!</p>", $current_precent, $i, $total_posts, $post);
    if ($i % $steps == 0 ){
      echo "<script>document.title = 'Updating $current_precent';
      document.querySelector('body').style.backgroundImage = 'linear-gradient(to right, rgba(0, 223, 56, 0.18) {$_precent}%, white {$_precent}%)';
      window.scrollTo(0, document.body.scrollHeight);</script>";
    }
    ob_end_flush(); ob_flush(); flush(); ob_start();
  }
  echo "<h1><strong>$success_items</strong> items of total <strong>$total_posts</strong> posts meta updated successfully.</h1>";
  ob_end_flush(); exit;
}

رفع مسئولیت: میدونم با خیلی روش های دیگه هم میشه این کارو کرد، شاید بهتر حتی!! ولی این روشی هست که من برای چند تا پروژه استفاده کردم و جواب گرفتم، بعلاوه در مورد سورس تستی که گذاشتم، میدونم کلی روش دیگه برای حل این مسئله وجود داره و فقط یک نمونه رو آوردم. اگر مشکل داشتید یا خوشتون اومد تو کامنت ها بهم اطلاع بدید، با تشکر.

از این ترفند برای نمایش درصد آپلود هم میشه استفاده کرد، همونطور که در اسکریپت Upload File from URL to WebServer از این روش استفاده کردم برای زمانی که فایل از URL در سرور آپلود میشه درصد رو نشون میده و پراگرس هم با رنگ بادی مشخص میشه.

برای دمو فیلم زیر رو ببینید:

کامنت ها (2)

2 دیدگاه. همین الان خارج شوید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

این قسمت نباید خالی باشد
این قسمت نباید خالی باشد
لطفاً یک نشانی ایمیل معتبر بنویسید.
شما برای ادامه باید با شرایط موافقت کنید

برای امنیت، از سرویس reCAPTCHA Google حریم خصوصی و شرایط استفاده استفاده کنید.

دسته بندی:
PHPآموزشیتکه کدتوسعهجاوا اسکریپتوردپرس
تگ ها:
کارهای ضروری بعد از نصب وردپرس (بخش 1)
تغییر کرزر های ویندوز به مک Big Sur
فهرست