如何修复sprintf和日期时间格式冲突?

时间:2015-10-21 04:41:36

标签: php mysql datetime printf contact-form-7

我正在尝试修改用于导入NinjaForms数据的代码段,以便与Contact Form 7(CF7)一起使用。当我在phpMyAdmin中测试它时,我做了一个查询,它产生与我在MySQL中的NinjaForms中看到的CF7表单数据类似的结果。

然而,当我为我的CF7修改运行php代码时,当它到达prepare函数时,我的$ query结束为空并抛出错误。 NinjaForms代码正常工作。我相信原因是我正在使用post_date变量的日期格式。这使得准备工作变得混乱。运行sprintf以替换%s和%f的函数。时间格式也使用%s格式指示符秒。我想Sprintf会把它看作一个字符串变量。

我可以使用哪些选项来运行此操作而不是混淆sprintf?

我对CF7的修改是:

$query =
"SELECT submit_time AS ID, from_unixtime(submit_time, '%Y-%m-%d %h:%i:%s') AS post_date, field_value AS user_login, form_name  AS form_title" .
"FROM {$wpdb->prefix}cf7dbplugin_submits" .
"WHERE field_order = %F";

$qparms = array(9999);
if ($date_from) {
  $query .= " AND from_unixtime(submit_time, '%Y-%m-%d %h:%i:%s')>= %s";
  $qparms[] = "$date_from 00:00:00";
}
if ($date_to) {
  $query .= " AND from_unixtime(submit_time, '%Y-%m-%d %h:%i:%s')<= %s";
  $qparms[] = "$date_to 23:59:59";
}
$query .= " ORDER BY submit_time";

$query = $wpdb->prepare($query, $qparms);
if (empty($query)) {
  $out['errmsg'] = "Internal error: wpdb prepare() failed.";
  return;
}

$rows = $wpdb->get_results($query, ARRAY_A);
foreach ($rows as $row) {
  $out['list'][] = array(
    'postid'   => $row['ID'],
    'user'     => (isset($row['user_login']) ? $row['user_login'] : ''),
    'datetime' => $row['post_date'],
    'type'     => $row['form_title'],
  );
}

在MySQL中,$ query产生以下内容:

ID              post_date           user_login          form_title
1445125066.4375 2015-10-17 04:37:46 clinicianusername   Demographics
1445232513.8809 2015-10-18 10:28:33 clinicianusername   Demographics

我使用的NinjaForms代码作为我的模型:

$query =
  "SELECT p.ID, p.post_date, u.user_login, om.meta_value AS form_title " .
  "FROM $wpdb->posts AS p " .
  "JOIN $wpdb->postmeta AS pm ON pm.post_id = p.ID AND pm.meta_key = '_form_id' " .
  "JOIN {$wpdb->prefix}nf_objectmeta AS om ON om.object_id = pm.meta_value AND om.meta_key = 'form_title' " .
  "LEFT JOIN $wpdb->users AS u ON u.ID = p.post_author " .
  "WHERE p.post_type = %s";
$qparms = array('nf_sub');
if ($date_from) {
  $query .= " AND p.post_date >= %s";
  $qparms[] = "$date_from 00:00:00";
}
if ($date_to) {
  $query .= " AND p.post_date <= %s";
  $qparms[] = "$date_to 23:59:59";
}
$query .= " ORDER BY p.post_date";

$query = $wpdb->prepare($query, $qparms);
if (empty($query)) {
  $out['errmsg'] = "Internal error: wpdb prepare() failed.";
  return;
}
$rows = $wpdb->get_results($query, ARRAY_A);
foreach ($rows as $row) {
  $out['list'][] = array(
    'postid'   => $row['ID'],
    'user'     => (isset($row['user_login']) ? $row['user_login'] : ''),
    'datetime' => $row['post_date'],
    'type'     => $row['form_title'],
  );
}

在MySQL中,$ query从NinjaForms

生成这个
ID  post_date               user_login          form_title
119 2015-10-05 05:36:24     clinicianusername   Demographics
120 2015-10-10 07:44:22     clinicianusername   Demographics

WordPress的准备功能

public function prepare( $query, $args ) {
    if ( is_null( $query ) )
        return;

    // This is not meant to be foolproof -- but it will catch obviously incorrect usage.
    if ( strpos( $query, '%' ) === false ) {
        _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
    }

    $args = func_get_args();
    array_shift( $args );
    // If args were passed as an array (as in vsprintf), move them up
    if ( isset( $args[0] ) && is_array($args[0]) )
        $args = $args[0];
    $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
    $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
    $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
    $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
    array_walk( $args, array( $this, 'escape_by_ref' ) );
    return @vsprintf( $query, $args );
}

0 个答案:

没有答案