PHP递归函数返回空JSON对象

时间:2018-04-09 15:10:01

标签: php json laravel recursion

我在PHP中有一个递归函数的问题,它返回一个JSON对象。当满足条件以再次运行该函数时,我总是得到一个空对象作为结果{}。一切都按照第一次运行的方式执行,但我总是得到一个空的结果。

这是我的代码(非常简化但功能正常):

public function run()
{
    $result = null;

    // .......
    // there is alot other stuff here, that all runs 
    // perfectly through also the second run
    // ......

    // Conditional Routing
    if($this->wfProfile->autoprocess){
        // select new wfProfile and go again.
        $this->autoprocess(function($data){
            if($data['error']==0){
                $result = null;
                $this->run(); // from here we start over !
            }else{
                return $data;
            }
        });
    }else{
        return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
    }
}

整个类中没有地方会返回一个空的JSON对象。必须在这里,我做错了或我在监督的事情。

编辑(我认为这不会有帮助)

private function autoprocess($callback)
{
    if(is_callable($callback)){
        $possibleWFprofiles = WfProfile::where('statusNow', $this->wfRequest->status)->where('conditionalRouting', 1)->get();
        if($possibleWFprofiles->count() == 0){
            // configuration error....
            $result = ["error"=>1, 'message'=>"Unable to find Conditional Routing enabled WfProfiles: ".$this->wfRequest->status];
        }
        foreach($possibleWFprofiles as $possibleWfProfile){
            if(array_search($possibleWfProfile->crFieldname, $this->wfRequestFields)===false){
                // fieldname wrongly configured
                $result = ["error"=>1, 'message'=>"Unable to find field ".$possibleWfProfile->crFieldname];
            }
            // see if this is the right one
            if($this->wfRequest[$possibleWfProfile->crFieldname] == $possibleWfProfile->crValue){
                  $this->wfProfile = $possibleWfProfile;
                  $result = ['error'=>0,'message'=>'Off to loop 2'];
            }
        }
        call_user_func($callback, $result);
    }
}

3 个答案:

答案 0 :(得分:3)

当您在匿名函数中创建return $data时,它将不会是运行的返回。

您在autoprocess函数中没有对此返回做任何操作。

您需要在autoprocess中返回一些内容,然后在if:

中返回
if($this->wfProfile->autoprocess){
    // select new wfProfile and go again.
    return $this->autoprocess(function($data){
        if($data['error']==0){
            $result = null;
            return $this->run(); // from here we start over !
        }else{
            return $data;
        }
    });
}else{
    return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
}

答案 1 :(得分:1)

您需要返回您的值,例如:

function callback($func, $val) {
    return call_user_func($func, $val);
}

function run($val) {
    if ($val < 10) {
        callback(function($val) { return run($val + 1); }, $val);
    } 
    return $val;
}

print(run(0));

这将打印为空,但如果你这样做:

function callback($func, $val) {
    return call_user_func($func, $val);
}

function run($val) {
    if ($val < 10) {
        return callback(function($val) { return run($val + 1); }, $val);
    } 
    return $val;
}

print(run(0));

它将打印10

你的职能:

public function run()
{
    $result = null;

    // lets say this is true...
    if($this->wfProfile->autoprocess){
        // now we are here, where does this return a value???
        $this->autoprocess(function($data){
            // if it goes here, it never returns a value.
            if($data['error']==0){
                $result = null;
                $this->run(); // from here we start over !
            }else{ // if it returns here it still just returns to 
                   // $this->autoprocess, which might return to the
                   // original run function, but you don't seem to be
                   // returning its return either...
                return $data;
            }
        });
    }else{
        return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
    }
}

答案 2 :(得分:1)

最后我选择了不那么优雅的方法来解决这个问题,因此我使用goto而不是再次调用该函数。这很容易阅读,并且将来可以调试/扩展。所以我们走了:

public function run()
{
  startover:
    $result = null;

    // more stuff going on here

    // Conditional Routing
    if($this->wfProfile->autoprocess){
        // select new wfProfile and go again.
        $result = $this->autoprocess();
        if($result['error']==0){
              goto startover; // easiest way :-)
        }else{
              return $result;
        }

    }else{
        return ['error'=>0,'message'=>'all good'];
    }
}

这里是自动过程函数

private function autoprocess()
{
    $possibleWFprofiles = WfProfile::where('statusNow', $this->wfRequest->status)->where('conditionalRouting', 1)->get();
    if($possibleWFprofiles->count() == 0){
        // configuration error....
        return ["error"=>1, 'message'=>"Unable to find Conditional Routing enabled WfProfiles: ".$this->wfRequest->status];
    }
    foreach($possibleWFprofiles as $possibleWfProfile){
        if(array_search($possibleWfProfile->crFieldname, $this->wfRequestFields)===false){
            // fieldname wrongly configured
            return ["error"=>1, 'message'=>"Unable to find field ".$possibleWfProfile->crFieldname];
        }
        // see if this is the right one
        if($this->wfRequest[$possibleWfProfile->crFieldname] == $possibleWfProfile->crValue){
            $this->wfProfile = $possibleWfProfile;
            return ['error'=>0,'message'=>'Off to loop 2'];
        }
    }
}