PHP

#10
TIOBE#15
PYPL#7
GitHub#14
RedMonk#4
IEEESpectrum#13
JetBrains#12
programming languageweb developmentserver-sideCMSWordPress

Programming Language

PHP (PHP: Hypertext Preprocessor)

Overview

PHP is a server-side scripting language specialized for web development. It can be embedded in HTML and is widely used for developing dynamic web pages and web applications. It has been adopted by CMS and frameworks such as WordPress, Drupal, and Laravel, occupying an important position as a foundational technology for web development.

Details

PHP was developed by Rasmus Lerdorf in 1995, originally standing for "Personal Home Page". It is now known as the recursive acronym "PHP: Hypertext Preprocessor".

Being open source and free to use, with relatively low learning costs, it has been adopted by many developers. Since PHP 7, significant performance improvements have been made, and PHP 8 has added modern language features such as strengthened type system and JIT compiler introduction.

Code Examples

Hello World

<?php
echo "Hello, World!";
?>

<!-- Combined with HTML -->
<!DOCTYPE html>
<html>
<head>
    <title>PHP Sample</title>
</head>
<body>
    <h1><?php echo "Hello, World!"; ?></h1>
    <p>Current time: <?php echo date('Y-m-d H:i:s'); ?></p>
</body>
</html>

Variables and Data Types

<?php
// Variable definition (starts with $ mark)
$name = "John";
$age = 25;
$height = 175.5;
$is_student = true;

// Arrays
$fruits = ["apple", "banana", "orange"];
$person = [
    "name" => "Jane",
    "age" => 23,
    "city" => "Tokyo"
];

// Variable display
echo "Name: $name\n";
echo "Age: {$age} years old\n";
echo "Height: " . $height . "cm\n";

// Array display
echo "Favorite fruit: " . $fruits[0] . "\n";
echo "Person info: " . $person["name"] . " (" . $person["age"] . " years old)\n";

// Type checking
var_dump($name);    // string
var_dump($age);     // int
var_dump($height);  // float
var_dump($is_student); // bool

// String concatenation
$greeting = "Hello, " . $name . "!";
echo $greeting . "\n";
?>

Functions and Classes

<?php
// Function definition
function greet($name, $time = "Hello") {
    return $time . ", " . $name . "!";
}

// Function with type declarations (PHP 7+)
function add(int $a, int $b): int {
    return $a + $b;
}

// Variadic function
function sum(...$numbers) {
    return array_sum($numbers);
}

// Class definition
class Person {
    private string $name;
    private int $age;
    private array $skills;
    
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
        $this->skills = [];
    }
    
    public function getName(): string {
        return $this->name;
    }
    
    public function getAge(): int {
        return $this->age;
    }
    
    public function addSkill(string $skill): void {
        $this->skills[] = $skill;
    }
    
    public function getSkills(): array {
        return $this->skills;
    }
    
    public function introduce(): string {
        $skillList = empty($this->skills) 
            ? "None" 
            : implode(", ", $this->skills);
        
        return "I'm {$this->name}. I'm {$this->age} years old. Skills: {$skillList}";
    }
}

// Usage examples
echo greet("John") . "\n";
echo greet("Jane", "Good morning") . "\n";
echo "Calculation result: " . add(5, 3) . "\n";
echo "Sum: " . sum(1, 2, 3, 4, 5) . "\n";

$person = new Person("John Doe", 30);
$person->addSkill("PHP");
$person->addSkill("JavaScript");
echo $person->introduce() . "\n";
?>

Database Connection (PDO)

<?php
try {
    // Database connection
    $pdo = new PDO(
        'mysql:host=localhost;dbname=testdb;charset=utf8',
        'username',
        'password',
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );
    
    // Table creation
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS users (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(100) NOT NULL,
            email VARCHAR(100) UNIQUE NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ");
    
    // Data insertion (prepared statements)
    $stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
    $stmt->execute(["John Doe", "[email protected]"]);
    $stmt->execute(["Jane Smith", "[email protected]"]);
    
    // Data retrieval
    $stmt = $pdo->query("SELECT * FROM users ORDER BY created_at DESC");
    $users = $stmt->fetchAll();
    
    echo "Registered users:\n";
    foreach ($users as $user) {
        echo "ID: {$user['id']}, Name: {$user['name']}, Email: {$user['email']}\n";
    }
    
    // Search for specific user
    $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
    $stmt->execute(["[email protected]"]);
    $user = $stmt->fetch();
    
    if ($user) {
        echo "Search result: {$user['name']} ({$user['email']})\n";
    }
    
    // Get user count
    $stmt = $pdo->query("SELECT COUNT(*) as count FROM users");
    $count = $stmt->fetch()['count'];
    echo "Total users: {$count}\n";
    
} catch (PDOException $e) {
    echo "Database error: " . $e->getMessage() . "\n";
}
?>

Web Form Processing

<?php
session_start();

// CSRF token generation
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Error message array
$errors = [];

// Form submission processing
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // CSRF token verification
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
        die('CSRF token mismatch');
    }
    
    // Validation
    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $message = trim($_POST['message'] ?? '');
    
    if (empty($name)) {
        $errors['name'] = 'Name is required';
    } elseif (strlen($name) > 50) {
        $errors['name'] = 'Name must be 50 characters or less';
    }
    
    if (empty($email)) {
        $errors['email'] = 'Email is required';
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'Please enter a valid email address';
    }
    
    if (empty($message)) {
        $errors['message'] = 'Message is required';
    } elseif (strlen($message) > 1000) {
        $errors['message'] = 'Message must be 1000 characters or less';
    }
    
    // Processing when no errors
    if (empty($errors)) {
        // Database saving or email sending processing
        // ...
        
        $_SESSION['success'] = 'Your inquiry has been received';
        header('Location: ' . $_SERVER['PHP_SELF']);
        exit;
    }
}

// Get and remove success message
$success = $_SESSION['success'] ?? null;
unset($_SESSION['success']);
?>

<!DOCTYPE html>
<html>
<head>
    <title>Contact Form</title>
    <style>
        .error { color: red; }
        .success { color: green; }
        .form-group { margin-bottom: 1rem; }
    </style>
</head>
<body>
    <h1>Contact Form</h1>
    
    <?php if ($success): ?>
        <p class="success"><?php echo htmlspecialchars($success); ?></p>
    <?php endif; ?>
    
    <form method="post">
        <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
        
        <div class="form-group">
            <label for="name">Name:</label><br>
            <input type="text" id="name" name="name" value="<?php echo htmlspecialchars($name ?? ''); ?>">
            <?php if (isset($errors['name'])): ?>
                <div class="error"><?php echo htmlspecialchars($errors['name']); ?></div>
            <?php endif; ?>
        </div>
        
        <div class="form-group">
            <label for="email">Email:</label><br>
            <input type="email" id="email" name="email" value="<?php echo htmlspecialchars($email ?? ''); ?>">
            <?php if (isset($errors['email'])): ?>
                <div class="error"><?php echo htmlspecialchars($errors['email']); ?></div>
            <?php endif; ?>
        </div>
        
        <div class="form-group">
            <label for="message">Message:</label><br>
            <textarea id="message" name="message" rows="5" cols="50"><?php echo htmlspecialchars($message ?? ''); ?></textarea>
            <?php if (isset($errors['message'])): ?>
                <div class="error"><?php echo htmlspecialchars($errors['message']); ?></div>
            <?php endif; ?>
        </div>
        
        <button type="submit">Submit</button>
    </form>
</body>
</html>

JSON API Creation

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type');

// Error handling function
function sendError($message, $code = 400) {
    http_response_code($code);
    echo json_encode(['error' => $message]);
    exit;
}

// Success response function
function sendResponse($data, $code = 200) {
    http_response_code($code);
    echo json_encode($data);
    exit;
}

// Get request method
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// Mock data array (usually retrieved from database)
$users = [
    ['id' => 1, 'name' => 'John Doe', 'email' => '[email protected]'],
    ['id' => 2, 'name' => 'Jane Smith', 'email' => '[email protected]'],
    ['id' => 3, 'name' => 'Bob Johnson', 'email' => '[email protected]'],
];

// Routing
switch ($method) {
    case 'GET':
        if (preg_match('/\/api\/users\/(\d+)$/', $path, $matches)) {
            // Get specific user
            $userId = (int)$matches[1];
            $user = array_filter($users, function($u) use ($userId) {
                return $u['id'] === $userId;
            });
            
            if (empty($user)) {
                sendError('User not found', 404);
            }
            
            sendResponse(array_values($user)[0]);
            
        } elseif ($path === '/api/users') {
            // Get all users
            $page = $_GET['page'] ?? 1;
            $limit = $_GET['limit'] ?? 10;
            $search = $_GET['search'] ?? '';
            
            // Search filter
            if ($search) {
                $users = array_filter($users, function($user) use ($search) {
                    return stripos($user['name'], $search) !== false ||
                           stripos($user['email'], $search) !== false;
                });
            }
            
            // Pagination
            $total = count($users);
            $offset = ($page - 1) * $limit;
            $users = array_slice($users, $offset, $limit);
            
            sendResponse([
                'data' => array_values($users),
                'pagination' => [
                    'page' => (int)$page,
                    'limit' => (int)$limit,
                    'total' => $total,
                    'pages' => ceil($total / $limit)
                ]
            ]);
        } else {
            sendError('Endpoint not found', 404);
        }
        break;
        
    case 'POST':
        if ($path === '/api/users') {
            // User creation
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input || !isset($input['name']) || !isset($input['email'])) {
                sendError('Name and email are required');
            }
            
            // Validation
            if (!filter_var($input['email'], FILTER_VALIDATE_EMAIL)) {
                sendError('Invalid email format');
            }
            
            // Create new user (usually saved to database)
            $newUser = [
                'id' => count($users) + 1,
                'name' => $input['name'],
                'email' => $input['email']
            ];
            
            sendResponse($newUser, 201);
        } else {
            sendError('Endpoint not found', 404);
        }
        break;
        
    default:
        sendError('Method not allowed', 405);
}
?>

File Upload Processing

<?php
// Upload settings
$uploadDir = 'uploads/';
$maxFileSize = 5 * 1024 * 1024; // 5MB
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];

// Create upload directory
if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0755, true);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload'])) {
    $file = $_FILES['upload'];
    $errors = [];
    
    // Error check
    if ($file['error'] !== UPLOAD_ERR_OK) {
        $errors[] = 'File upload failed';
    }
    
    // File size check
    if ($file['size'] > $maxFileSize) {
        $errors[] = 'File size is too large (max 5MB)';
    }
    
    // File type check
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimeType = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);
    
    if (!in_array($mimeType, $allowedTypes)) {
        $errors[] = 'Unsupported file format (JPEG, PNG, GIF only)';
    }
    
    // Save file if no errors
    if (empty($errors)) {
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = uniqid() . '.' . $extension;
        $destination = $uploadDir . $filename;
        
        if (move_uploaded_file($file['tmp_name'], $destination)) {
            echo "File uploaded: " . htmlspecialchars($filename);
            
            // Create thumbnail for images
            if (strpos($mimeType, 'image/') === 0) {
                createThumbnail($destination, $uploadDir . 'thumb_' . $filename);
            }
        } else {
            $errors[] = 'Failed to save file';
        }
    }
    
    // Display errors
    if (!empty($errors)) {
        foreach ($errors as $error) {
            echo "<p style='color: red;'>" . htmlspecialchars($error) . "</p>";
        }
    }
}

// Thumbnail creation function
function createThumbnail($source, $destination, $maxWidth = 200, $maxHeight = 200) {
    $imageInfo = getimagesize($source);
    if (!$imageInfo) return false;
    
    $originalWidth = $imageInfo[0];
    $originalHeight = $imageInfo[1];
    $mimeType = $imageInfo['mime'];
    
    // Load original image
    switch ($mimeType) {
        case 'image/jpeg':
            $originalImage = imagecreatefromjpeg($source);
            break;
        case 'image/png':
            $originalImage = imagecreatefrompng($source);
            break;
        case 'image/gif':
            $originalImage = imagecreatefromgif($source);
            break;
        default:
            return false;
    }
    
    // Calculate thumbnail size
    $ratio = min($maxWidth / $originalWidth, $maxHeight / $originalHeight);
    $newWidth = intval($originalWidth * $ratio);
    $newHeight = intval($originalHeight * $ratio);
    
    // Create thumbnail image
    $thumbnail = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled(
        $thumbnail, $originalImage,
        0, 0, 0, 0,
        $newWidth, $newHeight,
        $originalWidth, $originalHeight
    );
    
    // Save
    $result = imagejpeg($thumbnail, $destination, 80);
    
    // Free memory
    imagedestroy($originalImage);
    imagedestroy($thumbnail);
    
    return $result;
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>File Upload</title>
</head>
<body>
    <h1>File Upload</h1>
    <form method="post" enctype="multipart/form-data">
        <label for="upload">Image file (JPEG, PNG, GIF, max 5MB):</label><br>
        <input type="file" id="upload" name="upload" accept="image/*" required><br><br>
        <button type="submit">Upload</button>
    </form>
    
    <?php
    // Display list of uploaded files
    if (is_dir($uploadDir)) {
        $files = glob($uploadDir . '*');
        if (!empty($files)) {
            echo "<h2>Uploaded Files</h2>";
            foreach ($files as $file) {
                if (is_file($file) && strpos(basename($file), 'thumb_') !== 0) {
                    $filename = basename($file);
                    $thumbFile = $uploadDir . 'thumb_' . $filename;
                    
                    echo "<div style='margin: 10px; display: inline-block;'>";
                    if (file_exists($thumbFile)) {
                        echo "<img src='$thumbFile' alt='$filename' style='max-width: 200px; max-height: 200px;'><br>";
                    }
                    echo "<a href='$file' target='_blank'>" . htmlspecialchars($filename) . "</a>";
                    echo "</div>";
                }
            }
        }
    }
    ?>
</body>
</html>

Advantages and Disadvantages

Advantages

  • Low Learning Curve: Relatively easy syntax to master
  • Web Development Specialized: High compatibility with HTML, optimized for web development
  • Rich Documentation: Learning resources and community accumulated over years
  • Hosting Support: Standard support on many rental servers
  • CMS Ecosystem: Huge ecosystem with WordPress, Drupal, etc.
  • Frameworks: Choices like Laravel, Symfony, CodeIgniter

Disadvantages

  • Language Design Consistency: Inconsistent function names and specifications due to historical reasons
  • Performance: May be slower compared to other languages
  • Type Safety: Risk of runtime errors due to dynamic typing
  • Security: Easy to introduce vulnerabilities without proper measures
  • Enterprise Use: Limited adoption in large-scale systems

Key Links

Ranking Information

  • Overall Ranking: 10th
  • TIOBE Index: 15th
  • PYPL PopularitY: 7th
  • GitHub Usage: 14th
  • RedMonk Language Ranking: 4th
  • IEEE Spectrum: 13th
  • JetBrains Developer Survey: 12th

PHP is a server-side language with a long track record in web development, playing an important role in CMS development and web application construction.