Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何终止程序运行而又不影响几个hook的执行 #121

Open
leo108 opened this issue Sep 10, 2014 · 14 comments
Open

如何终止程序运行而又不影响几个hook的执行 #121

leo108 opened this issue Sep 10, 2014 · 14 comments
Labels

Comments

@leo108
Copy link

leo108 commented Sep 10, 2014

有两个场景

  • 在controller的init方法中如何终止后续action的执行,比如在init中判断用户是否拥有操作权限,如果没有权限就输出错误信息,并且不执行后续的具体action。
  • 我定义了一个类A,继承Yaf_Controller_Abstract,然后所有controller都继承类A,类A提供了一个方法success,如何实现A的子类调用A的success方法后就终止后续的代码执行。

以上两个场景可以在代码后面跟上exit或者die来实现,但这样的话会导致postDispatch和dispatchLoopShutdown两个hook不执行

@laruence
Copy link
Owner

throw exception..

@leo108
Copy link
Author

leo108 commented Sep 10, 2014

尝试过exception,并且将exception交给errorController处理,但是同样postDispatch和dispatchLoopShutdown两个hook不执行

@laruence
Copy link
Owner

hmm, 我看看, 如果真的是这样, 那应该是bug了...

@leo108
Copy link
Author

leo108 commented Sep 10, 2014

个人感觉应该提供一个forceFinishDispatch这样的方法,throw exception略感山寨

@lvyalin
Copy link

lvyalin commented Mar 19, 2015

exception交给errorController处理,但是同样postDispatch和dispatchLoopShutdown两个hook不执行 同现

@laruence laruence added the bug label Jun 16, 2015
@laruence
Copy link
Owner

如我们在群里的讨论, 你可以通过这个方式来实现:

public function init() {
     $this->DontExecute = true;
}

public function action() {
     if ($this->DontExecute) { return; }
}

另外我们也可以考虑对init加入支持, 比如如果init返回false就不在继续执行action. 但是问题在于, 如果init返回false, 框架应该怎么做, 抛出异常? 还是静默处理? 总感觉不对劲.

thanks

@leo108
Copy link
Author

leo108 commented Jun 25, 2015

如果在每个action里都去判断这个属性是否为true很不方便,也容易遗漏。
至于处理方式我感觉可以做成配置,就像Yaf可以配置成触发错误或者是抛异常。

@mlboy
Copy link

mlboy commented Jun 25, 2015

init加入return false 不执行action 不行。不一定是init比如说
inti 中又调用了个auth()方法 那么auth 还需要返回到init,再在init返回。比较复杂。
下面是我想的一个过程,能否可行:

不要通过xxAction的返回去判断当前controller的停止
而是在controller中有个方法如_halt(ture);通过这个去判断返回。

Yaf_Dispatcher对应的地方是(伪代码,没细看yafc代码,话说看也看不懂)

以前可能是这样的:

$action=将要执行的方法
$params=参数
$c = new controller();
call_user_func([$c,_init],$params);
call_user_func([$c,$action],$params);

修改成这样的:

$c = new controller();
$action=将要执行的方法
$params=参数
call_user_func([$c,halt],$bool,$action,$params);
然后在controller抽象类的中写死个方法
halt($bool,$action=null,$params=null){
if($bool){
return $bool;
}
call_user_func([$this,_init],$params);
return call_user_func([$this,$action],$params);
}

@letwang
Copy link

letwang commented Dec 6, 2018

已经解决 参考这里
https://github.com/letwang/HookPHP/blob/master/vendor/Hook/Hook/Hook.php

$html = '';
        foreach ($hookModule[$key] as $module) {
            $html .= call_user_func(array(Module::getInstance($module)->module, 'hook'.$key), $args);
        }
        return $html;

https://github.com/letwang/HookPHP/blob/master/app/admin/plugins/Hook.php
https://github.com/letwang/HookPHP/tree/master/app/admin/hooks

@welllog
Copy link

welllog commented Apr 7, 2019

ErrorController确实并不会执行postDispatch和dispatchLoopShutdown,这个问题会解决么

@shyandsy
Copy link
Contributor

emmm 15年讨论到19年

我是20年了,同问,有没有优雅的方式,比如init return false就不执行action了

@Attax
Copy link

Attax commented Feb 20, 2021

emmm 15年讨论到19年

我是20年了,同问,有没有优雅的方式,比如init return false就不执行action了


21年了,我也来问一遍

@50MetersBlue
Copy link

50MetersBlue commented Feb 23, 2021

在基类controller的int()方法调用$this->forward()跳转到【指定】控制器进行处理就行了,测了一下可以正常触发hook,init方法执行完后直接跳转到指定的action,不会调用原来的action

1、基类控制器
image

2、错误控制器
image

3、插件
image

@carter911
Copy link

这个问题解决了 我也需要用这个方法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants