Php关注点分离&;依赖注入
根据这里关于stackoverflow的一些好建议,我需要更多的指导。有人告诉我,关注点的分离对于保持代码整洁和模块化非常重要,我发现这是非常重要的 我的问题是:根据我读到的关于SOC的内容,我开发了两个类。供应商类和Csv类。供应商仅从db检索关于我的不同供应商的数据。Csv类从导入的Csv文件中检索数据,以及我需要解析的所有信息,最终目标是将数据插入我的供应商表中。为了实现将csv数据插入数据库的目标,我需要使用这两个类中的方法。我是创建一个名为ImportSuppliersCsv的第三个类,还是将导入函数创建为Suppliers类的方法更有意义 为了节省空间,我的课程如下:Php关注点分离&;依赖注入,php,oop,class,dependencies,code-injection,Php,Oop,Class,Dependencies,Code Injection,根据这里关于stackoverflow的一些好建议,我需要更多的指导。有人告诉我,关注点的分离对于保持代码整洁和模块化非常重要,我发现这是非常重要的 我的问题是:根据我读到的关于SOC的内容,我开发了两个类。供应商类和Csv类。供应商仅从db检索关于我的不同供应商的数据。Csv类从导入的Csv文件中检索数据,以及我需要解析的所有信息,最终目标是将数据插入我的供应商表中。为了实现将csv数据插入数据库的目标,我需要使用这两个类中的方法。我是创建一个名为ImportSuppliersCsv的第三个类
class Suppliers
{
public $db;
public $inv;
public $table;
public function __construct (PDO $db)
{
$this->db = $db;
$this->inv = 'lightsnh_inventory';
$this->table = 'suppliers';
}
public function getSuppliers()
{
$sql = 'SELECT * FROM `'.$this->inv.'`.`'.$this->table.'`';
$statement = $this->db->query($sql);
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
public function getActiveSuppliers()
{
$suppliers = $this->getSuppliers();
$active = array();
foreach($suppliers as $supplier) {
if($supplier['exclude'] == 0)
$active[] = $supplier;
}
return $active;
}
public function getDistributors()
{
$suppliers = $this->getSuppliers();
$distributors = array();
foreach($suppliers as $supplier) {
if($supplier['type'] == 1)
$distributors[] = $supplier;
}
return $distributors;
}
class Csv
{
public $form;
public function __construct($form_name)
{
$this->form = $form_name;
}
public function getFile()
{
if(isset($_POST[$this->form.'-upload-submit'])) {
return $_FILES[$this->form.'-file'];
}
}
public function getName()
{
$file = $this->getFile();
return $file['name'];
}
public function getExtension()
{
return end(explode('.',$this->getName()));
}
public function getType()
{
$file = $this->getFile();
return $file['type'];
} etc.....
从CSV插入新供应商不需要新类。您只需添加一个新方法并向其传递Csv对象即可。这样,所有与供应商相关的活动都将封装在一个类中
或者,如果您计划使用CSV以外的其他信息源,您可以让suppliers方法接受解析的信息,而不是CSV对象。两者都不接受。OOP/SoC/DI等不是目的,而是手段。SoC的目的是模块化架构,使维护更容易,尽管分离关注点总是通过模糊问题来扩大问题。 我发现用PHP设计一个好的设计最好的方法是先让它工作,然后重构。你也可以先在想象中这样做,以节省一些时间。以你认为最好的方式组织它。毕竟,这个想法是为了让维护代码的人能够轻松找到自己的方法,因为他们是这样组织代码的。简言之,谨防过度工程 在您的示例中,如果只在一个地方使用某个类,我就不会费心创建该类。例如:通常一个可以将CSV记录导入数据库的应用程序也有一个表单来编辑这些行,因此我假设Suppliers类中有一个“save”函数,因为它已经抽象了查询(很糟糕-没有缓存,没有WHERE子句,SQL注入等)。现在导入CSV文件的问题是以有序方式将数据呈现给此“保存”功能的问题 现在,将CSV文件导入数据库的基本代码本身如下所示:
$data = array_map( 'str_getcsv', explode("\n", file_get_contents( $filename ) ) );
$columns = array_shift( $data );
$sth = $db->prepareStatement( "INSERT INTO suppliers( " . implode( ',', $columns )
. ") VALUES ( " . substr(str_repeat(",?",count($columns)),1) . ")"
);
foreach ( $data as $line )
$sth->execute( $line );
通常情况下,它并不是那么理想——但这本质上是核心功能。它只有4条语句,四个关注点:解析CSV、映射字段、更新数据库以及效率/一致性(使用准备好的语句)
OOP仍然依赖于函数式编程——按功能进行组织。上面的内容仍然是一个脚本,由cron作业或web页面调用。它可以放在“导入csv”函数中,供这些任务重复使用。但是把它放在一个类中是过分的。
SoC还利用正面或接口。函数正是这样,如果需要,可以很容易地分组到类中。您只需要一个函数import\u csv($filename,$profile)。$profile将指示表(或多个表)、列映射等。通过将它们分开,您可以创建一个通用的CSV到DB映射编辑器,或者至少支持仅通过更改配置将任何CSV文件导入到任何表中。如果你把所有的东西都做成类,那么你最终会为你要导入的每个CSV文件编写一个类。当然,您可以创建一个CSVImporter类,但这只有在还有其他导入器类的情况下才有用——毕竟,创建一个类就是对功能进行抽象,而您不能仅从一个示例进行抽象
相反,想象一个通用导入器,而不考虑数据。关注功能,因为这就是代码。这是一种更好的方法,因为您的代码将不依赖于数据库结构——您已经抽象了它(通过使用公共接口扩展表基类,以便可以使用$Table->save())。您不会抽象CSV(正如第一行代码所示,这不值得),而是抽象映射
这不是你期望的答案,但我肯定你不希望答案是你给出的,因为你把它作为一个问题提出