このトピックは繰り返し尋ねられ、対処されてきたことに気づきました。数え切れないほどの同様の質問を読み、数え切れないほどの記事を読みましたが、いくつかの重要な懸念事項をまだ把握できていません...私は自分のMVCを構築しようとしています学習目的のためのフレームワークであり、OOP をよりよく理解するためのものです。これは個人的な個人的な使用のためのものであり、怠惰の言い訳として意味するものではありませんが、より堅牢なフレームワークのすべての機能を備えていることにはあまり関心がありません。
私のディレクトリ構造は次のとおりです。
public
- index.php
private
- framework
- controllers
- models
- views
- FrontController.php
- ModelFactory.php
- Router.php
- View.php
- bootstrap.php
すべてのリクエストを index.php に送信する .htaccess ファイルがあります。このファイルには、タイムゾーンやグローバル定数などの基本的な構成設定が含まれており、bootstrap.php ファイルをロードします。ブートストラップには、クラスのオートローダーが含まれており、セッションを開始し、プロジェクト全体で使用するグローバル関数を定義してから、ルーターを呼び出します。ルーターは URL からリクエストを分離し、ReflectionClass を使用して検証し、example.com/controller/method/params の形式でリクエストを実行します。
すべてのコントローラーは FrontController.php を拡張します。
<?php
namespace framework;
class FrontController
{
public $model;
public $view;
public $data = [];
function __construct()
{
$this->model = new ModelFactory();
$this->view = new View();
}
// validate user input
public function validate() {}
// determines whether or not a form is being submitted
public function formSubmit() {}
// check $_SESSION for preserved input errors
public function formError() {}
}
このフロント コントローラーは ModelFactory をロードします。
<?php
namespace framework;
class ModelFactory
{
private $db = null;
private $host = 'localhost';
private $username = 'dev';
private $password = '********';
private $database = 'test';
// connect to database
public function connect() {}
// instantiate a model with an optional database connection
public function build($model, $database = false) {}
}
そしてベースビュー:
<?php
namespace framework;
class View
{
public function load($view, array $data = [])
{
// calls sanitize method for output
// loads header, view, and footer
}
// sanitize output
public function sanitize($output) {}
// outputs a success message or list of errors
// returns an array of failed input fields
public function formStatus() {}
}
最後に、リクエストが現在どのように処理されているかを示すコントローラーの例を次に示します。
<?php
namespace framework\controllers;
use framework\FrontController,
framework\Router;
class IndexController extends FrontController implements InterfaceController
{
public function contact()
{
// process form if submitted
if ($this->formSubmit()) {
// validate input
$name = isset($_POST['name']) && $this->validate($_POST['name'], 'raw') ? $_POST['name'] : null;
$email = isset($_POST['email']) && $this->validate($_POST['email'], 'email') ? $_POST['email'] : null;
$comments = isset($_POST['comments']) && $this->validate($_POST['comments'], 'raw') ? $_POST['comments'] : null;
// proceed if required fields were validated
if (isset($name, $email, $comments)) {
// send message
$mail = $this->model->build('mail');
$to = WEBMASTER;
$from = $email;
$subject = $_SERVER['SERVER_NAME'] . ' - Contact Form';
$body = $comments . '<br /><br />' . "\r\n\r\n";
$body .= '-' . $name;
if ($mail->send($to, $from, $subject, $body)) {
// status update
$_SESSION['success'] = 'Your message was sent successfully.';
}
} else {
// preserve input
$_SESSION['preserve'] = $_POST;
// highlight errors
if (!isset($name)) {
$_SESSION['failed']['name'] = 'Please enter your name.';
}
if (!isset($email)) {
$_SESSION['failed']['email'] = 'Please enter a valid e-mail address.';
}
if (!isset($comments)) {
$_SESSION['failed']['comments'] = 'Please enter your comments.';
}
}
Router::redirect('contact');
}
// check for preserved input
$this->data = $this->formError();
$this->view->load('contact', $this->data);
}
}
私が理解できることから、私の論理は次の理由でオフになっています。
- 検証は、コントローラーではなくモデルで行う必要があります。ただし、モデルは $_POST 変数にアクセスできないため、この部分を正しく行っているかどうかは完全にはわかりません。これは彼らが「太ったコントローラー」と呼んでいるものだと思いますが、これは悪いことですが、何を変更する必要があるのか わかりません...
- コントローラーはビューにデータを送信するべきではありません。代わりに、ビューは独自のデータを要求するためにモデルにアクセスできる必要があります。
$data
プロパティを FrontController から ModelFactory に移動し、データを渡さずに Controller から View を呼び出すと、この問題は解決しますか? 技術的には、MVC フローチャートに準拠しますが、提案されたソリューションは、それほど単純であると仮定すると、取るに足らない、または些細なことのように見えますが、おそらくそうではありません.. - 実装全体に疑問を抱く部分は、ユーザーに対応するロールと権限でインスタンス化された User オブジェクトがあり、
isAllowed()
呼び出すことができるメソッドを作成する方法またはより具体的にはどこにあるかを理解しようとしているということですコントローラーとビューの両方。コントローラーとビューの両方がモデルにアクセスできる必要があるため、このメソッドをモデルに配置することは理にかなっていますか?
全体として、私はここで正しい道を進んでいますか、それとも正しい道を歩むために対処する必要がある明白な問題は何ですか? 「これを読んでください」ではなく、私の例に固有の個人的な応答を本当に望んでいます..正直なフィードバックと助けに感謝します。