Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/243.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结构-接口和stdClass变量_Php_Oop - Fatal编程技术网

PHP结构-接口和stdClass变量

PHP结构-接口和stdClass变量,php,oop,Php,Oop,作为项目的一部分,我正在构建一个类来处理Paypal IPN,因为我已经知道我需要在至少两个即将到来的工作中再次使用它——我想确保我的结构能够允许我在不重新编码类的情况下重复使用它——我只想处理业务逻辑中的更改 问题的第一部分是重新讨论。接口。我还没有完全掌握它们的用途以及何时/何地部署它们。如果我有我的类文件(“class.paypal ipn.php”),我会在该文件中实现接口吗 以下是我目前正在使用的功能(函数列表不完整,但仅用于说明): CLASS.PAYPAL-IPN-BASE.PHP

作为项目的一部分,我正在构建一个类来处理Paypal IPN,因为我已经知道我需要在至少两个即将到来的工作中再次使用它——我想确保我的结构能够允许我在不重新编码类的情况下重复使用它——我只想处理业务逻辑中的更改

问题的第一部分是重新讨论。接口。我还没有完全掌握它们的用途以及何时/何地部署它们。如果我有我的类文件(“class.paypal ipn.php”),我会在该文件中实现接口吗

以下是我目前正在使用的功能(函数列表不完整,但仅用于说明):

CLASS.PAYPAL-IPN-BASE.PHP

interface ipn_interface {

    //Database Functions
    // Actual queries should come from a project-specific business logic class
    // so that this class is reusable.

    public function getDatabaseConnection();
    public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb");
    public function dbQuery($SQL);

    //Logging Functions

    public function writeLog($logMessage);
    public function dumpLogToDatabase();
    public function dumpLogToEmail();
    public function dumpLogToFile();

    //Business Logic Functions

    private function getTransaction($transactionID);

    //Misc Functions

    public function terminate();
}

class paypal_ipn_base {

    //nothing to do with business logic here.

    public function getDatabaseConnection() {
    }

    public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb") {
    }

    public function dbQuery($SQL) {
    }

}
final class paypal_ipn extends paypal_ipn_base implements ipn_interface {

    //business logic specific to each project here

    private function getTransaction($transactionID) {

       $SQL = "SELECT stuff FROM table";
       $QRY = this->dbQuery($SQL);

       //turn the specific project related stuff into something generic

       return $generic_stuff; //to be handled by the base class again.

    }

}
CLASS.PAYPAL-IPN.PHP

interface ipn_interface {

    //Database Functions
    // Actual queries should come from a project-specific business logic class
    // so that this class is reusable.

    public function getDatabaseConnection();
    public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb");
    public function dbQuery($SQL);

    //Logging Functions

    public function writeLog($logMessage);
    public function dumpLogToDatabase();
    public function dumpLogToEmail();
    public function dumpLogToFile();

    //Business Logic Functions

    private function getTransaction($transactionID);

    //Misc Functions

    public function terminate();
}

class paypal_ipn_base {

    //nothing to do with business logic here.

    public function getDatabaseConnection() {
    }

    public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb") {
    }

    public function dbQuery($SQL) {
    }

}
final class paypal_ipn extends paypal_ipn_base implements ipn_interface {

    //business logic specific to each project here

    private function getTransaction($transactionID) {

       $SQL = "SELECT stuff FROM table";
       $QRY = this->dbQuery($SQL);

       //turn the specific project related stuff into something generic

       return $generic_stuff; //to be handled by the base class again.

    }

}
用法

在本项目中:

  • 需要基本类和业务逻辑类的类文件
  • Instatitate*paypal_ipn*
  • 编写代码
在其他项目中:

  • 在基本IPN类上复制
  • 在接口的约束范围内编辑/重写业务逻辑类*paypal_ipn*
  • 实例化*paypal_ipn*
  • 编写代码
正如你所看到的,我只是用它来定义相关函数组和添加注释。它使它更易于阅读,但它对我有什么(如果有的话)其他好处?是不是这样我可以将扩展程序和基类拉到一起,并在缺少某些内容时强制执行错误

stdClass问题

问题的第二部分是建立在可读性方面。在类本身中,存储变量的数量不断增加,有些是在构造函数中设置的,有些是由其他函数设置的-它们与保存数据库连接变量(以及连接资源本身)、代码是否应在测试模式下运行、日志和日志本身的设置等相关

我已经开始像往常一样构建它们(同样,下面是不完整的&用于说明):

但后来我发现,不断增长的列表可能需要一些结构,因此我将其调整为:

$this->database->connection = false;
$this->database->host = "";
$this->database->user = "";
$this->logging->enable = true;
$this->logging->sendByEmail = true;
$this->logging->emailTo = "user@domain.com";
当我在编码和测试时转储整个类时,这使我更容易阅读变量列表

完成后,我计划为泛型类编写一个特定于项目的扩展,在这里我将保留用于查询的实际SQL-从一个项目到另一个项目,Paypal的IPN过程和逻辑不会改变-但每个项目的数据库结构都会改变,因此对该类的扩展将把所有内容重新整理成单一格式,因此基类不必担心它,并且在编写之后永远不需要更改


总之,只是一个理智的检查-在我走得太远之前,这似乎是正确的方法吗?

如果您使用的是类自动加载器,我强烈建议,您不希望将接口和类保留在同一个文件中,这样接口就可以自动加载,而无需首先加载实现它的这个类

有关自动加载的详细信息:

另一件您可能要考虑的是,给定的类可能包含多个接口,并且多个类可以实现相同的接口。 接口主要用于各种设计模式、强制规则以及将类与任何依赖类解耦。当您将一个类与其依赖项解耦时,以后修改代码就容易多了

例如,假设您有一个类a,它接受另一个类B作为参数,这个类分布在您的代码中。您希望强制只接受具有特定方法子集的类作为此参数,但不希望将输入限制为一个具体类及其Decentant。将来,您可能会编写一个完全不同的类,它不扩展类B,但可以用作类A的输入。这就是为什么要使用接口。它是类之间的可重用契约

有些人会争辩说,由于PHP是一种动态语言,接口是一种不必要的复杂情况,可以使用duck类型来代替。然而,我发现在大型多用户代码库中,接口可以节省大量时间,让您更多地了解一个类如何使用另一个类,而无需深入研究代码

如果您发现自己有一大堆必须在对象或函数之间传递的变量,那么这些变量最终往往会得到属于它们自己的类,但每种情况都是不同的

--依赖注入示例--

现在您可以看到,您可以编写另一个类来实现foo方法(以及AInterface),并在类B中使用它


作为一个现实世界的例子(经常使用),假设您有一个数据库类,它具有与数据库交互的特定方法(getRecord、deleteRecord)。现在让我们说,稍后您会找到切换数据库rdbms的理由。现在,您需要使用完全不同的SQL语句来实现相同的目标,但是由于您使用了一个接口来暗示类型,因此您可以简单地创建一个实现该接口的新类,但在与不同的rdbms交互时,以完全不同的方式实现这些相同的方法。在创建这个新类时,您将确切地知道需要为这个新类编写哪些方法,以适应需要使用数据库对象的相同对象。如果使用用于创建对象并将其注入其他对象的容器类,则无需更改太多应用程序代码即可切换数据库类,从而切换数据库rdbms。您甚至可以使用factory类,它可以将您的更改限制为一行代码来进行这种类型的更改(理论上)。

我对我的原始问题进行了一些编辑,以详细说明我认为应该如何设置。如果这不对,