[PHP] 网站

会员注册


会员注册首页加载时

1. [安全] 域名检查

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('不允许的域名。');
}

2. 登录会话检查 (如果处于登录状态,强制跳转到主页)

if($_SESSION['session_id']){
    header('Location: '.$url);
    exit;
}

3. SSL 相关处理

if(!isset($_SERVER["HTTPS"])){
    $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('Location: '.$url);
}


4. i-Pin 认证,本人认证(手机)

对于该部分,利用 form 标签创建相关请求,并接收返回值进行处理。


5. 同意使用条款 </span>

使用 JavaScript 确认复选框是否被勾选后再进行下一步。

登录

1. 提交登录数据

: 使用表单标签提交 ID 和密码

2. [安全] 域名检查

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('不允许的域名。');
}

3. 防止外部生成的表单数据提交 </span>

function referer(){

	$http_referer = str_replace('http://','',$_SERVER['HTTP_REFERER']);
	$http_referer = str_replace('https://','',$http_referer);

	$referer = explode('/',$http_referer);

	if ($referer[0] <> $_SERVER['HTTP_HOST']) {

		//使用脚本显示警告框比较方便 echo '....';
		exit;
	}

}

4. 验证提交的值

$user_id = trim( $_POST['userid'] );

$user_id= $mysqli_accountdb_s1->real_escape_string( $userid );// 防止 SQL 注入

$pw = trim( $_POST['password'] );

$backurl = trim( $_POST['backurl'] );
if (!$backurl) {
	$backurl = trim( $_GET['backurl'] ); // 登录完成后跳转回的 URL
}
$backurl = xss_replace($backurl); // 通过跨站脚本攻击(XSS)过滤函数处理字符串

if (!$backurl) {
	$backurl = '设置主页地址'; // 如果没有跳转 URL,则设置为首页地址
}

5. 哈希处理

$encode_pw = sha1($pw);


6. 利用 Session 处理连续登录延迟

if($_SESSION['ss_logintime'] != '') {
	$chk_time = mktime(date("H"),date("i"),date("s")-10,date("m"),date("d"),date("Y"));

	if ($chk_time < strtotime($_SESSION['ss_logintime'])) {
		$msg = "正在登录中,请稍候。";
		msg($msg); // 显示通知
		ob_flush();
		flush();
		sleep(2);
	}
}

$_SESSION['ss_logintime'] = date('Y-m-d H:i:s');

7. IP 检查

利用 Cookie 进行 IP 检查 + 限制登录次数(10次以下) > 限制 10 分钟(将登录时间存入 Cookie 后处理)

8. 登录宏(自动化脚本)检查

防止暴力破解攻击

9. 真实用户检查

检查用户是否存在、是否为注销用户、密码是否正确 > 该部分可以通过查询检查,也可以在 PHP 内部检查。

10. 海外 IP 拦截用户检查

通过拦截海外 IP 防止绕过黑客攻击。

11. 登录失败次数累计 5 次以上禁止登录 > 引导至找回密码

如果登录失败次数超过 5 次,重定向到找回密码页面

12. 开始登录

创建 Session。

13. 更新用户最后登录信息

session_id、登录失败次数、登录日期、登录 IP

14. 添加登录历史

在登录历史表中记录登录日志。

15. 简易会员、Facebook 会员检查

强制跳转到转为正式会员的菜单。

16. 密码修改检查

检查是否距离上次修改密码已超过 90 天。

MySQL

1. 即使 Insert 报错,auto_increment 的值也会增加。

实际上,使用 MySQLi 发送 insert 查询语句后,即使因为 duplicate 等错误导致记录未插入,该 auto_increment 键值也会 +1 增加。

下一篇文章称这为 MySQL 的一个 Bug。

(http://desmart.com/blog/be-careful-with-mysqls-auto-increment-how-we-ended-up-losing-data)

QA

1. &#65279

如果屏幕上显示了以下代码,并且没有显示预期的 echo 值时。 &#65279;

这是“编码问题”。

解决方法是使用 Notepad++ 将该文件的编码转换为 UTF-8(无 BOM 格式)重新编码即可解决。

2. 如何在 HTML 文件中运行 PHP 代码

(1) 在 httpd.conf 文件中输入以下内容。

AddHandler application/x-httpd-php .html


(2) 在 .htaccess 文件中输入以下内容。


AddType application/x-httpd-php .html


global 是什么?

global 是当函数内使用的变量名与全局变量相同时,允许引用全局变量的关键字。

可以理解为类似于 iOS 代码中的 self.变量名 的感觉。

参考资料


[SERVER]

$_SERVER['REQUEST_URI'] = 当前页面地址(除去域名部分) = index.phpuser=&name=

$_SERVER['PHP_SELF'] = 当前页面地址(除去域名和传递参数部分) = index.php

[required 或 required_once,include 或 include_once]

原本使用 required、include,后来改用了 required_once、include_once。

使用这些 API 的目的是为了避免函数重定义错误。

然而,据说这些 API 会降低速度。

因此,建议按下述方式使用。

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

以下是对比结果。



php                  hhvm


if



defined



0.18587779998779



0.046600103378296


require_once


1.2219581604004



3.2908599376678


[额外提示]


echo 比 print 快。


包裹字符串时,单引号(') 比双引号(") 快。

原因是 PHP 会在双引号中查找变量,而单引号中则不会。

如果字符串中没有变量,请使用单引号。


使用预先计算好的值。为了使用 for 循环,确定最大值时不要将其放在循环中。

请在 for 循环开始前使用 $max = count($array)。

for($x=0;$x<count($array);$x++) ==> for($x=0;$x<$max;$x++)

为了释放内存, 大型数组应使用 unset null 进行处理。

str_replace 比 preg_replace 快。 通常情况下 str_replace 是最好的,但 strstr 有时在处理大数据字符串时更快。在 str_replace 中使用数组通常比多次使用 str_replace 更快。


else if 语句比 switch 快。


用完后请关闭数据库连接。


$row['id'] 比 $row[id] 快 7 倍。 如果不使用单引号,系统必须猜测你指的是哪个索引。


声明 PHP 时使用 <?php ... ?>。其他风格统统是不良习惯。



请使用严格代码,避免隐藏 notice、warning 和 error。这能带来更整洁的代码和更低的负荷。 考虑始终开启 error_reporting(E_ALL)。



使用 header('location:'.$url); 时,请记得配合 exit 使用。 否则即使 location 已经改变,脚本仍会继续运行。


请提前初始化变量。否则运行非常缓慢。


用来隐藏错误的 @ 符号速度非常慢。

进行简单 SELECT 操作时推荐使用 GET 方法,进行 UPDATE 操作时推荐使用 POST 通信。

因为 GET 有缓存机制,速度相对更快。(POST 不会被缓存)

PHP 5.2.9 中 array() 无法解析 '[ ]'。请注意。

如果现有源码在使用 '[ ]' 定义数组,在 5.2.9 版本中必须将其更改为 array()。

不要使用 preg_match()

如果你只是想检查一个字符串是否包含在另一个字符串中。

请改用 strpos() strstr() ,因为它们速度更快。

</span>

AD