我在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);
}
}
答案 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'];
}
}
}