我能否在函数COLUMN_DEFAULT中简化查询的使用

时间:2016-08-02 作者:Hermants

在下面的function column\\u default中,我有几个案例执行几乎相同的查询。

是否可以对所有3种情况仅使用1个查询?如果是,我如何在下面的示例中使用它?谢谢你帮助我。

function column_default($item, $column_name){
        global $wpdb;

 /*             
  if ( ! in_array( $column_name, [\'id\', \'user_id\', \'user_email\', \'answer\', \'answer_time\', \'ip_address\' ] ) )
    return \'\';

$sql = "SELECT $column_name as result 
        FROM {$wpdb->prefix}rdp_participants_answers 
        WHERE user_id = %d ORDER BY id DESC LIMIT 1 ";

$query = $wpdb->get_row( $wpdb->prepare( $sql, $item[ \'ID\' ] ) );

if ( is_object( $query ) )
    return $query->result;
    */      
    switch($column_name){
//      case \'id\':              return $item[\'ID\'];
    case \'user_id\':             return $item[\'ID\'];
    case \'user_email\':          $user_info = get_userdata($item[\'ID\']);
                                return $user_info->user_email;
    case \'display_name\':        $user_info = get_userdata($item[\'ID\']);
                                return $user_info->display_name;            
    case \'city\':                return get_user_meta($item[\'ID\'], \'city\', true);
    case \'age\':                 return get_user_meta($item[\'ID\'], \'age\', true);

    case \'user_status\':             $user_status = get_user_meta($item[\'ID\'], \'status\', true);

            if($user_status == 1) { 
                return \'
                <img src="\'.RDP_URL.\'images/icon_status_green.gif" />
                <a href="\'.get_admin_url().\'admin.php?page=rdp_admin_participants&off=\'.$item[\'ID\'].\'&status=update"><img src="\'.RDP_URL.\'images/icon_status_red_light.gif" /><a/> 
                \'; } 
                elseif($user_status == 0) { 
                return \'<a href="\'.get_admin_url().\'admin.php?page=rdp_admin_participants&on=\'.$item[\'ID\'].\'&status=update"><img src="\'.RDP_URL.\'images/icon_status_green_light.gif" /><a/> 
                <img src="\'.RDP_URL.\'images/icon_status_red.gif" />\';
            }
    case \'answer\':                  
            $arrAnswer = $wpdb->get_row( "SELECT answer FROM {$wpdb->prefix}rdp_participants_answers WHERE user_id = ".$item[\'ID\']." ORDER BY id DESC LIMIT 1 " );
                    if(count($arrAnswer) == null)
                    return 0;
                    else
                    return $arrAnswer->answer;  
    case \'answer_time\':         
            $arranswerTime = $wpdb->get_row( "SELECT answer_time FROM {$wpdb->prefix}rdp_participants_answers WHERE user_id = ".$item[\'ID\']." ORDER BY id DESC LIMIT 1 " );
                    if(count($arranswerTime) == null)
                    return 0;
                    else
                    return $arranswerTime->answer_time; 
    case \'ip_address\':          
            $arrIPAddress = $wpdb->get_row( "SELECT ip_address FROM {$wpdb->prefix}rdp_participants_answers WHERE user_id = ".$item[\'ID\']." ORDER BY id DESC LIMIT 1 " );
                    if(count($arrIPAddress) == null)
                    return 0;
                    else
                    return $arrIPAddress->ip_address;   
    case \'user_registered\': return $item[\'user_registered\'];
    case \'actions\':                 return $item[$column_name];
    default:                        return \'<a href="\'.get_admin_url().\'admin.php?page=rdp_admin_participants&edit_rdp=\'.$item[\'ID\'].\'" class="page-title-action">Edit</a><a href="\'.get_admin_url().\'admin.php?page=rdp_admin_participants&view_rdp=\'.$item[\'ID\'].\'" class="page-title-action">View</a>\'; 
    }
}
$query = "SELECT * FROM wp_users AS usr 
        JOIN wp_usermeta AS meta ON meta.user_id = usr.ID 
        LEFT JOIN wp_rdp_participants_answers as ans ON ans.user_id = usr.ID
        WHERE ans.answer IS NOT NULL
        GROUP BY usr.ID, usr.user_email ORDER BY ans.id ASC";               


$data = $wpdb->get_results($query,ARRAY_A);
$this->items = $data;

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

您的问题主要是PHP逻辑的变化,而不是WordPress。不管怎样,我们是来帮助你的,这在其他网站上也会是离题的,所以…

不幸的是,您必须访问全局变量才能使用当前的数据库连接。创造他人(6个月内完成)生活更轻松import global variables always at the top of a function body.

如果您稍后搜索对该变量的所有访问,您将为此感谢您过去的自己。:)
在我的代码中,我主要使用类方法作为回调,并传递$wpdb 对象作为类构造函数的依赖项,因此我只需在代码层次结构的最顶层接触一次全局变量。

每次使用几乎相同的查询时,请查看差异,并将其作为变量或统一起来。在您的情况下,您可以使用$column_name 变量,因为它与数据库表列名和whitelist of valid strings. 此外,您还可以重命名生成的变量:SELECT x as foo FROM …

  • $item[ \'ID\' ] 是未知的,它可以是任何东西。总是prepare unknown values before you send them to the database. $wpdb has方法prepare() 其工作原理类似于sprintf().

    你不需要跑步count() 在查询结果上。只有成功才能获得对象,因此针对is_object() 足够好了。

    将该代码移动到separate function. 它做得太多了。

    所有这些点的示例代码:

    function answer_query( $column_name, $id )
    {
        global $wpdb;
    
        $sql = "SELECT %s as result
                FROM {$wpdb->prefix}rdp_participants_answers
                WHERE user_id = %d ORDER BY id DESC LIMIT 1 ";
    
        $query = $wpdb->get_row( $wpdb->prepare( $sql, $column_name, $id ) );
    
        if ( is_object( $query ) )
            return $query->result;
    
        return 0;
    }
    
    在你的switch 语句,将代码缩短为:

    case \'answer\':
    case \'answer_time\':
    case \'ip_address\':
        return answer_query( $column_name, (int) $item[\'ID\'] ) );