先跑通一条最简单的请求(如get /test返回字符串),再深入框架机制;优先检查web根目录、路由配置、环境变量等基础项,而非直接啃文档。

ThinkPHP 和 Laravel 是当前 PHP 初学者上手最现实的两个选择,但直接照着文档抄路由、建模型、跑 php artisan serve 或 php think run 很容易卡在“能跑但不懂为什么”的状态。真正卡人的不是语法,是请求进来后那一整条链路里哪一步断了、谁该负责、错误信息到底指向哪一层。
先跑通一条请求,别碰框架文档前50页
新手最大的误区是打开 Laravel 文档从 “Installation” 开始读,或把 ThinkPHP 的《完全开发手册》当教科书背。你不需要知道 Route::middleware() 有几种注册方式,只需要让 GET /test 返回一个字符串。
- ThinkPHP:删掉默认
app/controller/Index.php,新建app/controller/Test.php,写一个空index()方法,然后在route/app.php加Route::get('test', 'test/index');—— 访问http://localhost/test能输出就代表 MVC 流水线通了 - Laravel:执行
php artisan make:controller TestController --invokable,在routes/web.php加Route::get('/test', [TestController::class, '__invoke']);,控制器里直接return 'OK'; - 如果 404,优先检查:
public/是否为 Web 根目录(不是项目根目录)、.env里APP_URL没乱填、Apache/Nginx 是否启用了mod_rewrite或配置了try_files $uri $uri/ /index.php?$query_string;
Db::name() 和 Model 别混用,尤其在 ThinkPHP
刚学数据库操作时,Db::name('user')->where('id', 1)->find() 看起来最直白,但它绕过了模型层所有约束和事件。等你要加软删除、自动时间戳、字段类型转换时,就得重写全部查询逻辑。
- ThinkPHP 必须先定义
app/model/User.php,继承think\Model,再用User::find(1)—— 这样才能触发boot()、自动填充、验证器等机制 - Laravel 中
DB::table('users')是裸 SQL 封装,User::find(1)才走 Eloquent,后者支持->with('posts')、->whereHas()等高级关系操作 - 常见坑:
Db::name('user')查询结果是数组,User::find()返回对象,混用会导致Call to a member function xxx() on array
$request->validate() 不是可选功能,是必开安全开关
很多教程教完表单接收就结束,但真实项目里 $_POST['email'] 直接进 SQL 或发邮件,等于把大门敞开。Laravel 的 validate() 和 ThinkPHP 的 validate()->check() 不只是“检查格式”,它同时做了过滤、类型转换、错误收集三件事。
- Laravel 示例:
$request->validate(['email' => 'required|email|unique:users', 'age' => 'integer|min:18']);—— 错误时自动跳回并带$errors变量,且$request->email已是 trim 后的字符串 - ThinkPHP 示例:定义
app/validate/User.php,在控制器里调(new UserValidate())->check($data),失败时$this->error()自动返回 JSON 或跳转 - 不加验证的后果:MySQL 报错
Data too long for column 'email'是轻的,更可能是 SQL 注入或 XSS 输出到页面
别提前学中间件、服务容器、契约,先搞清“谁在什么时候调用了谁”
框架的抽象层越厚,出问题时越难定位。Laravel 的 Auth::user() 看似一行,背后涉及 Session 驱动、Guard 配置、UserProvider、Eloquent Model 实例化四层;ThinkPHP 的 $this->assign() 表面是传变量,实际触发了模板引擎初始化、变量过滤、缓存键生成。
- 调试建议:在控制器方法开头加
dump(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2));(ThinkPHP)或dd(request()->route());(Laravel),看调用栈里上一层是谁 - 遇到“找不到类”错误,先查
composer dump-autoload是否执行,再确认命名空间路径是否和文件物理路径一致(app\controller\User对应app/controller/User.php,不是app/controller/user.php) - 性能影响:Laravel 的服务容器每次 resolve 都有反射开销,ThinkPHP 的动态加载在未启用 opcode 缓存时,每个请求都要重新扫描类文件 —— 这些都不是初学阶段要优化的点,但得知道它们存在
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











