Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 函数变成了一个无止境的循环_Php_Function - Fatal编程技术网

Php 函数变成了一个无止境的循环

Php 函数变成了一个无止境的循环,php,function,Php,Function,我用php编写的函数有一个问题。如您所见,函数使用自身返回一个值数组 public function getRepeat($day = "array") { if ($day == 'array') {//Return an array with the repeated days as values foreach (array(1,2,3,4,5,6,0) as $value) { if ($this->

我用php编写的函数有一个问题。如您所见,函数使用自身返回一个值数组

    public function getRepeat($day = "array")
{
    if ($day == 'array')
    {//Return an array with the repeated days as values
        foreach (array(1,2,3,4,5,6,0) as $value) 
        {
            if ($this->getRepeat($value))
            {
                $returnArray[] = $value;
            }
        }
        return $returnArray;
    }
    else if (in_array($day, array(1,2,3,4,5,6,0) ))
    {
        if ($day == 1)
            return $this->repeat1;
        if ($day == 2)
            return $this->repeat2;
        if ($day == 3)
            return $this->repeat3;
        if ($day == 4)
            return $this->repeat4;
        if ($day == 5)
            return $this->repeat5;
        if ($day == 6)
            return $this->repeat6;
        if ($day == 0)
            return $this->repeat0;
    }
}
一旦它调用自己来获取每个变量,它就会变成一个无止境的循环


什么原因导致这种情况?

您必须始终考虑将递归函数分为两部分编写:

  • 基本情况-在哪一点停止递归并返回值(即列表为空)
  • 递归情况-如何再次调用函数,以及输入与前一次调用有何不同(即,是否发送列表的尾部)
  • 如果输入有效,确保这两个规则保持不变将导致递归函数终止

    这里有一个递归解决方案——不过它是用Java实现的:)

    publicstaticvoidmain(字符串[]args){
    List testVals=new ArrayList();
    testVals.add(0);
    增加(1);
    增加(2);
    增加(3);
    增加(4);
    增加(5);
    List toMatch=新阵列列表(testVAL);
    列表匹配项=新的ArrayList();
    repeatRec(测试、比赛、托马奇);
    System.out.println(“匹配项”+匹配项);
    }
    公共静态void repeatRec(列表到测试、列表匹配、列表到匹配){
    if(toTest.isEmpty()){
    //我们完了
    返回;
    }否则{
    整数head=toTest.get(0);
    if(toMatch.contains(头部)){
    匹配。添加(头);
    }
    //如果我们只对第一场比赛感兴趣的话,这里还有别的吗
    repeatRec(toTest.subList(1,toTest.size()),matches,toMatch);
    }
    }
    
    我可以建议更好的解决方案是:

    public function getRepeat($day = "array")
    {
        foreach (array(1,2,3,4,5,6,0) as $value) 
        {
            $tmp = "repeat".$value;
            if ($this->$tmp)
            {
                $returnArray[] = $value;
            }
        }
        return $returnArray;
    }
    
    至于为什么你的函数没有结束,我不确定。通常情况下,我会使用两个独立的函数调用执行您正在尝试的操作,例如:

    public function getRepeat()
    {
                    foreach (array(1,2,3,4,5,6,0) as $value) 
                    {
                            if ($this->getRepeat_r($value))
                            {
                                    $returnArray[] = $value;
                            }
                    }
                    return $returnArray;
    }
    private function getRepeat_r($day)
    {
            if (in_array($day, array(1,2,3,4,5,6,0) ))
            {
                    if ($day == 1)
                            return $this->repeat1;
                    if ($day == 2)
                            return $this->repeat2;
                    if ($day == 3)
                            return $this->repeat3;
                    if ($day == 4)
                            return $this->repeat4;
                    if ($day == 5)
                            return $this->repeat5;
                    if ($day == 6)
                            return $this->repeat6;
                    if ($day == 0)
                            return $this->repeat0;
            }
    }
    

    这使得事情更容易阅读,也更稳定。此外,如果PHP在不应该的时候将某个东西解释为“数组”。

    想想看,这真的很简单

    0 == 'any text which does not start with a number'
    
    最后一位数字0将导致无止境循环。所以你需要把它改成

    if ($day === 'array')
    
    编辑

    我还冒昧地修改了您的代码:

    /**
     * @obsolete
     */
    public function getRepeat($day = "array")
    {
        if ($day === 'array') {
         return $this->getAllRepeat();
    }
        return $this->getRepeatByDay($day);
    
    }
    
    public function __construct()
    {
        $this->repeat = array_fill(0, 7, '');
    }
    
    public function getAllRepeat()
    {
        return $this->repeat;
    }
    
    public function __get($value) {
        switch ($value) {
            case 'repeat0':
            case 'repeat1':
            case 'repeat2':
            case 'repeat3':
            case 'repeat4':
            case 'repeat5':
            case 'repeat6':
                return $this->getRepeatByDay(intval(substr($value, -1, 1)));
        }
    }
    
    public function getRepeatByDay($day)
    {
        if (!isset($this->repeat[$day])) {
            return null;
        }
        return $this->repeat[$day];
    }
    

    事实上,当像这样调用时,这显然不是递归函数,除非repeat1/etc调用它,在这种情况下,我们确实需要查看该代码。当您请求字符串回复一天时,您的第一个示例将不起作用。第二个示例还需要在一天内重写调用代码,这是可以的,只是附加了_r的函数名不是描述性的。PHP有许多附加了
    \u r
    的函数,意思是递归的。此外,我的第一个示例与OP完全相同,只是没有那么详细。在第一个示例中,您不能指定一天。您将仅对阵列进行ge。在第二个例子中,名为_r的函数不是递归的。它不是真正的递归-它只是被黑客攻击了,允许你调用一个方法来做两件事。编辑掉了递归部分。谢谢你启发我。哇,这是一个讨厌的“功能”+OIS为1,PHP为1
    /**
     * @obsolete
     */
    public function getRepeat($day = "array")
    {
        if ($day === 'array') {
         return $this->getAllRepeat();
    }
        return $this->getRepeatByDay($day);
    
    }
    
    public function __construct()
    {
        $this->repeat = array_fill(0, 7, '');
    }
    
    public function getAllRepeat()
    {
        return $this->repeat;
    }
    
    public function __get($value) {
        switch ($value) {
            case 'repeat0':
            case 'repeat1':
            case 'repeat2':
            case 'repeat3':
            case 'repeat4':
            case 'repeat5':
            case 'repeat6':
                return $this->getRepeatByDay(intval(substr($value, -1, 1)));
        }
    }
    
    public function getRepeatByDay($day)
    {
        if (!isset($this->repeat[$day])) {
            return null;
        }
        return $this->repeat[$day];
    }