【问题标题】:WordPress Plugin Broken Due To PHP7 UpgradeWordPress 插件因 PHP7 升级而损坏
【发布时间】:2026-01-14 16:30:01
【问题描述】:

我现在正在维护的另一个开发人员不久前建立的网站已损坏。我已经查看了错误日志,这就是我所看到的:

[04-Apr-2018 05:30:47 UTC] PHP Warning:  count(): Parameter must be an array or an object that implements Countable in /.../.../.../.../plugins/taxonomy-order/taxonomy-order.php on line 280

现在您可能在想……我为什么不更新插件。我希望,该插件不再包含在 WordPress 中,开发人员已删除他/她的帐户并且没有支持选项。所以我现在正在尝试自己解决这个问题。

我找到了导致问题的代码:

if( count( $taxonomies === 1 ) ) $taxonomy = array_shift( $taxonomies );

这里尝试提供更多上下文是整个函数:

public function terms_clauses( $clauses, $taxonomies, $args ) {
    global $wpdb;

    $taxonomies = (array) $taxonomies;

    if( count( $taxonomies === 1 ) ) $taxonomy = array_shift( $taxonomies );
    else return $clauses;

    if( !$this->has_taxonomy_support($taxonomy) ) return $clauses;

    // Fields
    if ( strpos( 'COUNT(*)', $clauses['fields'] ) === false ) $clauses['fields'] .= ', tm.meta_key, tm.meta_value ';

    // Join
    $clauses['join'] .= " LEFT JOIN {$wpdb->termmeta} AS tm ON (t.term_id = tm.term_id AND tm.meta_key = 'order') ";

    // Order
    if( isset( $args['menu_order'] ) && !$args['menu_order'] ) return $clauses; // menu_order is false when not added Order Clause

    // Default to ASC
    if( !isset( $args['menu_order'] ) || !in_array( strtoupper( $args['menu_order'] ), array( 'ASC', 'DESC' ) ) ) $args['menu_order'] = 'ASC';

    $order = "ORDER BY CAST(tm.meta_value AS SIGNED) " . $args['menu_order'];

    if ( $clauses['orderby'] ) {
        $clauses['orderby'] = str_replace('ORDER BY', $order . ',', $clauses['orderby'] );
    }else{
        $clauses['orderby'] = $order;
    }

    return $clauses;
}

及用法:

add_filter( 'terms_clauses', array( $this, 'terms_clauses') , 10, 3 );

不幸的是,PHP 不是我的强项。我想我已经发现这是由于 PHP7 中的新规则导致的错误,但我不确定。

如果有人能帮我解决这个问题,我将非常感激。

干杯, 卢克。

更新

在@Norman 的 cmets 之后,我运行了他建议的代码,这是我得到的输出:

代码:

if( count( $taxonomies ) == 1 ) {
    echo '<pre>';print_r($clauses);
    echo '</pre>';die('call');
}
else {
    return $clauses;
}

结果:

Array
(
    [fields] => t.*, tt.*
    [join] => INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id
    [where] => tt.taxonomy IN ('nav_menu') AND tt.count > 0
    [orderby] => ORDER BY t.name
    [order] => ASC
    [limits] => 
)
call

感谢 Norman 的评论,问题现已解决

【问题讨论】:

  • @Noman 老实说,我不确定如何调试它,我尝试添加'ini_set('display_errors', 'On');,但没有显示任何错误。
  • if( count( $taxonomies === 1 ) ) 这不是将 $taxonomies 设置为 1 作为 int,而您正在计算它吗?
  • if( count( $taxonomies === 1 ) )更改为if( count( $taxonomies ) == 1 ),然后在return $clauses;之前更改echo '&lt;pre&gt;';print_r($clauses);echo '&lt;/pre&gt;';die('call');以调试实际导致的原因
  • 关于“说实话不确定如何调试” - 如果您不想在实时站点上调试,但想查看类似的小东西,并且没有测试环境,你可以使用在线测试器 - 比如phptester.net

标签: php wordpress php-7


【解决方案1】:

您需要更改语句,因为当您获得计数时,您需要单独检查它返回的数据

这不是 PHP 7 的问题而是简单的条件语句错误,你需要确定什么时候使用count,你还需要了解什么时候使用===== 看看区别here

if( count( $taxonomies === 1 ) )

到这个if( count( $taxonomies ) == 1 )

然后echo '&lt;pre&gt;';print_r($clauses);echo '&lt;/pre&gt;';die('call');return $clauses; 之前调试实际原因

【讨论】: