热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP中一些通用和易混淆技术点的最佳编程实践

PHP中一些通用和易混淆技术点的最佳编程实践

最新改进&维护

本文档最后一次于2013年3月8日审核。最后一次修改是在2013年3月8日。

这由我, Alex Cabal维护的。到现在我已经写了很长时间PHP代码了, 目前我运行Scribophile,为严肃作家提供的在线写作小组, Writerfolio, 为自由职业者提供的简单的在线写作文件夹, 和 Standard Ebooks, 有插画的出版物,无数字版权的公共领域电子图书 。 偶尔我会自由的去找那些让我感兴趣的项目和客户。

如果你认为我能够帮你些什么,或者有些关于本文的建议或勘误的话,那么写信给我


介绍

PHP是一门复杂的语言,让你长年承受内心的迂回,弯曲,拉伸和打击。它自相矛盾有时候充满bug。每个版本都有其独特的特性,缺点以及怪癖,而且你很难追踪什么版本有什么问题。不难想见为什么有时候它会招致那么多怨恨。

尽管如此,它是时下web中最流行的语言。由于它的悠久历史,你能找到许多教程,关于一些基本事情的做法,如密码哈希(一次性加密)和数据库访问。问题在于从五篇教程里,关于某件事情你很有可能找到五种完全不同的方法。哪个方法才是“正确”的方法呢?其它的方法有瑕疵或者意想不到的问题吗?确实很难弄清楚,而且你会在网络里到处点击,以试图确定正确的答案。

那也是为什么新的PHP程序员经常会为其丑陋,过时或不安全代码受到批评的原因之一。如果第一次Google搜索结果是一篇传授5年前方法的4年前的文章,他们就不能帮助这些有所改观。

这篇文章试图做这些工作。它尝试将一系列基本的操作提示汇集起来,这些可以被认为是PHP中处理普遍的令人困惑的难题时的最佳实践。如果PHP中一个低等级的任务具有多个和令人困惑的方法,它就属于这里。


它是什么

它是在面对PHP程序员可能会遇到的普通的低级任务时,由于PHP提供了 许多选择而不容易了解到的,最佳途径的建议指导。例如:对许许多多可能的PHP解决方案,连接到数据库是一个普通的任务,但这些方案并不都是好的——因此,这个问题包含在这篇文章中。

它是一系列短小,引导式的解决方案。你应该行动起来将例子运行于基础的配置环境,而且你应该自己研究从中找到对自己有用的东西。

它指出了我们所理解的最先进的PHP。但是,这也意味着如果你正使用较老版本的PHP,可能你就没有实现这些方案所需要的一些特性。

这是一篇动态文件,随着PHP的继续演进,我将努力保持相应更新。


它不是什么?

这篇文章不是PHP教程。你应该在别的地方学习基础和语法。

它不是普通web应用问题的指南,比如COOKIE存储,缓存,代码风格,文档等等。

它不是安全向导。当触及一些安全相关的问题时,你要自己研究怎么样才能对你的PHP应用加固。特别的,在着手实施以前,你应该仔细回顾一下这里给出的任何建议方案。你的代码责任在于你。

它不是某种代码风格,模式或者框架的拥护者。

它不是关于如何去做高等级任务,如用户注册,登录系统等等诸如此类任务的特定方法的支持者。这篇文章完全是为低等级任务,是因为PHP的长久历史,可能会令人困惑或者不甚清楚。

它不是终极意义的解决方案,也不是唯一的方案。下面描述的一些方法可能对你实际的情况不是最优的,而且有许多能达到同样目的的不同的方法。特别的,高负载的web应用可能会从更多的针对这些问题的秘密方案中获益。


我们使用的是哪个 PHP 版本?

带有 Suhosin-补丁的PHP 5.3.10-1ubuntu3.6, 安装于 Ubuntu 12.04 LTS.

PHP如同是网络世界的百年老龟。它的外壳上刻有一个丰富的,令人费解的,粗糙的历史。在一个共享主机的环境下,它的配置可能会限制你能做什么事情。

为了保留一丝明智,我们需要只专注于一个版本的PHP。截至2013年4月30,该版本是 带有Suhosin补丁的PHP5.3.10-1ubuntu3.6 。如果你使用apt-get从一个Ubuntu12.04 LTS服务器来安装PHP的话,你所得到的版本就是这个。换句话说,许多人在默认情况下已经很明智地使用了它。

您可能会发现本文这些解决方案能工作于不同或更旧版本的PHP。如果是这样的话,就要由你来研究在这些旧版本中的细微错误或安全问题的影响了


保存密码

使用 phpass 库计算密码的哈希值进行比较。

phpass 0.3 进行的测试。

散列化是在把用户密码保存进数据库之前对其进行保护的标准方法。许多常见的散列算法,如MD5,乃至SHA1,用于存储密码都是不安全的因为黑客可以使用这些散列算法轻松破解密码

要散列化密码最安全的方法是使用bcrypt算法。开源的phpass 库用一个易于使用的类来提供这个功能。

例子:

01
02 // 包含phpass库
03 require_once('phpass-0.3/PasswordHash.php');
04
05 // 初始化散列器为不可移植(这样更安全)
06 $hasher=newPasswordHash(8, false);
07
08 // 计算密码哈希值。$hashedPassword 将会是一长为60个字符的字符串.
09 $hashedPassword=$hasher->HashPassword('my super cool password');
10
11 // 你现在可以安全地保存$hashedPassword到数据库中!
12
13 // 通过比较用户输入内容(产生的哈希值)和我们之前计算出的哈希值,来判断用户是否输入了正确的密码
14 $hasher->CheckPassword('the wrong password',$hashedPassword);// 返回假
15
16 $hasher->CheckPassword('my super cool password',$hashedPassword);// 返回真
17 ?>

陷阱

  • 很多来源会建议你在计算密码的哈希值之前先给密码加点“作料”。这是个好主意,phpass已经利用HashPassword() 函数中的一部分代码来为你给密码加了作料。 这就意味着你并不需要自己再亲自做这个了。

进一步阅读

连接到并查询MySQL数据库

使用 PDO和它预定义的语句功能.

在PHP中有很多方法连接到一个MySQL数据库。 PDO (PHP Data Objects) 是其中最新最健壮的。对于许多不同类型的数据库,PDO都使用一致性的接口,采用面向对象的方式,并支持较新的数据库的提供的更多特性。

您应该使用PDO预定义语句的功能,以帮助防止SQL注入攻击。使用 bindValue() 函数确保你的SQL对于第一阶的SQL注入攻击是安全的(但这不是100%万无一失的,参考 进一步阅读 获得更详细说明)。在过去,这只能用一些“魔术引号”函数的复杂结合来实现。PDO使所有这些黏糊糊的东西变得不再必要了。


示例

01
02 try{
03    // Create a new connection.
04    // You'll probably want to replace hostname with localhost in the first parameter.
05    // The PDO options we pass do the following:
06    // \PDO::ATTR_ERRMODE enables exceptions for errors.  This is optional but can be handy.
07    // \PDO::ATTR_PERSISTENT disables persistent connections, which can cause concurrency issues in
certain cases.  See "Gotchas".
08    // \PDO::MYSQL_ATTR_INIT_COMMAND alerts the connection that we'll be passing UTF-8 data. 
This may not be required depending on your configuration, but it'll save you headaches down the road
if you're trying to store Unicode strings in your database.  See "Gotchas".
09    $link=new\PDO(  'mysql:host=your-hostname;dbname=your-db',
10                        'your-username',
11                        'your-password',
12                        array(
13                            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
14                            \PDO::ATTR_PERSISTENT => false,
15                            \PDO::MYSQL_ATTR_INIT_COMMAND =>'set names utf8mb4'
16                        )
17                    );
18
19    $handle=$link->prepare('select Username from Users where UserId = ? or Username = ? limit ?');
20
21    // PHP bug: if you don't specify PDO::PARAM_INT, PDO may enclose the argument in quotes.  This
can mess up some MySQL queries that don't expect integers to be quoted.
22    // See: https://bugs.php.net/bug.php?id=44639
23    // If you're not sure whether the value you're passing is an integer, use the is_int() function.
24    $handle->bindValue(1, 100, PDO::PARAM_INT);
25    $handle->bindValue(2,'Bilbo Baggins');
26    $handle->bindValue(3, 5, PDO::PARAM_INT);
27
28    $handle->execute();
29
30    // Using the fetchAll() method might be too resource-heavy if you're selecting a truly massive
amount of rows.
31    // If that's the case, you can use the fetch() method and loop through each result row one by
one.
32    // You can also return arrays and other things instead of objects.  See the PDO documentation
for details.
33    $result=$handle->fetchAll(\PDO::FETCH_OBJ);
34
35    foreach($resultas$row){
36        print($row->Username);
37    }
38 }
39 catch(\PDOException$ex){
40    print($ex->getMessage());
41 }
42 ?>

陷阱

  • 当绑定整型变量时,如果不传递PDO::PARAM_INT参数有事可能会导致PDO对数据加引号。这会 搞坏特定的MySQL查询。查看该bug报告

  • 未使用 `set names utf8mb4` 作为首个查询,可能会导致Unicode数据错误地存储进数据库,这依赖于你的配置。如果你 绝对有把握你的Unicode编码数据不会出问题,那你可以不管这个。

  • 启用持久连接可能会导致怪异的并发相关的问题。这不是一个PHP的问题,而是一个应用层面 的问题。只要你仔细考虑了后果,持久连接一般会是安全的。查看Stack Overfilow这个问题

  • 即使你使用了 `set names utf8mb4` ,你也得确认实际的数据库表使用的是utf8mb4字符集!

  • 可以在单个execute()调用中执行多条SQL语句。只需使用分号分隔语句,但注意这个bug,在该文档所针对的PHP版本中还没修复。

进一步阅读


PHP标签

使用.

界定PHP代码块有几种不同方式: ,和 <% %>。虽然更短的方式更便于输入,但能保证在所有PHP服务器上都能工作的只有。如果你计划把你的PHP程序部署到一个你不能控制其配置的服务器上,你必须始终使用

如果你有足够权限控制PHP运行环境的配置,你会发现使用更短的标签自然更方便。但要记住, 可能与XML声明冲突,而 <% %> 则实际是ASP的风格.

无论你选择哪一种,请确保保持一致

陷阱

  • 一个纯粹PHP文件(例如一个包含一个类定义的文件)中包含一个结束>标签确保不要在它后面留下任何尾随的换行符。因为虽然PHP解析器能安全“吃掉”一个关闭标签后面的换行符,其它的换行符却可能输出到浏览器,当你
推荐阅读
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 众筹商城与传统商城的区别及php众筹网站的程序源码
    本文介绍了众筹商城与传统商城的区别,包括所售产品和玩法不同以及运营方式不同。同时还提到了php众筹网站的程序源码和方维众筹的安装和环境问题。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
author-avatar
_____畫情
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有