Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Class_Dependencies_Code Injection - Fatal编程技术网

Php关注点分离&;依赖注入

Php关注点分离&;依赖注入,php,oop,class,dependencies,code-injection,Php,Oop,Class,Dependencies,Code Injection,根据这里关于stackoverflow的一些好建议,我需要更多的指导。有人告诉我,关注点的分离对于保持代码整洁和模块化非常重要,我发现这是非常重要的 我的问题是:根据我读到的关于SOC的内容,我开发了两个类。供应商类和Csv类。供应商仅从db检索关于我的不同供应商的数据。Csv类从导入的Csv文件中检索数据,以及我需要解析的所有信息,最终目标是将数据插入我的供应商表中。为了实现将csv数据插入数据库的目标,我需要使用这两个类中的方法。我是创建一个名为ImportSuppliersCsv的第三个类

根据这里关于stackoverflow的一些好建议,我需要更多的指导。有人告诉我,关注点的分离对于保持代码整洁和模块化非常重要,我发现这是非常重要的

我的问题是:根据我读到的关于SOC的内容,我开发了两个类。供应商类和Csv类。供应商仅从db检索关于我的不同供应商的数据。Csv类从导入的Csv文件中检索数据,以及我需要解析的所有信息,最终目标是将数据插入我的供应商表中。为了实现将csv数据插入数据库的目标,我需要使用这两个类中的方法。我是创建一个名为ImportSuppliersCsv的第三个类,还是将导入函数创建为Suppliers类的方法更有意义

为了节省空间,我的课程如下:

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(正如第一行代码所示,这不值得),而是抽象映射

这不是你期望的答案,但我肯定你不希望答案是你给出的,因为你把它作为一个问题提出