2017-05-22 2 views
1

Ich habe ein Projekt, das ich mit struktureller Programmierung erstellt habe, die ich als ein objektorientiertes Projekt in der "bestpractices" Weise umgestalten möchte. Ich werde wahrscheinlich der einzige sein, der dieses Projekt benutzt, es ist nicht wirklich für andere gedacht. Aber ich könnte es anderen als Beispiel für Exzellenz zeigen;)PHP-Projektstruktur

Meine Fragen sind ziemlich allgemein, aber ich hoffe, das ist in Ordnung.

Ich denke darüber nach, es auf drei Arten aufgeteilt zu haben; Backend (die Hauptklasse), Frontend (Get und Posts Check, Call Class Funktionalität), Visual (mit Twig Templating). Mein Projekt verwendet eine externe Integration für die IPS-Forum-Software (die Benutzersitzungen werden dort gespeichert). Siehe unten für meine Code-Idee, wie man das strukturiert.

Meine Fragen:

  1. Ist meine allgemeine Struktur mit der Klasse ok von "Frontend" wie folgt getrennt?
  2. Ist meine Idee, das Mitglied Lookup/Behandlung von IPS außerhalb der Klasse ok, wie ich später zu anderen Element-Funktionalität im Frontend wechseln können, ohne mit Backend zu verwirren? Setzen Sie das Member-Objekt von wo aus in die Klasse, und stellen Sie sicher, dass die Klasse mindestens immer verwendet wird.
  3. Sollte ich die Mitgliedsdaten als Parameter an die Klasse (Konstrukt) senden, oder es wie jetzt beibehalten und eine öffentliche Klassenvariable vom Frontend setzen?
  4. Sollte meine Klasse Ausnahmen auf Fehler werfen oder true/false zurückgeben und eine Fehlermeldung setzen?
  5. Sollte das Frontend auch eine Klasse sein? Die Hauptklasse erweitern?
  6. Das Setzen von Fehlermeldungen in __construct ist ok, oder sollte das anderswo gemacht werden?
  7. Soll die MyProject-Klasse in mehrere Klassen aufgeteilt werden? Das aktuelle Projekt im Strukturcode ist 10000 Zeilen, die neue Klasse könnte etwa die Hälfte sein, da ich eine Menge Visual-Rendering-Sachen wegnehme. Vielleicht Klassen für MyProjectDisplayData und MyProjectCreateData und so?
  8. Wenn Antwort auf 7 ja ist, sollte ich eine Kernklasse für Nachrichten, db und allgemeine Funktionalität haben, die die anderen spezifischen Klassen "erweitert"?
  9. Gibt es noch etwas, was man anders machen könnte?

myproject_class.php:

namespace MySpace; 

use \PDO; 
use \PDOException; 
use \Exception; 

class MyProject { 

    public $projectdata; 
    public $errormessages; 
    public $ips_member; 

    function __construct() { 
     //set up vars for error messages 
     $this->errormessages["database_queryfailed"] = "Query failed"; 
     $this->errormessages["general_missingdata"] = "Missing data"; 
     $this->errormessages["handling_something"] = "Some error"; 
    } 

    public function displaySomeData ($id) { 
     if ($id == ""){ 
      throw new Exception($this->$errormessages["general_missingdata"]); 
     } 

     try{ 
      $sql = "GET SOME DATA FROM DB"; 
      //PDO execute 
     }catch (PDOException $e) { 
      throw new Exception($this->$errormessages["database_queryfailed"] . " SQL: " . $sql); 
     } 

     $this->projectdata = array(); 
     $this->projectdata["one"] = "cool"; 
     $this->projectdata["two"] = "verycool"; 

     if ($someerror){ 
      throw new Exception($this->$errormessages["handling_something"]); 
     } 
    } 

    public function createSomeData(){ 
     try{ 
      $sql = "INSERT SOME DATA IN DB"; 
      //PDO execute 
     }catch (PDOException $e) { 
      throw new Exception($this->$errormessages["database_queryfailed"] . " SQL: " . $sql); 
     } 
    } 
} 

Frontend index.php:

require_once 'vendor/autoload.php'; 
require_once 'myproject_class.php'; 
require 'forum/init.php'; 

//forum initialize 
\IPS\Session\Front::i(); 
$ips_member = \IPS\Member::loggedIn(); 

//load class 
try { 
    $myproj = new MySpace\MyProject(); 
    $myproj->ips_member = $ips_member; 
} catch (Exception $e) { 
    die($e->getMessage()); //not die, but handle in some way 
} 

//check get or post var to decide what to do 
if ($_GET["dowhat"] == "display"){ 
    try { 
     $myproj->displaySomeData($_GET["id"]); 
    } catch (Exception $e) { 
     die($e->getMessage()); //not die, but handle in some way 
    } 
} 

//twig rendering 
$loader = new Twig_Loader_Filesystem('template'); 
$twig = new Twig_Environment($loader); 
$template = $twig->load('myproject.html'); 

echo $template->render(array('projectdata' => $myproj->projectdata, 'member' => $ips_member)); 

Vielen Dank für Ihre Hilfe!

+2

diese Frage gehört besser auf https://codereview.stackexchange.com/ – MikeT

Antwort

0

Wenn Ihre Codebasis ungefähr 10k Zeilen ist, gibt es keine Möglichkeit, dass Sie in zwei oder drei Klassen stopfen können (gut, anscheinend können Sie, aber es ist eine schreckliche Idee).

Zunächst sollten Sie Ihren HTML-Code in Vorlagen extrahieren. Zweig ist eine gute Wahl und sollte Ihnen gut dienen. Der nächste Schritt wäre jedoch wahrscheinlich die Einführung der Routing-Logik, mit der Sie die Auswahl der zu rendernden Vorlage automatisieren könnten.

In Bezug auf Ihr allgemeines Verständnis der OOP, würde ich empfehlen Ihnen zu beobachten this und this Vortrag. Weil ich das Gefühl habe, das OOP-Paradigma als Ganzes nicht wirklich zu verstehen.

Und nicht missbrauchen extends Schlüsselwörter. Es gibt dieses alte Zitat in OOP: "Sie sollten Zusammensetzung über Vererbung bevorzugen". Und das fasst es gut zusammen.

In Bezug auf Fehlerbehandlung, schrieb ich darüber nur vor ein paar Tagen, so werde ich nur faul sein und Sie auf eine older post, die kurz die üblichen Ansätze abgedeckt und berührt einige der Nachteile in jedem.

Und schließlich, für den Umgang mit DB: jede Klasse, die Zugriff auf DB benötigt, sollte eine Instanz von PDO (oder MySQLi) im Konstruktor übergeben werden. Wenn Sie mehr als eine solche Klasse haben, hilft das Lesen der this post beim Teilen dieser Verbindungsinstanz.