【问题标题】:Best practice for tiny code reuse in PHPPHP中微小代码重用的最佳实践
【发布时间】:2014-05-04 07:08:41
【问题描述】:

很长一段时间以来我都有一个问题 - 我是否应该重用一小部分代码,如果是的话,我应该怎么做,这将是最佳实践。

我的意思是小代码例如:

if (!is_array($table)) {
    $table = array($table);  
}

$x = explode("\n", $file_content);

$lines = array();

for ($i=0, $c = count($x); $i<$c; ++$i) {
  $x[$i] = trim($x[$i]);
  if ($x[$i] == '') {
     continue;
  }          
  $lines[] = $x[$i];      
}

这样一小部分代码可能会在一个项目的许多类中使用,但其中一些也可以在许多项目中使用。

我认为有很多可能的解决方案:

  1. 创建简单的函数文件,并将它们全部作为函数的可重用代码,简单地包含在项目中,并在需要时使用它们
  2. 为这些代码创建特征并在类中使用它们
  3. 通过简单的复制粘贴或在特定类中创建函数来重用代码 (??)
  4. 其他?

我认为所有这些解决方案都有其优点和缺点。

问题:我应该使用什么方法(如果有的话)来重用这些代码,为什么这种方法在您看来是最好的方法?

【问题讨论】:

    标签: php oop coding-style


    【解决方案1】:

    我认为“最佳方式”取决于许多因素,包括您的应用程序使用的技术(过程、OOP)、它们运行的​​ PHP 版本等。例如,特征很有趣且有用,但它们仅在php 5.4.0,因此使用此工具对代码进行分组 sn-ps 您将无法在运行早期 PHP 版本的系统中重用它们。另一方面,如果您的应用程序使用 OOP 样式并且您将可重复使用的小代码 sn-ps 组织在函数中,那么它们在 OOP 应用程序中的使用可能看起来很尴尬,并且与特定类中的函数名称冲突。在这种情况下,我认为将您的函数分组到类中似乎更自然。

    将所有内容放在一起,似乎类提供了更好的工具来按照上面概述的术语对可重复使用的代码 sn-ps 进行分组,即与早期 PHP 版本的向后兼容性,避免函数名冲突等)我个人主要在 OOP 中编写代码,所以我有一个 Util 类,我在其中对代表可重复使用的代码片段 sn-ps 的小函数进行分组,这些片段彼此不直接相关,因此无法在逻辑上分组到其他类中。

    【讨论】:

    • 好的,你是如何在你的应用程序中使用这些类的?您是创建这些类的许多对象还是创建一个并在构造函数中传递它/它们,或者像@Cleric 显示的那样在类中创建静态方法?
    • @MarcinNabiałek 你当然可以使用静态方法。另一种可能性是编写一个单例类,以不让您的应用程序充满完全相同的无穷无尽的对象。这是我大多数时候更喜欢的方法。如果我在应用程序中有几个这样的类,我通常将它们存储在一个单例注册表类中,该类充当某种身份映射,确保每个对象只加载一次。
    • 好的,我明白了。我也使用过注册表,但仅用于存储配置/路由/数据库等
    • @MarcinNabiałek 是的,我存储数据库访问类和我的配置类。我想知道这是否只是巧合))
    【解决方案2】:

    如前所述,特质是一件好事。但是一段时间后可能会有点难以管理,而且自从它新推出以来,它可能不会在所有地方都得到支持。

    我所做的是创建具有很多小的静态函数的工具类,例如:

    class ArrayTools
    {
    
        static public function CheckArray($array)
        {
            if (!is_array($array))
            {
                $array = array($array);  
            }
    
            return $array;
        }    
    
    }
    

    所以你可以用ArrayTools::CheckArray($array)调用它

    【讨论】:

    • 嗯,最好避免静态 :)
    • @ShankarDamodaran 这是一个简单的滑坡,但是对于这些特定的东西结合一些代码标准,很容易将它们用作 PHP 内置函数。但我同意你的看法,危险的东西:)
    【解决方案3】:

    如果您的代码主要涉及类和对象,请使用traits。因为特征的概念专门关注代码重用能力。

    【讨论】:

    • traits 仅从 php 5.4.0 开始可用。在早期版本的语言中,您将不得不使用不同的工具,例如函数或类。
    • @akhilless,对,在这​​种情况下,OP 必须采用解决方案 1。
    【解决方案4】:

    以下是我在普通 PHP 项目中实际使用的代码 sn-ps,这些代码 sn-ps 用于各种框架的良好特性和最佳实践。

    1。 下面的代码是用来检查你工作的环境,根据环境可以设置一些全局变量,报错等等。

    if(!defined('ENVIRONMENT')){
        define('ENVIRONMENT','DEVELOPMENT');
    }
    
    if (defined('ENVIRONMENT'))
    {
        switch (ENVIRONMENT)
        {
            case 'DEVELOPMENT':
            case 'TESTING':
                $base_url   =   'http://localhost/project_name/';
                error_reporting(E_ALL);
                break;
    
            case 'PRODUCTION':
                $base_url   =   'http://hostname/project_name/';
                error_reporting(0);
                break;
    
            default:
                exit('The application environment is not set correctly.');
        }
    }
    

    2.

    /* This function is used to PRINT the ARRAY data in the pre formatted manner */
    if (!function_exists('pr')) {
        function pr($data) {
            echo '<pre>', print_r($data), '</pre>';
        }
    }
    

    3.

    /* This function is used to Sanitize the user data and make data safe to insert into the database */
    function sanitize($data) {
        global $link;
        $data = trim($data);
        return htmlentities(strip_tags(mysqli_real_escape_string($link, $data)));
    }
    

    4.

    /* Used to get the difference of 2 arrays
       Returns the array with difference    
     */
    function multi_diff($arr1,$arr2){
      $result = array();
      foreach ($arr1 as $k=>$v){
        if(!isset($arr2[$k])){
          $result[$k] = $v;
        } else {
          if(is_array($v) && is_array($arr2[$k])){
            $diff = multi_diff($v, $arr2[$k]);
            if(!empty($diff))
              $result[$k] = $diff;
          }
        }
      }
      return $result;
    }
    

    5.

    /* This fnction is used to generate the random keys of specific length
      Accepts parameter of certain length if not specified it will generate 20 bit length automatically
     */
    function generate_random_key($length = 20) {
        //Initializing the varialble
        $keystring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
        $random_key = '';
        for ($i = 0; $i < $length; $i++) {
            $random_key.=$keystring[rand(0, strlen($keystring) - 1)];
        }
        //Return the randomly generated key
        return $random_key;
    }
    

    6.

    /* This function outputs the errors in ul>li format with unstyled
     * To get the bullets styling remove class='list-unstyled' in <ul> tag */
    function output_errors($errors){
        $output =   array();
    
        foreach ($errors as $error) {
            $output[]   =   '<li>'.$error.'</li>';
        }
        return '<ul class="list-unstyled">'.implode('', $output).'</ul>';
    }
    

    7.

    /* Checks whether the user is loggedin else will redirect to the protectect page */
    function protected_page(){
        if(is_loggedin() === false){
    //        header('Location: protected.php');
            header('Location: logout.php');
            exit();
        }
    }
    

    8.

    /* If user tries to access the page directly accessing through the URL,
     * If already loggedin then redirect him to any of the inner page 
     */
    function login_redirect(){
        if(is_loggedin() === true){
            header('Location: home.php');
        }
    }
    

    9.

    /* This function is used to check whether the user exists or not */
    function email_exists($email){
        /* Your Code */
    }
    
    
    /* This function is used to check whether the user isActive or not */
    function is_active($email){
        /* Your Code */
    }
    
    
    /* This function will get the userid from the email */
    function userid_from_email($email) {
        /* Your Code */
    }
    
    /* This fucntion is used to login the user based on the email-id and password */
    function login($email,$password){
        /* Your Code */
    }
    
    /* Check whether the USER is loggedin or not */
    function is_loggedin(){
        return (isset($_SESSION['userid'])) ? true : false;
    }
    

    希望这对您有所帮助。干杯!

    【讨论】:

    • 对数据库连接资源使用全局变量$link 是一种好习惯吗?从什么时候开始?
    • 它在普通 PHP 中不是 oops PHP 项目。即使我已经提到了这一点,请检查我上面的描述。如果你认为我的方法是错误的。请让我知道你是如何在普通 PHP 项目中实际做到这一点的。
    • 如果有人在任何地方覆盖$link,所有依赖于全局插入的函数都会中断。您的描述说这些代码 sn-ps 用于各种框架的良好特性和最佳实践。我的评论仅停留在两个词上,最佳实践。你的评论没有回答我的问题;)
    • 是的,我完全同意你的观点,如果有人覆盖了 $link,那么它可能不会按照它必须的方式行事。在纯 PHP 中,您没有任何其他替代方法可以在包含它的文件中使连接可用,如果您知道任何更好的方法,请告诉我,即使我会升级我的代码。
    • 如果你不这样做,那么我们最终可能会复制代码,所以我想出了那种选择。
    猜你喜欢
    • 2012-05-30
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    相关资源
    最近更新 更多