Estoy construyendo una clase para manejar Paypal IPNs como parte de un proyecto, y como ya sé que voy a necesitar usarlo de nuevo en al menos dos trabajos más, I quiero asegurarme de estructurarlo de una manera que me permita reutilizarlo sin tener que recodificar la clase; solo quiero tener que manejar los cambios en la lógica comercial.PHP Structure - Interfaces y stdClass vars
La primera parte de la pregunta es re. interfaces. Todavía no entendí su utilidad y cuándo/dónde desplegarlos. Si tengo mi archivo de clase ("class.paypal-ipn.php"), ¿implemento la interfaz en ese archivo?
Esto es lo que estoy trabajando con la medida (la lista de funciones es incompleta, pero es sólo para la ilustración):
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) {
}
}
CLASE .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.
}
}
Uso
En este proyecto:
- Exigir a los archivos de clase, tanto para la base, y la clase de lógica de negocio.
- Instatiate * paypal_ipn *
- Escribir código
En otros proyectos:
- Copiar sobre la base de clase IPN
- Editar/reescribir la clase de lógica de negocio * paypal_ipn * dentro de las limitaciones de la interfaz.
- Instantiate * * paypal_ipn
- Escribir código
Así como se puede ver que estoy literalmente a usarlo para definir grupos de funciones relacionadas y añadir comentarios. Hace que sea más fácil de leer, pero ¿para qué (si es que lo es) otro beneficio para mí? ¿Es para poder juntar el extensor y la clase base y forzar los errores si algo falta?
stdClass Pregunta
La segunda parte de la pregunta está construyendo en el aspecto de la legibilidad. Dentro de la clase hay un número cada vez mayor de variables almacenadas, algunas se establecen en el constructor, otras por otras funciones; se relacionan con cosas como mantener los vars de conexión de la base de datos (y el recurso de conexión en sí), si el código debe ejecutarse en modo de prueba, la configuración para el registro y el registro en sí, y así sucesivamente ...
había empezado a solo construirlos como de costumbre (de nuevo, a continuación incompleta & para la ilustración):
$this->dbConnection = false;
$this->dbHost = "";
$this->dbUser = "";
$this->enableLogging = true;
$this->sendLogByEmail = true;
$this->sendLogTo = "[email protected]";
Pero entonces me imaginé que la lista cada vez mayor podría hacer con un poco de estructura, por lo que lo adaptaron a:
$this->database->connection = false;
$this->database->host = "";
$this->database->user = "";
$this->logging->enable = true;
$this->logging->sendByEmail = true;
$this->logging->emailTo = "[email protected]";
lo que me da una mucho más fácil de leer la lista de variables cuando volcar toda la clase como código que & prueba.
Una vez completo, planeo escribir una extensión específica de proyecto para la clase genérica donde mantendré el SQL real para las consultas - de un proyecto a otro, el procedimiento de IPN de Paypal y la lógica no cambiarán - pero la estructura de la base de datos de cada proyecto lo hará, por lo que una extensión a la clase lo desinfectará todo en un solo formato, por lo que la clase base no tendrá que preocuparse por eso y nunca tendrá que cambiar una vez que esté escrito.
Así que en general solo un control de cordura - antes de ir demasiado lejos en este camino, ¿parece el enfoque correcto?
He editado mi pregunta original un poco para explicar cómo creo que debería estar configurando. Si esto no es correcto, ¿te importaría proporcionar una descripción de un ejemplo del mundo real? No necesito un código específico, simplemente algo con lo que me puedo relacionar :) (Si entiendo correctamente tu respuesta, las interfaces pueden ser la respuesta que he estado buscando al configurar una clase solo para manejar sesiones, y una para manejar completamente conexiones de base de datos: lógicamente, otras clases no son extensiones de éstas, pero sí requieren que estén presentes, es decir, para que un registro se pueda escribir en un DB; ¿así que las interfaces son la respuesta aquí?) – Codecraft
parece que cada una (sesiones, db) merecen sus propias clases, y al menos una interfaz cada una si otras clases dependen de ellas. Entonces, desearía inyectar los objetos derivados de estas clases en los objetos que dependan de ellos. A continuación, puede utilizar la sugerencia de tipo para asegurarse de que solo los objetos que implementan una interfaz específica puedan ser aceptados como argumentos. – dqhendricks
Podría usar un ejemplo de código para ilustrar eso, pero la bombilla en mi cabeza parpadea ... Continuaré pensando en tu respuesta y veré si puedo hacer que funcione de manera permanente, gracias :-) – Codecraft