• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Mysql queries im contruct

Jeremygolf

Mitglied
Hallo zusammen,

habe eine Klasse mit vielen funktionen, die Statistiken auswerten aus daten in einer datenbank. Nun benutze ich dieselben queries in verschiedenen Funktionen. Diese queries sind auch fast alle gleich bis auf die Tabelle. Nun wie könnte ich mein problem lösen um meinen unstrukturierten Code zu organisieren?

Danke
 
Werbung:
Schau dir mal Design Patterns und das Single Responsibility Prinzip an. Du könntest die auch einfach einen DatabaseHelper basteln.

Sowas hatte ich mir damals mal gebastelt, allerdings ist das schon etwas älter und nicht ganz ausgebaut. Soll auch nur als Beispiel dienen, ist nicht ganz so schön und noch mit noobigen Kenntnissen geschrieben.

Database
PHP:
<?php

class Database {

    /**
     * @access private
     * @var \PDO $pdo    PDO-Verbindung
     */
    private $pdo;

    /**
     * @access public
     * @var string $query  Der eigentliche SQL Query
     */
    public $query;

    /**
     * @access public
     */
    public function __construct() {
        $this->pdo = ZenFactory::getPdo();
    }

    /**
     * Gibt das DatabaseQuery Objekt zurück
     * @access public
     * @return object DatabaseQuery
     */
    public function getQuery() {
        return new DatabaseQuery();
    }

    /**
     * Baut den SQL Query zusammen
     * @access public
     * @param  object $query
     * @return void
     */
    public function setQuery($query) {
        if(is_object($query)) {
            if(isset($query->select) && !empty($query->select)) {
                $this->query .= 'SELECT ' . $query->select;
            }

            if(isset($query->from) && !empty($query->from)) {
                $this->query .= ' FROM ' . $query->from;
            }

            if(isset($query->where) && !empty($query->where)) {
                foreach($query->where as $key => $stmt) {
                    if($key === 0) {
                        $this->query .= ' WHERE ' . $stmt;
                    } else {
                        $this->query .= ' AND ' . $stmt;
                    }
                }
            }

            if(isset($query->orderby) && !empty($query->orderby)) {
                $this->query .= $query->orderby;
            }

            if(isset($query->groupby) && !empty($query->groupby)) {
                $this->query .= $query->groupby;
            }
        }
   }

   public function loadAssoc() {
       try {
           $stmnt = $this->pdo->query($this->query);
           $result = $stmnt->fetch(PDO::FETCH_ASSOC);
           return $result;
       } catch(\PDOException $e) {
           die("Error: " . $e->getMessage());
       }
   }

   public function loadAssocList() {
       try {
           $stmnt = $this->pdo->query($this->query);
           $result = $stmnt->fetchAll(PDO::FETCH_ASSOC);
           return $result;
       } catch(\PDOException $e) {
           die("Error: " . $e->getMessage());
       }
   }

   public function loadObject() {
       try {
           $stmnt = $this->pdo->query($this->query);
           $result = $stmnt->fetch(PDO::FETCH_OBJ);
           return $result;
       } catch(\PDOException $e) {
           die("Error: " . $e->getMessage());
       }
   }

   public function loadObjectList() {
       try {
           $stmnt = $this->pdo->query($this->query);
           $result = $stmnt->fetchAll(PDO::FETCH_OBJ);
           return $result;
       } catch(\PDOException $e) {
           die("Error: " . $e->getMessage());
       }
   }

   public function loadResult() {
       try {
           $stmnt = $this->pdo->query($this->query);
           $result = $stmnt->fetch(PDO::FETCH_COLUMN);
           return $result;
       } catch(\PDOException $e) {
           die("Error: " . $e->getMessage());
       }
   }

   public function execute() {

   }

   public function numRows() {

   }
}

?>

DatabaseQuery

PHP:
<?php

class DatabaseQuery {

    /**
     * @access public
     * @var string $select    SELECT Statement
     */
    public $select;

    /**
     * @access public
     * @var string $update     UPDATE Statement
     */
    public $update;

    /**
     * @access public
     * @var string $delete     DELETE Statement
     */
    public $delete;

    /**
     * @access public
     * @var string $from      FROM Statement
     */
    public $from;

    /**
     * @access public
     * @var string $where     WHERE Statement
     */
    public $where;

    /**
     * @access public
     * @var string $orderby     ORDER BY Statement
     */
    public $orderby;

    /**
     * @access public
     * @var string $groupby      GROUP BY Statement
     */
    public $groupby;

    /**
     * @access public
     * @var string $having      HAVING Statement
     */
    public $having;

    /**
     * @access public
     * @var string $join       JOIN Statement
     */
    public $join;

    /**
     * Erstellt das SELECT Statement für den SQL Query
     * @access public
     * @param  array|string $columns
     * @return $this
     */
    public function select($columns) {
        if(isset($columns) && !empty($columns)) {
            if(is_array($columns)) {
                $this->select .= implode(", ", $columns);
            } else if(is_string($columns)) {
                $this->select .= $columns;
            }
        }

        return $this;
    }

    /**
     * Erstellt das UPDATE Statement für den SQL Query
     * @access public
     * @param  array|string $columns
     * @return $this
     */
    public function update($columns) {
        if(isset($columns) && !empty($columns)) {
            if(is_array($columns)) {
                $this->update .= implode(", ", $columns);
            } else if(is_string($columns)) {
                $this->update .= $columns;
            }
        }

        return $this;
    }

    /**
     * Erstellt das DELETE Statement für den SQL Query
     * @access public
     * @param  array|string $columns
     * @return $this
     */
    public function delete($columns) {
        if(isset($columns) && !empty($columns)) {
            if(is_array($columns)) {
                $this->delete .= implode(", ", $columns);
            } else if(is_string($columns)) {
                $this->delete .= $columns;
            }
        }

        return $this;
    }

    /**
     * Erstellt das FROM Statement für den SQL Query
     * @access public
     * @param  string $table
     * @return $this
     */
    public function from($table) {
        if(isset($table) && !empty($table)) {
            if((is_string($table))) {
                $this->from .= $table;
            }
        }

        return $this;
    }

    /**
     * Erstellt das WHERE Statement für den SQL Query
     * @access public
     * @param array $condition
     * @param null $operator
     * @return $this
     */
    public function where($condition = [], $operator = null) {
        if(is_array($condition)) {
            if(isset($condition) && !empty($condition)) {
                if(isset($operator) && !empty($operator)) {
                    foreach($condition as $key => $value) {
                        if(is_string($value)) {
                            if(is_numeric($value)) {
                                $this->where[] .= $key . $operator . (int) $value;
                            } else {
                                $this->where[] .= $key . $operator . "'$value'";
                            }
                        }
                    }
                } else {
                    foreach($condition as $key => $value) {
                        if(is_string($value)) {
                            if(is_numeric($value)) {
                                $this->where[] = $key . '=' . (int) $value;
                            } else {
                                $this->where[] = $key . '=' . "'$value'";
                            }
                        } else if(is_int($value)){
                            $this->where[] = $key . '=' . $value;
                        }
                    }
                }
            }
        }

        return $this;
    }


    /**
     * Erstellt das GROUP BY Statement für den SQL Query
     * @access public
     * @param string $column
     * @param string $option
     * @return void
     */
    public function groupby($column, $option = 'ASC') {
        if(isset($column) && !empty($column)) {
            if(isset($option) && !empty($option)) {
                $this->groupby = ' GROUP BY ' . $column . $option;
            }
        }
    }

    /**
     * Erstellt das ORDER BY Statement für den SQL Query
     * @access public
     * @param string $column
     * @param string $option
     * @return void
     */
    public function orderby($column, $option = 'ASC') {
        if(isset($column) && !empty($column)) {
            if(isset($option) && !empty($option)) {
                $this->orderby = ' ORDER BY ' . $column . $option;
            }
        }
    }
}

?>
 
Schau dir mal Design Patterns und das Single Responsibility Prinzip an. Du könntest die auch einfach einen DatabaseHelper basteln.

Sowas hatte ich mir damals mal gebastelt, allerdings ist das schon etwas älter und nicht ganz ausgebaut. Soll auch nur als Beispiel dienen, ist nicht ganz so schön und noch mit noobigen Kenntnissen geschrieben.

Also bis jetzt hatte ich circa 14 Funktionen, bei jeder funktion musste ich aber noch userid, anfangsdatum, enddatum usw mitgeben. Diese Funktionen waren auch static. Nun habe ich private properties erstellt mit userid, datum usw, und führe alle queries (ca. 10) im contruct aus. Nach dem instanzieren der klasse kann ich also ganz einfach die funktion abfragen ohne diese variablen mitzugeben. Ist das ein guter ansatz?

Hier meine klasse + eine Funktion:

Code:
<?php namespace helpers;
   
use \PDO as PDO;

/*
 * Statistic Class
 *
 * @author Jeremy
 * @version 2.0
 * @date June 27, 2014
 */
class Statistic{
   
    static $db;
   
    public $userid;
    public $roundid;
    public $start;
    public $end;
   
    private $_score = array();
    private $_fir = array();
    private $_gir = array();
   
    public function __construct($userid, $roundid = null, $start = "2000-01-01", $end = "2030-01-01"){
        $this->userid = $userid;
        $this->roundid = $roundid;
        $this->start = $start;
        $this->end = $end;
           
        $this->queryTables();   
    }
   
    static function init(){
        self::$db = \helpers\database::get();
    }
   
   
    private function queryTables(){       
        $this->_score = self::$db->selectAssoc("SELECT score.* FROM score INNER JOIN rounds ON score.roundid = rounds.roundid WHERE rounds.userid = $this->userid AND rounds.date BETWEEN '$this->start' AND '$this->end'");
       
        $this->_fir = self::$db->selectAssoc("SELECT fairwayhit.* FROM fairwayhit INNER JOIN rounds ON fairwayhit.roundid = rounds.roundid WHERE rounds.userid = $this->userid AND rounds.date BETWEEN '$this->start' AND '$this->end'");
       
        $this->_gir = self::$db->selectAssoc("SELECT greenhit.* FROM greenhit INNER JOIN rounds ON greenhit.roundid = rounds.roundid WHERE rounds.userid = $this->userid AND rounds.date BETWEEN '$this->start' AND '$this->end'");
       
       
    }

    public function getScore(){
       
        $sum = 0;
        $count = 0;
        //Deletes roundid from array
        foreach($this->_score as $round){
            unset($round["roundid"]);
            if($round["hole1"] != 0){
                $sum += array_sum($round);
                $count++;
            }
        }
        if($count > 0){
            return $sum / $count;
        } else {
            return 0;
        }
       
    }
 
Werbung:
Also erstmal ein paar Tipps. Klassen-, Variablen- und Funktionsnamen am besten in der CamelCase Notation schreiben.

Alte Schreibweise:
PHP:
$array = array("foo" => "bar","bar" => "foo",);

Seit PHP 5.4:
PHP:
$array = ["foo" => "bar","bar" => "foo",];


Wenn du hier schon ein Datum mitgibst, dann am besten als DateTimeObject und nicht als String.
PHP:
public function __construct($userid, $roundid = null, $start = "2000-01-01", $end = "2030-01-01"){
        $this->userid = $userid;
        $this->roundid = $roundid;
        $this->start = $start;
        $this->end = $end;
     
        $this->queryTables();
    }


Ein Statistik Objekt könnte bspw. so aussehn, allerdings kenn ich nicht den genauen Hintergrund.
PHP:
class Statistic {

private $userId;
private $roundId;
private $start;
private $end;

public function __construct() {
      // Verbindung aufbauen
}

public function setUserId($userId) {
   $this->userId = $userId;
}

public function getUserId() {
    return $userId;
}

public function setRoundId($roundId) {
    $this->roundId= $roundId;
}

public function getRoundId() {
    return $roundId;
}

public function setStart(\DateTime $start) {
    $this->start= $start;
}

public function setEnd(\DateTime $end) {
    $this->end = $end;
}

public function getScore() {
   $userId = $this->getUserId();
   $roundId = $this->getRoundId();

  // .. weiter verarbeiten
}

public function __destruct() {
   // Verbindung schließen
}

}


Und wenn du 14 Funktionen außgenommen Getter- und Setter in deiner Klasse hast, dann machst du etwas falsch.

In der objektorientierten Programmierung sagt das SRP aus, dass jede Klasse nur eine fest definierte Aufgabe zu erfüllen hat. In einer Klasse sollten lediglich Funktionen vorhanden sein, die direkt zur Erfüllung dieser Aufgabe beitragen.
 
Zuletzt bearbeitet:
Also erstmal ein paar Tipps. Klassen-, Variablen- und Funktionsnamen am besten in der CamelCase Notation schreiben.

Alte Schreibweise:
PHP:
$array = array("foo" => "bar","bar" => "foo",);

Seit PHP 5.4:
PHP:
$array = ["foo" => "bar","bar" => "foo",];


Wenn du hier schon ein Datum mitgibst, dann am besten als DateTimeObject und nicht als String.
PHP:
public function __construct($userid, $roundid = null, $start = "2000-01-01", $end = "2030-01-01"){
        $this->userid = $userid;
        $this->roundid = $roundid;
        $this->start = $start;
        $this->end = $end;
    
        $this->queryTables();
    }


Ein Statistik Objekt könnte bspw. so aussehn, allerdings kenn ich nicht den genauen Hintergrund.
PHP:
class Statistic {

private $userId;
private $roundId;
private $start;
private $end;

public function __construct() {
      // Verbindung aufbauen
}

public function setUserId($userId) {
   $this->userId = $userId;
}

public function getUserId() {
    return $userId;
}

public function setRoundId($roundId) {
    $this->roundId= $roundId;
}

public function getRoundId() {
    return $roundId;
}

public function setStart(\DateTime $start) {
    $this->start= $start;
}

public function setEnd(\DateTime $end) {
    $this->end = $end;
}

public function getScore() {
   $userId = $this->getUserId();
   $roundId = $this->getRoundId();

  // .. weiter verarbeiten
}

public function __destruct() {
   // Verbindung schließen
}

}


Und wenn du 14 Funktionen außgenommen Getter- und Setter in deiner Klasse hast, dann machst du etwas falsch.
Also, es geht um golfstatistiken. Jede Funktion rechnet eine statistik aus und gibt sie zurück. Es könnten auch 50 funktionen sein. Was spielt das für eine rolle?
Kann mir aber jemand sagen ob mein code oben richtig ist?
 
Also, es geht um golfstatistiken. Jede Funktion rechnet eine statistik aus und gibt sie zurück. Es könnten auch 50 funktionen sein. Was spielt das für eine rolle?
Kann mir aber jemand sagen ob mein code oben richtig ist?
Der Aufbau ist definitiv nicht korrekt, habe die zählige Quellen genannt wie du das ganze aufbauen kannst. Es spielt eine Rolle wieviele Funktionen eine Klasse hat, lese dir das SRP durch!
 
Werbung:
Der Aufbau ist definitiv nicht korrekt, habe die zählige Quellen genannt wie du das ganze aufbauen kannst. Es spielt eine Rolle wieviele Funktionen eine Klasse hat, lese dir das SRP durch!
Es gibt aber keine andere möglichkeit. Wie soll ich 14 verschiedene Statistiken auslesen? Am anfang war es nur eine helper klasse mit den static funktionen, die ich aufrufen konnte und es funktionierte gut. Jedoch war der Code ein wenig unübersichtlich.

So lese ich dan die statistiken aus:

PHP:
$stats = new \helpers\statistic(Session::get('userid'));
        $data['score'] = $stats->getScore();
        $data['gir'] = $stats->getGir();
        $data['fir'] = $stats->getFir();
        $data['putts'] = $stats->getPutts();
        $data['puttsGir'] = $stats->getPuttsGir();
 
Es gibt aber keine andere möglichkeit. Wie soll ich 14 verschiedene Statistiken auslesen? Am anfang war es nur eine helper klasse mit den static funktionen, die ich aufrufen konnte und es funktionierte gut. Jedoch war der Code ein wenig unübersichtlich.

So lese ich dan die statistiken aus:

PHP:
$stats = new \helpers\statistic(Session::get('userid'));
        $data['score'] = $stats->getScore();
        $data['gir'] = $stats->getGir();
        $data['fir'] = $stats->getFir();
        $data['putts'] = $stats->getPutts();
        $data['puttsGir'] = $stats->getPuttsGir();

Wenn du dir die Design Pattern angeschaut hättest, wüsstest du eine Möglichkeit. Du schöpfst die Möglichkeiten der OOP noch nicht mal ansatzweise aus. Versteh mich jetzt nicht falsch, ich habe am Anfang auch Quellcode geschrieben der aussah wie ein Urwald. Allerdings möchte ich dir nur weitergeben wie man es richtig macht.

Wenn du dir die Zeit nimmst, das oben genannte durch zulesen, kommt dir vllt ein Ansatz in den Kopf. Btw. ist "PHP - The Right Way" ein guter Rat, wie man es richtig macht.
 
Wenn du dir die Design Pattern angeschaut hättest, wüsstest du eine Möglichkeit. Du schöpfst die Möglichkeiten der OOP noch nicht mal ansatzweise aus. Versteh mich jetzt nicht falsch, ich habe am Anfang auch Quellcode geschrieben der aussah wie ein Urwald. Allerdings möchte ich dir nur weitergeben wie man es richtig macht.

Wenn du dir die Zeit nimmst, das oben genannte durch zulesen, kommt dir vllt ein Ansatz in den Kopf. Btw. ist "PHP - The Right Way" ein guter Rat, wie man es richtig macht.
Ich habe es bereits durchgelesen. Jedoch verstehst du nicht ganz was ich machen muss.

P.S ich arbeite mit einem MVC falls das hilft
 
Werbung:
Ich glaube kaum das du es dir durchgelesen hast und ich verstehe auch was du erreichen willst ;) (Siehe oben) - btw. wenn du zu Stur bist meinen Rat anzunehmen, bin ich an der Stelle raus.

@bodo92 Bitte versuch es Ihm zu erklären, wenn er auf mich nicht hört..
 
Ich glaube kaum das du es dir durchgelesen hast ;) - btw. wenn du zu Stur bist meinen Rat anzunehmen, bin ich an der Stelle raus.
Ich bin nicht stur :D aber ich weis nicht genau wo anfangen. Du hast mir bis jetzt nur was zum lesen gegben und noch keinen guten ansatz zum umsetzen.

Also:

ich habe eine Datebank mit ca. 12 tabellen. Jede umfast einen bereich für jedes golf loch also hat jede tabelle 18 einträge.
Nun möchte ich reports generieren, wo ich diese turniere anhand von datum usw. sortieren und filtern kann.
Ich habe bis jetz ca. 14 statistiken die ich mit diesen daten auswerte.
Wo mache ich am besten diese Auswertung? Soll ich überhaupt ein objekt erstellen?
Ich habe auch einige andere seiten, die nicht alle statistiken brauchen sondern nur 5-7 von diesen 14.
Ist es am einfachsten einfach static methoden zu benutzen?
 
Ich bin nicht stur :D aber ich weis nicht genau wo anfangen. Du hast mir bis jetzt nur was zum lesen gegben und noch keinen guten ansatz zum umsetzen.

Also:

ich habe eine Datebank mit ca. 12 tabellen. Jede umfast einen bereich für jedes golf loch also hat jede tabelle 18 einträge.
Nun möchte ich reports generieren, wo ich diese turniere anhand von datum usw. sortieren und filtern kann.
Ich habe bis jetz ca. 14 statistiken die ich mit diesen daten auswerte.
Wo mache ich am besten diese Auswertung? Soll ich überhaupt ein objekt erstellen?
Ich habe auch einige andere seiten, die nicht alle statistiken brauchen sondern nur 5-7 von diesen 14.
Ist es am einfachsten einfach static methoden zu benutzen?
Ich fange gleich an zu weinen...

Ja ich habe dir was zum lesen gegeben und sogar Design Pattern wie man es am besten umsetzt. Du musst eine der Pattern doch nur auf dein Beispiel anwenden.

Klar mag es am Anfang schwer sein sich richtig in die OOP einzuarbeiten und alles zu verstehen aber dann hat macht man es wenigstens richtig.

Die Frage ob du ein Objekt erstellen sollst, ist lustig. Schließlich willst du doch objektorientiert arbeiten?

So du hast 14 Statistiken, soweit so gut. Da du Funktionen hast die in jeder Statistik wahrscheinlich gleich oder ähnlich sind, bietet sich eine Abstrakte Klasse an.

Ich kenne deine Ordnerstruktur nicht, weder ob du die MVC-Architektur (richtig) benutzt und und und.
 
Werbung:
Ich fange gleich an zu weinen...

Ja ich habe dir was zum lesen gegeben und sogar Design Pattern wie man es am besten umsetzt. Du musst eine der Pattern doch nur auf dein Beispiel anwenden.

Klar mag es am Anfang schwer sein sich richtig in die OOP einzuarbeiten und alles zu verstehen aber dann hat macht man es wenigstens richtig.

Die Frage ob du ein Objekt erstellen sollst, ist lustig. Schließlich willst du doch objektorientiert arbeiten?

So du hast 14 Statistiken, soweit so gut. Da du Funktionen hast die in jeder Statistik wahrscheinlich gleich oder ähnlich sind, bietet sich eine Abstrakte Klasse an.

Ich kenne deine Ordnerstruktur nicht, weder ob du die MVC-Architektur (richtig) benutzt und und und.
Die Statistiken sidn überhaupt nicht gleich. Es handlet sich nur um berechnungen. Welche überall anders sind.
 
Die Statistiken sidn überhaupt nicht gleich. Es handlet sich nur um berechnungen. Welche überall anders sind.
"Gleich oder Ähnlich" - Fakt ist du hast in jeder eine Berechnung, das ist doch schon eine Gemeinsamkeit.

Wahrscheinlich bringt es auch garnichts, hier weiter in die OOP und Design Patterns einzugehen, wenn der Rest deines Codes nicht darauf abgestimmt ist.
 
Werbung:
"Gleich oder Ähnlich" - Fakt ist du hast in jeder eine Berechnung, das ist doch schon eine Gemeinsamkeit.

Wahrscheinlich bringt es auch garnichts, hier weiter in die OOP und Design Patterns einzugehen, wenn der Rest deines Codes nicht darauf abgestimmt ist.
Wie soll ich es denn machen, wie bis jetzt? Ich habe in meinem projekt nichr gross objekte. Ich speichere eine Golfrunde ab und möchte statistiken zu der golfrunde auslesen und fertig.
 
Werbung:
Zurück
Oben