Mass import users into WordPress

Many, many users

I am working on a complex blog/e-commerce system together with my colleagues at @ntw. I had to import some 10.000 users into WP. WordPress doesn’t feature any automatic “import users” wizard, so it’s a bit like smuggling tons of containers, isn’t it?

How it is done

The task was easier than expected. The basic idea is leveraging on the `wp_insert_user($userdata)` function, defined in `wp-includes/registration.php`. If you look at the source, you’ll see that `$userdata` is an array containing a number of keys:

  • The $userdata array can contain the following fields:
  • ‘ID’ – An integer that will be used for updating an existing user.
  • ‘user_pass’ – A string that contains the plain text password for the user.
  • ‘user_login’ – A string that contains the user’s username for logging in.
  • ‘user_nicename’ – A string that contains a nicer looking name for the user.
  • The default is the user’s username.

The other keys are `user_url`,`user_email`, `display_name`, `nickname`, `first_name`, `last_name`, `description`, `rich_editing`, `user_registered`, `role`, `jabber`, `aim`, `yim`; for more detal consult the source itself.

My script goes like this:

<?php
include 'wp-blog-header.php';
include 'wp-includes/registration.php';
include 'wp-includes/pluggable.php';
ini_set("memory_limit","1024M");
ini_set("max_execution_time", "240");
global $wpdb;
?>

<h1>Importazione utenti EC</h1>

<?php
$connection = mysql_connect("host", "user", "password") or die("Unable to connect to MySQL");
mysql_select_db("database", $connection) or die("Unable to connect to the database");
$result = mysql_query("SELECT * FROM source_users ;");
	while ($row = mysql_fetch_object($result)) {
		echo "<strong>ID:</strong>".$row->id." <strong>login:</strong>".$row->user_name." <strong>password:</strong> ".$row->password." <strong>e-mail:</strong>".$row->email_address." <strong>name:</strong> ".$row->name." <strong>surname:</strong> ".$row->surname."<br/>";
		// Add the ID to trick WP
		$add_id = "INSERT INTO ".$wpdb->users." (id, user_login) VALUES (".$row->id.",'"."$row->user_name"."' ); ";
		 mysql_query($add_id) or die(mysql_error());
		// Add the rest
		$userdata = array(
		 'ID' => $row->id,
		 'user_login' => $row->user_name,
		 'user_pass' => wp_hash_password($row->password),
		 'user_nicename' => $row->user_name,
		 'user_email' => $row->email_address,
		 'first_name'  => $row->name,
		 'last_name'  => $row->surname,
		 'role' => 'subscriber'
		);
		wp_insert_user($userdata) ;
	}
}
mysql_close($connection);

Some highlights:

  • Import all the WP files you need
  • Change PHP memory and time limits if you have many records
  • Explicitly encrypt the password with `wp_hash_password`. I have no idea why this is necessary, the WP code should do this by itself; but trust me, it is.

Since we are using the `wp_insert_user()` function, WP will crate records both in the users and in the usermeta tables.

Some warning

This huge amount of users could conflict with your php settings. To get WP working properly I had to add this line to `wp-config.php`:

	define('WP_MEMORY_LIMIT', '64M');

Without it I could not get the users list in the admin session. I also [filed a bug](http://core.trac.wordpress.org/ticket/11151), but this last line should keep you on the safe side.
Enjoy!