wordpress添加访客ip并保存到后台

Published
2023-03-21
浏览次数 :  155

首先创建添加ip的函数:

function record_visitor_ip() {
  // Validate and sanitize the user agent and IP address variables
  $user_agent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_STRING);
  $visitor_ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);

  if (!$user_agent || !$visitor_ip) {
    // Invalid input, do nothing
    return;
  }

  global $wpdb;
  $table_name = $wpdb->prefix . 'visitor_ips'; // Replace "visitor_ips" with the name of the new table

  // Check if the visitor IP already exists in the table
  $query = $wpdb->prepare("SELECT id FROM $table_name WHERE ip = %s", $visitor_ip);
  $result = $wpdb->get_var($query);

  if (!$result) {
    // Insert the visitor info into the table
    $data = array(
      'ip' => $visitor_ip,
      'browser' => $user_agent,
      'time' => time()
    );

    $wpdb->insert($table_name, $data);
  }
}

记录iP的函数,我们还可以进行扩展,比方说我们要实现同一个ip地址1小时之内不再记录:

function record_visitor_ip() {
  // Validate and sanitize the user agent and IP address variables
  $user_agent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_STRING);
  $visitor_ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);

  if (!$user_agent || !$visitor_ip) {
    // Invalid input, do nothing
    return;
  }

  global $wpdb;
  $table_name = $wpdb->prefix . 'visitor_ips'; // Replace "visitor_ips" with the name of the new table

  // Check if the visitor IP already exists in the table and if it was created less than an hour ago
  $query = $wpdb->prepare("SELECT id FROM $table_name WHERE ip = %s AND time > DATE_SUB(NOW(), INTERVAL 1 HOUR)", $visitor_ip);
  $result = $wpdb->get_var($query);

  if (!$result) {
    // Insert the visitor info into the table
    $data = array(
      'ip' => $visitor_ip,
      'browser' => $user_agent,
      'time' => current_time('mysql')
    );

    $wpdb->insert($table_name, $data);
  }
}

更新后的函数使用DATE_SUB()MySQL函数从当前时间减去一小时,并检查数据库中的时间列是否大于结果。如果IP地址已经存在于数据库中,并且上一个条目是在不到一小时前创建的,则该函数将不执行任何操作。否则,它会将访问者的IP地址、浏览器和当前时间戳插入数据库。

然后通过wp_head钩子挂载到头部:

add_action('wp_head', 'record_visitor_ip');

然后设置主题启动的时候添加数据表:

add_action( 'after_switch_theme', 'my_theme_activation' );


function create_my_table_on_theme_activation() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'visitor_ips'; // Replace "visitor_ips" with the name of the new table
    
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE $table_name (
      id INT NOT NULL AUTO_INCREMENT,
      ip VARCHAR(45) NOT NULL,
      browser VARCHAR(255) NOT NULL,
      time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY  (id)
    ) $charset_collate;";
    
    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}


function my_theme_activation() {
    
    create_my_table_on_theme_activation();
}

然后用wp_list_table在后台展示出来。

class Visitor_IP_List_Table extends WP_List_Table {

  function __construct() {
    parent::__construct( array(
      'singular' => 'visitor',
      'plural' => 'visitors',
      'ajax' => false
    ) );
  }

  function column_default( $item, $column_name ) {
    switch( $column_name ) {
      case 'ip':
      case 'browser':
      case 'time':
        return $item[ $column_name ];
      default:
        return print_r( $item, true );
    }
  }

  function get_columns() {
    $columns = array(
      'ip' => 'IP Address',
      'browser' => 'Browser',
      'time' => 'Visit Time'
    );
    return $columns;
  }

  function prepare_items() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'visitor_ips'; // Replace "visitor_ips" with the name of the new table

    $per_page = 10; // Number of records per page

    $columns = $this->get_columns();
    $hidden = array();
    $sortable = $this->get_sortable_columns();

    $this->_column_headers = array( $columns, $hidden, $sortable );

    $current_page = $this->get_pagenum();

    $total_items = $wpdb->get_var( "SELECT COUNT(id) FROM $table_name" );

    $data = $wpdb->get_results(
      $wpdb->prepare(
        "SELECT * FROM $table_name ORDER BY time DESC LIMIT %d OFFSET %d",
        $per_page,
        ( $current_page - 1 ) * $per_page
      ),
      ARRAY_A
    );

    $this->items = $data;

    $this->set_pagination_args( array(
      'total_items' => $total_items,
      'per_page' => $per_page,
      'total_pages' => ceil( $total_items / $per_page )
    ) );
  }

  function get_sortable_columns() {
    $sortable_columns = array(
      'ip' => array( 'ip', true ),
      'browser' => array( 'browser', true ),
      'time' => array( 'time', true )
    );
    return $sortable_columns;
  }
}

在admin menu page的回调函数里,添加启动wp list table的函数:

function my_admin_menu_callback() {
  $table = new Visitor_IP_List_Table();
  $table->prepare_items();
?>
  <div class="wrap">
    <h2>Visitor IP List</h2>
    <?php $table->display(); ?>
  </div>
<?php
}

然后注册admin page:

function add_visitor_ips_page() {
  add_menu_page(
    'Visitor IPs',
    'Visitor IPs',
    'manage_options',
    'visitor-ips',
    'display_visitor_ips_page',
    'dashicons-admin-generic',
    30
  );
}
add_action('admin_menu', 'add_visitor_ips_page');

中间的细节需要微调,但是管用。

如果要添加搜索功能,需要修改一些地方,下面是完整版本代码:

class Record_Visitor_IP_List_Table extends WP_List_Table {

  function __construct() {
    parent::__construct( array(
      'singular' => 'visitor',
      'plural' => 'visitors',
      'ajax' => false
    ) );
  }

  function column_default( $item, $column_name ) {
    switch( $column_name ) {
      case 'id' :
      case 'ip':
      case 'browser':
      case 'time':
        return $item[ $column_name ];
      default:
        return print_r( $item, true );
    }
  }

  function get_columns() {
    $columns = array(
      'cb' => '<input type="checkbox" />',
      'id'         => 'ID',
      'ip' => 'IP Address',
      'browser' => 'Browser',
      'time' => 'Visit Time'
    );
    return $columns;
  }

  function prepare_items() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'visitor_ips'; // Replace "visitor_ips" with the name of the new table

    $per_page = 20; // Number of records per page

    $columns = $this->get_columns();
    $hidden = array();
    $sortable = $this->get_sortable_columns();

    $this->_column_headers = array( $columns, $hidden, $sortable );

    $current_page = $this->get_pagenum();


    //按最新时间排序
    $orderby = ( isset( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'time';
    $order = ( isset( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'DESC';




    $offset = ( $current_page - 1 ) * $per_page;

    $total_items = $wpdb->get_var( "SELECT COUNT(id) FROM $table_name" );

    $search_query = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : '';


        $where = '';

        if ( ! empty( $search_query ) ) {
            $where = "WHERE id LIKE '%$search_query%' OR ip LIKE '%$search_query%' OR browser LIKE '%$search_query%' OR time LIKE '%$search_query%'";
        }

    $data = $wpdb->get_results( "SELECT * FROM $table_name $where ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", ARRAY_A );

    $this->items = $data;

    $this->set_pagination_args( array(
      'total_items' => $total_items,
      'per_page' => $per_page,
      'total_pages' => ceil( $total_items / $per_page )
    ) );
  }

  function get_sortable_columns() {
    $sortable_columns = array(
      'id'  => 'id',
      'ip' => array( 'ip', true ),
      'browser' => array( 'browser', true ),
      'time' => array( 'time', true )
    );
    return $sortable_columns;
  }

public function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="submission[]" value="%s" />', absint( $item['id'] )
        );
    }


}

//调出wp list table 
function display_visitor_ips_record_page() {
 

  $table = new Record_Visitor_IP_List_Table();
  $table->prepare_items();
    echo '<form method="post">';
  $table->search_box( 'Search Submissions', 'ha_submission_search' );
  echo '</form>';

?>

  <div class="wrap">
    <h2>Visitor IP List</h2>
    <?php $table->display(); ?>
  </div>
<?php
}

Top