دیتابیس وردپرس: مقدمه ای بر کلاس wpdb و متدهای آن

چگونه از wpdb در وردپرس استفاده کنیم

کلاس ها و توابع مختلفی برای کار با دیتابیس وردپرس وجود دارد، wp_query، wp_insert_post، update_post_meta و موارد دیگری که می توانید متناسب با نیاز پروژه از آنها استفاده کنید.

اما گاهی اوقات روش های فوق برایتان محدودیت ایجاد می کنند، در واقع می خواهید خارج از چهارچوب ها عمل کنید.

به عنوان مثال برای افزونه خود جداول اختصاصی ایجاد کنید، کوئری های پیچیده بنویسید و … در چنین سناریوهایی راه چاره کلاس wpdb خواهد بود.

کلاس wpdb چیست؟

کلاس wpdb ابزاری ساده اما قدرتمند برای برقراری ارتباط مستقیم با پایگاه داده وردپرس است، از این کلاس در هر جایی می توانید استفاده کنید.

wpdb امکان افزودن، بروزرسانی و حذف هرگونه اطلاعاتی را فراهم می کند، ساختار این کلاس در فایل wp-db.php داخل دایرکتوری wp-includes قراردارد.

برای استفاده از کلاس wpdb ابتدا باید به آبجکت سراسری wpdb$ دسترسی پیدا کنید، این آبجکت شامل متدها و خصوصیات کار با پایگاه داده است.

global $wpdb

توجه داشته باشید که نبایستی مستقیما به متدهای کلاس wpdb دسترسی پیدا کنید، چرا که وردپرس به صورت پیش فرض یک نمونه(Instance) از کلاس wpdb را از طریق آبجکت wpdb$ در اختیارتان قرار می دهد.

پیشوند جداول وردپرس

وردپرس برای نامگذاری جداول دیتابیس خود به صورت پیش فرض از پیشوند “_wp” استفاده می کند، البته می توانید این مقدار پیش فرض را درهمان ابتدای نصب وردپرس تغییر دهید یا پس از نصب از طریق فایل کانفیگ وردپرس wp-config.php آن را اصلاح نمائید.

پس نتیجه می گیریم که پیشوند جداول وردپرس می تواند در هر سیستمی متفاوت باشد.

به عنوان مثال کوئری زیر در وردپرس هایی که پیشوند جداول آنها _wp است به درستی کار می کند، اما در وردپرسی که مثلا از پیشوند _mywp استفاده کرده است اجرا نمی شود.

global $wpdb;
$result = $wpdb->get_results(
    'SELECT * FROM wp_posts WHERE LENGTH( post_excerpt ) > 0'
);

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

global $wpdb;
$result = $wpdb->get_results(
    'SELECT * FROM ' . $wpdb->prefix .
            'posts WHERE LENGTH( post_excerpt ) > 0'
);

یا کار راحت تری انجام دهید و اصلا از پیشوند جداول استفاده نکنید.

global $wpdb;
$result = $wpdb->get_results(
    'SELECT * FROM ' . $wpdb->posts .
            ' WHERE LENGTH( post_excerpt ) > 0'
);

در ادامه متدهای مهم و کاربردی کلاس wpdb را معرفی خواهیم کرد.

۱- بازیابی و فراخوانی داده ها از دیتابیس

در کلاس wpdb متدهای مختلفی برای فراخوانی و بازیابی داده ها از دیتابیس وردپرس وجود دارد که هر کدام از آنها را با ذکر مثال توضیح می دهیم.

متد get_var

این متد یک پرس و جو(Query) به عنوان ورودی دریافت کرده و یک مقدار برگشت می دهد.

به عنوان مثال تعداد پست های منتشر شده(Publish) یا تعداد کاربرانی که دارای نقش نویسنده هستند، پس در مواقعی که قرار است کوئری شما به عنوان خروجی فقط یک مقدار برگشت دهد از متد get_var استفاه کنید.

$post_count = $wpdb->get_var(
    'SELECT count(*) FROM ' . $wpdb->posts .
    ' WHERE post_status = "publish"');

echo 'Published Posts = ' . $post_count;

متد get_row

گاهی مواقع نیاز دارید که فقط یک رکورد از پایگاه داده بازیابی کنید، به عنوان مثال نوشته ای با شناسه ۱۰ یا آخرین رکورد یک جدول، در چنین شرایطی get_row بهترین انتخاب خواهد بود.

پارامتر دوم get_row نوع مقدار برگشتی را مشخص می کند، مقادیری که می توانید ست کنید بدین صورت است:

  1. OBJECT: خروجی به صورت آبجکت(مقدار پیش فرض)
  2. ARRAY_A: آرایه انجمنی (Associative Array)
  3. ARRAY_N: آرایه با ایندکس عددی(Numeric Indexed Array)
$row = $wpdb->get_row(
    'SELECT * FROM ' . $wpdb->posts .
           ' WHERE post_type="post" and post_status="publish" 
             ORDER BY ID DESC', ARRAY_A);

echo $row['post_title'];

متد get_col

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

$user_emails = $wpdb->get_col(
    'SELECT user_email FROM ' . $wpdb->users
);

foreach ( $user_emails as $email ) {
    echo $email . "<br>";
}

متد get_results

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

$results = $wpdb->get_results(
    'SELECT p.post_title, u.user_login 
               FROM ' . $wpdb->posts . ' p
                   JOIN ' . $wpdb->users . ' u 
                     ON p.post_author=u.id 
                      WHERE p.post_type="post" 
                              AND p.post_status="publish"');

foreach ( $results as $result ) {
    echo $result->post_title . ' = ' . $result->user_login . '<br>';
}

۲- افزودن، آپدیت و حذف داده ها از جداول دیتابیس

متد Insert

به کمک این متد می توانید اطلاعات مدنظرتان را به جداول اختصاصی خود اضافه کنید، متد inert سه پارامتر دارد:

  1. عنوان جدول
  2. آرایه ای از مقادیر
  3. آرایه ای از فرمت و نوع مقادیر
$wpdb->insert(
    $wpdb->postmeta,
    array('post_id' => 1,
        'meta_key' => 'quantity',
        'meta_value' => '500'),
    array('%d', '%s', '%s')
);

متد update

آپدیت و بروزرسانی داده ها یکی از معمول ترین کارهایی است که بر روی دیتابیس انجام می شود، برای این منظور باید از متد update کلاس wpdb استفاده کنید.

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

  1. نام جدول
  2. آرایه ای از مقادیر که باید آپدیت شوند
  3. آرایه ای از شرط ها
$wpdb->update($wpdb->postmeta,
    array('meta_value' => '450'),
    array('post_id' => 1, 'meta_key' => 'quantity'));

متد delete

برای حذف رکوردهای مدنظرتان می توانید از متد delete استفاده کنید.

$wpdb->delete( $wpdb->postmeta, 
            array( 'post_id' => 1 ) );

سایر متدهای کار با دیتابیس

متد query

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

کلیه متدهایی که تا اینجا بررسی کردیم به راحتی با متد query قابل پیاده سازی هستند.

$wpdb->query('DELETE p FROM ' . $wpdb->posts . ' p 
                     INNER JOIN ' . $wpdb->users . ' u 
                           ON u.ID = p.post_author 
                     INNER JOIN ' . $wpdb->usermeta . ' um 
                           ON um.user_id = u.ID 
                     WHERE p.post_status= "publish" 
                              AND um.meta_key = "last_name" 
                              AND um.meta_value ="yavarnia"
  ');

یا در مثالی دیگر به جای متد insert داده ها را اینگونه در دیتابیس ثبت کنیم.

$post_id = $_POST['post_id'];
$meta_key = $_POST['meta_key'];
$meta_value = $_POST['meta_value'];

$wpdb->query('INSERT INTO ' . $wpdb->postmeta .
    ' ( post_id, meta_key, meta_value ) 
           VALUES ( $post_id, $meta_key, $meta_value )
  ');

متد prepare

برای اینکه کوئری های شما در برابر حملات SQL Injection مقاوم باشد باید از متد prepare کلاس wpdb استفاده کنید.

به عنوان مثال در کوئری بالا که از متد query برای اینسترت اطلاعات استفاده کردیم مستعد حمله Injection است.

پس برای حفظ امنیت دیتابیس متد query را با متد prepare ترکیب می کنیم.

$wpdb->query(
    $wpdb->prepare(
        'INSERT INTO ' . $wpdb->postmeta .
        ' ( post_id, meta_key, meta_value ) 
        VALUES ( %d, %s, %s )',
        $post_id, $meta_key, $meta_value)
);

در مثال بالا که به روش sprintf نوشته شده است نوع متغیرها را اینگونه تعریف کردیم:

  1. s% داده رشته ای یا String
  2. d% داده صحیح یا Integer
  3. f% داده اعشاری یا Float

می توانید متغیرها را به جای sprinft به روش vsprintf ارسال کنید، کافی است آنها را در یک آرایه قرار دهید.

$wpdb->query(
    $wpdb->prepare('INSERT INTO ' . $wpdb->postmeta .
        ' ( post_id, meta_key, meta_value ) 
        VALUES ( %d, %s, %s )',
        array($post_id, $meta_key, $meta_value)
    )
);

نکته بسیار مهم

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

به عنوان مثال می خواهیم تگ یا برچسب های مشخصی را از دیتابیس فراخوانی کنیم، آیا باید از کلاس wpdb استفاده کنیم؟ مسلما خیر، چون توابع مختلفی برای اینکار وجود دارد.

برای پاسخ به این سوال تگ های مدنظرمان را به کمک تابع get_terms از دیتابیس وردپرس فراخوانی می کنیم.

<?php
    $tag_ids = array(5, 21, 17, 11);

    $tags = get_terms(
        array('taxonomy' => 'post_tag',
            'orderby' => 'include',
            'hide_empty' => true,
            'include' => $tag_ids)
    );

    foreach ($tags as $tag) { ?>
        <a href="<?php echo get_tag_link($tag->term_id); ?>">
            <?php echo $tag->name; ?>
        </a>
    <?php
}
?>

جمع بندی

کلاس wpdb قابلیتی مفید و کاربردی برای کسانی است که می خواهند از زاویه ای نزدیک تر با وردپرس تعامل داشته باشند، اما بدانید هر گونه استفاده نادرست از این کلاس می تواند مشکلات امنیتی برایتان بوجود بیاورد.

برچسب ها
سعید یاورنیا 117 نوشته 118 دیدگاه

توسعه دهنده وب، کارشناس ارشد نرم افزار.

دیدگاه ‌ها

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

نشانی ایمیل شما منتشر نخواهد شد، بخش‌های موردنیاز با * مشخص شده‌اند.