Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP代码复制。在什么情况下,复制代码才是正确的方法?_Php_Codeigniter_Refactoring_Code Duplication - Fatal编程技术网

PHP代码复制。在什么情况下,复制代码才是正确的方法?

PHP代码复制。在什么情况下,复制代码才是正确的方法?,php,codeigniter,refactoring,code-duplication,Php,Codeigniter,Refactoring,Code Duplication,我正在使用CodeIgniter,但这个问题在一般意义上也适用 我有一个带有列的事务表 item_name | type | date | price | document 我想在两种完全独立的情况下执行以下操作 1) 获取特定日期范围内的事务列表。 2) 获取特定日期范围内每笔交易的总价。键入 前者可以通过简单地使用带有>datetimestamp的select语句来实现 后者可以通过选择SUM和按类型分组来实现,同时像实现任何必需的where条件一样,例如使用>datetimestamp

我正在使用CodeIgniter,但这个问题在一般意义上也适用

我有一个带有列的事务表

item_name | type | date | price | document
我想在两种完全独立的情况下执行以下操作

1) 获取特定日期范围内的事务列表。 2) 获取特定日期范围内每笔交易的总价。键入

前者可以通过简单地使用带有>datetimestamp的select语句来实现

后者可以通过选择SUM和按类型分组来实现,同时像实现任何必需的where条件一样,例如使用>datetimestamp

虽然这是一个简单的例子,但要实现这一点,我需要两种方法,但是这两种方法(即WHERE子句)的大部分在两种方法中都是重复的

就速度等而言,这并不重要,但似乎是毫无意义的代码复制


第二个例子如下

我以前有一个方法
get_data($ID)
,它将根据传入的ID从表中获取一行

因此,在一个单独的方法中,我将获得我的100个项目,例如。。返回一个数组,遍历它们并为每个数组调用get_data

这种设置意味着许多不同的方法可以从不同的源获取不同的列表,然后仍然使用相同的get_data函数和循环来获取所需的数据

这最小化了代码重复,但难以置信的是效率低下,因为这意味着要循环加载数据项和数百个db查询

在我当前的设置中,我只是在我的每个方法中加入数据表-代码重复,但效率明显提高


最后一个例子如下

在codeigniter中,我可以具有如下功能:

get_thing($ID)
{
$this->load->database();
$this->db->where('ID',$ID);
$this->db->get('table');
}
但在其他情况下,我可能只想获取特定文件夹中的项目。。因此,使函数更通用更有效。。e、 g

get_thing($array)
{
$this->load->database();
$this->db->where($array);
$this->db->get('table');
}
但是,我可能希望在两种不同的上下文中使用此功能,例如用户页面和管理员页面,管理员可以在其中查看所有项目,甚至是未经验证的项目。我的代码现在变成:

get_thing($array,$show_unverified = false)
{
$this->load->database();
$this->db->where($array);
if($show_unverified == false)
{
$this->db->where('verified','YES');
}
$this->db->get('table');
}
正如您可能看到的,这可能很快失控,方法可能变得过于复杂、混乱,并且充满条件


我的问题如下-减少代码重复的最佳实践是什么?如何将其应用于上述情况?我花了好几个小时试图使我的代码更高效,但我一事无成,因为我无法锻炼我真正应该努力实现的目标


干杯

关于数据库访问函数中的代码复制,我的想法是,通常最好将其分开

这里我的规则是,函数不应根据参数返回不同类型的数据,例如,它有时不应返回单个用户,有时不应返回一个用户数组。但它可能返回错误代码(false)


不过,如果函数实现了不同的访问级别(这些访问级别在多个页面上共享),这也没问题。

这基本上总是回到常识上来的。您应该尽量减少重复代码,并尽量减少单个函数的复杂性。保持它们小而简单

因此,基本上每次你尝试推广这样的函数时,你都会问,重复代码的问题是否比过于复杂的函数的问题更严重

在本例中,我将在您的第二点停止,接下来您可以为最常见的任务创建一些包装(但请小心不要制作一个迷宫般的包装)


这回答了你问题的第一部分。假设您使用的是mysql\u fetch\u assoc或类似软件。在迭代结果集时,可以在循环中的一个变量中存储每个交易类型的总价的计数值

第二部分,只要您不无限重复代码,这将导致您在维护代码库时出现问题,就可以了。对于函数,始终可以测试传递给函数的变量类型,并相应地设置条件行为


查看与软件设计模式相关的工厂模式或战略模式,以获得进一步的见解。

我完全同情!希望CodeIgniter(或其他框架)的专家能在这个问题上提供一些智慧。是的,我可以,但在这种情况下,如果有10000条记录,这个循环将比使用SUM花费更长的时间。。
//you generic function
function get_thing($array)
{
$this->load->database();
$this->db->where($array);
$this->db->get('table');
}

// a nice and friendly wrapper
function get_thing_by_id($id)
{
  get_thing(array('id' => $id));
}

// this is just getting silly. don't go crazy with wrappers, only for very often used things.
// and yes the function name is purposely crazy ;)
function get_thing_verified_by_name_and_city_and_some_more($name, $city, $somethingElse)
{
  get_thing(array('name' => $name, 'city' => $city, 'somethingelse' => $somethingElse));
}