当前位置:首页 > 热点

php网站开发实战项目式教程

打开编辑器,站开战项新建一个文件夹叫 shop,发实里面只放三个文件:index.php、目式style.css、教程config.php。站开战项这就是发实一个电商网站的全部起点。别急着上框架,目式先把 PHP 原生写顺了,教程后面学 Laravel 或 ThinkPHP 才不会晕。站开战项

config.php 里只做一件事——连数据库。发实我习惯用 PDO,目式不为什么,教程就因为它预处理防注入这点比 mysqli 省心。站开战项写四行代码:

$dsn = 'mysql:host=localhost;dbname=shop;charset=utf8mb4'; $user = 'root'; $pass = '123456'; $pdo = new PDO($dsn,发实 $user, $pass); 

这三行里 charset 必须写 utf8mb4,别用 utf8。目式utf8 在 MySQL 里是残废的,存 emoji 会直接报错。我见过有人存用户昵称带个笑脸符号,页面白屏半小时找不到原因。

index.php 是商品列表页。从 products 表里查数据,foreach 循环输出。这里有个新手常踩的坑:把 SQL 写在循环里。比如每输出一个商品就去查一次分类名,二十个商品查二十次数据库。正确做法是一次性 JOIN 查出来,或者用 IN 把分类 id 全取出来再查一次。我实测过,列表页从 0.8 秒降到 0.05 秒,差别就这么大。

商品图片上传是另一个实战点。move_uploaded_file 之前必须检查三样东西:文件类型、文件大小、文件名后缀。别信前端 accept 属性,那玩意儿用 Burp Suite 一抓就能绕。我通常这么写:

$allow = ['image/jpeg', 'image/png', 'image/webp']; if (!in_array($_FILES['img']['type'], $allow)) {  die('格式不对'); } $newname = md5(time() . rand()) . '.jpg'; move_uploaded_file($_FILES['img']['tmp_name'], 'uploads/' . $newname); 

md5 加时间戳加随机数,防止文件名冲突。uploads 目录要设 755 权限,别给 777。777 意味着任何脚本都能往里写东西,等于给黑客留后门。

购物车用 session 实现最直接。$_SESSION['cart'] 存一个关联数组,键是商品 id,值是数量。加购、减购、删除、清空,四个操作对应四个 if 分支。有人问为什么不用 cookie?cookie 存在客户端,用户改一下数量你都不知道。session 存服务器,安全得多。但 session 也有坑:默认 1440 秒过期,用户逛久了购物车就空了。在 php.ini 里把 session.gc_maxlifetime 改成 86400,或者用 Redis 接管 session。

订单提交要做事务处理。插入 orders 表拿到订单 id,再批量插入 order_items,最后扣库存。三步必须包在 beginTransaction 和 commit 之间。少写一个 commit,数据就丢了。我见过一个实习生的代码,扣库存写在事务外面,结果订单没生成但库存减了,对账对了三天。

后台管理别搞太复杂。一个 admin 文件夹,login.php 做登录验证,product_list.php 做增删改查。密码存 password_hash 生成的哈希,验证用 password_verify。别用 md5 存密码,彩虹表一查就出来。登录成功后写 $_SESSION['admin'] = true,每个后台页面开头检查这个变量,没有就 header 跳回登录页。

部署上线前把 display_errors 关掉,error_reporting 设成 E_ALL 但日志写到文件。线上直接显示错误信息等于把数据库密码告诉所有人。我习惯在入口文件加一行 ini_set('display_errors', 0),开发环境再打开。

这套流程走完,一个能跑的小型商城就出来了。代码量不大,但每个环节都是真实项目里绕不开的坎。写完再回头看框架的文档,会发现它帮你封装的正是这些琐碎又必须处理的东西。

分享到: