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