PHP: JSON and Email

JSON is the universal language of the web—frontend-backend communication depends on it, API data transfer uses it, and even config files are written in it. Email is a must-have feature for any web application—registration verification, password resets, and notifications. This lesson covers both.

1. JSON Basics

PHP
<?php
// PHP array/object → JSON string
$data = [
    'name' => 'John',
    'age'  => 25,
    'skills' => ['PHP', 'MySQL', 'JavaScript'],
    'isActive' => true,
    'score' => null,
];

$json = json_encode($data);
echo $json;
// {"name":"John","age":25,"skills":["PHP","MySQL","JavaScript"],"isActive":true,"score":null}
?>

(1) Common json_encode Options

PHP
<?php
$data = ['name' => 'John', 'age' => 25, 'score' => null];

// Pretty print (human-readable)
echo json_encode($data, JSON_PRETTY_PRINT);
/*
{
    "name": "John",
    "age": 25,
    "score": null
}
*/

// Don't escape Unicode (preserves non-ASCII characters)
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// {"name":"John","age":25,"score":null}

// Combine options
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

// Handle null (PHP 8.3+)
echo json_encode($data, JSON_UNESCAPED_UNICODE, JSON_INVALID_UTF8_IGNORE);
?>
Option Effect
JSON_PRETTY_PRINT Indented formatting
JSON_UNESCAPED_UNICODE Don't escape non-ASCII to \uXXXX
JSON_UNESCAPED_SLASHES Don't escape / to \/
JSON_NUMERIC_CHECK Convert numeric strings to numbers
JSON_FORCE_OBJECT Output {} for empty arrays

2. json_decode — Parsing JSON

PHP
<?php
$json = '{"name":"John","age":25,"skills":["PHP","MySQL"]}';

// Default: returns an object
$obj = json_decode($json);
echo $obj->name;  // John
echo $obj->skills[0];  // PHP

// Second parameter true → returns an associative array
$arr = json_decode($json, true);
echo $arr['name'];  // John

// Error handling
$badJson = '{name: John}';  // Missing double quotes
$result = json_decode($badJson);
if (json_last_error() !== JSON_ERROR_NONE) {
    echo "JSON parse error: " . json_last_error_msg();
    // JSON parse error: Syntax error
}

// PHP 7.3+ cleaner syntax
$result = json_decode($badJson);
echo json_last_error_msg();
?>

▶ サンプル: Reading and Writing JSON Files

PHP
<?php
// === Writing a JSON File ===
$config = [
    'app_name' => 'MyBlog',
    'version'  => '1.2.0',
    'database' => [
        'host' => 'localhost',
        'name' => 'myblog',
    ],
    'features' => ['blog', 'comments', 'search'],
];

$json = json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
file_put_contents('config.json', $json, LOCK_EX);
echo "Config file written ✅";

// === Reading a JSON File ===
$json = file_get_contents('config.json');
$config = json_decode($json, true);

echo "App name: {$config['app_name']}<br>";
echo "Database host: {$config['database']['host']}<br>";
echo "Features: " . implode(', ', $config['features']) . "<br>";
?>
▶ 試してみよう

▶ サンプル: REST API Simulation

PHP
<?php
// api.php — simple JSON API
header('Content-Type: application/json; charset=utf-8');

$method = $_SERVER['REQUEST_METHOD'];
$path = $_GET['path'] ?? '';

$users = [
    ['id' => 1, 'name' => 'John', 'email' => 'j@j.com'],
    ['id' => 2, 'name' => 'Jane', 'email' => 'ja@ja.com'],
];

if ($method === 'GET' && $path === 'users') {
    echo json_encode(['status' => 'ok', 'data' => $users], JSON_UNESCAPED_UNICODE);
} elseif ($method === 'GET' && preg_match('/users\/(\d+)/', $path, $m)) {
    $id = (int)$m[1];
    $user = $users[$id - 1] ?? null;
    if ($user) {
        echo json_encode(['status' => 'ok', 'data' => $user], JSON_UNESCAPED_UNICODE);
    } else {
        http_response_code(404);
        echo json_encode(['status' => 'error', 'message' => 'User not found']);
    }
} elseif ($method === 'POST' && $path === 'users') {
    $input = json_decode(file_get_contents('php://input'), true);
    // In a real app this would write to the database
    echo json_encode(['status' => 'ok', 'message' => 'User created']);
} else {
    http_response_code(404);
    echo json_encode(['status' => 'error', 'message' => 'Unknown endpoint']);
}
?>
▶ 試してみよう

3. Sending Email

(1) mail() Basics

PHP
<?php
$to = "user@example.com";
$subject = "=?UTF-8?B?" . base64_encode("Password Reset Notification") . "?="; // Encoded subject
$message = "Hello, please click the link below to reset your password:\n\n";
$message .= "https://myblog.com/reset?token=abc123";
$headers = "From: noreply@myblog.com\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";

if (mail($to, $subject, $message, $headers)) {
    echo "Email sent ✅";
} else {
    echo "Email failed ❌";
}
?>
💡 Tip: mail() requires the server to have sendmail/Postfix configured. XAMPP doesn't include one by default—for testing email functionality, it's better to use SMTP (next section).

▶ サンプル: HTML Verification Email

PHP
<?php
function sendVerificationEmail(string $to, string $token): bool {
    $subject = "=?UTF-8?B?" . base64_encode("Please verify your email") . "?=";
    
    // HTML email
    $message = "<html><body>";
    $message .= "<h2>Welcome to MyBlog!</h2>";
    $message .= "<p>Please click the link below to verify your email:</p>";
    $message .= "<a href='https://myblog.com/verify?token={$token}'>Verify Email</a>";
    $message .= "<p>If the link doesn't work, copy and paste this address:</p>";
    $message .= "<p>https://myblog.com/verify?token={$token}</p>";
    $message .= "</body></html>";
    
    $headers = "From: noreply@myblog.com\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=UTF-8\r\n";
    
    return mail($to, $subject, $message, $headers);
}

$token = bin2hex(random_bytes(32));
sendVerificationEmail('user@example.com', $token);
?>
▶ 試してみよう

mail() is simple but limited. PHPMailer is the de facto standard for PHP email:

BASH
# Install
composer require phpmailer/phpmailer
PHP
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

function sendEmailSMTP(string $to, string $subject, string $body): bool {
    $mail = new PHPMailer(true);
    
    try {
        // Server settings
        $mail->isSMTP();
        $mail->Host       = 'smtp.gmail.com';    // SMTP server
        $mail->SMTPAuth   = true;
        $mail->Username   = 'your@gmail.com';     // Sender email
        $mail->Password   = 'app-password';       // App-specific password
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;
        $mail->CharSet    = 'UTF-8';
        
        // Recipients
        $mail->setFrom('your@gmail.com', 'MyBlog');
        $mail->addAddress($to);
        
        // Content
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body    = $body;
        $mail->AltBody = strip_tags($body);  // Plain-text fallback
        
        $mail->send();
        return true;
    } catch (Exception $e) {
        echo "Email failed: {$mail->ErrorInfo}";
        return false;
    }
}

sendEmailSMTP(
    'user@example.com',
    'Password Reset',
    '<h3>MyBlog Password Reset</h3><p>Click <a href="#">here</a> to reset your password.</p>'
);
?>
💡 Tip: When testing with Gmail: enable 2-step verification → generate an app-specific password → use that password (not your Gmail login password). Gmail will reject connections if you use your actual password directly.


5. Email Best Practices

PHP
<?php
class MailService {
    public function sendWelcome(string $email, string $username): bool {
        $subject = "Welcome to MyBlog";
        $body = file_get_contents(__DIR__ . '/templates/welcome.html');
        $body = str_replace('{{username}}', htmlspecialchars($username), $body);
        
        return sendEmailSMTP($email, $subject, $body);
    }
    
    public function sendPasswordReset(string $email, string $token): bool {
        $link = "https://myblog.com/reset?token={$token}";
        $subject = "Password Reset";
        $body = "
            <h3>Password Reset Request</h3>
            <p>Click the link below to reset your password (valid for 1 hour):</p>
            <a href='{$link}'>{$link}</a>
            <p>If you didn't request a password reset, please ignore this email.</p>
        ";
        return sendEmailSMTP($email, $subject, $body);
    }
    
    public function sendNotification(string $email, string $title, string $message): bool {
        $subject = "📢 {$title}";
        $body = "<h3>{$title}</h3><p>{$message}</p>";
        return sendEmailSMTP($email, $subject, $body);
    }
}
?>

❓ よくある質問

Q Why is JSON more popular than XML?
A It's lightweight (fewer tags), natively supported by JavaScript (JSON.parse), and highly readable. In PHP, json_encode/json_decode handles it in one line, whereas XML takes several steps.
Q Should I use mail() or an SMTP library?
A mail() is convenient for local dev (if configured). Use an SMTP library (PHPMailer) in production—it has better error handling, supports attachments, multiple recipients, and isn't affected by server mail configuration.
Q Can I use a JSON file as a database?
A Yes, for small datasets and single-user scenarios (like config files). For multi-user concurrent reads/writes and complex queries, you must use MySQL. The problems with JSON as a database: no concurrent writes, no indexes so slow queries, and performance degrades as data grows.

📖 まとめ

📝 練習問題

  1. Create a settings.json config file and use PHP to read and display all configuration items.
  2. Write a simple JSON API: /users returns all users, /users/1 returns the user with ID=1. Simulate with GET parameters.
  3. Add email verification to your registration system: generate a verification token on registration (store in a file/database), send a verification email (test locally with mail() or SMTP).
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%