考虑以下代码:
$tests = array(
array ("a", "b", "c"), array ("1", "2", "3"), array ("!", "@")
);
foreach ($tests as $test)
test($test[0], $test[1], $test[2]);
function test($param1, $param2, $param3) {
// do whatever
}
在进入$ test [2]之前没有任何问题,当然在数组中没有第三个元素,导致PHP吐出:
Notice: Undefined offset: 2
除此之外,有没有办法解决这个问题:
foreach ($tests as $test) {
if (count($x) == 2)
test($test[0], $test[1]);
else
test($test[0], $test[1], $test[2]);
}
function test($param1, $param2, $param3=null) {
// do whatever
}
随着每个$ test数组的大小变大,这变得笨拙。 或者我应该忽略通知呢?
编辑:以下是我实际尝试做的事情:
// wanted this:
function validate() {
$pass = true;
$rules = array (array ('field1', '!=', 'banana'),
array('field2', 'notempty')
);
for ($i=0; $i<count($rules) && $pass; $i++)
$pass = check($rules[$i][0], $rules[$i][1], $rules[$i][1]);
return $pass;
}
function check($field, $operator, $expected) {
$value = $this->getValue($field);
switch ($operator) {
case '!=':
$pass = ($value != $expected);
break;
case '==':
$pass = ($value == $expected);
break;
case 'empty':
$pass = empty($value);
break;
default:
$pass = !empty($value);
break;
}
return $pass;
}
//instead of
function validate() {
$pass = true;
for ($i=0; $i<count($rules) && $pass; $i++)
$pass = check($rules[$i]);
return $pass;
}
function check($check) {
$value = $this->getValue($check[0]);
switch ($check[1]) {
case '!=':
$pass = ($value != $check[2]);
break;
case '==':
$pass = ($value == $check[2]);
break;
case 'empty':
$pass = empty($value);
break;
default:
$pass = !empty($value);
break;
}
return $pass;
}
基本上是出于风格上的原因。
答案 0 :(得分:6)
有趣。
你为什么不做这样的事情?
foreach($tests as $test) {
test($test);
}
function test($test) {
// loop through $test to get all the values as you did originally
}
如果你有一个数组的动态大小,我不明白为什么你不能只将整个数组传递给函数而不是分开的参数。
答案 1 :(得分:0)
请改用:
$tests = array(
array ("a", "b", "c"), array ("1", "2", "3"), array ("!", "@")
);
foreach ($tests as $test)
test($test);
function test($test)
{
for($i=0; $i < count($test); $i++)
{
if (! isset($test[$i]) )
$test[$i] = '';
}
// do whatever
}
答案 2 :(得分:0)
为什么使用$ param1,$ param2而不是直接使用Array作为参数,例如:
$tests = array(
array( 'a', 'b', 'c' ),
array( '1', '2', '3' ),
array( '!', '@' )
);
foreach ( $tests as $test )
{
test( $test );
}
function test( $params )
{
$param1 = $params[0]; // Or use directly $params[index], than you need not to set it.
}
或者另一种方式(但这种方式不是最好的方式,上面的方式更好;)
$tests = array(
array( 'a', 'b', 'c' ),
array( '1', '2', '3' ),
array( '!', '@' )
);
foreach ( $tests as $test )
{
test( $test );
}
function test( $params )
{
for( $i=0; $i<=count( $params )-1; $i++ )
{
$param$i = $params[$i];
}
}
答案 3 :(得分:0)
如果问题的关键是如何迭代多维数组,那么执行
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($theArray)
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $key => $val) {
echo "$key = $val \n"
}
如果您想知道如何将可变数量的参数传递给函数,请考虑
function throwItAtMe()
{
$args = func_get_args();
print_r($args);
}
throwItAtMe(1,2,3,4,5, 'foo', 'bar', 'baz');
对于您的规则/断言,只需使用Strategy Pattern或查看Specification pattern。
答案 4 :(得分:0)
你真的应该选择Bartek的解决方案,但为了完整性,这里有一个,这可能更像你想要它:
foreach ($tests as $test) {
test($test[0], $test[1], isset($test[2]) ? $test[2] : null);
}
但老实说:如果阵列的大小可以增加,你真的想每次都改变功能签名吗?享受我们的直播和传递阵列。
如果它最多有3个条目,那么你可以使用上面的代码。
答案 5 :(得分:0)
foreach($tests as $test) {
test($test);
}
function test($test) {
@list($field, $operator, $expected) = $test;
// if $test size is 2 then $expected will be NULL, @ is to suppress Notice, if you don't show notices you may ommit it
}
答案 6 :(得分:0)
通过call_user_func_array
:
foreach ($tests as $test) {
call_user_func_array('test', $test);
}
function test($param1, $param2, $param3 = null) {
// ...
}
虽然我很可能更喜欢Bartek的解决方案。