PHP似乎非常不一致,(编译器)无法生成逻辑。让我们开始调查,首先使用一组简单的 JSON 数据。
[
{
"customer": "cust01",
"assembly": "assem01",
"date_received": "02-08-2015",
"time_received": "09:15",
"date_completed": "02-23-2015",
"time_completed": "10:27"
},
{
"customer": "lov_01",
"assembly": "lov_02",
"date_received": "lov_03",
"time_received": "lov_04",
"date_completed": "lov05",
"time_completed": "lov_06"
}
]
然后在 PHP 中,我们检索该数据的数组
$t_json_string = file_get_contents($t_json_file_path);
$t_json_arr = json_decode($t_json_string, true);
假设我们在这样的数组中检索帖子值
$t_new_entry = [
"customer" => "lov_01",
"assembly" => "lov_02",
"date_received" => "lov_03",
"time_received" => "lov_04",
"time_completed"=> "lov_05",
"time_completed"=> "lov_06"
];
目标是通过两个数组是否具有超过 2 个相似值的条件来验证 JSON 数组中是否存在新条目,为此我使用 $t_count 来计算类似出现的次数。我写了 2 种方法,用于在将相同的数据传递到数据池时进行检查。
// $t_boo = $db_entry_check($t_new_entry, $t_json_arr); echo $t_boo;
// true, $t_count shows 3.
$t_bool = $db_entry_exist($t_new_entry, $t_json_arr); echo $t_bool;
// False. It has to be true with the $t_count printed out at 3.
第一个使用call_user_function_array,我测试了它并且有效,所以我将其注释掉了。在这里为它编写代码:
$db_entry_check = function($needle, $haystack){
$t_exist = 'false';
$t_count = 0;
function h_loop (&$t_count, $value, $array){
foreach ($array as $key => $val){
if (is_array($val)){
h_loop($t_count, $value, $val);
} else {
echo "<br/> --- value: ". $value. "<br/> --- val: ". $val . "<br/><br/>";
if ($val === $value){
$t_count += 1;
echo "<br/>" . $t_count . "<br/>";
continue;
}
}
}
}
function n_loop (&$t_count, $arr, $array){
foreach ($arr as $key => $value){
if (is_array($value)){
n_loop($t_count, $value, $array);
} else {
if ($t_count > 2) continue;
call_user_func_array('h_loop', [&$t_count, $value, $array]);
}
}
}
n_loop($t_count, $needle, $haystack);
echo "<br/>" . $t_count . "<br/>";
if ($t_count > 2) $t_exist = 'true';
return $t_exist;
};
第二个是我尝试在每个组件函数上使用 lambda。我尝试将$value,$array和$t_count放入use()部分,因为这些变量存在于$db_entry_exist范围内,用于数据绑定和依赖注入。当涉及到考虑参数(用于函数)与依赖项(用于使用)h_loop时,我发现令人困惑,PHP 努力实现 Javascript 概念是多么混乱。
无论我传递给函数部分的参数是什么,也无论在 use() 部分中注入了什么变量。许多变体已经过测试,但没有一个有效。我通常会收到"函数名称必须是字符串"的错误。在PHP中调用另一个闭包中的闭包似乎不像Javascript中的逻辑那样工作。每当我尝试传递 $h_loop($t_count, $value, $array); 或回显 $factorial(5); 在 n_loop 函数的 else 部分时,它都会失败。我不明白的是$db_entry_exist本身是一个lambda(PHP称之为闭包),并且可以在内部调用n_loop函数而没有任何错误,但是通过相同的方法调用/调用孙子(h_loop)函数不起作用,通常会导致上述相同的错误。
$db_entry_exist = function($needle, $haystack){
$t_exist = 'false';
$t_count = 0;
// n_loop($t_count, $needle, $haystack);
$h_loop = function (&$t_count, $value, $array) use (&$h_loop) {
foreach ($array as $key => $val){
if (is_array($val)){
h_loop($t_count, $value, $val);
} else {
echo "<br/> --- value: ". $value. "<br/> --- val: ". $val . "<br/><br/>";
if ($val === $value){
$t_count += 1;
echo "<br/>" . $t_count . "<br/>";
continue;
}
}
}
};
$factoral = function($n) use (&$factoral) {
if ($n <= 1)
return 1;
else
return $n * $factoral($n - 1);
}; // source: https://gist.github.com/superic/8290704
$n_loop = function (&$t_count, $arr, $array) use (&$n_loop) {
foreach ($arr as $key => $value){
if (is_array($value)){
$n_loop($t_count, $value, $array);
} else {
if ($t_count > 2) continue;
$h_loop($t_count, $value, $array);
}
}
};
/*$n_loop = function ($arr, $array) use (&$n_loop, &$t_count){
// echo "<br/> --- nloop.t_count: " . $t_count . "<br/>";
foreach ($arr as $key => $value){
if (is_array($value)){
$n_loop($value);
} else {
if ($t_count > 2) continue;
// $h_loop($value, $array);
}
}
};*/
$n_loop($t_count, $needle, $haystack);
echo "<br/>" . $t_count . "<br/>";
if ($t_count > 2) $t_exist = 'true';
return $t_exist;
};
这是查看我的整个代码的链接:
<script src="http://ideone.com/e.js/YjLkZF" type="text/javascript" ></script>
综上所述,主要有2个问题我不明白,也想不通:
- $n_loop在$db_entry_exist方法中被很好地调用,但$h_loop不是。
在 $db_entry_exists 的上下文中,如何将哪些变量传递给函数 () 并将哪些变量作为依赖项传递给 use() 部分。
$n_loop = function (&$t_count, $arr, $array) use (&$n_loop){}------或-------许多其他变体也存在。$n_loop = function ($arr, $array) use (&$n_loop, &$t_count){}
请调查代码并让我知道您的想法。谢谢。
你的代码中有两个误解,影响了你的理解。
第一:PHP 实际上没有嵌套函数。当你说:
function outer()
{
function foo() {}
function bar() {}
}
你真正想说的是,当调用outer()
时,在全局范围内定义foo()
和bar()
。这意味着一旦您呼叫outer()
一次,任何人都可以(不仅仅是outer()
)拨打foo()
并bar()
。这也意味着第二次调用outer()
会导致Cannot redeclare foo()
错误。
第二:PHP 中的闭包不会自动关闭其父作用域中的任何变量。任何打算成为闭包一部分的变量都必须显式包含在use()
列表中。这意味着当您编写:
$n_loop = function (&$t_count, $arr, $array) use (&$n_loop) {
//...
$h_loop($t_count, $value, $array);
//...
};
对$h_loop
的调用将始终失败,因为在该函数的范围内,没有名为 $h_loop
的变量。如果将$h_loop
添加到use()
列表中,则可以按预期调用它。