How to Create Your MU Online Server Website from Scratch
Complete guide to building a MU Online private server website: web stack setup, SQL Server integration, account registration and ranking pages.
Overview
Building a website for your MU Online private server is a critical step for giving players a central hub for account registration, rankings, event information and support. This guide covers full web stack installation, SQL Server integration with MuServer's database, and configuration of essential features.
MuOnline). Adjust paths and versions to match your environment.Prerequisites
Before you start, make sure you have:
- Windows Server 2008 R2 or later (or Windows 10/11 for local testing)
- SQL Server 2012 or later with the
MuOnlinedatabase already created by MuServer - Administrator access to the server
- A domain or public IP pointed at the server (for production)
Step 1 — Install IIS and PHP
1.1 Open Server Manager → Add Roles and Features → select Web Server (IIS).
Check the following additional components:
- CGI (required for PHP via FastCGI)
- Basic Authentication
- Static and Dynamic Content Compression
- URL Rewrite (download separately from the Microsoft website as URL Rewrite Module)
1.2 Download PHP 8.1 (Non-Thread-Safe, x64) from https://windows.php.net/download/ and extract it to C:\PHP\.
1.3 Rename C:\PHP\php.ini-production to C:\PHP\php.ini and edit the following lines:
; C:\PHP\php.ini — essential settings for MU website
extension_dir = "C:\PHP\ext"
extension=pdo_sqlsrv ; SQL Server PDO driver
extension=sqlsrv ; SQL Server alternative driver
extension=mbstring
extension=openssl
extension=curl
extension=gd
date.timezone = "America/New_York"
upload_max_filesize = 10M
post_max_size = 10M
max_execution_time = 60
1.4 Configure IIS to use PHP as a FastCGI handler:
Open IIS Manager → default site → Handler Mappings → Add Module Mapping:
Request path: *.php
Module: FastCgiModule
Executable: C:\PHP\php-cgi.exe
Name: PHP_via_FastCGI
Step 2 — Create the Website Directory Structure
Set the site root to C:\inetpub\muweb\ and create the following structure:
C:\inetpub\muweb\
├── index.php
├── register.php
├── ranking.php
├── events.php
├── admin\
│ ├── index.php
│ └── players.php
├── assets\
│ ├── css\
│ ├── js\
│ └── img\
├── includes\
│ ├── db.php ← SQL Server connection
│ ├── functions.php
│ └── config.php
└── web.config ← IIS rewrite rules
Create the directory and apply permissions via PowerShell:
New-Item -ItemType Directory -Path "C:\inetpub\muweb\includes"
New-Item -ItemType Directory -Path "C:\inetpub\muweb\admin"
New-Item -ItemType Directory -Path "C:\inetpub\muweb\assets\css"
# Read permission for IIS_IUSRS
icacls "C:\inetpub\muweb" /grant "IIS_IUSRS:(OI)(CI)R" /T
Step 3 — Configure the SQL Server Database Connection
Edit C:\inetpub\muweb\includes\config.php:
<?php
// includes/config.php — central configuration for MU website
define('DB_HOST', '127.0.0.1'); // SQL Server IP (localhost or remote IP)
define('DB_NAME', 'MuOnline'); // default MuServer database name
define('DB_USER', 'mu_web'); // SQL user with limited permissions
define('DB_PASS', 'YourPasswordHere');
define('DB_PORT', 1433);
define('SITE_NAME', 'My MU Server');
define('SITE_URL', 'http://yourdomain.com');
define('MAX_CHARS', 4); // characters per account
define('SERVER_VERSION', 'Season 6 Episode 3');
Create the connection file C:\inetpub\muweb\includes\db.php:
<?php
// includes/db.php — PDO connection to SQL Server
require_once __DIR__ . '/config.php';
try {
$dsn = sprintf(
'sqlsrv:Server=%s,%d;Database=%s;TrustServerCertificate=1',
DB_HOST, DB_PORT, DB_NAME
);
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
]);
} catch (PDOException $e) {
die('Database connection error: ' . $e->getMessage());
}
sa account for web connections. Create a dedicated SQL user with restricted permissions on only the necessary tables. Run in SQL Server Management Studio: CREATE LOGIN mu_web WITH PASSWORD='YourPasswordHere'; USE MuOnline; CREATE USER mu_web FOR LOGIN mu_web; GRANT SELECT, INSERT ON MEMB_INFO TO mu_web;Step 4 — Build the Account Registration System
The main account table in MuServer Season 6 is MEMB_INFO in the MuOnline database. Relevant columns:
-- Key columns in the MEMB_INFO table (Season 6)
-- memb__id varchar(10) -- login (max 10 chars)
-- memb__pw varchar(10) -- password (plain text in default S6)
-- memb_name varchar(10) -- member name
-- memb_guid int -- unique ID (identity)
-- mail_addr varchar(60) -- email address
-- bloc_code tinyint -- 0=active, 1=blocked
-- ctl1_code tinyint -- account level (0=player, 255=GM)
Create C:\inetpub\muweb\register.php:
<?php
require_once 'includes/db.php';
require_once 'includes/functions.php';
$error = '';
$success = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$login = trim($_POST['login'] ?? '');
$pass = trim($_POST['pass'] ?? '');
$email = trim($_POST['email'] ?? '');
$name = trim($_POST['name'] ?? '');
// Basic validation
if (!preg_match('/^[a-zA-Z0-9]{4,10}$/', $login)) {
$error = 'Login must be 4–10 alphanumeric characters.';
} elseif (strlen($pass) < 4 || strlen($pass) > 10) {
$error = 'Password must be 4–10 characters.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Invalid email address.';
} else {
// Check if login already exists
$stmt = $pdo->prepare("SELECT COUNT(*) FROM MEMB_INFO WHERE memb__id = ?");
$stmt->execute([$login]);
if ($stmt->fetchColumn() > 0) {
$error = 'This login is already in use.';
} else {
// Insert new account
$stmt = $pdo->prepare("
INSERT INTO MEMB_INFO
(memb__id, memb__pw, memb_name, mail_addr, bloc_code, ctl1_code)
VALUES
(?, ?, ?, ?, 0, 0)
");
$stmt->execute([$login, $pass, $name, $email]);
$success = true;
}
}
}
?>
memb__pw field in the database and adapt the insert: $pass = md5($_POST['pass']);Step 5 — Build the Ranking Page
The character ranking reads from the Character table in the MuOnline database:
<?php
// ranking.php — top 10 characters by resets and level
require_once 'includes/db.php';
$stmt = $pdo->query("
SELECT TOP 10
Name AS name,
Class AS class,
cLevel AS level,
Resets AS resets,
PkCount AS pks,
GuildName AS guild
FROM Character
ORDER BY Resets DESC, cLevel DESC
");
$ranking = $stmt->fetchAll();
To display the class name instead of the numeric code, add this helper function:
// includes/functions.php
function className(int $code): string {
$classes = [
0 => 'Dark Wizard', 1 => 'Soul Master',
16 => 'Dark Knight', 17 => 'Blade Knight',
32 => 'Fairy Elf', 33 => 'Muse Elf',
48 => 'Magic Gladiator',
64 => 'Dark Lord',
80 => 'Summoner',
96 => 'Rage Fighter',
];
return $classes[$code] ?? "Class $code";
}
Step 6 — Configure web.config for Clean URLs
Create C:\inetpub\muweb\web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="PHP extensionless URLs" stopProcessing="true">
<match url="^([^.]+)$" />
<conditions>
<add input="{REQUEST_FILENAME}.php" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.php" />
</rule>
</rules>
</rewrite>
<defaultDocument>
<files>
<add value="index.php" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
Step 7 — Configure SQL Server Permissions for the Web User
Run the following in SQL Server Management Studio (SSMS) as sa:
-- Create login and user for the website
USE [master];
CREATE LOGIN [mu_web] WITH PASSWORD = 'YourSecurePassword123!',
DEFAULT_DATABASE = [MuOnline],
CHECK_EXPIRATION = OFF,
CHECK_POLICY = OFF;
USE [MuOnline];
CREATE USER [mu_web] FOR LOGIN [mu_web];
-- Minimum required permissions
GRANT SELECT ON [dbo].[MEMB_INFO] TO [mu_web];
GRANT INSERT ON [dbo].[MEMB_INFO] TO [mu_web];
GRANT SELECT ON [dbo].[Character] TO [mu_web];
GRANT SELECT ON [dbo].[Guild] TO [mu_web];
GRANT SELECT ON [dbo].[GuildMember] TO [mu_web];
-- Deny access to sensitive tables
DENY SELECT ON [dbo].[WAREHOUSE] TO [mu_web];
DENY SELECT ON [dbo].[AccountCharacter] TO [mu_web];
Troubleshooting Common Issues
"Could not find driver" error when connecting to SQL Server
Verify that the PDO SQL Server drivers are installed. Download Microsoft Drivers for PHP for SQL Server from https://learn.microsoft.com/en-us/sql/connect/php/ and place the .dll files in C:\PHP\ext\. Confirm that php.ini has extension=sqlsrv and extension=pdo_sqlsrv without a leading semicolon.
Blank page after configuring PHP
Temporarily enable error display in C:\PHP\php.ini:
display_errors = On
error_reporting = E_ALL
Restart IIS with iisreset in the command prompt and reload the page.
Characters not showing up in the ranking
Confirm that the Character table exists in the MuOnline database and that mu_web has SELECT permission. Run in SSMS:
SELECT TOP 5 Name, cLevel, Resets FROM MuOnline.dbo.Character;
C:\xampp\, place your site files in C:\xampp\htdocs\muweb\ and configure the php_sqlsrv.dll extension in C:\xampp\php\php.ini to connect to your local SQL Server instance.Perguntas frequentes
Which web stack is recommended for MU Online private servers?
For beginners, XAMPP with PHP 7.4 is the simplest option. For Season 6 servers using SQL Server, webEngineNET (ASP.NET + IIS) is preferred because it ships with native MSSQL connectors and ready-made MU templates.
Can I use MySQL instead of SQL Server?
Yes, but it requires adapting queries. Most MuServer table structures use SQL Server-specific types (smalldatetime, tinyint). If you use MySQL, convert the types and adjust stored procedures manually.
How do I protect the website admin panel?
Place the /admin directory outside the web root, use HTTPS with an SSL certificate (Let's Encrypt), implement two-factor authentication, and restrict access by IP in IIS or via .htaccess in Apache.
Does website account registration create the character automatically?
No. Registration only creates a record in the MEMB_INFO table of the MuOnline database. The character is created by the game client itself after the first login, on the character selection screen.