Php 如何重构这个嵌套的try-catch

Php 如何重构这个嵌套的try-catch,php,refactoring,try-catch,Php,Refactoring,Try Catch,我是一个新手,最近一直在重构大量代码,以跟上开发的原则。然而,我仍然有一些我不能完全理解的场景。例如,在我正在开发的多语言应用程序中,我想让用户通过在URL的查询字符串中传递两个字母的国家代码来设置接口语言,或者如果用户没有请求,让应用程序使用默认语言: // Which language shall we use? $language = new language(); if(isset($_GET['language_code'])){ try { $language

我是一个新手,最近一直在重构大量代码,以跟上开发的原则。然而,我仍然有一些我不能完全理解的场景。例如,在我正在开发的多语言应用程序中,我想让用户通过在URL的查询字符串中传递两个字母的国家代码来设置接口语言,或者如果用户没有请求,让应用程序使用默认语言:

// Which language shall we use?
$language = new language();
if(isset($_GET['language_code'])){
    try {
        $language->set_by_language_code($_GET['language_code']);
    } catch(e_language_not_found $e){
        try {
            $language->set_default_language();
            // TODO - use 'e_language_not_found' to display an error in the default language
        } catch(Exception $e){
            exit('No default language found');
        }
    }
} else {
    try {
        $language->set_default_language();
    } catch(Exception $e){
        exit('No default language found');
    }
}

问题是,当用户根本没有请求任何语言时,我重复了set_default_language块。如何重构代码,以便在应用程序中只调用该方法一次?谢谢

在我看来,你应该在你的语言课上实现这些方法:

language::hasLanguage,它返回一个布尔值,指示语言的存在而不引发异常

language::GetDefling,返回默认语言标识符

您还应该为catch块指定更详细的异常类型


您还可以在if语句中使用language::hasLanguage来替换try…catch块。

我认为,您应该在语言类中实现以下方法:

language::hasLanguage,它返回一个布尔值,指示语言的存在而不引发异常

language::GetDefling,返回默认语言标识符

您还应该为catch块指定更详细的异常类型


您还可以在if语句中使用language::hasLanguage来替换try…catch块。

事实上,您在两个位置调用函数本身就不错。它不会影响性能,重构它会降低代码的可读性

这就是我为您的代码所想到的:

// Which language shall we use?
$language = new language();
try {
  try {
    if(isset($_GET['language_code'])){
      $language->set_by_language_code($_GET['language_code']);
    } else {
      $language->set_default_language();     
    }
  } catch(e_language_not_found $e){    
      $language->set_default_language();    
  }
} catch (Exception $e){
  exit('No default language found');
}

事实上,您在两个地方调用函数本身并不坏。它不会影响性能,重构它会降低代码的可读性

这就是我为您的代码所想到的:

// Which language shall we use?
$language = new language();
try {
  try {
    if(isset($_GET['language_code'])){
      $language->set_by_language_code($_GET['language_code']);
    } else {
      $language->set_default_language();     
    }
  } catch(e_language_not_found $e){    
      $language->set_default_language();    
  }
} catch (Exception $e){
  exit('No default language found');
}


我认为这个问题更适合代码审查测试版:如果用户没有请求任何语言,我猜语言代码不会设置为第二组,默认语言将被调用,要解决这个问题,您可以在while语言设置中添加另一个条件。但是我不明白你的问题是什么,我认为这个问题更适合代码审查测试版:如果用户没有请求任何语言,我猜语言代码不会被设置为第二集,默认语言将被调用,为了解决这个问题,你可以在while语言设置中添加另一个条件。然而,我不明白你对嵌套的try-catch的疑问,我不需要为set\u default\u语言调用的每个调用都使用try-catch吗?据我所知,这段代码与你的代码是等效的。外部try{}catchException$e将处理来自set_default_language的所有异常,无论它们被抛出到何处。感谢@Mchl,只要set_default_language抛出了一个e_default_language_not_found异常而不是一个通用异常,我就可以在外部块中捕捉到它?好吧。。。是的,因为所有异常都扩展了异常类。不过我不认为这会很清楚。再次感谢。为什么我喜欢这样-两种不同的方法在10分钟的空间!我不需要为每个set\u default\u语言调用都使用try-catch吗?据我所知,这段代码与您的代码相当。外部try{}catchException$e将处理来自set_default_language的所有异常,无论它们被抛出到何处。感谢@Mchl,只要set_default_language抛出了一个e_default_language_not_found异常而不是一个通用异常,我就可以在外部块中捕捉到它?好吧。。。是的,因为所有异常都扩展了异常类。不过我不认为这会很清楚。再次感谢。为什么我喜欢这样-两种不同的方法在10分钟的空间!确切地说,这是编写goAs的一种更好的方法,我仍然需要在getDefLang方法中使用try-catch和exception,以防找不到默认语言,这只是把这个逻辑移到了另一个容器中——这就是你的意思吗?@boatingcow问题是,a你只需要调用一次set_by_语言_代码,b因此你只有一个try…catch block。您还可以使用编辑中编写的hasLanguage来替换它。您应该决定是将does exist逻辑存储在language类中还是存储在用户代码中。确切地说,编写Goa是一种更好的方法,我仍然需要在getDefLang方法中设置一个try-catch和异常,以防找不到默认语言,这只是把这个逻辑移到了另一个容器中——这就是你的意思吗?@boatingcow问题是,a你只需要调用一次set_by_语言_代码,b因此你只有一个try…catch block。您还可以使用编辑中编写的hasLanguage来替换它。您应该决定是否应该使用“确实存在”逻辑 存储在语言类或用户代码中。