不理解 PHP 中的这些 $_POST、数组和验证技术

发布于 2024-12-22 13:45:12 字数 1737 浏览 2 评论 0原文

我正在通过教程学习,讲师使用了我感到困惑的验证例程。

在表单页面上,他有具有以下名称的输入字段:

  • menu_name
  • 位置
  • 可见

在表单处理页面上,他有以下 php 块(我们称之为 块 A):

$menu_name = mysql_prep($_POST['menu_name']);
$position = mysql_prep($_POST['position']);
$visible = mysql_prep($_POST['visible']);

在该块下面是另一个将数据插入 MySQL 的 php 块——这一切都工作正常。


然后,他在上面块A添加了以下php块(我们称之为块B):

$errors = array();
$required_fields = array('menu_name', 'position', 'visible');

foreach ($required_fields as $fieldname) {
    if (!isset($_POST[$fieldname]) || empty($_POST[$fieldname])) {
        $errors[] = $fieldname;
    } 
}   
if (!empty($errors)) {
    redirect_to("new_subject.php");
    exit;
}

问题1

I'我很困惑为什么在他的 $required_fields 数组中,他直接引用字段名称。为什么不将块 A 移到块 B 之上,然后只引用从 $_POST 分配的变量呢?

然后只需在 foreach 循环 内的 if 语句 中使用这些变量即可。

我想我是在问我的替代方法是否有效?他采取这种做法有明显的原因吗?

(仅供参考,mysql_prep 是他构建的一个自定义函数,用于删除斜杠等。)


问题 2

如果我正确理解他的代码,他的第一个 if 语句< /code> 正在测试 $fieldname 是否为 !isset(即未设置)

有什么区别?由于我不知道其中的区别,我也不清楚他为什么使用 || 运算符。你能解释一下吗?


问题 3

最后,他的第一个 if 语句 似乎捕获了所有错误,并将它们放入 $errors 数组 顶部的 $errors 数组中。 >区块B

然后,他使用第二个 if 语句 来检查 $errors 数组 中是否有任何内容,如果有,则重定向 + 退出。

这种方法有明显的原因吗?在我看来,如果发现任何错误,第一个 if 语句似乎可以重定向 + 退出。为什么要在 $errors 数组 中捕获它们?

I'm learning by way of tutorials, and the instructor used a validation routine that I'm confused about.

On the form page, he has input fields with the following names:

  • menu_name
  • position
  • visible

On the form processing page, he has the following block of php (let's call it block A):

$menu_name = mysql_prep($_POST['menu_name']);
$position = mysql_prep($_POST['position']);
$visible = mysql_prep($_POST['visible']);

Below this block is another php block that inserts the data into MySQL -- this all works fine.


He then added the following php block above block A (let's call it block B):

$errors = array();
$required_fields = array('menu_name', 'position', 'visible');

foreach ($required_fields as $fieldname) {
    if (!isset($_POST[$fieldname]) || empty($_POST[$fieldname])) {
        $errors[] = $fieldname;
    } 
}   
if (!empty($errors)) {
    redirect_to("new_subject.php");
    exit;
}

Question 1

I'm confused why in his $required_fields array, he is referencing the field names directly. Why not move block A above block B and then just reference the variables that were assigned from the $_POST?

Then just use those variables in the if statement within the foreach loop.

I guess I'm asking if my alternative approach is valid? Is there an apparent reason for why he took his approach?

(FYI the mysql_prep is a custom function he built to remove slashes and such.)


Question 2

If I'm understanding his code correctly, his first if statement is testing if the $fieldname is !isset (i.e. not set) or empty.

What's the difference? Since I don't know the difference, I'm also not clear on why he used the || operator. Can you please explain?


Question 3

And finally, it seems his first if statement is capturing any errors and putting them into the $errors array at the top of block B.

He then uses a second if statement to check if that $errors array has anything in it, and re-directs + exits if it does.

Is there a discernible reason for this approach? In my mind, it seems the first if statement could redirect + exit if any errors were found. Why capture them in that $errors array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

匿名。 2024-12-29 13:45:12
  1. 据我了解,如果您想在准备之前检查输入是否存在,或者反之亦然,则没有区别。

  2. isset() 检查变量是否已设置(存在),而如果变量存在,empty() 将返回 true,但不保存任何数据。 || 运算符是 OR 运算符。如果 isset() 返回 false (!) 或 empty() 返回 true,则该语句为 true。

  3. 我怀疑他填充错误数组的原因是为了能够显示表单中的所有错误,而不仅仅是第一个错误,当用户重新提交时,他会得到下一个错误。

  1. As far as I understand you, there is no difference if you want to check that input exists before you are preparing it or the other way around.

  2. isset() checks if the variable is set (exists) while empty() will return true if the variable exists, but does not hold any data. The || operator is a OR operator. The statement is true if isset() returns false (!) OR empty() returns true.

  3. I suspect the reason why he is populating the error array is to be able to display all errors with the form, and not just the first one, and when the user resubmits he gets the next.

长途伴 2024-12-29 13:45:12

问题1

这里发生的事情是他首先检查某些变量是否存在。如果它们不存在,则需要重定向。
我不知道 prep 函数是做什么的,但是对可能的空变量调用 prep 函数是不合逻辑的。你可以扭转它,但那将是.. 好吧.. 扭转一切;)

首先检查你是否拥有所需的一切,然后开始清理。

问题2

未设置表示在POST 中不可用。复选框会发生这种情况(如果您不选中它们,它们就不存在。文本输入将为空。
即使您只有文本输入,在检查其内容之前,最好先确保它们存在(调用帖子中可能存在问题,有人可能会破解您的表单):PHP 当然非常宽容,但是检查不存在的东西的内容并不是很好。

摘要:isset 正在检查它是否存在,empty 正在检查它的值是什么。

问题3

您可以将重定向和退出语句放在 if 中,这样会快一点。但没有那么多,而且你所做的事情对于一些程序员来说是意想不到的:你在循环(2 个循环)中间的某个地方改变了程序的流程。
这对我来说是可读的,但我认为在第一个“错误”时退出没有任何问题。

稍后您可能想要对缺少的 POST 值(所有这些值)执行某些操作,例如为它们指定某个类,因此这是稍后这样做的可能原因吗?

Question 1

What happens here is he checks for the existence of certain variables first. If they do not exist, you need to redirect.
I don't know what the prep function does, but it would be illogical to call a prep function on a possible empty variable. You could turn it around, but that would be.. well.. turning stuff around ;)

First check if you've got all you need, and then start cleaning up.

Question 2

Not set means it is not available in the POST. This will happen for checkboxes (if you don't check them , they don't excist. Text inputs will be empty.
Even if you have only text inputs, it is good for to be sure that they exist (there could be a problem in the calling post, someone might be hacking your form), before you check their contents: PHP is very forgiving ofcourse, but it's not really nice to check the contents of something that does not exist.

Summary: isset is looking if it is there at all, and empty is checking what it's value is.

Question 3

You could put the redirect and exit statements in the if, and this would be a tiny bit faster. But not so much, and what you do is unexpected for some programmers: you change the flow of the program somewhere in the middle of a loop (2 loops).
This is readable for me, but I don't see any problem with exiting at the first 'error'.

Later on you might want to do something with the missing POST values (all of them), like giving them a certain class, so that's a possible reason to do it this way later on?

小姐丶请自重 2024-12-29 13:45:12

在学习如何编码时,学生最常面临的挑战不是语言的语法,而是如何以逻辑结构进行编码。您对代码功能的解释表明了您的理解,并且您提出了有效的问题。 IMO 代码是以逻辑且简洁的方式编写的。原因如下:

块 A 在将 3 个 POST 变量提交到数据库之前对其进行准备。够清楚了。对于块 A 中的代码执行而言,重要的是,如果这 3 个变量中的任何一个不存在,那么 PHP 将引发异常并停止。另外,如果所有变量都存在,但其中任何一个为空,那么 MySQL 可能会抛出异常并导致 PHP 停止执行。这就是为什么我们有块 B a) 接收 POST 变量; b) 验证它们; c) 在将变量传递给块 A 之前处理任何错误。让我们考虑一下块 B 的 3 个逻辑部分:

  1. “声明”2 个数组
  2. 根据 2 个条件验证每个预期的 var,如果验证失败,则将 var 名称放入错误列表中,
  3. 检查错误列表:如果它包含任何 var 名称然后将用户重定向到另一个页面,否则继续进行 var prepping & db commit

$required_fields 是一个包含 3 个预期 var 名称的数组(从前面表单中的“必填字段”中获取)。因此,$required_fields 的内容不是 POST 变量本身,而只是它们的名称列表。

然后,$required_fields 列表中的每个项目(变量名称)都会由 foreach 循环进行迭代(顺序使用),以避免我们写出 if 语句 3 次(每个变量一次)。因此,关于您的第一个问题,创建 $required_fields 数组是因为方便的 foreach 循环需要它(想象一下,例如,如果有 20 个变量!)。

摘要:

foreach (list as item) {
    if (condition1 is true) or (condition2 is true) {
        #do something
    } 
}

实际:

foreach ($required_fields as $fieldname) {
    if (!isset($_POST[$fieldname]) || empty($_POST[$fieldname])) {
        $errors[] = $fieldname;
    } 
}

if 语句将(例如,在 foreach 循环的第一次迭代期间)评估 var $_POST['menu_name'] - 首先确定它是否未设置(即不存在 - 例如当它从未从表单传递时),或者其次,它已设置(即确实存在)但为空(没有值)。如果其中一个条件为 True,则 var 名称(现在包含在 var $fieldname 中)将被添加到 $errors 列表中。您的第三个问题正确地识别了此操作。

回答问题 3:是的,第一个 if 语句可以重定向 &出现错误时退出,但这会混淆我们目前代码中的逻辑分离。想一想:如果错误处理也由第一个 if 语句完成,那么一旦任何一个 var 验证失败,我们就会重定向并退出(此脚本)。通过将代码分成具有特定功能的块(就像现在一样),我们现在有了一个错误列表,可以在网络应用程序的其他地方使用,例如

echo "You must enter values in the following required fields: ";
foreach ($errors as &$item) {
    echo $item . " ";
}

希望澄清代码结构和逻辑。

When learning how to code students are most often challenged not by the syntax of the language but by how to code in logical structures. Your explanation of what the code does shows understanding and you ask valid questions. IMO the code is written in a logical and concise way. Here's why:

Block A preps each of the 3 POST vars before they are committed to the db. Clear enough. What is significant in terms of code execution in Block A is the fact that, should any of those 3 vars not exist then PHP will throw an exception and stop. Also, should all the vars exist but any of them be empty then, possibly, MySQL will throw an exception and also cause PHP to stop execution. This is why we have Block B to a) receive the POST vars; b) to validate them; and c) to handle any errors, before passing the vars to Block A. Let's consider the 3 logical parts of Block B:

  1. 'declare' 2 arrays
  2. validate each expected var against 2 conditions, putting the var name in an errors list should it fail validation
  3. check the errors list: if it contains any var name then redirect the user to another page, else proceed to var prepping & db commit

$required_fields is an array of 3 expected var names (harvested from 'required fields' in a preceding form). The content of $required_fields is therefore not the POST variables themselves, but simply a list of their names.

Each item (var name) in the $required_fields list is then iterated (used sequentially) by the foreach loop to circumvent the need for us to write out the if statement 3 times (once for each var). So regarding your 1st question, the $required_fields array is created because it will be needed by the convenience foreach loop (imagine, for example, if there were 20 vars!).

abstract:

foreach (list as item) {
    if (condition1 is true) or (condition2 is true) {
        #do something
    } 
}

actual:

foreach ($required_fields as $fieldname) {
    if (!isset($_POST[$fieldname]) || empty($_POST[$fieldname])) {
        $errors[] = $fieldname;
    } 
}

The if statement will (e.g. during the first iteration of the foreach loop) evaluate the var $_POST['menu_name'] - firstly to determine if it is not set (i.e. does not exist - such as when it was never passed on from the form) OR secondly, it is set (i.e. does exist) but is empty (has no value). If either of these conditions are True then the var name (now contained in var $fieldname) will be added to the $errors list. Your 3rd question correctly identifies this action.

To answer Q3: yes, the first if statement could redirect & exit in case of errors but this would confuse the logical separation that we have in the code at the moment. Think about it: if error handling was also done by the first if statement then we would have a redirect and exit (of this script) as soon as any one var failed validation. By separating the code into blocks with specific functions (as it currently is), we now have a list of errors that we can use elsewhere in our web app, e.g.

echo "You must enter values in the following required fields: ";
foreach ($errors as &$item) {
    echo $item . " ";
}

Hope that clarifies the code structure and logic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文