问题描述

$wpdb 查询方法将所有查询结果作为字符串返回。例如,’ID’ 列将返回一个字符串值,如'42'而不是整数 42

有没有办法配置 WP 数据库类以使数据库内容类型与 PHP types 匹配?或者我需要继续手动如下所示?

$results = $wpdb->get_results('SELECT * FROM my_table');

foreach ($results as $result)
{
    // All integer values
    foreach (array('id', 'user_id', 'comment_count') as $field)
    {
        $result->$field = (int) $result->$field;
    }
    // All float values
    foreach (array('price') as $field)
    {
        $result->$field = (float) $result->$field;
    }
    // All boolean values
    foreach (array('is_open', 'is_confirmed') as $field)
    {
        $result->$field = (bool) $result->$field;
    }
    // Etc.
}

为什么麻烦,你可能会想?那么,对于初学者来说,干净的代码是有趣的。整数值不应该作为字符串存储。当您创建一个自定义函数来查找某个东西时,例如,我喜欢根据传递的参数的数据类型区分该字段以查找:

function load_product($id_or_slug)
{
    if (is_int($id_or_slug))
    {
        // Look up by ID
    }
    else
    {
        // Look up by slug
    }
}

最佳解决方法

没有办法自动使 wpdb 这样做。这实际上是 WordPress 不会发生的 PHP 的限制。 wpdb 没有任何可以帮助你的钩子或动作,所以你可以做的最好的事情是编写你自己的包装函数,并通过它来运行你的查询,以避免重复你自己。

首先,您可以查看 http://us2.php.net/manual/en/function.mysql-fetch-field.php 以使您的包装更加动态。

其次,wpdb 将这些信息存储在 wpdb :: col_info 中,可以通过 wpdb :: get_col_info() 进行访问。每个查询后该变量被覆盖,所以你必须立即访问它。此外,它是数字索引,所以你需要知道你的字段在哪个顺序 (或循环,这是一个不必要的工作量) 。

只是从这里的臀部拍摄,但像…

function get_typed_results($sql, $output = OBJECT) {
    global $wpdb;
    $rows = $wpdb->get_results($sql, ARRAY_N);
    $new_result = array();
    foreach ($rows as $row) {
        $new_row = array();
        foreach ($row as $i => $value) {
            if ( $wpdb->col_info[$i]->numeric ) {
                if ( $wpdb->col_info[$i]->type == 'float' || $wpdb->col_info[$i]->type == 'double' )
                    $new_row[$wpdb->col_info[$i]->name] = (float)$value;
                elseif ( $wpdb->col_info[$i]->type == 'bool' || $wpdb->col_info[$i]->type == 'boolean' )
                    $new_row[$wpdb->col_info[$i]->name] = (bool)$value;
                else
                    $new_row[$wpdb->col_info[$i]->name] = (int)$value;
            }
            elseif ( $wpdb->col_info[$i]->type == 'datetime' )
                $new_row[$wpdb->col_info[$i]->name] = strtotime($value);
            else
                $new_row[$wpdb->col_info[$i]->name] = $value;
        }
        if ($output == ARRAY_A) $new_result[] = $new_row;
        elseif ($output == OBJECT) $new_result[] = (object)$new_row;
        else $new_result[] = array_values($new_row);
    }
    return $new_result;
}

我实际上并不知道它返回的是什么类型的,如果它们是 float 或 double 或者是什么,那么你需要测试它,并在适当的时候修正它。此外,我认为布尔被认为是数字,但也许这是不正确的 – 再次测试。祝你好运!

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。