PHP structure - interfaces and stdClass vars

I am creating a class for processing IPP Paypal as part of the project, and since I already know that I will need to use it again in at least the next two upcoming assignments - I want to make sure that I structure it in such a way that allows me reuse it without having to recode the class - I just want to handle the changes in business logic.

The first part of the question is re. interfaces. I did not quite understand their usefulness and when / where to deploy them. If I have a class file ("class.paypal-ipn.php"), should I implement the interface in this file?

Here is what I'm working so far (the list of functions is not complete, but its just to illustrate):

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) { } } 

CLASS.PAYPAL-IPN.PHP

 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. } } 

Using

In this project:

  • Require class files for both the base and business logical classes.
  • Instatiate * paypal_ipn *
  • Enter code

In other projects:

  • Copy over IPN base class
  • Change / rewrite the business logic class * paypal_ipn * within the limits of the interface.
  • Instant * paypal_ipn *
  • Enter code

So, as you can see, I literally just use it to define groups of related functions and add comments. This makes reading easier, but what (if there is) another advantage for me is that I can combine the expander and the base class and cause errors if something is missing?

stdClass Question

The second part of the question is based on the aspect of readability. Inside the class itself, the number of stored variables is constantly growing, some of them are set in the constructor, some by other functions - they relate to such things as storing connection shafts to the database (and the connection resource itself), should the code be executed in test mode, settings logging and the journal itself, and so on ...

I started just creating them as usual (again, below incomplete and for illustration):

 $this->dbConnection = false; $this->dbHost = ""; $this->dbUser = ""; $this->enableLogging = true; $this->sendLogByEmail = true; $this->sendLogTo = " user@domain.com "; 

But then I thought that a growing list might work with some kind of structure, so I adapted it for:

 $this->database->connection = false; $this->database->host = ""; $this->database->user = ""; $this->logging->enable = true; $this->logging->sendByEmail = true; $this->logging->emailTo = " user@domain.com "; 

Which makes it a lot easier for me to read the variable list when I unload the whole class due to code and test.

As soon as I finish, I plan to write a project extension for the general class, where I will store the actual SQL for queries - as from one project to another, the IPv procedure and Paypal logic will not change - but each project database structure will be, so the class extension will deactivate everything back to one format, so the base class will not have to worry about it and will never have to change it after writing it.

So, everything is just a sanity check - before I went too far along this road, does this seem like the right approach?

+6
source share
1 answer

If you use the class autoloader, which I highly recommend, you wonโ€™t want to save the interface and the class in one file so that the interface can automatically load without first loading this one class that implements it.

For more information about startup: http://php.net/manual/en/language.oop5.autoload.php

another thing you might want to consider is that a given class can implement multiple interfaces, and multiple classes can implement the same interface.

Interfaces

mainly used for various design patterns, to enforce rules, and to decouple a class from any dependent classes. when you separate a class from its dependencies, it greatly simplifies code changes later.

for example, let's say you have a class A that takes in another class B as an argument, and that class extends throughout your code. you want to ensure that only a class with a specific subset of methods can be accepted as this argument, but you do not want to limit the input to one particular class and its decanders. in the future, you can write a completely different class that does not extend class B, but will be useful as input for class A. That's why you should use the interface. it is a reusable contract between classes.

some would argue that since PHP is a dynamic language, interfaces are an unnecessary complication, and duck typing can be used instead. However, I am in large multi-user codebases that interfaces can save a lot of time, letting you learn more about how one class uses the other, without the need for in-depth code study.

if you find that you have a large list of variables that you must pass between objects or functions, they often deserve their own class, but each case is different.

- an example of dependency injection -

 class A implements AInterface { public function foo($some_var) {} } interface AInterface { public function foo($some_var); } class B { protected $localProperty; // inject into the constructer. usually used if the object is saved in a property and used throughout the class public function __construct(AInterface $a_object) { $this->localProperty = $a_object; } // inject into a method. usually used if the object is only needed for this particular method public function someMethod(AInterface $a_object) { $a_object->foo('some_var'); } } 

now you can see that you can write another class that will implement the foo (and AInterface) method and use it in class B.

as an example of the real world (often used), let's say you have a database class with certain methods that interact with the database (getRecord, deleteRecord). now let's say later when you discover the reason for switching the rdbms database. now you need to use completely different SQL statements to achieve the same goals, but since you used an interface to hint at the type, you can just create a new class that will implement this interface, but introduces the same methods in completely different ways. as it interacts with different rdbms. when you create this new class, you will know exactly what methods must be written for this new class to fit into the same objects that the database object should use. if you use the container class that is used to create the objects and paste them into other objects, you will not need to change too much application code to switch the database classes and therefore switch the rdbms database. you could even use a factory class that could restrict your changes to a single line of code to make this type of change (theoretically).

+5
source

Source: https://habr.com/ru/post/889637/


All Articles