PHP表单
PHP
脚本可以通过_GET
或_POST
来获取相应表单的提交内容。
预定义的$_REQUEST
变量包含了 $_GET、$_POST 和 $_COOKIE
的内容。
$_REQUEST
变量可用来收集通过 GET 和 POST
方法发送的表单数据。
函数传入表单元素name
可以获取该name
表单元素所填的值,函数返回该值或数组。
如果对于表单中的selector
多w个option
,你可以选择将该selector
的name
定义为一个数组,如name=p[]
,这样,返回的就是一个所有被选择的option 的 value
构成的p
数组,当然,前提是你给selector
设置了multiple="multiple"
。
所以,对于单选按钮,返回的name
设置为变量,多选返回的name
设置为数组。
应用
如果在客户端就对表单进行验证,则可以减少服务器的负担,而且浏览器速度更快。
如果用户输入需要插入数据库,应该考虑使用服务器验证。在服务器验证表单的一种好的方式是,可以把表单的数据传给当前页面(异步提交的方式更好),而不是跳转到不同的页面。这样用户就可以在同一张表单页面得到错误信息。用户也就更容易发现错误了。
几个$_SERVER数组的区别
URL 地址如下:
1 | http://www.5idev.com/php/index.php/test/foo?username=hbolive |
$_SERVER['PHP_SELF']
得到:/php/index.php/test/foo
,一般用来引用当前网页地址,并且它是系统自动生成的全局变量$_SERVER['SCRIPT_NAME']
得到:/php/index.php
$_SERVER['REQUEST_URI']
得到:/php/index.php/test/foo?username=hbolive
从该例子可以看出:
$_SERVER['PHP_SELF']
则反映的是PHP
程序本身;$_SERVER['SCRIPT_NAME']
反映的是程序文件本身(这在页面需要指向自己时非常有用);$_SERVER['REQUEST_URI']
则反映了完整URL
地址(不包括主机名)。
_SERVER['PHP_SELF']
的避免使用
安全漏洞
如果你有一段代码像这样:
1 | <form action="<?php echo $_SERVER['PHP_SELF']; ?>"> <input type="submit" name="submit" value="submit" /> |
运行之后,你可在地址后面输入任何东西,检查元素之后会发现action
发生了变化,如果你加入了一段js
代码,则后果
将会直接影响页面的效果。这些都容易被黑客利用来修改页面中一些重要参数、全局变量等。
所以,一般使用如下方式可以解决上述问题:
htmlentities($_SERVER['PHP_SELF'])
来替代简单的$_SERVER['PHP_SELF']
;可以的条件下,使用
$_SERVER['SCRIPT_NAME']
或$_SERVER['REQUEST_URI']
替代$_SERVER['PHP_SELF']
Cookie
Cookie 是什么
Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。
浏览器需要保存这段数据,不得轻易删除。
此后每次浏览器访问该服务器,都必须带上这段数据。
Cookie
就是这么简单,这就是 Web
开发里 Cookie
的含义。
如何使用 Cookie
Cookie
一般有两个作用。
第一个作用是识别用户身份。
比如用户 A
用浏览器访问了 http://a.com,那么 http://a.com 的服务器就会立刻给 A 返回一段数据「uid=1」(这就是 Cookie
)。当 A
再次访问 http://a.com 的其他页面时,就会附带上「uid=1」这段数据。
同理,用户 B
用浏览器访问 http://a.com 时,http://a.com 发现 B
没有附带 uid 数据,就给B
分配了一个新的 uid,为2,然后返回给 B
一段数据「uid=2」。B
之后访问 http://a.com 的时候,就会一直带上「uid=2」这段数据。
借此,http://a.com 的服务器就能区分 A 和 B
两个用户了。
第二个作用是记录历史。
假设 http://a.com 是一个购物网站,当 A
在上面将商品 A1 、A2
加入购物车时,Js、PHP
都可以设置或改写 Cookie
,改为「uid=1; cart=A1,A2
」,表示购物车里有A1 和 A2
两样商品了。
这样一来,当用户关闭网页,过三天再打开网页的时候,依然可以看到 A1、A2
躺在购物车里,因为浏览器并不会无缘无故地删除这个 Cookie
。
借此,就达到里记录用户操作历史的目的了。(实际的网站使用 Cookie
时会更谨慎一些。)
在PHP
中,当某个客户端向服务器第一次发起访问之后,服务器端运行的PHP
文件中可以使用setCookie()
函数生成Cookie
,服务器把Cookie
发送到客户端并保存在客户端指定的路径下,你也可以设置保存的时间限制等。然后,在PHP
中使用$_COOKIE[name]
获取Cookie
信息;
Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。
Cookie注意事项
对于某些客户端是不支持或禁止
Cookie
的;每个
Cookie
的内存限制为4KB
左右;- 只能有
300
个Cookie
左右可以存储在客户端; - 有些浏览器对
Cookie
“喜新厌旧”,尽管旧Cookie
还未过期。 - 只要 Cookie 在设置的时候设置了只允许加密传输,Cookie 传递的时候就会只走加密的 HTTPS。
局限
- cookie相对不是太安全,容易被盗用导致
cookie
欺骗 - 单个
cookie
的值最大只能存储4k
,每次请求都要进行网络传输,占用带宽 - 用户信息既可以存储在
sessioin
中,也可以存储在cookie
中,他们之间的差别在于session
可以方便的存取多种数据类型,而cookie
只支持字符串类型,同时对于一些安全性比较高的数据,cookie
需要进行格式化与加密存储,而session
存储在服务端则安全性较高。
Session
由于HTTP
协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识别具体的用户,这个机制就是session
.典型的场景比如购物车,当你点击下单按钮时,由于HTTP
协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的session
,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。
cookie
中就包含了一个叫PHPSESSID
的会话ID
唯一标识用户,这里用到了session
。
简介
session
是将用户的会话数据存储在服务端,没有大小限制session
的工作机制是:为每个访客创建一个唯一的id (UID)
,并基于这个UID
来存储变量。UID
存储在cookie
中,或者通过URL
进行传导。- 通过一个
session_id
进行用户识别,PHP默认情况下session_id
是通过cookie
来保存的,因此从某种程度上来说,seesion
依赖于cookie
。 - 但这不是绝对的,
session_id
也可以通过参数来实现,只要能将session_id
传递到服务端(如果用户浏览器不支持cookie
或者关闭了它,session_id
将会通过URL
来传播,即每次HTTP
交互,URL
后面都会被附加上一个诸如sid=xxxxx
这样的参数,服务端据此来识别用户。)进行识别的机制都可以使用session
。
session
信息存储在服务端,相对于存储在客户端的cookie
更为安全,所以正常一般网站在用于“判断用户是否登录”时,确实是使用session
,例如可以在session
里存储如下一个数组。
1 | //验证用户名和密码成功后 |
而后在需要验证登录的地方加入类似如下判断
1 | if(empty($_SESSION['userinfo']) || empty($_SESSION['userinfo']['uid'])){ |
以上是使用session
做用户登录的基本存储和验证逻辑,当然实际开发过程中会将这部分的代码封装。
注意点
- 在服务端保存
session
的方法很多,内存、数据库、文件都有。集群的时候也要考虑session
的转移,在大型的网站,一般会有专门的session
服务器集群,用来保存用户会话,这个时候session
信息都是放在内存的,使用一些缓存服务比如Memcached
之类的来放session
。 - 默认情况下,
session
是以文件形式存储在服务器上的,因此当一个页面开启了session
之后,会独占这个session
文件,这样会导致当前用户的其他并发访问无法执行而等待。可以采用缓存或者数据库的形式存储来解决这个问题。 - 默认情况下,
session
的超时时间(Timeout)
是20分钟,即用户保持连续20分钟不访问网站,则session
被收回。如果在这20分钟内用户又访问了一次页面,那么20分钟就重新计时了。
PHP编程
在您把用户信息存储到PHP session
中之前,首先必须启动会话。
使用session_start()
启动会话,此时用户的会话被注册,然后使用$_SESSION
数组存储session
数据
您也可以通过调用 session_destroy()
函数彻底销毁 session
。
PHP、MySQL
PHP 5 及以上版本建议使用以下方式连接 MySQL :
- MySQLi extension (“i” 意为 improved)
- PDO (PHP Data Objects)
不同点
MySQLi
和PDO
有它们自己的优势:
PDO
应用在 12
种不同数据库中,MySQLi
只针对 MySQL
数据库。
所以,如果你的项目需要在多种数据库中切换,建议使用 PDO
,这样你只需要修改连接字符串和部分查询语句即可。 使用 MySQLi
, 如果不同数据库,你需要重新编写所有代码,包括查询。
两者都是面向对象, 但 MySQLi
还提供了 API
接口。
两者都支持预处理语句。 预处理语句可以防止 SQL
注入,对于 web
项目的安全性是非常重要的。
在使用之前需要先查看phpinfo()
有没有mysqli
和PDO
的安装信息。
Ajax
ajax的全称是AsynchronousJavascript+XML。异步传输+js+xml
。所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果我们可以再来处理这个事。(当然,在其他语境下这个解释可能就不对了)
这个很重要,如果不是这样的话,我们点完按钮,页面就会死在那里,其他的数据请求不会往下走了。这样比等待刷新似乎更加讨厌。
(虽然提供异步通讯功能的组件默认情况下都是异步的,但它们也提供了同步选项,如果你好奇把那个选项改为false的话,你的页面就会死在那里)
xml只是一种数据格式,在这件事里并不重要,我们在更新一行字的时候理论上说不需要这个格式,但如果我们更新很多内容,那么格式化的数据可以使我们有条理地去实现更新。
现在大部分人其实是用JSON
这种格式来代替XML
的,因为前者更加简洁,据说目前的解析速度也更快。多快好省,能省则省啊。
总结:只要是JS
调用异步通讯组件并使用格式化的数据来更新web
页面上的内容或操作过程,那么我们用的方法就可算是AJAX
。