PHP学习笔记

PHP表单

PHP脚本可以通过_GET_POST来获取相应表单的提交内容。

预定义的$_REQUEST变量包含了 $_GET、$_POST 和 $_COOKIE 的内容。

$_REQUEST 变量可用来收集通过 GET 和 POST方法发送的表单数据。

函数传入表单元素name可以获取该name表单元素所填的值,函数返回该值或数组。

如果对于表单中的selector多w个option,你可以选择将该selectorname定义为一个数组,如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

从该例子可以看出:

  1. $_SERVER['PHP_SELF']则反映的是 PHP 程序本身;
  2. $_SERVER['SCRIPT_NAME']反映的是程序文件本身(这在页面需要指向自己时非常有用);
  3. $_SERVER['REQUEST_URI']则反映了完整 URL 地址(不包括主机名)。

_SERVER['PHP_SELF']的避免使用

安全漏洞

如果你有一段代码像这样:

1
2
<form action="<?php echo $_SERVER['PHP_SELF']; ?>"> <input type="submit" name="submit" value="submit" />
</form>

运行之后,你可在地址后面输入任何东西,检查元素之后会发现action发生了变化,如果你加入了一段js代码,则后果

将会直接影响页面的效果。这些都容易被黑客利用来修改页面中一些重要参数、全局变量等。

所以,一般使用如下方式可以解决上述问题:

  1. htmlentities($_SERVER['PHP_SELF'])来替代简单的$_SERVER['PHP_SELF']

  2. 可以的条件下,使用 $_SERVER['SCRIPT_NAME']$_SERVER['REQUEST_URI'] 替代 $_SERVER['PHP_SELF']

Cookie

  1. Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。

  2. 浏览器需要保存这段数据,不得轻易删除。

  3. 此后每次浏览器访问该服务器,都必须带上这段数据。

Cookie就是这么简单,这就是 Web 开发里 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注意事项

  1. 对于某些客户端是不支持或禁止Cookie的;

  2. 每个Cookie的内存限制为4KB左右;

  3. 只能有300Cookie左右可以存储在客户端;
  4. 有些浏览器对Cookie“喜新厌旧”,尽管旧Cookie还未过期。
  5. 只要 Cookie 在设置的时候设置了只允许加密传输,Cookie 传递的时候就会只走加密的 HTTPS。

局限

  1. cookie相对不是太安全,容易被盗用导致cookie欺骗
  2. 单个cookie的值最大只能存储4k,每次请求都要进行网络传输,占用带宽
  3. 用户信息既可以存储在sessioin中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同时对于一些安全性比较高的数据,cookie需要进行格式化与加密存储,而session存储在服务端则安全性较高。

Session

由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识别具体的用户,这个机制就是session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。

cookie中就包含了一个叫PHPSESSID的会话ID唯一标识用户,这里用到了session

简介

  1. session是将用户的会话数据存储在服务端,没有大小限制
  2. session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID存储在 cookie 中,或者通过 URL进行传导。
  3. 通过一个session_id进行用户识别,PHP默认情况下session_id是通过cookie来保存的,因此从某种程度上来说,seesion依赖于cookie
  4. 但这不是绝对的,session_id也可以通过参数来实现,只要能将session_id传递到服务端(如果用户浏览器不支持cookie或者关闭了它,session_id将会通过URL来传播,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。)进行识别的机制都可以使用session

session信息存储在服务端,相对于存储在客户端的cookie更为安全,所以正常一般网站在用于“判断用户是否登录”时,确实是使用session,例如可以在session里存储如下一个数组。

1
2
3
4
5
//验证用户名和密码成功后
$_SESSION['userinfo'] = [
'uid' => 123,
'username' => 'testuser'
];

而后在需要验证登录的地方加入类似如下判断

1
2
3
if(empty($_SESSION['userinfo']) || empty($_SESSION['userinfo']['uid'])){
//未登录,引导登录
}

以上是使用session做用户登录的基本存储和验证逻辑,当然实际开发过程中会将这部分的代码封装。

注意点

  1. 在服务端保存session的方法很多,内存、数据库、文件都有。集群的时候也要考虑session的转移,在大型的网站,一般会有专门的session服务器集群,用来保存用户会话,这个时候 session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 session
  2. 默认情况下,session是以文件形式存储在服务器上的,因此当一个页面开启了session之后,会独占这个session文件,这样会导致当前用户的其他并发访问无法执行而等待。可以采用缓存或者数据库的形式存储来解决这个问题。
  3. 默认情况下,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)

不同点

MySQLiPDO 有它们自己的优势:

PDO 应用在 12 种不同数据库中,MySQLi 只针对 MySQL 数据库。

所以,如果你的项目需要在多种数据库中切换,建议使用 PDO ,这样你只需要修改连接字符串和部分查询语句即可。 使用 MySQLi, 如果不同数据库,你需要重新编写所有代码,包括查询。

两者都是面向对象, 但 MySQLi 还提供了 API接口。

两者都支持预处理语句。 预处理语句可以防止 SQL注入,对于 web项目的安全性是非常重要的。

在使用之前需要先查看phpinfo()有没有mysqliPDO的安装信息。

Ajax

ajax的全称是AsynchronousJavascript+XML。
异步传输+js+xml。所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果我们可以再来处理这个事。(当然,在其他语境下这个解释可能就不对了)
这个很重要,如果不是这样的话,我们点完按钮,页面就会死在那里,其他的数据请求不会往下走了。这样比等待刷新似乎更加讨厌。
(虽然提供异步通讯功能的组件默认情况下都是异步的,但它们也提供了同步选项,如果你好奇把那个选项改为false的话,你的页面就会死在那里)
xml只是一种数据格式,在这件事里并不重要,我们在更新一行字的时候理论上说不需要这个格式,但如果我们更新很多内容,那么格式化的数据可以使我们有条理地去实现更新。

现在大部分人其实是用JSON这种格式来代替XML的,因为前者更加简洁,据说目前的解析速度也更快。多快好省,能省则省啊。

总结:只要是JS调用异步通讯组件并使用格式化的数据来更新web页面上的内容或操作过程,那么我们用的方法就可算是AJAX

不要投钱给我
0%