Frage

Ich benutze CodeIgniter ein PHP-Web-Anwendung zu erstellen, und ich versuche, gute OO Praktiken zu nutzen - von denen es viele Denkschulen zu sein scheint. Ich habe speziell eine Klasse biography_model mit einer MySQL-Tabelle zu interagieren. Dieses Datenmodell hat einige Klasseneigenschaften die Spalten in der Tabelle darstellen, aber es hat auch einige Eigenschaften nicht in der Tabelle wie $image_url. Die Klassenkonstruktors Funktion akzeptiert einen optionalen Datensatz-ID Parameter, der dann diesen Datensatz aus der Tabelle abruft und setzt alle Objekteigenschaften durch die get_biography() Methode aufrufen, einschließlich der $image_url Eigenschaft nicht in der Tabelle. Auf diese Weise hat ich ein neues biography_model Objekt in der Steuerung mit allen nützlichen Eigenschaften instanziieren bereit zu gehen: $bio = new biography_model($id);

Aber, was ist der beste Ansatz, wenn wir eine mehrreihige Ergebnismenge von Datensätzen aus der Tabelle zurückkommen? Für jeden Datensatz muß ich auch den $image_url gesetzt. Ich konnte dies in der Steuerung tun, indem Sie die Liste der Datensätze in der Tabelle abfragt und dann jede ID in die neue biography_model vorbei ($ id) Objekt. Aber dann würde ich eine Situation, wo der Controller direkt auf die Datenbank abfragt, das Modell zu umgehen.

Stattdessen wähle ich aus der biography_model eine Reihe von biography_model Objekten zurückzukehren.

Beispiel:

    class Biography_model extends Model
    {
        /**
         *  This model manages biography information in the 'biography_content' table.
         *  If a biography ID is passed in when instantiating a new object,
         *  then all class properties are set.
         */
        protected $id;
        protected $person_name;
        protected $title;
        protected $image_file_name;
        protected $image_url;
        protected $biography_text;
        protected $active;

        /**
         * Constructor
         *
         *  If an id is supplied when instantiating a new object, then
         *  all class variables are set for the record.
         */
        public function __construct($person_id = NULL)
        {
            parent::Model();
            if(isset($person_id))
            {
                $this->set_property('id',$person_id);
                $this->get_biography();
            }
        }

        /**
         * Sets supplied property with supplied value.
         */
        public function set_property($property, $value)
        {
            // Set image path if $value is the file name
            if($property == 'image_file_name')
            {
                $this->set_property('image_url',$this->get_bio_img_url($value));
            }

            $this->$property = $value;
        }

        /**
         * Gets requested property value.
         */
        public function get_property($property)
        {
            return $this->$property;
        }

        /**
         *  Returns the biography thumbnail image URL
         */
        public function get_bio_img_url($image_name)
        {
            return $this->config->item('parent_url').'assets/img/biography/'.$image_name;
        }

        /**
         * Get one or more biography entries
         */
        public function get_biography()
        {
            // If the ID is set then set model properties.
            if($this->get_property('id'))
            {
                $this->db->where('id',$this->get_property('id'));
                $query = $this->db->get('biography_content');

                if($query->num_rows() == 1)
                {
                    foreach($query->row() as $key => $value)
                    {
                        $this->set_property($key, $value);
                    }
                }
            }
            // Otherwise return result set of all biographies
            else
            {
                // Get the list of record ID's
                $this->db->select('id');
                $query = $this->db->get('biography_content');

                if ($query->num_rows() > 0)
                {   
                    // New array to return result set
                    $biography_list = array();

                    // For each record, return a new biography_model object
                    foreach($query->result() as $value)
                    {
                        $biography_list[] = new biography_model($value->id);
                    }
                }
                return $biography_list;
            }
        }
    }

    // End of Biography_model Class

Es funktioniert. Aber ist es ein sinnvoller Ansatz? Gibt es noch andere mehr akzeptierte Methoden? Ich bin mir sehr bewusst, dass ich die Datenbank zweimal bin Abfrage, aber ich war nicht sicher, ein besserer Weg, dies zu umgehen. Alle Vorschläge sind willkommen!

Danke, Wolf

War es hilfreich?

Lösung

Normalerweise ist es besser für Funktionen einen Job zu haben. Ihre get_biography () Funktion hat 2: eine Biographie erhalten und alle Biographien bekommen. Betrachten Splitting sie in zwei Funktionen auf. Auch gibt es keine Notwendigkeit für den mehr DB-Zugriff.

public function get_biography($id=null)
{
    $this->db->where('id', $this->get_property($id))
    $query = $this->db->get('biography_content');

    foreach($query->row() as $key => $value)
    {
        $this->set_property($key, $value);
    }
}

public function get_biographies()
{
    $biography_list = array();

    // don't limit this query to just id's - get everything
    $query = $this->db->get('biography_content');

    // For each record, return a new biography_model object
    foreach($query->result() as $row)
    {
        $model = new biography_model();
        // set the properties you already have straight onto the new model
        // instead of querying again with just the id
        foreach($row as $key => $value)
        {
            $model->set_property($key, $value);
        }
        $biography_list[] = $model;
    }
    return $biography_list;
}

Auch sollten Sie die Vorteile von PHP __get und __set magischen Methoden zu übernehmen:

public function __get($property)
{
    if(!isset($this->$property))
        return null;

    return $this->$property;
}

public function __set($property, $value)
{
    if(!property_exists($this, $property))
        return;

    if($property == 'image_file_name')
    {
        $this->image_url = $this->get_bio_img_url($value);
    }
    else
        $this->$property = $value;
}

So können Sie Eigenschaften auf Ihrem Modell wie diese:. $bio->title statt $bio->get_property('title'), während zur gleichen Zeit einen Platz zur Verfügung stellen Sie später neue Logik einführen können

Andere Tipps

ein Array Mit Hilfe einer Reihe von Datensätzen darzustellen, ist eine absolut gültige Ansatz.

Doch die Eigenschaft image_url hängt direkt von dem Wert einer anderen Eigenschaft, so macht es keinen Sinn machen, es als separates Feld zu speichern. berechnen sie nur im Fluge, in Ihrem Fall würden Sie, dass in der get_property Methode zu tun haben.

Auf der anderen Seite sollte das Modell wirklich verantwortlich sein mit URLs für den Umgang? Ich glaube nicht. Es sollte ein Verfahren außerhalb des Modells sein, der die Aufgabe übernimmt Biography_model und erzeugt die URL des Bildes auf der Grundlage seiner image_file_name. Wenn Sie bereits einige Routing-Modul für die Zuordnung von Controllern URLs verantwortlich sind, sollten Sie diesen Code wahrscheinlich landen dort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top