PHP LogoUser Profile Page

A User Profile Page is a dedicated section within a web application where individual users can view and manage their personal information, settings, and sometimes their activity history. It serves as a central hub for a user's account details and preferences.

Key Features and Components:
1. Display User Information: Shows static details like username, full name, email address, profile picture, join date, and a short bio.
2. Edit Profile: Allows users to update their editable information, such as full name, email, profile picture, and bio. This typically involves a form for input and server-side processing to save changes to a database.
3. Change Password: Provides a secure way for users to update their account password. This often requires entering the current password for verification, along with the new password and a confirmation.
4. Privacy Settings: Users might be able to control the visibility of their profile, manage email notifications, or configure other privacy-related preferences.
5. User Activity/Content: Depending on the application, a profile page might display content created by the user (e.g., posts, comments, uploaded files) or their recent activity within the platform.
6. Account Management: Options like deleting the account, managing connected third-party accounts, or viewing billing information (for e-commerce/subscription services).

Technical Considerations:
* Authentication and Authorization: The page must ensure that only the logged-in user can access and modify their own profile data. This involves session management and verifying user identity.
* Database Interaction: User data is typically stored in a database. The profile page needs to fetch current user data for display and update it upon submission of edit forms.
* Form Handling and Validation: All input fields (e.g., name, email, new password) must be properly validated on both client-side (for user experience) and server-side (for security and data integrity). Server-side validation is crucial.
* Security: This is paramount for a profile page. Measures include:
* Input Sanitization: Preventing cross-site scripting (XSS) by sanitizing user-generated content before displaying it.
* Prepared Statements: Using parameterized queries to prevent SQL injection when interacting with the database.
* Password Hashing: Storing passwords as strong hashes (e.g., using `password_hash()` in PHP) rather than plain text, and using `password_verify()` for comparison.
* Secure Session Management: Protecting session IDs and ensuring sessions expire properly.
* Access Control: Ensuring a user can only update their own profile.
* User Experience (UX): A clear, intuitive layout for displaying and editing information, with proper feedback messages (success/error) for user actions.

Example Code

```php
<?php
session_start();

// Simulate user authentication. In a real application, this would come from a login process.
// If the user is not logged in, redirect them to the login page.
if (!isset($_SESSION['user_id'])) {
    header('Location: login.php'); // Assuming a login page exists
    exit();
}

// Simulate fetching user data from a database
// In a real application, you would connect to a database (e.g., MySQLi or PDO)
// and fetch user details using $_SESSION['user_id']
$user_id = $_SESSION['user_id'];

// --- Database connection and data fetching (simulated) ---
// Example placeholder for actual database interaction:
/*
try {
    $pdo = new PDO('mysql:host=localhost;dbname=your_database', 'your_user', 'your_password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare('SELECT username, email, full_name, bio, password_hash FROM users WHERE id = ?');
    $stmt->execute([$user_id]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$user) {
        // User not found, handle error or redirect
        echo 'User not found.';
        exit();
    }
} catch (PDOException $e) {
    echo 'Database error: ' . $e->getMessage();
    exit();
}
*/

// For demonstration, let's hardcode some user data. In a real app, this would be $user from DB.
$user = [
    'username' => 'john.doe',
    'email' => 'john.doe@example.com',
    'full_name' => 'John Doe',
    'bio' => 'Passionate about web development and open source.',
    'password_hash' => password_hash('current_secure_password', PASSWORD_DEFAULT) // Simulated stored hash
];
// If actual data was fetched from DB, you'd use that:
// if (isset($db_user)) { $user = $db_user; }

$message = '';
$error = '';

// Handle form submission for updating profile
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_profile'])) {
    // Sanitize and validate input
    $new_full_name = filter_input(INPUT_POST, 'full_name', FILTER_SANITIZE_STRING);
    $new_email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    $new_bio = filter_input(INPUT_POST, 'bio', FILTER_SANITIZE_STRING);

    if (empty($new_full_name) || empty($new_email)) {
        $error = 'Full Name and Email are required.';
    } elseif (!filter_var($new_email, FILTER_VALIDATE_EMAIL)) {
        $error = 'Invalid email format.';
    } else {
        // --- Database update (simulated) ---
        // In a real application, you would update the user data in the database
        // using prepared statements to prevent SQL injection.
        /*
        try {
            $stmt = $pdo->prepare('UPDATE users SET full_name = ?, email = ?, bio = ? WHERE id = ?');
            if ($stmt->execute([$new_full_name, $new_email, $new_bio, $user_id])) {
                $message = 'Profile updated successfully!';
                // Update the $user array to reflect new data immediately without re-fetching
                $user['full_name'] = $new_full_name;
                $user['email'] = $new_email;
                $user['bio'] = $new_bio;
            } else {
                $error = 'Failed to update profile.';
            }
        } catch (PDOException $e) {
            $error = 'Database error during profile update: ' . $e->getMessage();
        }
        */

        // For demonstration purposes, just update the in-memory array
        $user['full_name'] = $new_full_name;
        $user['email'] = $new_email;
        $user['bio'] = $new_bio;
        $message = 'Profile updated successfully (simulated)!';
    }
}

// Handle form submission for changing password
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['change_password'])) {
    $current_password = $_POST['current_password'] ?? '';
    $new_password = $_POST['new_password'] ?? '';
    $confirm_password = $_POST['confirm_password'] ?? '';

    if (empty($current_password) || empty($new_password) || empty($confirm_password)) {
        $error = 'All password fields are required.';
    } elseif ($new_password !== $confirm_password) {
        $error = 'New password and confirm password do not match.';
    } elseif (strlen($new_password) < 8) { // Example password policy
        $error = 'New password must be at least 8 characters long.';
    } else {
        // --- Database password update (simulated) ---
        // In a real application:
        // 1. Fetch the user's hashed password from the database (already done if $user is from DB).
        // 2. Verify the $current_password against the stored hash using password_verify().
        // 3. If valid, hash the $new_password using password_hash() and update the database.
        /*
        if (password_verify($current_password, $user['password_hash'])) {
            $new_password_hash = password_hash($new_password, PASSWORD_DEFAULT);
            try {
                $stmt = $pdo->prepare('UPDATE users SET password_hash = ? WHERE id = ?');
                if ($stmt->execute([$new_password_hash, $user_id])) {
                    $message = 'Password changed successfully!';
                    $user['password_hash'] = $new_password_hash; // Update in-memory hash
                } else {
                    $error = 'Failed to change password.';
                }
            } catch (PDOException $e) {
                $error = 'Database error during password change: ' . $e->getMessage();
            }
        } else {
            $error = 'Current password is incorrect.';
        }
        */
        // For demonstration
        if ($current_password === 'current_secure_password') { // Simplified check for demo
            $message = 'Password changed successfully (simulated)!';
            // In a real app, clear the password fields on success and update the hash.
        } else {
            $error = 'Current password is incorrect (simulated).';
        }
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>User Profile - <?php echo htmlspecialchars($user['username']); ?></title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; line-height: 1.6; }
        .container { max-width: 800px; margin: auto; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        h1, h2 { color: #333; border-bottom: 1px solid #eee; padding-bottom: 10px; margin-bottom: 20px; }
        .profile-info p { margin-bottom: 10px; }
        .profile-info strong { display: inline-block; min-width: 120px; margin-right: 10px; }
        form { margin-top: 20px; padding-top: 20px; border-top: 1px solid #eee; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input[type="text"], input[type="email"], input[type="password"], textarea {
            width: calc(100% - 22px); padding: 10px; margin-bottom: 15px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;
        }
        textarea { resize: vertical; min-height: 80px; }
        input[type="submit"] {
            background-color: #007bff; color: white; padding: 10px 15px; border: none; border-radius: 4px;
            cursor: pointer; font-size: 16px;
        }
        input[type="submit"]:hover { background-color: #0056b3; }
        .message { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; padding: 10px; margin-bottom: 20px; border-radius: 4px; }
        .error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; padding: 10px; margin-bottom: 20px; border-radius: 4px; }
        a { color: #007bff; text-decoration: none; }
        a:hover { text-decoration: underline; }
    </style>
</head>
<body>
    <div class="container">
        <h1>User Profile: <?php echo htmlspecialchars($user['username']); ?></h1>

        <?php if ($message): ?>
            <div class="message"><?php echo htmlspecialchars($message); ?></div>
        <?php endif; ?>
        <?php if ($error): ?>
            <div class="error"><?php echo htmlspecialchars($error); ?></div>
        <?php endif; ?>

        <div class="profile-info">
            <h2>Your Information</h2>
            <p><strong>Username:</strong> <?php echo htmlspecialchars($user['username']); ?></p>
            <p><strong>Full Name:</strong> <?php echo htmlspecialchars($user['full_name']); ?></p>
            <p><strong>Email:</strong> <?php echo htmlspecialchars($user['email']); ?></p>
            <p><strong>Bio:</strong> <?php echo nl2br(htmlspecialchars($user['bio'])); ?></p>
            <p><a href="logout.php">Logout</a></p>
        </div>

        <form action="" method="POST">
            <h2>Edit Profile</h2>
            <label for="full_name">Full Name:</label>
            <input type="text" id="full_name" name="full_name" value="<?php echo htmlspecialchars($user['full_name']); ?>" required>

            <label for="email">Email:</label>
            <input type="email" id="email" name="email" value="<?php echo htmlspecialchars($user['email']); ?>" required>

            <label for="bio">Bio:</label>
            <textarea id="bio" name="bio"><?php echo htmlspecialchars($user['bio']); ?></textarea>

            <input type="submit" name="update_profile" value="Update Profile">
        </form>

        <form action="" method="POST" style="margin-top: 40px;">
            <h2>Change Password</h2>
            <label for="current_password">Current Password:</label>
            <input type="password" id="current_password" name="current_password" required>

            <label for="new_password">New Password:</label>
            <input type="password" id="new_password" name="new_password" required>

            <label for="confirm_password">Confirm New Password:</label>
            <input type="password" id="confirm_password" name="confirm_password" required>

            <input type="submit" name="change_password" value="Change Password">
        </form>
    </div>
</body>
</html>
```