默认WordPress设置API数据清理

时间:2012-08-06 作者:sigF

在我看来,当通过设置API将数据保存到数据库时,Wordpress默认会清理数据。我的意思是,如果我查看数据库中的原始设置选项,它们(至少)已经通过了wordpress等价的htmlentities()。是否有确切消毒过程的文件?我不想在我自己的验证函数中重复任何内容,我想确保我在回调时正确使用数据。。。。。

UPDATE:为了回应克里斯托弗·戴维斯(ChristopherDavis)的回答,这里有一些更详细的信息。我正在使用register_setting 注册一组设置。此组是使用add_settings_field. 将所有设置的数组(使用register\\u settings回调)传递给单个验证方法,该方法只检查所有内容是否正确(即reg exp检查电子邮件是否为电子邮件,整数是否为整数等)。我没有进行消毒,也没有引用任何Wordpress消毒方法。但是,一个选项值包含一个标记,在数据库中查看时,该标记已转换为HTML实体。我假设Wordpress(至少)在默认情况下对存储在数据库中的任何选项都是这样做的。也许只是通过将数组转换为字符串以将其存储在数据库中的方式?

1 个回复
最合适的回答,由SO网友:chrisguitarguy 整理而成

WordPress不会为您进行任何数据清理。它确实对默认选项进行清理/验证。

您必须传入register_setting 您可以使用自己的验证回调函数,也可以使用其中一个内置函数。

例如,如果您的选项只包含一个字符串,您可以这样做。

<?php
register_setting(\'your_group\', \'your_setting\', \'esc_attr\');
如果查看源代码,可以跟踪WP如何保存选项register_setting (英寸wp-admin/includes/plugin.php):

<?php
/**
 * Register a setting and its sanitization callback
 *
 * @since 2.7.0
 *
 * @param string $option_group A settings group name. Should correspond to a whitelisted option key name.
 *  Default whitelisted option key names include "general," "discussion," and "reading," among others.
 * @param string $option_name The name of an option to sanitize and save.
 * @param unknown_type $sanitize_callback A callback function that sanitizes the option\'s value.
 * @return unknown
 */
function register_setting( $option_group, $option_name, $sanitize_callback = \'\' ) {
    global $new_whitelist_options;

    if ( \'misc\' == $option_group ) {
        _deprecated_argument( __FUNCTION__, \'3.0\', __( \'The miscellaneous options group has been removed. Use another settings group.\' ) );
        $option_group = \'general\';
    }

    $new_whitelist_options[ $option_group ][] = $option_name;
    if ( $sanitize_callback != \'\' )
        add_filter( "sanitize_option_{$option_name}", $sanitize_callback );
}
关键位是函数的最后几行。如果有清理回调,WP会将其添加到过滤器中sanitize_option_{$name}.

该筛选器应用于sanitize_option (英寸wp-includes/formatting.php):

<?php
/**
 * Sanitises various option values based on the nature of the option.
 *
 * This is basically a switch statement which will pass $value through a number
 * of functions depending on the $option.
 *
 * @since 2.0.5
 *
 * @param string $option The name of the option.
 * @param string $value The unsanitised value.
 * @return string Sanitized value.
 */
function sanitize_option($option, $value) {

    switch ( $option ) {
        case \'admin_email\' :
        case \'new_admin_email\' :
            $value = sanitize_email( $value );
            if ( ! is_email( $value ) ) {
                $value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
                if ( function_exists( \'add_settings_error\' ) )
                    add_settings_error( $option, \'invalid_admin_email\', __( \'The email address entered did not appear to be a valid email address. Please enter a valid email address.\' ) );
            }
            break;

        case \'thumbnail_size_w\':
        case \'thumbnail_size_h\':
        case \'medium_size_w\':
        case \'medium_size_h\':
        case \'large_size_w\':
        case \'large_size_h\':
        case \'embed_size_h\':
        case \'default_post_edit_rows\':
        case \'mailserver_port\':
        case \'comment_max_links\':
        case \'page_on_front\':
        case \'page_for_posts\':
        case \'rss_excerpt_length\':
        case \'default_category\':
        case \'default_email_category\':
        case \'default_link_category\':
        case \'close_comments_days_old\':
        case \'comments_per_page\':
        case \'thread_comments_depth\':
        case \'users_can_register\':
        case \'start_of_week\':
            $value = absint( $value );
            break;

        case \'embed_size_w\':
            if ( \'\' !== $value )
                $value = absint( $value );
            break;

        case \'posts_per_page\':
        case \'posts_per_rss\':
            $value = (int) $value;
            if ( empty($value) )
                $value = 1;
            if ( $value < -1 )
                $value = abs($value);
            break;

        case \'default_ping_status\':
        case \'default_comment_status\':
            // Options that if not there have 0 value but need to be something like "closed"
            if ( $value == \'0\' || $value == \'\')
                $value = \'closed\';
            break;

        case \'blogdescription\':
        case \'blogname\':
            $value = addslashes($value);
            $value = wp_filter_post_kses( $value ); // calls stripslashes then addslashes
            $value = stripslashes($value);
            $value = esc_html( $value );
            break;

        case \'blog_charset\':
            $value = preg_replace(\'/[^a-zA-Z0-9_-]/\', \'\', $value); // strips slashes
            break;

        case \'date_format\':
        case \'time_format\':
        case \'mailserver_url\':
        case \'mailserver_login\':
        case \'mailserver_pass\':
        case \'ping_sites\':
        case \'upload_path\':
            $value = strip_tags($value);
            $value = addslashes($value);
            $value = wp_filter_kses($value); // calls stripslashes then addslashes
            $value = stripslashes($value);
            break;

        case \'gmt_offset\':
            $value = preg_replace(\'/[^0-9:.-]/\', \'\', $value); // strips slashes
            break;

        case \'siteurl\':
            if ( (bool)preg_match( \'#http(s?)://(.+)#i\', $value) ) {
                $value = esc_url_raw($value);
            } else {
                $value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
                if ( function_exists(\'add_settings_error\') )
                    add_settings_error(\'siteurl\', \'invalid_siteurl\', __(\'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.\'));
            }
            break;

        case \'home\':
            if ( (bool)preg_match( \'#http(s?)://(.+)#i\', $value) ) {
                $value = esc_url_raw($value);
            } else {
                $value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
                if ( function_exists(\'add_settings_error\') )
                    add_settings_error(\'home\', \'invalid_home\', __(\'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.\'));
            }
            break;

        case \'WPLANG\':
            $allowed = get_available_languages();
            if ( ! in_array( $value, $allowed ) && ! empty( $value ) )
                $value = get_option( $option );
            break;

        case \'timezone_string\':
            $allowed_zones = timezone_identifiers_list();
            if ( ! in_array( $value, $allowed_zones ) && ! empty( $value ) ) {
                $value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
                if ( function_exists(\'add_settings_error\') )
                    add_settings_error(\'timezone_string\', \'invalid_timezone_string\', __(\'The timezone you have entered is not valid. Please select a valid timezone.\') );
            }
            break;

        case \'permalink_structure\':
        case \'category_base\':
        case \'tag_base\':
            $value = esc_url_raw( $value );
            $value = str_replace( \'http://\', \'\', $value );
            break;
    }

    $value = apply_filters("sanitize_option_{$option}", $value, $option);

    return $value;
}
正如您所看到的,有很多情况可以处理所有内置的,但没有默认的清理。

已在中调用清理选项update_option 在数据进入数据库之前进行清理/验证。

<?php
/**
 * Update the value of an option that was already added.
 *
 * You do not need to serialize values. If the value needs to be serialized, then
 * it will be serialized before it is inserted into the database. Remember,
 * resources can not be serialized or added as an option.
 *
 * If the option does not exist, then the option will be added with the option
 * value, but you will not be able to set whether it is autoloaded. If you want
 * to set whether an option is autoloaded, then you need to use the add_option().
 *
 * @since 1.0.0
 * @package WordPress
 * @subpackage Option
 *
 * @uses apply_filters() Calls \'pre_update_option_$option\' hook to allow overwriting the
 *  option value to be stored.
 * @uses do_action() Calls \'update_option\' hook before updating the option.
 * @uses do_action() Calls \'update_option_$option\' and \'updated_option\' hooks on success.
 *
 * @param string $option Option name. Expected to not be SQL-escaped.
 * @param mixed $newvalue Option value. Expected to not be SQL-escaped.
 * @return bool False if value was not updated and true if value was updated.
 */
function update_option( $option, $newvalue ) {
    global $wpdb;

    $option = trim($option);
    if ( empty($option) )
        return false;

    wp_protect_special_option( $option );

    if ( is_object($newvalue) )
        $newvalue = clone $newvalue;

    $newvalue = sanitize_option( $option, $newvalue );
    $oldvalue = get_option( $option );
    $newvalue = apply_filters( \'pre_update_option_\' . $option, $newvalue, $oldvalue );

    // If the new and old values are the same, no need to update.
    if ( $newvalue === $oldvalue )
        return false;

    if ( false === $oldvalue )
        return add_option( $option, $newvalue );

    $notoptions = wp_cache_get( \'notoptions\', \'options\' );
    if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
        unset( $notoptions[$option] );
        wp_cache_set( \'notoptions\', $notoptions, \'options\' );
    }

    $_newvalue = $newvalue;
    $newvalue = maybe_serialize( $newvalue );

    do_action( \'update_option\', $option, $oldvalue, $_newvalue );
    if ( ! defined( \'WP_INSTALLING\' ) ) {
        $alloptions = wp_load_alloptions();
        if ( isset( $alloptions[$option] ) ) {
            $alloptions[$option] = $_newvalue;
            wp_cache_set( \'alloptions\', $alloptions, \'options\' );
        } else {
            wp_cache_set( $option, $_newvalue, \'options\' );
        }
    }

    $result = $wpdb->update( $wpdb->options, array( \'option_value\' => $newvalue ), array( \'option_name\' => $option ) );

    if ( $result ) {
        do_action( "update_option_{$option}", $oldvalue, $_newvalue );
        do_action( \'updated_option\', $option, $oldvalue, $_newvalue );
        return true;
    }
    return false;
}
那有点冗长。我只是想展示一下你能经历并弄明白这类事情的过程。

Edit

应该注意的是,选项数组将被序列化(通过maybe_serialize).

结束

相关推荐

Corrupt Wordpress Database

我认为这是最奇怪的文字印刷问题。一个拥有大量帖子数据库的客户网站已经有了自己的想法。前一分钟一切似乎都很好,接下来的帖子、类别和标签都不见了。此时仪表板告诉我9个类别中有2309个帖子,但当我单击admin中的categories链接时,列表中没有任何帖子。我可以在admin中看到所有帖子,但尽管它们过去被分配到类别并列出标签,但现在它们都“未分类”,没有标签。很明显,wordpress数据库在某种程度上已经损坏,但从哪里开始尝试修复呢!?以下是我迄今为止测试的内容:插件–我关闭了所有当前的插件。主题–我