janochen
  • 0
Мастер

Неправильно ли обращаться непосредственно к базе данных mysql при разработке плагина?

  • 0

Это пример плагина Vote It Up :

//Run this to create an entry for a post in the voting system. Will check if the post exists. If it doesn't, it will create an entry.
function SetPost($post_ID) {
    global $wpdb;

    //prevents SQL injection
    $p_ID = $wpdb->escape($post_ID);

    //Check if entry exists
    $id_raw = $wpdb->get_var("SELECT ID FROM ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    if ($id_raw != '') {
        //entry exists, do nothing
    } else {
        //entry does not exist
        $wpdb->query("INSERT INTO ".$wpdb->prefix."votes (post, votes, guests, usersinks, guestsinks) VALUES(".$p_ID.", '', '', '', '') ") or die(mysql_error());
    }
}

//Run this to create an entry for a user in the voting system. Will check if the user exists. If it doesn't, it will create an entry.
function SetUser($user_ID) {
    global $wpdb;

    //prevents SQL injection
    $u_ID = $wpdb->escape($user_ID);

    //Check if entry exists
    $id_raw = $wpdb->get_var("SELECT ID FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
    if ($id_raw != '') {
        //entry exists, do nothing
    } else {
        //entry does not exist
        $wpdb->query("INSERT INTO ".$wpdb->prefix."votes_users (user, votes, sinks) VALUES(".$u_ID.", '', '') ") or die(mysql_error());
    }
}

//Returns the vote count
function GetVotes($post_ID, $percent = false) {
    global $wpdb;

    //prevents SQL injection
    $p_ID = $wpdb->escape($post_ID);

    //Create entries if not existant
    SetPost($p_ID);

    //Gets the votes
    $votes_raw = $wpdb->get_var("SELECT votes FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $sinks_raw = $wpdb->get_var("SELECT usersinks FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $guestvotes_raw = $wpdb->get_var("SELECT guests FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $guestsinks_raw = $wpdb->get_var("SELECT guestsinks FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
/* Deprecated
    $uservotes_raw = $wpdb->get_var("SELECT votes FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
    $usersinks_raw = $wpdb->get_var("SELECT sinks FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
*/

    //Put it in array form
    $votes = explode(",", $votes_raw);
    $sinks = explode(",", $sinks_raw);
    $guestvotes = explode(",", $guestvotes_raw);
    $guestsinks = explode(",", $guestsinks_raw);
/* Deprecated
    $uservotes = explode(",", $uservotes_raw);
    $usersinks = explode(",", $usersinks_raw);
*/
    $uservotes = 0;
    $usersinks = 0;

    $initial = 0; //Initial no. of votes [will be placed at -1 when all posts receive votes]

(и так далее…)

Я слышал от многих людей, что это плохая практика — обращаться непосредственно к базе данных mysql. Что код может развалиться в будущих версиях WordPress.

Или это необходимо в некоторых плагинах, таких как Vote It Up?

Share
  1. Плагин использует пользовательские таблицы, выбора действительно нет, либо либо, $wpdb либо прямые mysql_query вызовы, когда вы имеете дело с неосновными таблицами. На мой взгляд, самая большая проблема с этим плагином (как я указал в другом вашем вопросе) заключается в том, как структурированы таблицы базы данных плагина.

    • 0
  2. Привет @janoChen:

    Правильный ответ: «Это зависит».

    В общем, лучше использовать встроенные функции WordPress, чем использовать прямой SQL , когда есть встроенные функции, которые могут предоставить вам то, что вам нужно. Тем не менее, ответы на многие вопросы, которые я вижу здесь на WPSE, таковы (к сожалению): «вам нужно использовать прямой SQL для этого, потому что WordPress просто не предоставляет (эффективной) функции для обеспечения того, что вам нужно».

    В случае плагина Vote It Up можно утверждать, что их выбор прямого SQL был правильным, потому что в базе данных WordPress нет эффективного места для хранения голосов. С другой стороны, есть те, кто утверждает, что они должны были использовать wp_postmeta и wp_usermeta хранить эту информацию. Лично я на пороге плагина для голосования; На самом деле мне пришлось бы реализовать один (что я сделал, но это было почти 2 года назад и с тех пор многому научился), чтобы действительно иметь мнение о том, как это сделать лучше всего.

    Одна вещь, которую я скажу, это то, что почти везде, где это возможно, я предпочитаю использовать встроенные таблицы с WordPress, а не добавлять новые таблицы. Добавление таблицы оказывает более существенное влияние, чем добавление кода SQL для доступа к существующим таблицам. Учитывая это само по себе, я мог бы научиться использовать метатаблицы для плагина для голосования, но я, честно говоря, не могу утверждать это однозначно, если и до тех пор, пока я действительно не попытался реализовать такую ​​​​функциональность.

    ОБНОВИТЬ

    Я только что прочитал код c.bavota, и в чем-то он хорош, в чем-то он меня беспокоит. Мне нравится, что он использует метаданные поста, но мне не нравится, что он помещает список user_id, разделенных запятыми, в метаполе поста. Что происходит, когда пост набирает 25 000 голосов? Очевидно, что его код не масштабируется для сайта с высокой посещаемостью. И его код очень замедлял бы получение списка всех постов, за которые проголосовал данный пользователь, для любого сайта с большим количеством постов.

    Если он собирается поместить все идентификаторы пользователей для голосов в метаполе, он должен сделать это более масштабируемым способом, например, хранить идентификаторы сообщений в метаданных пользователей, поскольку шансы на то, что один пользователь проголосует 25 000 раз или даже 2500 раз, довольно малы. Или он мог хранить голоса, встраивая идентификатор пользователя в мета-ключ поста, т. е "user_vote_{$user_id}" . (хотя, возможно, 25 000 мета-записей сами по себе вызовут проблемы).

    OTOH, если вам действительно нужно отслеживать голоса пользователей, я мог бы привести аргументы в пользу таблицы, и прямой SQL может иметь смысл.

    Более того, он запускает собственный веб-сервис вместо использования встроенных функций AJAX для веб-сервисов. Хотя мне не нравится, что встроенная функциональность не RESTful, я не думаю, что воссоздавать инфраструктуру веб-службы — хорошая идея, если вы не сделаете это правильно. Если все сделать правильно, это будет включать встроенную безопасность, а код c.bavota не беспокоится о безопасности; без экранирования $_POST значений, без использования одноразовых номеров, ничего.

    И его код может легко недосчитать голоса, если два или более человека голосуют одновременно. Что немного пугает, так это то, что этот парень продает темы премиум-класса, а в его статьях с практическими рекомендациями есть код, который нарушает несколько известных передовых практик. Но я думаю, что он вряд ли уникален как поставщик тем, у которого есть код с проблемами безопасности или масштабируемости. .

    Я оставил комментарий об этих проблемах и предложил ему немедленно предупредить своих пользователей и обновить с помощью лучших методов, но в настоящее время он находится на модерации. Будем надеяться, что он его опубликует.

    ОБНОВЛЕНИЕ2

    Зачем использовать такие функции, update_post_meta() а не обновлять базу данных напрямую? Несколько причин, но гораздо важнее для плагинов или тем, которые вы планируете распространять, чем для кода, который вы пишете для своего собственного сайта (хотя в идеале это полезно и для последнего):

    1. По какой-то небольшой случайности WordPress может изменить структуру базы данных для метаданных. Они делали это раньше и могут сделать это снова. Если вы используете встроенные функции вместо SQL, ваш код продолжит работать, но очевидно, что прямой код SQL сломается при обновлении WordPress.

    2. Если вы используете update_post_meta() его, он будет работать для одного сайта и для нескольких сайтов. Прямой код SQL будет работать для одного, но не для другого.

    3. Если вы используете, update_post_meta() а кто-то хочет использовать плагин, который хранит часто используемые значения в MemCached, ваш код будет поддерживать его, но не в том случае, если вы пишете прямой SQL.

    4. В общем, если подключаемый модуль или тема update_post_meta() подключаются, то ловушка будет работать, если вы используете, update_post_meta() но не если вы используете прямой SQL.

    5. И я уверен, что есть и другие причины, о которых я сейчас не могу думать.

    Достаточно сказать, что использование встроенных функций обеспечивает надежность и гибкость, с которыми прямой SQL не может сравниться; поэтому используйте прямой SQL только тогда, когда вы не можете сделать это с помощью встроенных функций. JMTCW.

    • 0
  3. Для большинства плагинов достаточно использовать WordPress Options-API. Хотя это прекрасно работает для кнопок, строк и других простых вещей, более сложные плагины иногда нуждаются в собственной таблице базы данных. Если вы находитесь в такой ситуации, вам следует следовать официальным рекомендациям на странице Создание таблиц с помощью плагинов.

    Нет ничего плохого в том, чтобы напрямую войти в базу данных, если вы правильно проверяете ввод и убедитесь, что ваш код абсолютно безопасен. В WordPress есть множество функций, которые значительно упрощают эту задачу (опять же, см. Создание таблиц с помощью плагинов ), поэтому я лично рекомендую именно этот способ.

    • 0

Оставить ответ

You must login to add an answer.