本文目录导读:

在 PHP 中实现 SSR(服务端渲染)主要有以下几种方式,根据项目复杂度选择合适的方案:
传统 PHP 模板引擎(最常用)
Blade(Laravel)
// routes/web.php
Route::get('/users', function () {
$users = User::all();
return view('users.index', ['users' => $users]);
});
// resources/views/users/index.blade.php
@extends('layouts.app')
@section('content')
<h1>用户列表</h1>
@foreach($users as $user)
<div class="user-card">
<h2>{{ $user->name }}</h2>
<p>{{ $user->email }}</p>
</div>
@endforeach
@endsection
Twig(Symfony)
// 控制器
class UserController extends AbstractController
{
public function index()
{
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
return $this->render('user/index.html.twig', [
'users' => $users,
]);
}
}
// templates/user/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<h1>用户列表</h1>
{% for user in users %}
<div class="user-card">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
{% endfor %}
{% endblock %}
原生 PHP 模板
<?php
// 直接从数据库获取数据
$users = $db->query("SELECT * FROM users")->fetchAll();
// 加载 HTML 模板
include 'templates/header.php';
?>
<h1>用户列表</h1>
<?php foreach ($users as $user): ?>
<div class="user-card">
<h2><?= htmlspecialchars($user['name']) ?></h2>
<p><?= htmlspecialchars($user['email']) ?></p>
</div>
<?php endforeach; ?>
<?php include 'templates/footer.php'; ?>
前后端分离 + PHP API + 前端 SSR
如果已经有前端框架,可以用 PHP 作为后端 API:
Laravel + Nuxt.js
// Laravel API
Route::get('/api/users', function () {
return response()->json([
'users' => User::all()
]);
});
// Nuxt.js 服务端渲染
// pages/users/index.vue
export default {
async asyncData({ $axios }) {
const { data } = await $axios.get('/api/users')
return { users: data.users }
},
template: `
<div>
<h1>用户列表</h1>
<div v-for="user in users" :key="user.id">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
</div>
`
}
混合 SSR(高级方案)
使用 PHP 渲染初始 HTML,再加载 JavaScript 增强交互:
<!-- index.php -->
<!DOCTYPE html>
<html>
<head>用户列表</title>
<style>
.user-card { border: 1px solid #ddd; padding: 10px; margin: 10px 0; }
</style>
</head>
<body>
<div id="app">
<?php
// PHP 渲染初始数据
$users = getUsersFromDB();
foreach ($users as $user) {
echo '<div class="user-card" data-user-id="' . $user['id'] . '">';
echo '<h2>' . htmlspecialchars($user['name']) . '</h2>';
echo '<p>' . htmlspecialchars($user['email']) . '</p>';
echo '<button class="delete-btn">删除</button>';
echo '</div>';
}
?>
</div>
<script>
// JavaScript 增强交互
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const userId = this.closest('.user-card').dataset.userId;
fetch('/api/delete-user/' + userId, { method: 'POST' })
.then(response => response.json())
.then(data => {
if (data.success) {
this.closest('.user-card').remove();
}
});
});
});
</script>
</body>
</html>
使用 Laravel Livewire(推荐)
对于需要交互性的应用,Livewire 提供类似 SPA 体验但保持服务端渲染:
// app/Http/Livewire/UserList.php
class UserList extends Component
{
public $search = '';
public function render()
{
$users = User::where('name', 'like', "%{$this->search}%")->get();
return view('livewire.user-list', ['users' => $users]);
}
public function deleteUser($userId)
{
User::find($userId)->delete();
}
}
<!-- resources/views/livewire/user-list.blade.php -->
<div>
<input type="text" wire:model="search" placeholder="搜索用户...">
@foreach($users as $user)
<div class="user-card">
<h2>{{ $user->name }}</h2>
<p>{{ $user->email }}</p>
<button wire:click="deleteUser({{ $user->id }})">删除</button>
</div>
@endforeach
</div>
最佳实践建议
- 简单网站/博客 → 使用 Blade 或 Twig
- 需要 SEO 和快速首屏 → 传统模板引擎
- 复杂交互应用 → Laravel Livewire 或 Inertia.js
- 已有前端项目 → PHP 作为 API + 前端 SSR 框架
性能优化技巧
// 使用缓存
$cacheKey = 'users_list_page';
$html = Cache::remember($cacheKey, 3600, function () {
$users = User::all();
return view('users.index', compact('users'))->render();
});
echo $html;
选择方案时考虑:团队熟悉度、项目规模、SEO 要求、交互复杂度等因素。