资讯动态

301页PHP入门笔记:HTML表格表单与GET/POST接收端实战

发布时间:2026/9/17 23:28:08 来源:尧图企业网站定制
简介这份《PHP从入门到精通完整笔记》以单份301页PDF形式呈现面向零基础想系统学习Web开发的初学者以及需要完整课堂讲义用于复习巩固的在校学生。内容按课程进度编排前22讲梳理HTML与CSS基础从超文本标记语言的历史沿革、W3C标准、本地运行与远程访问原理讲起逐步深入到html、head、body基本结构成对标记与单标记、字符实体、超链接target属性、图片宽高设置以及table表格的行列合并与对齐控制第23至149讲转入PHP部分覆盖变量、条件判断、循环、数组、函数、类与对象并延伸至与MySQL数据库交互的动态网页开发。压缩包内仅1个PDF文件体积约2.14MB轻便易存手机与电脑均可随时翻阅。目前已有1083人学习适合按讲次顺序精读也可作为查漏补缺的速查手册。1. 301 页笔记摊开来看先啃 HTML 表格与表单再进 PHP 接收端很多人上手 PHP 的第一件事是找一套 php网站源码改改数据库配置就跑起来等到要自己加一个注册框、把数据存进库才发现卡住的地方不在 PHP 语法而在 HTML 表单的 name 怎么命名、method 为什么前后端对不上、复选框为什么取不到值。这份《PHP从入门到精通完整笔记》的编排恰好对症前 22 讲铺 HTML 与 CSS从 html/head/body 骨架讲到表格的 colspan、rowspan再到 frameset、iframe 与表单控件族第 23 讲往后才切进 PHP把「页面长什么样」和「数据往哪送」接成了一条线。零基础跟着走一遍不吃力半路出家的运维、测试也能拿它补表单这块短板。301 页不用一次读完值得反复翻的只有三处表格合并、表单控件、提交方法其余当手册查。2. HTML 文档结构与表格布局head/body、单标记、colspan 与 rowspan 的实战浏览器解析一份文档先看结构再看内容最后才谈样式。笔记里 HTML 部分的开头几讲没急着上 CSS而是把「结构」这件事讲透这个顺序对新手是对的结构错了后面写多少样式都救不回来。表格这块尤其典型它是这套笔记里代码量最大的一节也是后面表单排版的基础。2.1 文档骨架、单双标记与字符实体的最小约定一份 HTML 文件的骨架就三层html是根head装元信息标题、编码、外链资源body装用户在页面上看得见的东西。标记分两类成对出现的叫双标记比如head/head、b/b只有一个标签的是单标记比如br/、img/、input/、hr/。属性统一写成属性名值值加双引号是习惯不加多数浏览器也认但遇到带空格的值就会翻车。!DOCTYPE html html head !-- head 里的 charset 决定中文会不会乱码必须写在最前 -- meta charsetutf-8 / title我的第一个页面/title /head body !-- 双标记有开始有结束 -- b横看成岭侧成峰/bbr/ !-- 单标记自闭合没有结束标签 -- font colorred远近高低各不同/fontbr/ !-- 内联样式优先级高于 font 的 size 属性 -- font stylefont-size:30px;不知庐山真面目/fontbr/ !-- 字符实体把保留字符当普通文本显示 -- plt;tablegt; 是块级元素nbsp;nbsp;这里有两个空格/p /body /html这段代码里有两处值得单独记一是stylefont-size:30px与font size1..7同时存在时内联样式生效font的size只能取 1 到 7 这七个档位粒度太粗所以笔记里同时给了两种写法二是字符实体lt;输出左尖括号nbsp;输出不换行空格copy;输出版权符。只要是 HTML 的保留字符、、要显示成文字就必须走实体否则浏览器会当成标签解析。顺带说一个常被当面试题的点.html和.htm后缀有什么区别。同一目录下同时存在 index.html 和 index.htm服务器默认优先返回.html.htm的存在是早期 DOS 系统 8.3 命名规范的遗留那时主文件名不能超过 8 个字符扩展名不能超过 3 个。今天写.htm不会有问题但没必要。运行方式上本地直接双击是file://协议把文件丢到 Web 服务器目录再访问是http://协议。W3C 负责给 HTML、XHTML、CSS、XML 这些定标准但各家浏览器实现有差异同一个页面在不同内核下渲染结果可能不一致所以才有了历史上的 hack 写法。这块在笔记里只是一笔带过但它是理解后面 CSS 兼容问题的前提。2.2 表格属性速查与 colspan/rowspan 合并规则笔记里表格的入门例子直接堆了一串属性初看很杂其实是三组控制整体外观的、控制行内对齐的、控制单元格合并的。把下面这张表记住再看代码就不乱了。属性作用常见取值写在哪个标签上align水平对齐方式left / center / righttable、tr、tdborder边框宽度0 或像素值tablebordercolor边框颜色#E76BFF或颜色名tablebgcolor背景色yellow /#RRGGBBtable、tr、tdwidth/height宽高400px或百分比table、tdcellpadding单元格内容与边框的内边距像素值tablecellspacing单元格之间的间距0 表示紧贴tablecolspan横向合并几列数字td、throwspan纵向合并几行数字td、th把属性套进一个课表结构里colspan和rowspan的作用立刻清楚table border1 bordercolor#579AFE cellspacing0 cellpadding4 width500px aligncenter tr aligncenter td项目/td !-- 横跨 5 列上课 -- td colspan5上课/td !-- 横跨 2 列休息 -- td colspan2休息/td /tr tr bgcolorpink aligncenter th星期/thth星期一/thth星期二/thth星期三/th th星期四/thth星期五/thth星期六/thth星期日/th /tr tr aligncenter !-- 纵跨 4 行上午 -- td rowspan4上午/td td语文/tdtd数学/tdtd英语/tdtd英语/tdtd物理/td td计算机/td !-- 纵跨 4 行休息 -- td rowspan4休息/td /tr tr aligncenter td数学/tdtd数学/tdtd地理/tdtd历史/tdtd化学/tdtd计算机/td /tr tr aligncenter td化学/tdtd语文/tdtd体育/tdtd计算机/tdtd英语/tdtd计算机/td /tr tr aligncenter td政治/tdtd英语/tdtd体育/tdtd历史/tdtd地理/tdtd计算机/td /tr /tablecellspacing0让单元格紧贴这是做细边框表格的常规操作不写就是默认的两像素缝。aligncenter写在 table 上是整表居中写在 tr 上是该行内容居中写在 td 上是该格内容居中作用范围逐层收窄td 上的设置会覆盖 tr。2.2.1 合并单元格最容易踩的三个坑第一个坑是行内 td 数量算错。rowspan占掉的行在后续的行里不能再写对应的 td否则整张表会往右错位。判断方法很简单每一行实际写的 td 数加上被上面 rowspan 占用的列数必须等于总列数。上面例子里表头是 8 列第二行写了 8 个 td第三行只有 1 加 6 加 1 共 8 个后面的行因为被第一列的rowspan4和最后一列的rowspan4各占一格所以只写 6 个 td。第二个坑是colspan与rowspan同时用时的交叉覆盖这种结构在真实项目里基本只出现在复杂表头建议拆成嵌套表或改用 CSS Grid别硬扛。第三个坑是把 table 当布局工具。笔记里明确写了早年页面布局要求不高时确实用表格排版但今天横向对齐用display:flex纵向栅格用 Grid表格只负责展示二维数据混用会让移动端适配直接失效。2.3 列表、超链接与图片的属性细节列表分无序和有序两种。无序列表ul的type可以取 disc实心圆默认、circle空心圆、square方块有序列表ol的type可以取 1、A、a、I、istart指定从第几项开始编号做条款类文档时很有用。超链接的核心是href和targethref写相对路径就站内跳转写完整 URL 就跳外站写mailto:就唤起邮件客户端。ul typecircle li英雄/li li精武门/li /ul ol typeI start3 li卢俊义/li li吴用/li /ol !-- target 的四个保留值_self 本窗口、_blank 新窗口、 _top 跳出所有框架、_parent 上一级框架 -- a hrefa.html target_blank新窗口打开 a.html/a a hrefhttp://www.example.com跳转到外站/a a hrefmailto:adminexample.com联系管理员/a !-- 相对路径优先width/height 建议只写一个让浏览器等比缩放 -- img srcimages/logo.png width120 /target除了四个下划线开头的保留值还能直接写某个 frame 或 iframe 的 name这个特性在第 3 章会用到。图片这里有个老笔记里常见的写法img srcF.GIF dynsrcclock.avi loop2 startmouseover/用图片占位、鼠标移上去才播放视频这是早期 IE 的私有行为现在只有历史价值知道它存在就行别往新项目里抄。3. frameset、iframe 与图像映射老派页面拼装技术在后台页面的复用框架集、画中画、图像热区这三样东西在今天的前端教程里基本被删干净了但后台管理系统、旧项目维护、以及需要嵌第三方页面的场景里它们还在跑。笔记里这几节代码给得比较全值得花时间过一遍至少做到能读懂、能改。3.1 frameset 分割页面与 target 定向frameset 的作用是把一个浏览器窗口切成几块每块装一个独立页面。它和 body 是互斥的用了frameset的页面里不能再出现body否则整个框架结构会失效这是新手最常犯的错。!-- A2.html左侧 30% 是菜单右侧自适应 -- frameset cols30%,* !-- noresize 去掉才能拖动分割线frameborder0 去边框 -- frame nameframe1 srcb.html noresize frameborder0 / frame nameframe2 srcc.html frameborder0 / /frameset!-- b.html菜单页点击后内容在 frame2 里打开 -- body bgcolorpink !-- target 直接写 frame 的 name就把内容定向到那一格 -- a hrefzjl.html targetframe2周杰伦/abr/ a hrefqq.html targetframe2齐秦/abr/ /body多级分割靠嵌套外层用rows20%,*切成上下两块下面那块再嵌一个cols20%,*切成左右两块就构成了「上标题、左菜单、右内容」的经典后台布局。注意rows和cols的值可以是百分比也可以是像素还可以用*表示剩余空间写20%,*时后面的星号会吃掉剩余全部宽度。scrollingno关掉滚动条noresize锁住分割线这两个属性在处理标题栏和菜单栏时用得最多。要提醒的是frameset 页面没法做 SEO浏览器的前进后退和收藏行为也会变乱URL 里只显示框架集页面地址内容页地址用户看不到。它只适合内部系统不适合对外站点。3.2 iframe 画中画有 body 的页面里嵌页面frameset 是把整页切了iframe 是在一个正常页面里挖一块窗口。它必须有 body用法和普通元素一样src指定要嵌的页面width、height控制尺寸name供 target 引用。html body h1hello,world/h1 !-- 点击链接目标页面在 iframe1 里打开页面本身不跳转 -- a hrefhttp://www.example.com targetiframe1在浮动窗口打开示例站/abr/ a hrefdetail.html targetiframe1在浮动窗口打开详情页/abr/ iframe nameiframe1 srcwelcome.html width500px height400px/iframe /body /htmltargetiframe1这个写法在「列表页 详情页」的后台里非常常见左边点一条记录右边 iframe 里刷详情页面不整体刷新。如果嵌的是外部站点很多站点会返回X-Frame-Options或Content-Security-Policy响应头阻止被嵌入表现为 iframe 一片空白这时打开 F12 看 Console 会直接报拒载信息属于对方站点的策略不是自己代码写错了。维度framesetiframediv CSS 布局能否有 body不能有必须有必须有分割范围整页分割局部窗口局部窗口地址栏与前进后退容易混乱影响较小正常移动端适配差一般好常见场景老式后台菜单嵌外部页、预览、详情现代页面结构3.3 图像映射 area 的 coords 与 fieldset 表单分组图像映射解决的是「一张图上有多个可点区域」的问题比如楼层平面图、身体部位图。写法是给img加usemap#名字再用map name名字定义若干area。html head script languagejavascript function show(){ window.alert(点击了矩形区域); } /script /head body img srcmapimg.gif usemap#abc / map nameabc !-- shaperect 时coords 是 x1,y1,x2,y2 左上角与右下角 -- area shaperect coords140,20,280,60 onclickshow(); href# / /map /body /htmlcoords的含义随shape变化rect是左上角与右下角两个坐标点circle是圆心 x、圆心 y、半径poly是一串首尾相连的顶点坐标。调试热区最土也最好用的办法是在图片上临时加一层半透明遮罩把坐标网格画出来或者直接用图片编辑工具读像素坐标比反复改数字试快得多。表单分组用fieldset加legend视觉上是一个带标题的框语义上也把一组相关控件圈在一起fieldset stylewidth:300px legendfont colorblue审核状态/font/legend form input typeradio namestate value1已经审核 input typeradio namestate value0没有审核 input typeradio namestate valueall全部 /form /fieldset同一组单选框必须共用同一个name浏览器才会把它们当成互斥选项value是提交到服务端的真实值页面上显示的文字和提交值不一定一致这一点在接 PHP 时经常出事。4. 从表单控件到 PHP 接收端GET/POST 提交链路的完整跑通HTML 部分学完真正见分晓的是数据能不能送进 PHP。笔记在表单这一节给了一个登录页的例子但只到静态页面就停了缺了接收端那一半。补上这一半整条链路才算闭环。4.1 GET 与 POST 的语义差异与表单写法表单的本质是「浏览器把控件里的值打包按指定方法发给一个 URL」。打包方式、参数位置、长度限制GET 和 POST 完全不一样。对比项GETPOST参数位置拼在 URL 的?后面放在请求体里可见性地址栏、日志、历史记录都能看到不显示在地址栏长度限制受 URL 长度限制基本只受服务端配置限制中文与特殊字符需要 URL 编码表单默认编码相对省心幂等 / 缓存幂等可被缓存、可收藏非幂等一般不缓存PHP 超全局$_GET$_POST典型用途查询、分页、筛选登录、注册、写入、上传登录页的正确写法是把action指向接收脚本method用 post!-- login.html -- form actionlogin.php methodpost !-- name 的值就是 PHP 端 $_POST 的键名不要用关键字 -- 用户名:input typetext nameusername /br/ 密 码:input typepassword namepassword /br/ input typesubmit value登录系统 / input typereset value重新填写 / /formaction写相对路径时相对的是当前页面所在目录method不写默认是 GET很多人调试时发现密码出现在地址栏就是这里漏了。submit的value是按钮上显示的字reset把表单恢复成初始值。4.2 PHP 接收端isset、trim 与输出转义接收端第一件事是判断键存在而不是直接取值。用户可能通过 curl、或者禁用 JS 后绕过页面直接提交未勾选的复选框压根不会出现在数组里硬取值会直接报未定义索引。?php // login.php接收 login.html 用 POST 提交的数据 header(Content-Type: text/html; charsetutf-8); // isset 先判存在再 trim 去首尾空白 $username isset($_POST[username]) ? trim($_POST[username]) : ; $password isset($_POST[password]) ? trim($_POST[password]) : ; if ($username || $password ) { http_response_code(400); exit(用户名或密码为空); } // 输出到页面时必须转义否则用户名里写脚本会被执行 echo 收到用户名 . htmlspecialchars($username, ENT_QUOTES, UTF-8);isset()返回布尔值比array_key_exists轻配合三元表达式是最常见的写法。trim()去掉用户误输的首尾空格密码两边不加空格很少有人故意这么干去掉利大于弊。htmlspecialchars()把、、、转成实体参数ENT_QUOTES表示单双引号都转第三个参数指定字符集漏掉它在 utf-8 页面上可能出现乱码或转义失效。真正存密码时不能明文入库常见做法是用password_hash($password, PASSWORD_DEFAULT)生成哈希校验时用password_verify()比对。header()那一行必须在任何输出之前调用前面多一个空格或 BOM 都会报 headers already sent。表单页和接收页的字符集要一致meta charsetutf-8与 PHP 端的Content-Type都写 utf-8中文才不会变成问号。4.3 复选框数组、下拉多选与文件上传的接收写法同一个name的多个复选框服务端只会拿到最后一个值要收成数组必须在 name 后面加[]。下拉列表的multiple同理。文本域用textarea值放在标签之间而不是 value 属性里。!-- form.html注意文件上传必须改 enctype且 method 只能是 post -- form actionsubmit.php methodpost enctypemultipart/form-data 您最喜欢哪些城市: input typecheckbox namecities[] valuebeijing北京 input typecheckbox namecities[] valueshanghai上海 input typecheckbox namecities[] valuelondon伦敦br/ 您的性别是: input typeradio namesex valueman男 input typeradio namesex valuewoman女br/ !-- 隐藏域用户看不见但会随表单一起提交 -- input typehidden namesource valueweb /br/ select nameaddress[] size3 multiple option valuesichuan四川/option option valuebeijing北京/option /selectbr/ textarea nameremark cols40 rows10/textareabr/ input typefile namemyfile /上传文件br/ input typesubmit value测试 / /form接收端对应处理?php // submit.php // 复选框可能一个都没勾先给默认空数组再转成数组类型 $cities isset($_POST[cities]) ? (array)$_POST[cities] : []; echo 城市 . implode(、, array_map(function ($v) { return htmlspecialchars($v, ENT_QUOTES, UTF-8); }, $cities)) . br/; $sex isset($_POST[sex]) ? $_POST[sex] : 未选择; echo 性别 . htmlspecialchars($sex, ENT_QUOTES, UTF-8) . br/; // 文件上传先看 error 码再判断是不是真的上传文件 if (isset($_FILES[myfile]) $_FILES[myfile][error] UPLOAD_ERR_OK) { $tmp $_FILES[myfile][tmp_name]; // 服务器临时文件 $name basename($_FILES[myfile][name]); // 只取文件名防目录穿越 $size $_FILES[myfile][size]; if ($size 2 * 1024 * 1024) { exit(文件超过 2MB); } // 第 4 个参数传 true会检查是不是真的通过 HTTP 上传的 move_uploaded_file($tmp, __DIR__ . /uploads/ . $name); echo 上传成功 . htmlspecialchars($name, ENT_QUOTES, UTF-8); } else { echo 未选择文件或上传失败错误码 . ($_FILES[myfile][error] ?? none); }$_FILES的五个键是固定结构name原始文件名、typeMIME 类型、tmp_name临时路径、error错误码、size字节数。error为 0UPLOAD_ERR_OK才算成功1 表示超过 php.ini 里的upload_max_filesize2 表示超过表单里MAX_FILE_ORDER的限制4 表示没选文件。上传目录一定要单独放别和可执行脚本混在一起文件名也要过滤掉../这类路径片段basename()是最低成本的防线。4.4 用内置服务器与 curl 跑通提交链路不用配 Apache 或 NginxPHP 自带的开发服务器足够验证表单逻辑。# 在项目目录的上一级执行-t 指定站点根目录 php -S 127.0.0.1:8000 -t D:\web\demo # 另开一个终端用 curl 直接模拟 POST 提交绕过浏览器 curl -i -X POST http://127.0.0.1:8000/login.php \ -d usernameadminpassword123456 # 查看已加载的扩展确认 curl、mbstring、fileinfo 这些是否可用 php -m-S启动的是单进程服务器改完 PHP 文件刷新即可生效不用重启。-t的路径写错会直接 404注意写站点根目录而不是某个文件。curl 的-i让响应头一起输出方便看状态码和Content-Type是否符合预期-d默认以application/x-www-form-urlencoded编码发送最接近浏览器默认表单的行为。文件上传就得换成-F myfileD:\test.pngcurl 会自动切成 multipart 编码。Windows 下在编辑器里配 PHP 路径时php.validate.executablePath指向 php.exe 的绝对路径写完带反斜杠要转义或者直接用正斜杠否则校验器静默失效看着像插件坏了。5. 表单与请求的验证技巧用 curl、DevTools 和 PHP 调试脚本定位提交问题链路跑通一次不难难的是出问题时知道先看哪。踩得最多的三类症状是提交后页面没反应、PHP 端取到的值是空的、中文变乱码。这三类问题有一套固定的排查顺序按顺序走基本不会绕远路。5.1 三层排错顺序先看提交了什么再看收到什么最后看输出编码第一层看请求本身。浏览器按 F12 打开 Network 面板勾上 Preserve log提交一次表单点开那条请求看 Payload 或者 Form Data 区域里到底带了哪些键值。常见发现是复选框一个没勾所以完全没出现、name拼错了比如写成user_name而 PHP 里取的是username、或者 method 写成了 GET 所以数据跑到了 Query String 里。这一步能解决掉大约七成的「取不到值」。第二层看 PHP 收到了什么。在接收脚本最开头插一段临时调试代码把超全局变量原样打印出来然后终止?php // debug.php只在本地开发时用上线前必须删掉 header(Content-Type: text/plain; charsetutf-8); // 纯文本输出避免标签被解析 echo GET:\n; var_dump($_GET); echo POST:\n; var_dump($_POST); echo FILES:\n; var_dump($_FILES); exit; // 终止后续逻辑避免带出业务副作用用text/plain输出是为了让var_dump的结构不被 HTML 吞掉exit是防止后面的写库逻辑真的跑起来。等键名和类型都对上了再把这段删掉。第三层才是编码页面meta charset、PHP 的header()、数据库连接字符集这三处任意一处不一致中文就会变问号或乱码三处统一成 utf-8 是唯一稳妥的做法。5.2 建立「控件名 → 服务端键名」映射表表单控件一多最容易失控的是命名。建议每做一个表单就顺手记一张映射表前端改动时对照着改后端比翻代码快得多。控件类型HTML 写法服务端取值注意点文本框nameusername$_POST[username]必填要做非空校验密码框namepassword$_POST[password]存哈希不存明文单选框namesex$_POST[sex]未选中时键不存在复选框namecities[]$_POST[cities]数组一个都没勾时键不存在下拉多选nameaddress[]multiple$_POST[address]数组同复选框隐藏域namesource$_POST[source]值可被篡改不能当凭证文本域textarea nameremark$_POST[remark]值写在标签之间文件域namemyfileenctype$_FILES[myfile]method 必须 post图片按钮input typeimage namebtn$_POST[btn_x]、$_POST[btn_y]会额外带点击坐标这张表里最后一行很多人不知道图片按钮提交时除了自身 name还会带name_x和name_y两个坐标值接收端如果只找btn会一直取不到。上传那行的enctype漏写$_FILES会是空数组浏览器不会报任何错只是文件永远传不上去。一个可以马上动手的验证习惯每写一个表单先用 curl 手动发一次请求确认服务端逻辑独立于浏览器也能跑通再去页面上点。这样一旦出问题就能立刻判断是前端少传了字段还是后端逻辑本身有问题把排查范围缩小一半。curl 返回的响应头里Content-Type如果没有charsetutf-8中文乱码的根源也就顺手定位了。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价