1.1 PHP编程概述与运行环境搭建
我刚开始接触PHP的时候,脑子里其实有个很大的问号——这玩意儿到底能干嘛?后来慢慢才搞明白,PHP最核心的战场就是Web开发。你平时访问的那些网站,有相当大一部分背后跑的就是PHP代码。像WordPress这种全球用量最大的内容管理系统,底层全是PHP写的。再比如说早期的Facebook、Wikipedia,也是靠PHP撑起来的。中小型企业的官网、电商后台、API接口服务,PHP都能干。它的应用场景集中在服务端脚本,处理HTTP请求、读写数据库、生成动态页面,这些是PHP的主场。
聊到运行原理,其实没想象中那么玄乎。用户浏览器发一个请求到服务器,服务器上的PHP解释器把.php文件里的代码执行一遍,生成HTML内容,再吐回给浏览器。整个过程是同步阻塞的,一个请求一个响应。PHP本身是解释型语言,不需要编译成二进制,改完代码刷新页面就能看到效果。这也是很多人觉得PHP入门快的原因之一。当然现在有了OPcache和JIT,性能比早年好太多了。
环境搭建这块,我早期踩过的坑真不少。最省事的办法是用集成环境,比如XAMPP、phpStudy、MAMP,一键装好Apache、MySQL、PHP,适合刚上手的时候快速跑起来。等你稍微熟悉了,可以试试手动配Nginx + PHP-FPM + MySQL。Nginx负责处理静态资源和反向代理,PHP-FPM管理PHP进程池,两者通过FastCGI协议通信。这种架构在生产环境里更常见,性能也更能扛。开发工具方面,我一开始用Sublime Text,后来转到VS Code,装个PHP Intelephense插件,代码提示和跳转就很顺手了。PhpStorm功能更全,不过占内存也大,看个人习惯。搭建环境时注意PHP版本和扩展,比如mysqli、pdo_mysql、gd这些,后面做数据库和图片处理都要用到。
1.2 PHP基础语法与核心数据类型
变量在PHP里就是个带美元符号的名字,比如$name、$age。它不用提前声明类型,赋什么值就是什么类型。这点跟JavaScript有点像。不过PHP的变量作用域得留心,函数内部默认拿不到外部变量,要用global关键字或者$GLOBALS超全局数组。我写第一个函数的时候就犯过这个错,函数里怎么都读不到外面的变量,找了半天才反应过来。
常量用define()或者const定义,一旦定下来就不能改。适合放一些配置项,比如数据库主机名、API密钥。运算符这块,除了加减乘除,PHP有个===全等比较,不光比值还比类型。'1' == 1是true,'1' === 1就是false。这个细节在表单验证的时候特别关键,用户提交上来的数据默认都是字符串,你得判断清楚。
流程控制无非就是if、else、switch、for、while、foreach。foreach遍历数组是PHP里用得最多的,写起来也舒服。函数定义用function关键字,支持默认参数和可变参数。PHP 7之后支持类型声明,参数和返回值都能指定类型,代码更严谨一些。数组是PHP的灵魂,分为索引数组和关联数组。$arr = ['name' => '张三', 'age' => 25]这种就是关联数组,用起来像字典。字符串处理函数特别多,strlen、substr、str_replace、explode、implode,这些日常写代码基本天天见。我建议新手把数组和字符串的常用函数挨个过一遍,后期写业务逻辑会顺畅很多。
1.3 PHP表单交互与会话控制
表单提交是PHP跟用户交互的第一步。GET请求把参数拼在URL后面,适合搜索、筛选这种场景。POST请求把数据放在请求体里,适合登录、注册这些涉及敏感信息的操作。$_GET和$_POST这两个超全局数组能直接拿到提交的数据。不过千万别直接信任用户输入,我见过有人把用户提交的内容直接拼进SQL语句,结果数据库被拖走了。表单验证至少要做两层:前端JavaScript做即时提示,后端PHP做最终校验。empty()、isset()、filter_var()这些函数可以帮你判断数据是否为空、格式是否合法。
Cookie是存在浏览器端的小块数据,用来记住用户状态。比如“记住用户名”这个功能,就是把用户名写进Cookie。Session存在服务器端,通过一个Session ID跟浏览器关联。用户登录后,把用户信息存进$_SESSION,后续请求就能识别身份。Session比Cookie安全,但会占用服务器资源。用session_start()开启会话,session_destroy()销毁会话。注意Session ID的传递方式,默认用Cookie,如果Cookie被禁用可以配trans_sid,不过现在基本没人这么干了。
文件上传用$_FILES数组接收,配合move_uploaded_file()把临时文件挪到目标位置。上传前要检查文件类型、大小、后缀名。别光看后缀,MIME类型也要验证。我吃过亏,有人把.php文件伪装成.jpg传上来,然后通过URL访问直接执行了。上传目录千万别给执行权限。文件处理方面,file_get_contents()读文件,file_put_contents()写文件,fopen()、fread()、fwrite()适合大文件分块操作。
1.4 PHP数据库操作与安全入门
MySQL是PHP最常搭配的数据库。学PHP不碰数据库等于白学。先搞懂基本SQL:SELECT、INSERT、UPDATE、DELETE,还有WHERE条件、ORDER BY排序、LIMIT分页。表设计要遵循范式,字段类型选合适的,主键索引用好。PDO是PHP连接数据库的推荐方式,支持多种数据库驱动,切换数据库不用改太多代码。连接代码大概长这样:$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'password')。记得设置错误模式为异常,出问题能及时暴露。
增删改查用PDO的prepare()和execute()配合。预处理语句能有效防SQL注入,原理是SQL模板和参数分两次发送,数据库先解析模板,参数后填充。攻击者想通过输入拼接SQL语句就行不通了。我强烈建议所有涉及用户输入的查询都用预处理,别图省事直接query()。事务处理用beginTransaction()、commit()、rollBack(),保证一组操作要么全成功要么全回滚。
XSS攻击是往页面注入恶意脚本。防护办法是用htmlspecialchars()转义输出内容。用户提交的评论、昵称这些展示到页面上之前,统统转义一遍。CSRF是跨站请求伪造,攻击者诱导用户在自己已登录的网站上执行非预期操作。防护手段是在表单里加一个token,服务器端验证token是否匹配。这个token存在Session里,每次表单渲染时生成。PDO预处理、输出转义、CSRF Token,这三样是PHP安全的基本功。密码存储用password_hash()和password_verify(),别用md5,彩虹表早就把md5破了。
1.5 原生PHP小型项目实战
我选留言板作为练手项目。需求不复杂:用户可以提交留言,留言展示在页面上,有基本的表单验证。数据库建一张messages表,字段有id、nickname、content、created_at。用一个index.php做入口,提交表单走POST请求。接收数据后用trim()去空格,htmlspecialchars()转义,再通过PDO预处理插入数据库。展示留言时从数据库查出来,foreach循环渲染。分页功能可以后面加上,用LIMIT offset, count实现。
编码过程中会遇到各种小问题。比如中文乱码,需要在数据库连接时设置charset=utf8mb4,HTML头部声明UTF-8。时间格式化用date()函数把数据库的datetime转成友好的显示格式。表单重复提交可以用Session存一个token,提交后销毁。留言板做完之后可以试试待办清单,增加已完成/未完成状态切换,练习UPDATE操作和AJAX交互。
本地部署就是把项目文件放到Web服务器的根目录下,Apache默认是htdocs或者www,Nginx在配置里指定root路径。数据库用phpMyAdmin或者命令行导入SQL文件。访问localhost/你的项目目录就能跑起来。部署完检查一下错误日志,PHP的error_log()或者服务器自己的日志文件,有报错信息就照着修。这个留言板虽小,但覆盖了PHP编程入门教程里输入处理、数据库操作、输出转义、会话管理这些核心知识点。做完一遍,对PHP怎么干活就有实感了。
2.1 为什么使用PHP框架:MVC模式、Composer依赖管理、路由、中间件、ORM、模板引擎与工程化思维
我最早写PHP的时候,一个文件里HTML、PHP逻辑、SQL查询全混在一起,改个按钮颜色都得在几百行代码里翻找。那种写法做个留言板还行,稍微大一点的项目就乱成一锅粥。后来朋友推荐我试试框架,我才明白什么叫“各司其职”。MVC模式把数据操作、业务逻辑、页面展示拆成三个部分,模型管数据库,控制器管流程,视图管输出。你改样式不用动逻辑,改逻辑不用碰SQL。路由这个东西也让我省心,以前用GET参数判断页面,比如index.php?action=edit&id=5,一堆if-else。框架里一条路由规则就能把URL映射到控制器方法,看着清爽多了。
Composer是PHP的依赖管理工具,有了它,你不需要手动去下载某个类库再include进来。在composer.json里写清楚要什么包,一条composer install命令全部搞定。中间件像一道过滤网,请求进入控制器之前可以先做身份验证、日志记录、跨域处理。我做过一个项目,所有后台接口都要检查登录状态,用中间件写一次,所有路由自动生效,不用每个方法里重复写。ORM把数据库表变成对象,比如$user->name,不用自己拼SQL。模板引擎让前端同事也能参与,Blade或者Twig语法简单,学起来快。
工程化思维是框架带来的最大价值。项目结构统一了,新人接手能快速看懂。代码有地方放,配置有文件管,测试有工具跑。我参与过一个团队协作的项目,大家用同一个框架,代码风格自然就一致了。版本控制、自动化部署、持续集成这些也能顺利接上。说白了,框架不是万能的,但它帮你把脏活累活干了,你专注写业务就好。
2.2 PHP编程常用框架概览与选型:Laravel、Symfony、ThinkPHP、Yii、CodeIgniter特点与适用场景对比
Laravel是我用得最多的框架。它的生态太丰富了,官方文档写得像教程,社区活跃,遇到问题搜一下基本都有答案。Eloquent ORM写起来很舒服,Blade模板也直观。适合快速开发中小型项目,尤其是创业公司或者个人接活。Symfony更像一套组件工具箱,很多大项目比如Drupal、Shopware都基于它。它的灵活性高,但学习曲线陡一些。如果你需要高度定制化的企业级应用,Symfony值得考虑。
ThinkPHP在国内很流行,中文文档齐全,上手快。它的设计对新手友好,很多培训机构教这个。适合做中小型项目,尤其是外包或者内部系统。Yii的性能不错,代码生成工具(Gii)能自动生成CRUD,开发效率高。它适合对性能有要求、又不想太复杂的场景。CodeIgniter非常轻量,几乎没有强制约定,文件小,运行快。如果你维护老服务器,或者只想用个小框架做简单API,CodeIgniter很合适。
选型这件事,我自己的经验是看三点。团队熟悉什么框架,别为了新潮去选没人会用的。项目规模和生命周期,小项目别上重型框架,大项目别用太简陋的。社区和文档质量,遇到坑有人帮你填。我见过有人非要用Symfony做一个小博客,结果配置花了两天。也见过用CodeIgniter硬撑大型电商,后期扩展痛苦。没有最好的框架,只有最合适的。
2.3 Laravel核心入门:安装配置、路由与控制器、Eloquent ORM、Blade模板、数据库迁移与数据填充
安装Laravel用Composer最方便,composer create-project laravel/laravel myapp。装好后配置.env文件,填数据库账号密码。Laravel的目录结构很清晰,app放核心代码,routes放路由定义,resources/views放模板。路由文件web.php里写Route::get(‘/hello’, function () { return ‘Hello’; }); 就能访问。控制器用artisan命令生成,php artisan make:controller UserController。控制器里写方法,路由指向控制器方法。我一开始不习惯用命令行,后来发现artisan能省很多手动建文件的时间。
Eloquent ORM是Laravel的数据库操作层。每个表对应一个模型,比如User模型对应users表。查询用User::where(‘age’, ‘>’, 18)->get(),返回的是对象集合。关联关系也好写,一个用户有多篇文章,在模型里定义hasMany就行。Blade模板引擎用{{ $name }}输出变量,@if、@foreach做流程控制。模板继承用@extends和@section,布局文件可以复用。数据库迁移用php artisan make:migration,在迁移文件里写Schema::create定义表结构。执行php artisan migrate就建表。数据填充用Seeder类,可以批量插入测试数据。这套组合让我做新项目时,数据库搭建速度翻倍。
我学Laravel的时候踩过一个坑,忘了在.env里改APP_KEY,结果Session用不了。后来知道安装完要执行php artisan key:generate。还有一次路由缓存没清理,改了路由不生效,用php artisan route:clear解决。这些小命令记熟了,开发过程就顺了。
2.4 ThinkPHP与Symfony快速上手:项目结构、请求生命周期、数据库操作、常用组件与扩展机制
ThinkPHP的项目结构很符合国内开发者的习惯。public/index.php是入口文件,application目录放模块,每个模块有controller、model、view。请求生命周期从入口文件开始,经过路由解析、中间件、控制器方法,最后返回响应。数据库操作可以用Db类,比如Db::name(‘user’)->where(‘id’, 1)->find(),也可以用模型。模型支持自动验证、关联查询。扩展机制通过composer或者自定义标签库。ThinkPHP的文档中文写得很细,跟着做一遍基本就会了。
Symfony的入门方式不太一样。用composer create-project symfony/skeleton安装,然后用symfony console make:controller生成控制器。它的请求生命周期由HttpKernel处理,经过事件分发器,你可以在不同阶段挂载监听器。数据库用Doctrine ORM,实体类用注解或者属性定义字段。常用组件很多,比如Form、Validator、Security,可以独立使用。扩展机制靠Bundle,一个Bundle打包功能,注册到bundles.php就能用。Symfony的调试工具栏很强大,开发时能看到请求、数据库查询、性能分析。
我同时学这两个框架的时候,感觉ThinkPHP像自动挡汽车,上手快,约定多。Symfony像手动挡,自由度高,但需要了解内部机制。如果你赶项目,ThinkPHP能让你快速出活。如果你想深入理解框架设计,Symfony值得花时间。
2.5 框架项目实战与进阶:RESTful API开发、用户认证授权、缓存、队列、测试、部署与性能优化
用Laravel做RESTful API很顺手。定义资源路由Route::apiResource(‘posts’, PostController::class),自动生成增删改查的接口。控制器里返回JSON,用response()->json()或者直接返回数组。认证授权可以用Laravel Passport或者Sanctum。Sanctum适合SPA和移动端,发Token给客户端,请求时带上Authorization头。授权用Gate和Policy,比如判断用户能不能修改某篇文章。缓存用Redis驱动,把热点数据存起来,减少数据库压力。Laravel的Cache门面支持remember方法,先查缓存,没有再去数据库。
队列用来处理耗时任务,比如发邮件、生成报表。把任务丢进队列,后台进程慢慢处理,用户不用等。配置QUEUE_CONNECTION=database或者redis。测试用PHPUnit,Laravel提供了很多测试辅助方法,比如$response->assertStatus(200)。我习惯给每个API写功能测试,改代码后跑一遍,心里踏实。部署的时候用Nginx + PHP-FPM,配置好root指向public目录,设置OPcache。Laravel有优化命令,php artisan config:cache、route:cache、view:cache,生产环境跑一遍能提速。性能优化还包括数据库索引、Eloquent的预加载(with方法)避免N+1查询。
我做过一个API项目,上线后发现某个列表接口特别慢。用Laravel Debugbar一看,每条记录都去查一次用户表,典型的N+1问题。加上with(‘user’)之后,查询次数从几百次降到几次。缓存也帮了大忙,把分类列表缓存十分钟,数据库负载明显下降。队列处理图片上传的缩略图生成,用户上传完立刻返回,后台慢慢转码。测试覆盖了主要接口,部署时用Envoy脚本一键发布。这套流程走下来,项目维护起来轻松很多。