PHP 递归函数返回空的 JSON 对象



我在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);
    }
}

当你在匿名函数内进行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
}

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

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
    }
}

最后我选择了恕我直言不太优雅的方式来解决这个问题,所以我使用了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'];
        }
    }
}

最新更新