PHP MVC benim ilk girişimi eleştirmek Lütfen [kapalı]

3 Cevap php

Peki bu yüzden ben seçim benim dil (PHP) basit bir uygulama oluşturmak için deneyin düşündüm ben büyük bir çerçeve adam değilim ama ben bütün MVC hareketi hakkında işitme oldum ne sevme oldum

Ben nereye yanlış yaptım: Ben soru sanırım? Ben ancak ben içeri datatier uyum konusunda düşüncelerinizi özellikle merak ediyorum, kontrolör / model yüzden umarım biz önleyebilirsiniz nasıl olmalı yağ gibi bir tartışma çok şey olduğunu biliyorum

Bunu eylem olarak görmek istiyorsanız www.omgmvc.com gidebilirsiniz böylece Ayrıca ben bazı testler yapmak için bir etki alanı satın aldı

Öncelikle, burada benim veritabanı şeması bulunuyor:

CREATE TABLE `movies` (
  `id` int(11) NOT NULL auto_increment,
  `movie_name` varchar(255) NOT NULL,
  `release_date` date NOT NULL,
  `directors_name` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
);

INSERT INTO `movies` VALUES (1,'Star Wars', '1977-05-25', 'George Lucas');
INSERT INTO `movies` VALUES (2,'The Godfather', '1972-03-24', 'Francis Ford Coppola');
INSERT INTO `movies` VALUES (3,'The Dark Knight', '2008-07-18', 'Christopher Nolan');

Ve burada dosyalar bulunuyor:

index.php (controller)

<?php

include('datatier.php');
include('models/m_movie.php');

if (isset($_GET['movie']) && is_numeric($_GET['movie']))
{
    $movie = new Movie($_GET['movie']);

    if ($movie->id > 0)
    {
        include('views/v_movie.php');
    }
    else
    {
        echo 'Movie Not Found';
    }
}
else
{
    $movies = Movie::get_all();

    include('views/v_list.php');
}

?>

datatier.php (data tier)

<?php

class DataTier
{
    private $database;

    function __construct()
    {
        $this->connect();
    }

    function __destruct()
    {
        $this->disconnect();
    }

    function connect()
    {
        $this->database = new PDO('mysql:host=localhost;dbname=dbname','username','password');
    }

    function disconnect()
    {
        $this->database = null;
    }

    function get_all_from_database($type)
    {
        $database = new PDO('mysql:host=localhost;dbname=dbname','username','password');

        switch ($type)
        {
            case 'movie':
                $query = 'SELECT id FROM movies';
                break;
        }

        $movies = array();

        foreach ($database->query($query) as $results)
        {
            $movies[sizeof($movies)] = new Movie($results['id']);
        }

        $database = null;

        return $movies;
    }

    function get_from_database($type,$id)
    {
        switch ($type)
        {
            case 'movie':
                $query = 'SELECT movie_name,release_date,directors_name FROM movies WHERE id=?';
                break;
        }

        $database_call = $this->database->prepare($query);
        $database_call->execute(array($id));

        if ($database_call->rowCount() > 0)
        {
            return $database_call->fetch();
        }
        else
        {
            return array();
        }
    }
}

?>

models/m_movie.php (model)

<?php

class Movie extends DataTier
{
    public $id;
    public $movie_name;
    public $release_date;
    public $directors_name;

    function __construct($id)
    {
        parent::connect();

        $results = parent::get_from_database('movie',$id);

        if ($results == array())
        {
            $this->id = 0;
        }
        else
        {
            $this->id = $id;
            $this->movie_name = $results['movie_name'];
            $this->release_date = $results['release_date'];
            $this->directors_name = $results['directors_name'];
        }
    }

    function __destruct()
    {
        parent::disconnect();
    }

    static function get_all()
    {
        $results = parent::get_all_from_database('movie');

        return $results;
    }
}

?>

views/v_list.php (view)

<html>
    <head>
        <title>Movie List</title>
    </head>
    <body>
        <table border="1" cellpadding="5" cellspacing="5">
            <thead>
                <tr>
                    <th>Movie Name</th>
                    <th>Directors Name</th>
                    <th>Release Date</th>
                </tr>
            </thead>
            <tbody>
<?php foreach ($movies as $movie) { ?>
                <tr>
                    <td><a href="/?movie=<?php echo $movie->id; ?>"><?php echo $movie->movie_name; ?></a></td>
                    <td><?php echo $movie->directors_name; ?></td>
                    <td><?php echo $movie->release_date; ?></td>
                </tr>
<?php } ?>
            </tbody>
        </table>
    </body>
</html>

views/v_movie.php (view)

<html>
    <head>
        <title><?php echo $movie->movie_name; ?></title>
    </head>
    <body>
        <h1><?php echo $movie->movie_name; ?></h1>
        <h2>Directed by <?php echo $movie->directors_name; ?></h2>
        <h3>Released <?php echo $movie->release_date; ?></h3>
    </body>
</html>

3 Cevap

İlk olarak, ayrı şeyler tutmak oldukça iyi yapıyor. O geri gelecek öder, bu yüzden vazgeçmek yok.

Veritabanı düzeni (ya da veritabanının kendisi) MVC özüne alakasız. Çoğu durumda, ancak MVC (siz de XML depolama ya da ızgara / bulut kullanabilirsiniz) açıkça gerektirmez ilişkisel veritabanı olur. Ne MVC için çok önemlidir yaptın ki, diğerlerinden ayrılmış Model tutmaktır.

Your View da açıkça diğerlerinden ayrılır. Benzer MVC M parçası, Views, Views çeşitli şekillerde mevcut HTML, ancak herhangi bir metin, temsil çıkışı (XML, XML + XSL, RSS, düz metin, hatta e-posta mesajları) sadece uygulanabilir olabilir: PHP sizinki gibi içerir , şablonları (yani Smarty) veya metin serializable tam teşekküllü nesneler. Ben çok iyi olduğu strateji yargılamak, bireysel kodlama tarzı ve proje gereksinimlerine meselesi değilim.

Sizin denetleyicisi (o Uygulama Kontrolörü daha Sayfa Denetleyicisi'dir) karıştırıyor. Bu MVC mimarisinde bir gizli bölüm var ki, muhtemelen aslında kaynaklanmaktadır. Bu Front Controller ya da Dispatcher adlandırılır. Bu, giriş ayrıştırmak (Uygulama Kontrolörü gibi) denetleyicisi örneğini ve istenen yöntemini çağırmak için Dispatcher'ın kalmıştır. Size özel MVC uygulaması ile devam etmek istiyorsanız, ben size URL Kontrol sınıf ve yöntem adı geçen bazı yaygın bir şekilde kullanmanızı öneririz, yani

index.php/Movies/list
index.php/Movies/details/35

Sadece $ _SERVER ['PATH_INFO'] ayrıştırmak index.php O zaman yeni olarak, sınıf Movies örneğini ve list yöntemini, yani çağrı

$args = explode('/', ltrim($_SERVER['PATH_INFO'], '/'));
$className = array_shift($args);
$method = array_shift($args);
require "$className.php";
call_user_func_array(array(new $className(), $method), $args);

Sonra sadece Filmler sınıfta iki ayrı yöntemlere if-else bloğunun içeriğini taşıyın.

class Movies { // may extend generic Controller class if you wish

    public function list() {
        $movies = Movie::get_all();
        include 'views/v_list.php';
    }

    public function details($movieId) {
        $movie = new Movie($movieId);
        if ($movie->id > 0) {
            include 'views/v_movie.php';
        } else {
            echo "Movie Not Found";
    }

}

Birden eylemler, her biri birden çok denetleyicileri var bu şekilde.

Son söz.

  • Veritabanı tarafında varolan ORM çerçeveler birini kullanmak için kullanışlı olacaktır. Onlar iş günlerini kurtaracak ve muhtemelen el yapımı db katmanında daha gerçekleştirecek. Ben de her model nesne PDO'yu başlatmasını gibi PDO örneğinin örnekleme işleme temiz yolu değildir öneririm. Gibi bir şey DBFactory::getConnection yapardı.

  • HTML dönen yerine denetleyicisi dışarı yankılanan düşünebilirsiniz. Bu uygulamaya Intercepting Filters denetleyicisi örtecek, çıkışını durdurmak ve öncesi veya sonrası süreç isterseniz esneklik konuşmam verir. Otomatik olarak HTML başlık ve altbilgi ekler bir filtre olması süper kullanışlı.

  • Özel bir çerçeve oluşturma, ancak ben daha ciddi görevler için mevcut çerçeveler birini kullanarak öneririm, çok eğlenceli ve değerli bir eğitim deneyimi.

Tüm iyi.

Sen iyi yapıyoruz, ama bir kaç öneri var:

  1. Kullandığınız yana php5 __ özdevinimli_yükle işlevi hakkında unutma.
  2. Bu Modeli olarak veri katmanı isim daha iyidir.
  3. get_all_from_database static olarak bildirilmiş değil ama statik diyorlar, bu bir E_STRICT seviye uyarı oluşturur. Set error_reporting (E_ALL | E_STRICT); ve uyarı görmelisiniz.
  4. Eğer her model için yeniden yazmak zorunda değilsin ki get_all () statik işlev, (sizin durumunuzda Datatier olarak) Model sınıfta olmalıdır. Eğer bu işlevi yapmak için gereken tek değişiklik hattını değiştirmek için:

    $ Sonuç = parent :: get_all_from_database ('film');

ile

$results = $this->get_all_from_database(get_class($this));

Bu modellerin ismi veritabanındaki tabloların isimlerini eşleşmesi gerektiğini varsayar

"Garip" olarak (zaten söz edilmemiştir) hemen bana atlar tek şey aynı veritabanına konuşmak için iki PDO örneğini kullanarak konum olmasıdır. Kendisi çok kötü, ama aynı zamanda iki kez kullanıcı adı, şifre ve dsn kalanını depolamak değil.

Bu web tho gönderilen örnek kod sadece, çünkü olabilir.