诱发灾难的drupal_goto()

你在这里

诱发灾难的drupal_goto()

Drupal CMS系统中,开发人员常用drupal_goto()函数进行便利的页面跳转,然而这常常是诱发灾难性后果的源泉,ZZKOOK建议,如果有其它的选择,尽量不要使用该函数进行页面跳转。因为不正确的使用drupal_goto()函数,会为后期的bug排查带来巨大的工作量,使其成为各种疑难杂症的元凶。
drupal_goto()之所以成为Drupal开发者页面跳转的首选是因为其便利的特性,似乎它能隐式的处理掉很多页面跳转时比较麻烦的细节操作。果真如此吗?让我们看看以下危险的使用案例:
一、在表单提交时使用
在表单验证和提交函数中使用drupal_goto最为危险,如下面所示的代码:
<?php
function module_node_form_form_alter(&$form, &$form_state, $form_id) {
  ... some stuff ...
  $form['submit'][] = 'module_submit_function';
  ... some other stuff ....
}
 
function module_submit_function($form, &$form_state) {
  if (my condition) {
    drupal_goto('a random page');
  }
}
?>
上面的示例中在node提交表单中增加了新的提交处理函数,且在该函数中调用了一个drupal_goto()跳转的指定页面。该操作会造成node写入数据库的过程终止,数据库写操作失败并回滚。
正确的做法:使用表单状态的$form_state['redirect']项设置表单处理完毕后跳转的页面,例如:
function module_submit_function($form, &$form_state) {
  global $user;
  if (my condition) {
    $redirect = 'user/' . $user->uid;
    if (!empty($_GET['destination'])) {
      $redirect = $_GET['destination'];
    }
    $form_state['redirect'] = $redirect;
  }
}
?>
二、在有Ajax过程中使用
笔者遇到的问题就是在启用了modal_form模块(在用户登录时使用叠层)和legal模块后,当legal协议更新时,登录表单会报Ajax 200响应报错,这是一个典型的drupal_goto()调用引发的跨模块Ajax错误。因为legal模块在其实现倒钩函数legal_user_login()时,调用了drupal_goto()。而如果同时启用了登录表单的modal form功能,该跳转就会在Ajax中进行,从而引发200响应错误。
另一种引发错误的情况是在hook_init()的实现中调用drupal_goto(),其引发的Ajax错误与前面的案例中类似,浏览器的弹窗中会报JS严重错误,并打印出大段的html代码,依然是200响应错误。这种bug发生后调试是非常困难的,且通常是跨模块的。
正确的做法:在不确定该页面过程中一定没有Ajax时,不使用drupal_goto()。
三、在Drush过程中使用
喜欢使用Drush的开发者会发现drupal_goto()会导致Drush被异常终止:
Drush command terminated abnormally due to an unrecoverable error: [error]
 
综上所述,Drupal开发者应该谨慎使用drupal_goto(),在以下情况不要使用它:
1.在else语句中或类似的选择语句中,这会为bug最终带来巨大的困难;
2.表单提交和验证函数中,导致数据库写入失败;
3.在页面访问检查权限中,这会导致搜索引擎困惑,使页面收录存在问题;
4.在可能的Ajax过程中,这会导致严重的弹窗告警;
5.如果喜欢使用Drush,则禁忌就更多了!
 
著作权归作者所有。商业转载请联系本站作者获得授权,非商业转载请注明出处 ZZKOOK

您可能感兴趣的文章

登录以发表评论

评论

难得!

 
101
夏秋冬的头像

零差评

 
128
赵州的头像

很讨厌项目组里那些保守的前辈,谢谢ZZKOOK

 
129
图灵的头像