php 多进程编程_使用PHP进行防御性编程的更多技巧

php 多进程编程

The general definition of defensive programming (as seen in Part 1, an overview piece on Defensive Programming in PHP) being used here is thus:

因此,此处使用的防御性编程的一般定义(如第1部分中介绍的PHP中的防御性编程概述)是:

Defensive programming, simply put, is programming with the intent to anticipate likely failure points. The goal is to circumvent those likely problems before they occur.

简而言之,防御性编程是为了预期可能的故障点而进行的编程。 目的是在可能出现的问题发生之前就规避它们。

This definition is a wide one. Many people argue against defensive programming, but this is often because of the types of methods they have seen espoused by some as defensive programming. Defensive programming should not be viewed as a way to avoid test driven development or as a way to simply compensate for failures and move on.

这个定义很宽泛。 许多人反对防御性编程,但这通常是因为他们认为某些人拥护防御性编程。 防御性编程不应被视为避免测试驱动开发的一种方法,也不应被视为简单地弥补故障并继续前进的一种方法。

“Fail Fast” should not be seen as a counter to defensive programming. It all falls under the same umbrella. What are these methods, if not ways to anticipate that your program may fail, and either prevent those, or else ways in which to handle those failures appropriately?

应该将“快速失败”视为防御性编程的反击。 一切都归于同一伞下。 这些方法是什么?如果不是可以预见的程序可能会失败的方法,或者可以防止这些错误,或者可以通过哪些方法适当地处理这些失败?

Shield target being hit by arrows

快速失败,大声地 (Fail Fast, and Loudly)

Simply put, failing fast and loudly means that when an error occurs, it will do so as early as possible, and alert whomever it should alert, as opposed to silently continuing on in an error state that may cause more issues. Here is an excellent article on fail-fast style development. The premise of fail-fast methodology is to fail when acquiring input that might later compromise the program (or, more generally, to enter a failure state as soon as any problems could possibly be detected, rather than allowing bad data to travel and a program to run un-checked, or worse, bad data to be stored somewhere). This is most useful when dealing with user input, or dealing with input that is arriving from outside the script, module, or even out of your system via an API. An example of where this could be employed would be a check for invalid values or data types passed into functions.

简而言之,快速而大声地失败意味着发生错误时,它将尽早这样做,并警告应该警告的人,而不是在可能导致更多问题的错误状态下静默继续。 是一篇有关快速失败样式开发的出色文章。 快速失败方法的前提是在获取可能稍后危害程序的输入时失败(或更普遍地,一旦可能检测到任何问题就进入故障状态,而不是允许不良数据通过并传播程序)运行未经检查的或更坏的坏数据存储在某个地方)。 在处理用户输入,或处理从脚本,模块外部甚至通过API发出的输入时,这非常有用。 例如,可以检查传递给函数的无效值或数据类型。

function thisTestFunction($testInt)
{
	if(!is_int($testInt)){
		// Do something here
	}
}

One mistake that some programmers make with fail-fast methodology is to simply throw Exceptions and errors out to the user without making proper provisions for handling them. You don’t want normal users to be worried or confused by your error messaging. And more importantly, you don’t want users with malicious intent learning things from the information displayed to them. Display a helpful message to the user, log your errors, and perform any other tasks that need to be a result of that exception. You don’t want to just fail fast, you also want to be loud (know there’s a problem, right away) and secure (don’t let your poor exception handling or complete lack thereof cause even more security issues).

一些程序员使用快速失败方法所犯的一个错误是,简单地将异常和错误抛出给用户,而没有为处理它们制定适当的规定。 您不希望普通用户为您的错误消息所担心或困惑。 更重要的是,您不希望有恶意的用户从显示给他们的信息中学习东西。 向用户显示一条有用的消息,记录您的错误,并执行该异常导致的其他所有任务。 您不希望只是快速失败,还想要大声(立即知道有问题)并保持安全(不要让不良的异常处理或完全缺乏异常处理引起更多的安全问题)。

输入验证 (Input Validation)

There are many methods by which to validate user input safely.

有许多方法可以安全地验证用户输入。

Typecasting is an interesting way to “validate” user input. Sometimes it goes a bit like this:

类型转换是一种“验证”用户输入的有趣方式。 有时会有点像这样:

$member->property = (int) $_GET['property'];

Instead of using another method to avoid cross-site scripting attacks, the value is simply being captured, typecast, and assigned. This only works when you have an expected type, and any value of that type is safe (Otherwise, you’d need to also check for appropriate int values). The problem with this approach, that I see (in most situations) is that you aren’t really checking the input, you’re just forcing it to become what it should be. This could have unforeseen consequences. Instead, a better approach might be to check for appropriate values using filter_input(). Here is a great article on that subject. Basically, that comes out like this:

代替使用另一种方法来避免跨站点脚本攻击,该值只是被捕获,类型转换和分配。 仅当您具有期望的类型并且该类型的任何值都是安全的时,此方法才有效(否则,您还需要检查适当的 int值)。 我看到的这种方法的问题(在大多数情况下)是您没有真正检查输入,只是在强迫它变成应有的样子。 这可能会带来无法预料的后果。 相反,更好的方法可能是使用filter_input()检查适当的值。 是一篇关于该主题的好文章。 基本上,结果是这样的:

$member->property = filter_input(INPUT_GET, 'property', FILTER_VALIDATE_INT);

if (false === $member->property) {
  throw new Exception('Property was not an int');
}

There are many benefits to using the native filter_input function in modern PHP, and you can read more about them in the aforementioned article or on php.net.

在现代PHP中使用本机filter_input函数有很多好处,您可以在上述文章php.net上阅读有关它们的更多信息。

在比较中防止意外分配 (Preventing Accidental Assignment in Comparisons)

This is an easy, and often noted, tenet of defensive programming. A simple change in the way that you do your comparisons can have great effects. Consider the following:

这是防御性编程的简单且经常被提及的原则。 您进行比较的方式的简单更改可能会产生很大的效果。 考虑以下:

if($member->property == 12345){
	// Do crazy cool stuff
} else {
	// Don't do any fun stuff
}

This is a relatively normal comparison, yes? However, what happens if you accidentally use the “=” instead of “==” (or, in most cases, the even better “===”)? A simple slip of the finger on the keyboard? Absentmindedness, maybe? All of a sudden, your comparison now reads true, all of the time, in all cases. Unless you have a good IDE warning you about this, how long will it take you to find out? In some cases, this could be a silent error for some time. However, there’s an extremely simple way to prevent this:

这是一个相对正常的比较,是吗? 但是,如果不小心使用“ =”而不是“ ==”(或者在大多数情况下甚至使用更好的“ ===” )会怎样? 手指在键盘上的简单滑动? 心不在,吗? 突然之间,您的比较现在在任何情况下都始终显示为真。 除非您有一个不错的IDE警告您,否则您需要多长时间才能找到答案? 在某些情况下,这可能是一段时间以来的无声错误。 但是,有一种非常简单的方法可以防止这种情况:

if(12345 == $member->property){
	// Do crazy cool stuff
} else {
	// Don't do any fun stuff
}

Now, if you accidentally use one equals sign, the error will not be silent. Obviously, this may not occur often, it may be mitigated by your testing, and it’s not useful in all cases, especially when doing variable to variable comparisons. But it’s still not a bad idea if this tends to happen to you.

现在,如果您不小心使用了一个等号,该错误将不会消失。 显然,这可能不经常发生,可以通过测试缓解,并且在所有情况下都没有用,尤其是在进行变量到变量比较时。 但是,如果这容易发生在您身上,这仍然不是一个坏主意。

处理try / catch和异常 (Dealing with Try/Catch and Exceptions)

try/catch statements are another hot topic among PHP developers. Let’s first get a quick look at what we’re talking about.

try/catch语句是PHP开发人员中的另一个热门话题。 首先让我们快速看一下我们在说什么。

try {
	if($member->property <= 0){
		throw new Exception("Value must be 1 or greater");
	}
	// If no exception was thrown, this will be output.
	echo "The value is acceptable";
} catch(Exception $e) {
	echo 'Message: '.$e->getMessage();
}

A well known tool of defensive programming is the try/catch statement and the Exception class. These are excellent for catching and logging errors, when used correctly. A good programmer will employ try/catch statements to anticipate possible errors or other situations that might disrupt the normal flow. When those Exceptions occur, they must be handled in an appropriate way. The user of the application, where required, should get a reasonable error message that is as useful as it can be without divulging sensitive information. The administrator(s) of the application should receive detailed alerts and/or logs. Exceptions that are mishandled, or ignored, ignore the “Fail Loudly” advice, and may allow the program to continue in essentially a silent error state for some time, which is not good for anyone involved.

防御编程的一种众所周知的工具是try/catch语句和Exception类。 如果使用正确,它们非常适合捕获和记录错误。 一个好的程序员将使用try/catch语句来预测可能的错误或其他可能干扰正常流程的情况。 当这些异常发生时,必须以适当的方式处理它们。 应用程序的用户在需要时应获得合理的错误消息,该消息应尽可能有用,而不会泄露敏感信息。 应用程序的管理员应收到详细的警报和/或日志。 错误处理或忽略的异常会忽略“大声地失败”建议,并可能使程序在本质上处于静默错误状态下持续一段时间,这对所涉及的任何人都是不利的。

For a bit more on exceptions in PHP, see here and here.

有关PHP异常的更多信息,请参见此处此处

交易次数 (Transactions)

Transactions are a feature of databases that allow queries to be grouped together, so that if one query fails, all of them fail. This is an implementation of ACID, about which you can read more here. The idea is that grouping multiple queries together into one process can sometimes be a safer and more stable solution, especially when the queries depend on each other. PHP developers often completely ignore transactions, or assume that they are unnecessary, but when interacting with databases, a little bit of defensive programming can go a long way. Transactions are discussed in more depth in this excellent post, but in a nutshell, transactions allow you to run your MySQL updates, and then check the results before actually committing the results. If you are using PDO (you should be), you may use PDO methods to begin a transaction, commit the results, as well as roll back. In addition to the aforementioned overview of transactions, delve into them further with this in-depth guide.

事务是数据库的一项功能,它允许将查询分组在一起,因此,如果一个查询失败,则所有查询都会失败。 这是ACID的实现,您可以在此处阅读更多内容。 这个想法是,将多个查询组合到一个流程中有时可能是一种更安全,更稳定的解决方案,尤其是当查询彼此依赖时。 PHP开发人员通常完全忽略事务,或者认为它们是不必要的,但是当与数据库进行交互时,一些防御性编程可能会走很长一段路。 在这篇出色的文章中对事务进行了更深入的讨论,但简而言之,事务允许您运行MySQL更新,然后在实际提交结果之前检查结果。 如果您正在使用PDO (应该这样做) ,则可以使用PDO方法开始事务,提交结果以及回滚。 除了上述交易概述之外,还可以通过本深入指南进一步研究交易。

Here’s a quick example of what the use of transactions in PDO might look like:

这是一个在PDO中使用事务的样子的简单示例:

try{
	// Start the transaction
	$db->beginTransaction();

	// Perform one update
	$statement1 = $db->prepare("QUERY LANGAUGE HERE");
	$statement1->execute(array($a,$b));

	// Perform another update
	$statement2 = $db->prepare("MORE QUERY LANGUAGE HERE");
	$statement2->execute(array($a,$b,$c));

	// Commit the transaction
	$db->commit();
} catch(PDOException $ex) {
	// If an exception occurs, first, roll back updates
	$db->rollBack();
	// Then, in this block, further handle the exception
}

结论 (Conclusion)

Again, these are just general tips. Obviously, each of them has their uses and each has notable situations where it would not be used. However, if you take concepts like these and work them into your daily development regimes, it can make you more efficient at what you do. And while this is generally a topic that is more applicable to developers who are currently learning PHP, it’s a good refresher on practices for everyone.

同样,这些只是一般性提示。 显然,它们每个都有自己的用途,并且每个都有明显的使用的情况。 但是,如果您采用这些概念并将其应用于您的日常开发体系中,则可以使您的工作效率更高。 虽然这通常是一个主题,更适合当前正在学习PHP的开发人员,但对于每个人来说,它都是一个很好的实践入门。

If only a single thing is taken away from this, especially by newer developers, it is that you should program defensively – plan for the possibility of mistakes and errors. Handle them appropriately. Don’t allow silent errors to progress. Fail fast. Test your code. By building robust applications that test for and resolve issues, and anticipate and handle future ones, you are making your applications more dependable, and hopefully assisting in the creation of a better user experience from behind the scenes.

如果仅从这件事中删除一件事,尤其是对于新开发人员而言,那就应该是防御性编程–规划错误和错误的可能性。 适当处理它们。 不允许出现静默错误。 快速失败。 测试您的代码。 通过构建可测试和解决问题并预测和处理未来问题的健壮应用程序,您可以使应用程序更加可靠,并有望在幕后协助创建更好的用户体验。

翻译自: https://www.sitepoint.com/more-tips-for-defensive-programming-in-php/

php 多进程编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值