Skip to main content

Course Progress

Loading...

GET vs POST Methods

Duration: 30 minutes
Module 2: Working with Forms

Learning Objectives

  • Master PHP programming concepts
  • Write clean, maintainable code
  • Apply best practices
  • Build dynamic applications

Understanding HTTP Methods in Forms

When creating HTML forms, one of the most critical decisions is choosing the appropriate HTTP method for sending data to the server. The two primary methods used in web forms are GET and POST. Each has specific use cases, advantages, and limitations that impact how your web applications work, how secure they are, and how users interact with them.

The Postcard vs. Sealed Letter Analogy

To understand the difference between GET and POST, think of sending information through the postal system:

  • GET is like a postcard: The information is written directly on the card, visible to anyone who handles it or sees it. It's simple, lightweight, and perfect for non-sensitive information.
  • POST is like a sealed letter: The information is enclosed inside an envelope, not visible to casual observers. It's more secure for sensitive information and can contain much more content.

The Basics of GET and POST

Feature GET Method POST Method
Data Location Appended to URL as query string Sent in the HTTP request body
Visibility Visible in URL/browser history Not visible in URL/browser history
Data Length Limit Limited (typically 2048 characters) Virtually unlimited
Caching Can be cached and bookmarked Not cached or bookmarked
Form Data Types Only ASCII characters Binary data allowed (file uploads)
Security Less secure (data in URL) More secure (data in request body)
Idempotence Idempotent (repeatable without side effects) Not idempotent (may change server state)
Back Button Behavior Safe to use back button May trigger form resubmission warning
Diagram
Sequence Diagram (Diagram converted to static representation) sequenceDiagram participant User participant Brows...

Implementing GET and POST in HTML Forms

Setting the form method is straightforward in HTML. The method attribute of the form element determines how data is sent.

GET Method Example

<form action="search.php" method="get">
    <label for="query">Search:</label>
    <input type="text" id="query" name="query">
    <button type="submit">Search</button>
</form>

When submitted, this creates a URL like: search.php?query=keyword

POST Method Example

<form action="process.php" method="post">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username">
    <label for="password">Password:</label>
    <input type="password" id="password" name="password">
    <button type="submit">Login</button>
</form>

When submitted, the URL remains process.php with data sent invisibly in the request body.

Visualization of Data Flow

Client Server Form with GET /script.php?name=John&age=25 Form with POST /script.php name=John&age=25 $_GET['name'] $_POST['name'] Browser URL

When to Use GET vs POST

Choosing the appropriate method is crucial for functionality, security, and user experience. Here are guidelines for when to use each method:

Use GET When:

  • For search forms: Users expect to be able to bookmark and share search results
  • For filtering data: Filter parameters are non-sensitive and useful in URLs
  • For pagination: Page numbers and sort orders work well as URL parameters
  • For idempotent operations: Operations that retrieve data without modifying server state
  • For improving SEO: Search engines can index parametrized URLs
  • When shareable URLs are needed: Users can share exact views or search results

Use POST When:

  • For login forms: Passwords should never appear in URLs
  • For registration forms: Personal information should be kept private
  • For file uploads: Binary data can only be sent via POST
  • For large amounts of data: When data exceeds URL length limitations
  • For state-changing operations: Adding, updating, or deleting data
  • For sensitive information: Any data that shouldn't be visible in the URL
  • For multi-part form data: When using enctype="multipart/form-data"

Real-World Examples

Search Engine (GET)

Google, Bing, and other search engines use GET for search forms. This allows users to:

  • Bookmark specific search results
  • Share search queries with others
  • Navigate through search results using browser history
<form action="https://www.google.com/search" method="get">
    <input type="text" name="q">
    <button type="submit">Search</button>
</form>

E-commerce Checkout (POST)

Online stores use POST for checkout forms because they:

  • Contain sensitive payment information
  • Include large amounts of data (shipping details, product info)
  • Change server state (create orders, process payments)
<form action="/process_order.php" method="post">
    <!-- Customer information -->
    <input type="text" name="full_name">
    
    <!-- Credit card details -->
    <input type="text" name="card_number">
    
    <!-- Shipping information -->
    <textarea name="shipping_address"></textarea>
    
    <button type="submit">Complete Purchase</button>
</form>

WordPress Comment Form (POST)

WordPress uses POST for comment forms because they:

  • Create new data on the server (comments)
  • May contain lengthy text content
  • Should prevent accidental resubmission
<form action="/wp-comments-post.php" method="post">
    <input type="hidden" name="comment_post_ID" value="123">
    <textarea name="comment"></textarea>
    <input type="text" name="author">
    <input type="email" name="email">
    <button type="submit">Post Comment</button>
</form>

Security Considerations

Understanding the security implications of GET and POST is crucial for building secure web applications.

GET Security Concerns

  • Data Exposure in URLs: All parameters are visible in the browser address bar
  • Browser History: Query parameters are stored in browser history
  • Server Logs: URLs with query parameters are typically logged on servers
  • Proxy Servers: GET requests may be cached by proxy servers
  • Referrer Headers: URLs may be sent in Referrer headers to other sites

POST Security Considerations

  • Data Not in URL: Data is less exposed but not encrypted by default
  • Network Sniffing: POST data can still be intercepted with network sniffing tools
  • HTTPS Requirement: Always use HTTPS for forms with sensitive data
  • CSRF Vulnerability: POST requests may be vulnerable to Cross-Site Request Forgery
  • XSS Concerns: Both GET and POST data must be sanitized to prevent XSS attacks

Best Practices

  • Never use GET for sensitive data, even with HTTPS
  • Always use HTTPS for all forms, regardless of method
  • Implement CSRF protection for POST forms using tokens
  • Sanitize all input data, regardless of method
  • Validate data on both client and server sides
  • Set appropriate Content-Type headers for POST requests
  • Implement rate limiting to prevent abuse

CSRF Protection Example

When using POST, it's important to implement CSRF protection:

<?php
// Generate a CSRF token and store in session
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>

<form action="process.php" method="post">
    <!-- Include CSRF token as hidden field -->
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    
    <!-- Form fields -->
    <input type="text" name="username">
    <button type="submit">Submit</button>
</form>

<?php
// Verify CSRF token on submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
        die('CSRF token validation failed');
    }
    
    // Process form data...
}
?>

Technical Details and HTTP Specifications

Understanding the underlying HTTP protocol helps clarify why GET and POST behave differently.

HTTP GET Request

GET /search?query=php&sort=relevance HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Connection: keep-alive

HTTP POST Request

POST /process.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
Connection: keep-alive

username=john&password=secret

Key HTTP Specifications

  • Idempotence: GET requests should be idempotent (repeatable without changing state)
  • Cacheable: GET responses can be cached, POST generally not
  • Content-Length: Required for POST requests to specify body size
  • Content-Type: Specifies the format of POST data

Common Content-Type Values for POST

  • application/x-www-form-urlencoded: Default for HTML forms, data in name=value pairs
  • multipart/form-data: Used for file uploads
  • application/json: Used for AJAX requests with JSON data
  • text/plain: Plain text content

Form Encoding Example

<!-- Default encoding (for most forms) -->
<form action="process.php" method="post">
    <!-- Form fields -->
</form>

<!-- For file uploads -->
<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="document">
    <button type="submit">Upload</button>
</form>

Handling Form Data in PHP

PHP provides superglobal arrays to access form data, making it easy to work with both GET and POST methods.

Accessing GET Data

<?php
// URL: process.php?name=John&age=25

// Check if parameter exists
if (isset($_GET['name'])) {
    // Access GET parameters
    $name = $_GET['name'];
    $age = $_GET['age'];
    
    echo "Name: " . htmlspecialchars($name) . "<br>";
    echo "Age: " . htmlspecialchars($age);
}
?>

Accessing POST Data

<?php
// Form submitted with POST method

// Check if form was submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Access POST parameters
    $username = $_POST['username'];
    $password = $_POST['password'];
    
    // NEVER echo passwords in a real application!
    echo "Username: " . htmlspecialchars($username);
    
    // Process login...
}
?>

Complete PHP Form Processing Example

<!-- HTML Form (contact.html) -->
<form action="process_contact.php" method="post">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" required>
    
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    
    <label for="message">Message:</label>
    <textarea id="message" name="message" required></textarea>
    
    <button type="submit">Send Message</button>
</form>

<!-- PHP Processing (process_contact.php) -->
<?php
// Check if form was submitted via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Validate required fields exist
    if (
        !isset($_POST['name']) || 
        !isset($_POST['email']) || 
        !isset($_POST['message'])
    ) {
        die("Missing required fields");
    }
    
    // Sanitize input data
    $name = htmlspecialchars($_POST['name']);
    $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
    $message = htmlspecialchars($_POST['message']);
    
    // Validate email format
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        die("Invalid email format");
    }
    
    // Process the data (e.g., send email)
    $to = "admin@example.com";
    $subject = "New Contact Form Submission";
    $body = "Name: $name
Email: $email

Message:
$message";
    $headers = "From: $email";
    
    if (mail($to, $subject, $body, $headers)) {
        echo "Thank you for your message!";
    } else {
        echo "Sorry, an error occurred.";
    }
} else {
    // If accessed directly without POST
    echo "This script should be accessed via the contact form.";
}
?>

The $_REQUEST Superglobal

PHP also provides the $_REQUEST array, which contains data from $_GET, $_POST, and $_COOKIE:

<?php
// Access form data regardless of method
$name = $_REQUEST['name'];

// However, this is generally not recommended because:
// 1. It's less explicit about where data comes from
// 2. It can lead to confusion when GET and POST have same parameter names
// 3. It presents potential security concerns

// Better practice is to explicitly use $_GET or $_POST
?>

Understanding URL Structure with GET Parameters

When using the GET method, parameters are appended to the URL in a specific format. Understanding this structure is important for both creating and processing forms.

Anatomy of a URL with Query Parameters

https://www.example.com/search.php?query=wordpress&category=plugins&sort=rating
Diagram
> C["/search.php"] C > E["query=wordpress"] E > G["category=plugins"] G https:// www.example.com /search.php ? query=wordpress & category=plugins & sort=rating

URL Components

  • Protocol: https://
  • Domain: www.example.com
  • Path: /search.php
  • Query string delimiter: ?
  • Parameters: name=value pairs
  • Parameter separator: &

URL Encoding

Special characters in GET parameters must be URL encoded to ensure proper transmission:

Character URL Encoded Description
Space %20 or + Spaces are encoded as %20 or + (plus sign)
? %3F Question mark (begins query string)
& %26 Ampersand (separates parameters)
= %3D Equals sign (separates name and value)
/ %2F Forward slash

PHP URL Encoding Functions

<?php
// Properly encode a parameter value
$search_term = "PHP & WordPress";
$encoded = urlencode($search_term); // Result: "PHP+%26+WordPress"

// Build a GET URL with encoded parameters
$base_url = "search.php";
$params = [
    "query" => "PHP & WordPress",
    "category" => "tutorials",
    "level" => "beginner"
];

$query_string = http_build_query($params);
$url = $base_url . "?" . $query_string;

echo $url; // Outputs: search.php?query=PHP+%26+WordPress&category=tutorials&level=beginner
?>

Browser Behavior and User Experience

The choice between GET and POST affects browser behavior and user experience in several important ways.

Page Reloading and Caching

Behavior GET Method POST Method
Page Refresh Data is resubmitted without warning Browser warns about form resubmission
Back Button Works normally, retrieves cached page May trigger resubmission warning
Bookmarking Works with all parameters preserved Only bookmarks the target URL, no data
Caching Results can be cached by browser Generally not cached

Form Resubmission Warning

When users refresh a page after a POST submission, browsers typically show a warning like this:

Confirm Form Resubmission

The page that you're looking for used information that you entered. Returning to that page might cause any action you took to be repeated. Do you want to continue?

PRG Pattern: Post/Redirect/Get

To avoid form resubmission warnings, use the PRG (Post/Redirect/Get) pattern:

<?php
// Process form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Process form data
    $name = $_POST['name'];
    // Save to database, etc.
    
    // Store success message in session
    session_start();
    $_SESSION['message'] = "Form submitted successfully!";
    
    // Redirect to a confirmation page (GET request)
    header('Location: confirmation.php');
    exit;
}
?>

<!-- confirmation.php -->
<?php
session_start();
if (isset($_SESSION['message'])) {
    echo "<div class='success'>" . $_SESSION['message'] . "</div>";
    // Clear the message to prevent it showing again on refresh
    unset($_SESSION['message']);
}
?>

Modern Approaches: AJAX and Fetch API

Modern web applications often use JavaScript to submit forms asynchronously, but the underlying GET/POST methods still apply.

AJAX Form Submission with jQuery

<!-- HTML Form -->
<form id="contact-form" action="process.php" method="post">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    <textarea name="message" required></textarea>
    <button type="submit">Send</button>
</form>

<div id="response"></div>

<!-- JavaScript with jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
    $('#contact-form').on('submit', function(e) {
        e.preventDefault(); // Prevent normal form submission
        
        $.ajax({
            type: 'POST', // Same as form method
            url: 'process.php',
            data: $(this).serialize(), // Serializes form inputs
            success: function(response) {
                $('#response').html(response);
            },
            error: function(xhr, status, error) {
                $('#response').html('An error occurred: ' + error);
            }
        });
    });
});
</script>

Fetch API (Modern JavaScript)

<!-- HTML Form -->
<form id="contact-form" action="process.php" method="post">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    <textarea name="message" required></textarea>
    <button type="submit">Send</button>
</form>

<div id="response"></div>

<!-- JavaScript with Fetch API -->
<script>
document.addEventListener('DOMContentLoaded', function() {
    const form = document.getElementById('contact-form');
    const responseDiv = document.getElementById('response');
    
    form.addEventListener('submit', function(e) {
        e.preventDefault(); // Prevent normal form submission
        
        const formData = new FormData(form);
        
        fetch('process.php', {
            method: 'POST',
            body: formData
        })
        .then(response => response.text())
        .then(data => {
            responseDiv.innerHTML = data;
        })
        .catch(error => {
            responseDiv.innerHTML = 'An error occurred: ' + error;
        });
    });
});
</script>

Working with JSON Data

Modern API-driven applications often use JSON for data exchange:

<!-- JavaScript sending JSON data -->
<script>
const userData = {
    name: 'John Doe',
    email: 'john@example.com',
    message: 'Hello world!'
};

fetch('api/contact.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(userData)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
</script>

<!-- PHP API endpoint handling JSON -->
<?php
// Get JSON data from request body
$json = file_get_contents('php://input');
$data = json_decode($json, true);

// Now $data contains the JSON values
$name = $data['name'] ?? '';
$email = $data['email'] ?? '';
$message = $data['message'] ?? '';

// Process data...

// Return JSON response
header('Content-Type: application/json');
echo json_encode(['status' => 'success', 'message' => 'Thank you for your submission!']);
?>

Integration with WordPress

WordPress provides several built-in functions and security features for handling form data.

WordPress Form Processing

<!-- WordPress form with nonce for security -->
<form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="post">
    <input type="hidden" name="action" value="custom_form_action">
    <?php wp_nonce_field('custom_form_nonce', 'custom_form_nonce'); ?>
    
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" required>
    
    <button type="submit">Submit</button>
</form>

<!-- WordPress form processing in functions.php or plugin file -->
<?php
// Hook for both logged in and non-logged in users
add_action('admin_post_custom_form_action', 'handle_custom_form');
add_action('admin_post_nopriv_custom_form_action', 'handle_custom_form');

function handle_custom_form() {
    // Verify nonce
    if (!isset($_POST['custom_form_nonce']) || 
        !wp_verify_nonce($_POST['custom_form_nonce'], 'custom_form_nonce')) {
        wp_die('Security check failed');
    }
    
    // Get and sanitize data
    $name = sanitize_text_field($_POST['name']);
    
    // Process data (e.g., save to database)
    // ...
    
    // Redirect after processing
    wp_redirect(home_url('/thank-you/'));
    exit;
}
?>

WordPress AJAX Form Processing

<!-- WordPress AJAX form -->
<form id="ajax-form">
    <input type="text" name="name" required>
    <button type="submit">Submit</button>
</form>

<div id="response"></div>

<script>
jQuery(document).ready(function($) {
    $('#ajax-form').on('submit', function(e) {
        e.preventDefault();
        
        $.ajax({
            type: 'POST',
            url: '<?php echo admin_url('admin-ajax.php'); ?>',
            data: {
                action: 'my_ajax_action',
                name: $('input[name="name"]').val(),
                security: '<?php echo wp_create_nonce('my_ajax_nonce'); ?>'
            },
            success: function(response) {
                $('#response').html(response.data);
            }
        });
    });
});
</script>

<!-- WordPress AJAX handler in functions.php or plugin file -->
<?php
// Hook for both logged in and non-logged in users
add_action('wp_ajax_my_ajax_action', 'handle_ajax_request');
add_action('wp_ajax_nopriv_my_ajax_action', 'handle_ajax_request');

function handle_ajax_request() {
    // Verify nonce
    check_ajax_referer('my_ajax_nonce', 'security');
    
    // Get and sanitize data
    $name = sanitize_text_field($_POST['name']);
    
    // Process data
    // ...
    
    // Send response
    wp_send_json_success('Form submitted successfully!');
}
?>

Homework: GET vs POST Practice

Complete the following exercises to reinforce your understanding of GET and POST methods:

Task 1: Method Analysis

Review 5 different websites you use regularly and determine which method (GET or POST) they use for their forms. For each, explain why you think they chose that method and whether it's appropriate.

Suggested sites to analyze:

  • A search engine (Google, Bing)
  • An e-commerce site (Amazon, eBay)
  • A social media platform (Facebook, Twitter)
  • A banking or financial site
  • Any WordPress site with forms

Task 2: Create and Process Forms

Create two simple forms and their PHP processing scripts:

  1. GET Form: Create a product filter form with at least 3 filter options (category, price range, color, etc.) that uses the GET method. Write the PHP code to process and display the filtered results.
  2. POST Form: Create a user registration form with username, email, password, and bio fields that uses the POST method. Write the PHP code to validate the form data and display a confirmation.

Task 3: URL Parameter Construction

Write a PHP function that builds a properly encoded URL with multiple parameters:

  • The function should accept a base URL and an associative array of parameters
  • It should properly encode parameter values
  • It should handle array values (e.g., multiple checkboxes)
  • Test it with at least 3 different scenarios
<?php
// Example function signature to implement
function build_url($base_url, $params) {
    // Your code here
}

// Test cases
$url1 = build_url('search.php', [
    'query' => 'PHP & MySQL',
    'category' => 'books'
]);

$url2 = build_url('products.php', [
    'categories' => ['shirts', 'pants', 'shoes'],
    'size' => 'large',
    'price_range' => '20-50'
]);

echo $url1 . "
";
echo $url2 . "
";
?>

Additional Resources

Coming Up Next: Accessing Form Data with $_GET and $_POST

In our next lecture, we'll dive deeper into how to access and process form data in PHP:

  • Working with the $_GET and $_POST superglobals
  • Handling different data types (text, numbers, arrays)
  • Checking if form variables exist
  • Common pitfalls and how to avoid them
  • Best practices for accessing form data

Be sure to complete the homework exercises to reinforce your understanding of GET and POST methods before moving on!