一聚教程网:一个值得你收藏的教程网站

热门教程

Yaf中Action再次Dispatch导致PHP段错误Segmentation fault

时间:2022-06-25 00:55:46 编辑:袖梨 来源:一聚教程网

首先,这个问题是在Yaf群偶然看到的,这些小伙儿不折腾不畅快,今天闲来,扫了一下代码,得出结论。
其次,另外一个观点是,工具在运用时一定要清楚其原理,不然就是自己跳坑了没有人救的。
先简单明了看一下,在基于Yaf的PHP代码示例:

 代码如下 复制代码

use Yaf\Dispatcher;
use Yaf\Controller_Abstract;

final class IndexController extends Controller_Abstract
{
    public function init()
    {
        // 无
    }

    public function indexAction()
    {
            $request = new Yaf\Request\Simple('API', 'index', 'index', 'simple');
            Dispatcher::getInstance()->dispatch($request);
            $this->_view->assign('displayWelcome', 1);
            $this->_view->assign('hello', 'hello world!');
    }

    public function simpleAction()
    {
            echo 'xudianyang';
    }
}

在默认的indexAction中,我创建了一个Yaf\Request\Simple的请求对象$request,参数的意思是请求Index模块和Index控制器的Simple动作,这里需要注意的是,如果你将请求设置为和当前action的路由参数相同,那么你将进入死循环,都不用大拇指想就知道。然后调用派遣器Dispatcher的dispatch方法,进行路由分发。

Yaf中Action再次Dispatch导致PHP段错误Segmentation fault
从图中可以看出,在“新一轮分发”的过程中,任何一个环节出现问题,或者exit,return都不会产生程序崩溃。比如,simpleAction方法这样写:

 代码如下 复制代码

public function simpleAction()

{

    echo  'xudianyang';

    exit;

}

再比如:simple方法对应的模板文件views/index/simple.phtml不存在,也不会生产Segmentation fault。
产生段错误的原因在图中说得也很明显,指针引用不再可用,因为新一轮分发是调用了Dispatcher::getInstance()->dispatch($request);此方法会重置Yaf\Dispatcher单实例的$_request属性。
通过gdb调试core文件也可以得出:

 代码如下 复制代码
(gdb) bt
#0 0x083d58d4 in zend_std_read_property (object=0xb777c020, member=0xb73f8938, type=3, key=0x0)
at /home/vagrant/php-5.4.31/Zend/zend_object_handlers.c:431
#1 0x083b4508 in zend_read_property (scope=0xa392cb8, object=0xb777c020, name=0xcb64c6 "module", name_length=6, silent=1 '\001')
at /home/vagrant/php-5.4.31/Zend/zend_API.c:3859
#2 0x00c96c85 in yaf_dispatcher_fix_default (dispatcher=0xb778143c) at /home/vagrant/yaf-2.3.2/yaf_dispatcher.c:236
#3 yaf_dispatcher_dispatch (dispatcher=0xb778143c) at /home/vagrant/yaf-2.3.2/yaf_dispatcher.c:927
#4 0x00c91bd6 in zim_yaf_application_run (ht=0, return_value=0xb7799fcc, return_value_ptr=0x0, this_ptr=0xb777a140,
return_value_used=0) at /home/vagrant/yaf-2.3.2/yaf_application.c:468
#5 0x0841f5d4 in zend_do_fcall_common_helper_SPEC (execute_data=)
at /home/vagrant/php-5.4.31/Zend/zend_vm_execute.h:643
#6 0x084137a6 in execute (op_array=0xb777a408) at /home/vagrant/php-5.4.31/Zend/zend_vm_execute.h:410
#7 0x083b1c6e in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/vagrant/php-5.4.31/Zend/zend.c:1315
#8 0x08357706 in php_execute_script (primary_file=0xbfb72338) at /home/vagrant/php-5.4.31/main/main.c:2502
#9 0x0845c1cb in main (argc=6, argv=0xbfb72494) at /home/vagrant/php-5.4.31/sapi/fpm/fpm/fpm_main.c:1933

最后,其实分析这个只是熟悉一下Yaf的分发策略及其源码。另外,想要在一个action中执行另外一个action,其实鸟哥已经考虑了,通过Yaf_Controller_Abstract::forward就可以了。我们在实际应用中,不要异想天开,乱来!

热门栏目