مستندات وردپرس

بهینه سازی سرعت ایجاد یا ویرایش محتوا در دیتابیس وردپرس

دیتابیس وردپرس برای ذخیره سازی یا ویرایش اطلاعات همواره یک فرآیند ثابتی را طی می کند ، طی این فرآیند ابتدا داده ها دریافت می شود ، سپس داده ها طبق ساختار جدول مورد نظر اعتبار سنجی یا Validation می شوند و در نهایت ذخیره سازی اطلاعات صورت می گیرد.

کلاس wpdb

کلاس wpdb که وظیفه ی اصلی ارتباط با دیتابیس وردپرس را بر عهده دارد برای اعتبار سنجی داده ها از ساختار جداول یا Schema آن ها بهره میگیرد. به عنوان مثال در جدول wp_posts وردپرس که محل ذخیره پست ها می باشد همواره فیلد post_title به صورت رشته یا string ذخیره سازی می شود. ای بدان معنا است که اگر از سمت PHP برای این فیلد یک مقداری غیر از رشته مثلا به صورت صحیح/غلط یا Boolean ارسال شود جلوی این کار گرفته خواهد شد.

وردپرس برای دریافت ساختار یا Schema جداول از یک کوئری ثابت استفاده می کند مثلا برای دریافت اطلاعات ساختار جدول wp_options که محل ذخیره تنظیمات وردپرس می باشد از Query زیر بهره مند می شود:

SHOW FULL COLUMNS FROM `wp_options`;

خروجی این دستور در PHPMyAdmin بدین گونه هست:

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

با توجه به اینکه وردپرس قبل از اجرای فرآیند Insert یا Update در پایگاه داده همیشه یکبار برای صحت سنجی نوع فیلد،  این کوئری را اجرا می کند ، در هیچ بخشی از هسته ی وردپرس این مورد کش نمی شود تا به سرعت سیستم کمک رسانی شود.

تصویر زیر از کوئری در زمان ایجاد آپشن جدید وردپرس در افزونه Query Monitor می باشد:

 

ایجاد افزونه Drop-ins دیتابیس وردپرس

اگر مقاله انواع افزونه وردپرس را مطالعه کرده باشید ، می دانید که بوسیله ی افزونه های Drop-in ما می توانیم تغییراتی در عملکرد های اصلی هسته ی وردپرس داشته باشیم.یکی از این افزونه ها به نام db.php می باشد که با کمک آن می شود کلاس اصلی ارتباط با دیتابیس وردپرس یعنی wpdb را بصورت کامل تغییر و یا متدهای این کلاس را بازنویسی کنیم.حتی در صورتی که میخواهیم وردپرس را به دیتابیسی غیر از MySQL مانند mongoDB یا PostgreSQL وصل کنیم تنها کافیست متدهای مربوط به درایور دیتابیس را با متدهای کلاس WPDB هماهنگ سازی کنید.

حتما بخوانید : انواع افزونه وردپرس و دلیل پیدایش ساختار آن ها در هسته وردپرس

نحوه ی اجرای کش اطلاعات Schema جداول دیتابیس وردپرس

ابتدا در پوشه ی wp-content وردپرس یک فایل به نام db.php ایجاد می کنیم ، در این فایل ابتدا میبایست یک کلاس PHP جدید ساخته شود که از کلاس اصلی wpdb ارث بری یا extend شده است. به شکل آماده میتوان از کد زیر استفاده نمود:

<?php
class dbDropIns extends wpdb
{
    public function __construct()
    {
        parent::__construct(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
    }
}

global $wpdb;
$wpdb = new dbDropIns();

اگر به فایل wpdb-class.php که در فولدر wp-includes وردپرس قرار دارد توجه کنید ، در متدی به نام get_table_charset در حال دریافت اطلاعات ساختار جداول توسط کوئری می باشد ، سناریویی که ما در نظر داریم بدین صورت هست که پس از دریافت اطلاعات ساختاری هر جدول آن را در یک فایل PHP قرار دهیم تا برای دفعات آتی وردپرس به دیتابیس مراجعه نکند.

برای این کار ابتدا در فولدر Storage وردپرس که در مسیر uploads قرار دارد یک فولدر با نام دلخواه مانند table-schema ایجاد می کنیم. حال در کدها ابتدا چک میکنیم اگر در این فولدر فایل PHP قبلا به نام جدول مورد نظر وجود داشت اطلاعات از آن جا خوانده شود در غیر این صورت ریکوئست به دیتابیس ارسال شود و پس از دریافت ذخیره سازی صورت گیرد.

اگر بخواهیم از فایل نهایی رونمایی کنیم خواهیم داشت:

<?php

class dbDropIns extends wpdb
{

    public function __construct()
    {
        parent::__construct(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
        add_action('_core_updated_successfully', [$this, 'remove_cache_dir']);
    }

    protected function get_table_charset($table)
    {
        $tablekey = strtolower($table);

        /**
         * Filters the table charset value before the DB is checked.
         *
         * Returning a non-null value from the filter will effectively short-circuit
         * checking the DB for the charset, returning that value instead.
         *
         * @param string|WP_Error|null $charset The character set to use, WP_Error object
         *                                      if it couldn't be found. Default null.
         * @param string $table The name of the table being checked.
         * @since 4.2.0
         *
         */
        $charset = apply_filters('pre_get_table_charset', null, $table);
        if (null !== $charset) {
            return $charset;
        }

        if (isset($this->table_charset[$tablekey])) {
            return $this->table_charset[$tablekey];
        }

        $charsets = array();
        $columns = array();

        $table_parts = explode('.', $table);
        $table = '`' . implode('`.`', $table_parts) . '`';

        $path = wp_upload_dir(null, false);
        $fileName = $path['basedir'] . '/table-schema/' . $table . '.php';
        if (file_exists($fileName)) {

            $results = include $fileName;
        } else {

            $results = $this->get_results("SHOW FULL COLUMNS FROM $table");

            $data = var_export($results, true);
            $content = "<?php\n return {$data};\n";
            file_put_contents($fileName, $content);
        }

        if (!$results) {
            return new WP_Error('wpdb_get_table_charset_failure', __('Could not retrieve table charset.'));
        }

        foreach ($results as $column) {
            $columns[strtolower($column->Field)] = $column;
        }

        $this->col_meta[$tablekey] = $columns;

        foreach ($columns as $column) {
            if (!empty($column->Collation)) {
                list($charset) = explode('_', $column->Collation);

                $charsets[strtolower($charset)] = true;
            }

            list($type) = explode('(', $column->Type);

            // A binary/blob means the whole query gets treated like this.
            if (in_array(strtoupper($type), array('BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB'), true)) {
                $this->table_charset[$tablekey] = 'binary';
                return 'binary';
            }
        }

        // utf8mb3 is an alias for utf8.
        if (isset($charsets['utf8mb3'])) {
            $charsets['utf8'] = true;
            unset($charsets['utf8mb3']);
        }

        // Check if we have more than one charset in play.
        $count = count($charsets);
        if (1 === $count) {
            $charset = key($charsets);
        } elseif (0 === $count) {
            // No charsets, assume this table can store whatever.
            $charset = false;
        } else {
            // More than one charset. Remove latin1 if present and recalculate.
            unset($charsets['latin1']);
            $count = count($charsets);
            if (1 === $count) {
                // Only one charset (besides latin1).
                $charset = key($charsets);
            } elseif (2 === $count && isset($charsets['utf8'], $charsets['utf8mb4'])) {
                // Two charsets, but they're utf8 and utf8mb4, use utf8.
                $charset = 'utf8';
            } else {
                // Two mixed character sets. ascii.
                $charset = 'ascii';
            }
        }

        $this->table_charset[$tablekey] = $charset;
        return $charset;
    }

    public function remove_cache_dir(): void
    {
        $path = wp_upload_dir(null, false);
        $files = glob($path['basedir'] . '/table-schema/*');
        foreach ($files as $file) {
            if (is_file($file)) {
                wp_delete_file($file);
            }
        }
    }
}

global $wpdb;
$wpdb = new dbDropIns();

حال اگر پس از اجرای وب سایت پوشه ی table-schema واقع در فولدر uploads را مشاهده کنیم ، خواهیم دید که وردپرس به ازای هر جدول یک فایل کش ایجاد کرده که اطلاعات Information schema جدول در آن قرار گرفته شده است و از این پس وردپرس برای اجرای دستورات insert/update به این فایل رجوع می کند.

چه زمانی وردپرس دیتابیس را بروز می کند؟

وردپرس تنها در زمان آپدیت هسته ی خود در وب سایت شما با بروزرسانی هایی که انجام می دهد گاها ساختار دیتابیس جداول را کمی تغییر می دهد ، در نتیجه ما میتواینم از هوک وردپرس در زمان آپدیت هسته ی آن استفاده کنیم و همه ی کش ها را پاک کنیم تا سیستم اتوماتیک اطلاعات ساختاری جدید را جایگزی کند.
اگر تابع update_core در وردپرس را بررسی کنیم در پایان از هوکی به نام core_updated_successfully استفاده می کند که ما در کد بالا نیز به آن اشاره نمودیم.

مهرشاد درزی

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

انتشار
انتشار توسط
مهرشاد درزی

آخرین مطالب

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

همان طور که می دانید افزونه ووکامرس درنسخه های اخیر یک تغییر عمده در سفارشات…

3 هفته پیش

هماهنگ کردن محصولات ووکامرس با نرم افزار حسابداری

در زمان تهیه افزونه های وردپرس برای اتصال نرم افزار حسابداری به سیستم فروشگاهی ووکامرس…

3 هفته پیش

هوش مصنوعی در وردپرس

بالاخره در نسخه ی وردپرس 7.0 سرویس اتصال به سرویس هی خارجی مانند هوش مصنوعی…

1 ماه پیش

معرفی بهترین افزونه‌های پشتیبانی وردپرس

تا به حال شده با دل‌نگرانی در داشبورد سایت وردپرسی‌تان بنشینید، چون بخشی از سایت…

9 ماه پیش

هماهنگی محتوا و پشتیبانی سایت؛ چطور تیم فنی را با محتوا هم‌راستا کنیم؟

شاید شما هم این صحنه را دیده باشید که تیم محتوا با شوق فراوان مقاله‌ای…

9 ماه پیش

چگونه از افت رتبه سایت در گوگل جلوگیری کنیم؟

صبح زود از خواب بیدار می‌شوید، قهوه‌تان را برمی‌دارید و مثل همیشه سری به سرچ…

9 ماه پیش
برای نمایش نسخه اصلی این صفحه اینجا لمس کنید