php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 04.07.2010, 17:02  
Erfahrener Benutzer
 
Registriert seit: 06.11.2008
Beiträge: 212
stayInside befindet sich auf einem aufstrebenden Ast
Standard Klassenaufbau

Hallo,

ich bin gerade dabei eine Klasse zu programmieren mit der ein ein SQL Statement zusammenbasteln kann.

Bislang sieht das ganze so aus.

PHP-Code:
final class SQLAssembler
{
    
/**
     * 
     * 
     * @var <array>
     */
    
private $arrTables              = array();

    
/**
     *
     *
     * @var <array>
     */
    
private $arrJoinTables          = array();

    
/**
     *
     *
     * @var <array>
     */
    
private $arrFields              = array();

    
/**
     *
     * @var <array>
     */
    
private $arrJoins               = array();

    
/**
     *
     *
     * @var <array>
     */
    
private $arrWhereConditions     = array();

    
/**
     *
     *
     * @var <array>
     */
    
private $arrOrderByConditions   = array();

    
/**
     *
     *
     * @var <array>
     */
    
private $arrGroupByConditions   = array();

     
/**
      *
      *
      * @var <array>
      */
     
private $arrBlocks             = array();

     
/**
      *
      *
      * @var <array>
      */
     
private $arrConnectors         = array();

    
/**
     *
     *
     * @var <integer>
     */
    
private $intElementsCount       0;

    public function 
__get($strKey)
    {
        
$blnSuccess false;

        switch (
$strKey)
        {
            case 
'or':
            case 
'xor':
            case 
'and':
                
$this->arrConnectors[$this->intElementsCount 1] = mb_strtoupper($strKey);

                
$blnSuccess true;
                break;

            case 
'blockStart':
                
$this->arrBlocks[$this->intElementsCount 1] = '(';
                
                
$blnSuccess true;
                break;

            case 
'blockEnd':
                
$this->arrBlocks[$this->intElementsCount 1] = ')';
                
                
$blnSuccess true;
                break;
        }

        if (
$blnSuccess === true)
        {
            ++
$this->intElementsCount;
        }

        return (
$this);
    }

    
/**
     *
     *
     * @param <string>              $strTableName   Tabellenname
     * @param <string|optional>     $strAliasName   Tabellenalias
     *
     * @return <object>
     */
    
public function addTable($strTableName$strAliasName null)
    {
        
$strTable '';
        
        if (!empty(
$strTableName) &&
            
is_string($strTableName))
        {
            
$strTable '`' $strTableName '`';
        }

        if (!empty(
$strTable) &&
            !empty(
$strAliasName) &&
            
is_string($strAliasName))
        {
            
$strTable .= ' AS `' $strAliasName '`';
        }

        if (!empty(
$strTable))
        {
            
$this->arrTables[] = $strTable;
        }
        return (
$this);
    }

    
/**
     *
     *
     * @param <string>              $strFieldName               Feldname
     * @param <string|optional>     $strFieldAlias              Feldalias
     * @param <string|optional>     $strFieldFunction           Funktionsname
     * @param <string|optional>     $strFieldFunctionArguments  Funktionsargumente
     *
     * @return <object>
     */
    
public function addField($strFieldName$strFieldAlias null$strFieldFunction null$strFieldFunctionArguments null)
    {
        
$strField '';
        
        if (empty(
$strFieldFunction))
        {
            
$strField '`' $strFieldName '`';
        }
        else if (!empty(
$strFieldFunction))
        {
            
$arrValidFunctions = array
            (
                
'DATE_FORMAT'
            
);     
        }

        if (!empty(
$strField) &&
            !empty(
$strFieldAlias))
        {
            
$strField .= ' AS `' $strFieldAlias '`';
        }

        if (!empty(
$strField))
        {
            
$this->arrFields[] = $strField;
        }

        return (
$this);
    }

    public function 
addWhere($strField$strCondition$mixValue)
    {
        
$this->arrWhereConditions[$this->intElementsCount 1] = '`' $strField '` ' $strCondition ' ' $mixValue;

        ++
$this->intElementsCount;
        
        return (
$this);
    }

    
/**
     *
     *
     * @param <string>              $strOrderByName     Feldname
     * @param <string|optional>     $strOrderBySort     Sortierreihenfolge
     *
     * @return <object>
     */
    
public function addOrderBy($strOrderByName$strOrderBySort 'desc')
    {
        
$strOrderBy '';

        if (!empty(
$strOrderByName) &&
            
is_string($strOrderByName))
        {
            
$strOrderBy '`' $strOrderByName '`';
        }

        if (!empty(
$strOrderBy) &&
            !empty(
$strOrderBySort) &&
            
in_array($strOrderBySort, array('asc''desc')))
        {
            
$strOrderBy .= ' ' mb_strtoupper($strOrderBySort);
        }

        if (!empty(
$strOrderBy))
        {
            
$this->arrOrderByConditions[] = $strOrderBy;
        }

        return (
$this);
    }

    
/**
     *
     * 
     * @param <sring>   $strGroupByName     Feldname
     *
     * @return <object>
     */
    
public function addGroupBy($strGroupByName)
    {
        
$strGroupBy '';
        
        if (!empty(
$strGroupByName) &&
            
is_string($strGroupByName))
        {
            
$strGroupBy '`' $strGroupByName '`';
        }

        if (!empty(
$strGroupBy))
        {
            
$this->arrGroupByConditions[] = $strGroupBy;
        }

        return (
$this);
    }

    private function 
generateStatement()
    {
        
$strTables implode(', '$this->arrTables);
        
$strFields implode(', '$this->arrFields);

        
$strWhere '';

        
$arrWhereKeys   array_merge(array_keys($this->arrWhereConditions), array_keys($this->arrBlocks), array_keys($this->arrConnectors));
        
$arrWhereValues array_merge($this->arrWhereConditions$this->arrBlocks$this->arrConnectors);

        
$arrWhereCondition array_combine($arrWhereKeys$arrWhereValues);

        
ksort($arrWhereCondition);

        
$strWhere implode(' '$arrWhereCondition);

        
$strGroupBy implode(', '$this->arrGroupByConditions);

        
$strOrderBy implode(', '$this->arrOrderByConditions);

        
$strQuery $strFields ' FROM ' $strTables;

        if (!empty(
$strWhere))
        {
            
$strQuery .= ' WHERE ' $strWhere;
        }

        if (!empty(
$strGroupBy))
        {
            
$strQuery .= ' GROUP BY ' $strGroupBy;
        }

        if (!empty(
$strOrderBy))
        {
            
$strQuery .= ' ORDER BY ' $strOrderBy;
        }

        return (
$strQuery);
    }

    public function 
getQuery($blnForceGenerate false)
    {
        static 
$strStatement;

        if (empty(
$strStatement) ||
            
$blnForceGenerate === true)
        {
            
$strStatement $this->generateStatement();
        }

        return (
$strStatement);
    }

Der Aufruf sieht beispielsweise so aus.

PHP-Code:
$SQLAssembler = new SQLAssembler();

$SQLAssembler   ->addField('Id')
                ->
addField('Title''NewTitle')
                ->
addTable('tabelle1''tabelleas1')
                ->
addTable('tabelle2')
                ->
addWhere('Id''='5)
                ->
and
                    
->blockStart
                    
->blockStart
                        
->addWhere('Name''!=''name1')
                            ->
or
                        
->addWhere('Name''!=''name2')
                    ->
blockEnd
                    
->xor
                    
->blockStart
                        
->addWhere('Name''!=''name3')
                            ->
or
                        
->addWhere('Name''!=''name4')
                    ->
blockEnd
                    
->blockEnd
                
->addGroupBy('Id')
                ->
addOrderBy('Name''asc')
                ->
addOrderBy('Id''desc'); 
Ich habe mir in letzter Zeit angewöhnt das ich immer erst alle Daten sammel und dann verarbeite. In diesem Falle wäre es meiner Meinung nach "einfacher" wenn ich bei jeden Methodenaufruf ein String erweitere.

Was ist eure Meinung nach sauberer? Erst Daten sammeln und dann verarbeiten oder sofort Daten verarbeiten?
stayInside ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 04.07.2010, 17:06  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ehrlich gesagt, ich finde das mega-häßliche und sehe auch Null vorteile gegenüber einem einfachen String-Statement. Kann mir auch nur schwer vorstellen, dass sowas
Zitat:
PHP-Code:
->or
  
->addWhere('Name''!=''name2'
funktioniert. Mal davon abgesehen, dass Du bspw. Klammerebenen oder komplexe Ausdrücke damit nicht umsetzen kannst.

Ganz ehrlich - wer soll so eine Klasse benutzen?
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Alt 04.07.2010, 17:29  
Erfahrener Benutzer
 
Registriert seit: 23.03.2010
Beiträge: 626
PHP-Kenntnisse:
Anfänger
ByStones befindet sich auf einem aufstrebenden Ast
Standard

Ich persönlich muss sagen, dass ich es viel zu umständlich finde so ein Megakonstrukt zu benutzen, wenn man es auch viel einfacher haben kann.
Einfache SQL-Kommandos so zu bauen wäre vllt noch ok, aber sobald JOIN und verschachtelte Bedingungen zusammenkommen muss ich mit so einer Klasse 30 Zeilen lang ein SQL-Statement zusammenbauen obwohl als normales "von-Hand-schreiben" übersichtlicher, schneller, einfacher geht.

Also nichts für mich...

Grüße
ByStones ist offline   Mit Zitat antworten
Alt 04.07.2010, 17:50  
Benutzer
 
Registriert seit: 06.11.2008
Beiträge: 57
PHP-Kenntnisse:
Anfänger
illuminatus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Der einzige Mehrwert ist doch, dass man die Klasse unabhängig vom Backend (Datenbank o.ä.) benutzen kann...
P of EAA: Query Object

Allerdings hat deine Klasse imo überhaupt keinen Sinn, weil du dich viel zu wenig vom SQL Syntax löst bzw. das Statement nicht hinreichend abstrahierst...


Aber irgendwie meine ich diese Diskussion erst neulich hier im Forum gelesen zu haben...
illuminatus ist offline   Mit Zitat antworten
Alt 04.07.2010, 19:13  
Erfahrener Benutzer
 
Registriert seit: 30.07.2008
Beiträge: 1.169
PHP-Kenntnisse:
Fortgeschritten
xm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphäre
Standard

Mal abgesehen davon, dass so etwas elementares wie limit gar nicht implementiert ist. @TE: Mal ehrlich, meinst Du, Du fährst besser mit diesem Konstrukt, ein Statement zusammen zu bauen, als es einfach in einen String zu schreiben? Man muss nicht aus allem ein Objekt machen, nur weil man es kann..

Mit den selfmade-ORMs, das scheint irgendwie wieder zuzunehmen - Warum benutzt man nicht, wenn schon, ein bereits vorhandenes? Es gibt sie in zig Ausführungen..
xm22 ist offline   Mit Zitat antworten
Alt 04.07.2010, 21:32  
Erfahrener Benutzer
 
Registriert seit: 10.02.2009
Beiträge: 929
ragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Mensch
Standard

Was mir nicht gefällt:

Von der IDE hinzugefügte Kommentare die nicht genützt werden.
Entweder ausschalten oder benützen, aber so nicht
ragtek ist offline   Mit Zitat antworten
Alt 04.07.2010, 22:01  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Was meinst DU?
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Alt 04.07.2010, 22:16  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Die Angaben zu dem Typ von Parameter und return Werten ist doch schon fast ausreichend. Klar wäre nen Kommentar noch praktisch aber für den Editor ist es schon mal sehr nützlich wenn die return Typen bekannt sind.
Flor1an ist offline   Mit Zitat antworten
Alt 04.07.2010, 23:35  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

@stayInside: was möchtest du eigentlich bezwecken? Ist ist sicher eine schöne Fingerübung eine SQL-Abstraktion in Code auszuformulieren aber wozu? Mein Ansatz wäre hier eine Ebene höher anzusiedeln, nämlich "echte" Strukturen aus der Datenbank per Parametrisierung beziehen zu können. Der Generic O/R Mapper des APF beispielsweise kann Objekte und Beziehungen per definierter API aus der Datenbank laden. Sofern Parameter mitgegeben werden müssen - z.B. die Einschränkung auf Attribute - kann das mit einem Criterion-Objekt erledigt werden. Das ist für meinen Geschmack eine Abstraktion, die dir auch wirklich nützt. Statt diversen Zeilen SQL kannst du da z.B. per

PHP-Code:
$crit = new GenericCriterionObject();
$crit->addOrderIndicator(...);
$entries $gb->loadRelatedObjects('entries',$crit); 
die Einträge eines Gästebuchs laden. Inhalt des generierten Statements sind 2 JOINs und diverse WHERE-Bedingungen nebst einem ORDER. Formuliere ich Criterion das nach deinem Verfahren aus, ist das sicher nicht so übersichtlich.

Du musst sich also immer fragen, ob das Vorgehen wirklich einen Mehrwert für dich schafft oder einfach nur nett ist.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 09.07.2010, 14:19  
Neuer Benutzer
 
Registriert seit: 09.07.2010
Beiträge: 5
PHP-Kenntnisse:
Fortgeschritten
flobog befindet sich auf einem aufstrebenden Ast
flobog eine Nachricht über ICQ schicken flobog eine Nachricht über Skype™ schicken
Standard

Zitat:
Zitat von ByStones Beitrag anzeigen
Ich persönlich muss sagen, dass ich es viel zu umständlich finde so ein Megakonstrukt zu benutzen, wenn man es auch viel einfacher haben kann.
Einfache SQL-Kommandos so zu bauen wäre vllt noch ok, aber sobald JOIN und verschachtelte Bedingungen zusammenkommen muss ich mit so einer Klasse 30 Zeilen lang ein SQL-Statement zusammenbauen obwohl als normales "von-Hand-schreiben" übersichtlicher, schneller, einfacher geht.

Also nichts für mich...

Grüße
Ich sehe das genauso. Da kann man gleich den SQL-Befehl selbst schreiben. Zumal es solche (Anm.: wie ich finde bessere) Lösungen etwa mit CakePHP schon gibt. Und ich denke an der Stelle muß man ja nicht zwingend das Rad noch mal erfinden.
flobog ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Brauche Ratschläge bzg. Klassenaufbau und Sicherheit NONNNNN PHP-Fortgeschrittene 13 25.03.2008 15:05

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php klassenaufbau, klassenaufbau php, php klassen aufbau, klassen aufbau php, klassen aufbau, php klasse aufbau, klassenaufbau, php addwhere, $bln php, php class aufbauen funktion, php class aufbau, php \addwhere\, klassen pressitent, beispiel php klassenaufbau, string klassenaufbau, $bln empty php, $bln...empty php, addwhere php, beispiel klassenaufbau php, strquery

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:39 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum