ホームページ バックエンド開発 PHPチュートリアル PHP MVCフレームワークから開発(1)

PHP MVCフレームワークから開発(1)

Jun 13, 2016 pm 01:14 PM
gt news php quot

独自の PHP MVC フレームワークを開発する (1)

このチュートリアルは、John Squibb の『Build a PHP MVC Framework in an Hour』から翻訳されたものですが、元のアドレス: http://johnsquibb.com/tutorials

このチュートリアルでは、誰もが MVC モードを使用した PHP アプリケーション開発の基本概念を習得できます。このチュートリアルは 3 つの部分に分かれており、これは最初の部分です。

現在、誰もが使用できる人気のフレームワークが数多く市場に出ていますが、mvc モデルを使用すると、アプリケーションの開発に費やす時間を大幅に削減でき、プロジェクトのソース コードをより適切に整理できます。 、その中には、他のプロジェクトでも使用できるモジュールもあります。ここで、簡単な MVC フレームワークの書き方を教えたいと思います。このプロジェクトは非常にシンプルで軽量であるため、ベストプラクティスではない可能性があり、安全でもありません。実際のアプリケーションでは改善する必要があります。

使用されるテクノロジー: PHP、オブジェクト指向開発手法。

開始

まず、Web サイトのルート ディレクトリに 3 つのフォルダーを作成します

    モデル
  • ビュー
  • コントローラー

次に、ルート ディレクトリに新しいファイルを作成します:

    index.php

プロジェクト構造は次のようになります

§ Web サイトのルート ディレクトリ

§index.php

§ モデル/

§ ビュー/

§ コントローラー/


index.php は Web アプリケーション全体のエントリ ポイントであり、すべてのユーザー リクエストはそれを通過します。ユーザーリクエストをコントローラーフォルダーに保存されている対応するコントローラーにディスパッチするためのコードを作成します。その後、次のメソッドを使用してページジャンプを実現できます:

    http://あなたのドメイン名.com/index.php?page1
  • http://あなたのドメイン名.com/index.php?page2
  • http://youドメイン名 .com/index.php?page3
フロントエンドコントローラーのindex.phpを設定します

まず、アプリケーション全体でアクセスできるように、index.php で Web サイトのルート ディレクトリと Web サイトのドメイン名を定義します。

<?php

//应用的根目录就是index.php的父目录
define("SERVER_ROOT", dirname(__FILE__));

//你的域名.comm 是你的服务器域名
define('SITE_ROOT' , 'http://你的域名.com');
ログイン後にコピー

任意の PHP ファイルで Web サイトのルート ディレクトリを定義すると、他のディレクトリにある PHP ファイルを簡単に参照できます。これは、index.php がエントリ ファイルであるため、アプリケーション全体でその中で定義された PHP ファイルにアクセスできるためです。変数。

ルーターの router.php を設定します (ユーザーリクエストを対応するコントローラーに転送します)

controllers ディレクトリに「router.php」という名前の新しいファイルを作成します。このファイルはすべてのページリクエストを処理するために使用されます。家のルーターが、家のすべてのコンピューターにインターネットをルーティングする役割を果たしていると想像してください。 router.php ファイルは、受信ページリクエストをindex.phpに受け取り、そのリクエストを別のコントローラにディスパッチします。

route.php のコード:

<?php

//获取所有请求
$request = $_SERVER['QUERY_STRING'];
ログイン後にコピー
このコードは、アプリケーションに渡されるリクエスト パラメーターを取得します。 QUERY_STRING は、「?」以降のすべての文字列です。

    http://yourdomain.com/index.php?page1
上記のアドレスは、コード内で「page1&action=login」を取得します。page1 を次のパラメーターから分離するには、次のコードをroute.phpに追加する必要があります。

次に、index.php に Route.php を導入する必要があります。

//解析$request变量,得到用户请求的页面(page1)和其它GET变量(&分隔的变量)如一个请求http://你的域名.com/index.php?page1&article=buildawebsite,则被解析为array("page1", "article=buildawebsite")
$parsed = explode('&' , $request);

//用户请求的页面,如上面的page1,为$parsed第一个变量,shift之后,数组为array("article=buildawebsite")
$page = array_shift($parsed);

//剩下的为GET变量,把它们解析出来
$getVars = array();
foreach ($parsed as $argument)
{
    //用"="分隔字符串,左边为变量,右边为值
    list($variable , $value) = split('=' , $argument);
    $getVars[$variable] = $value;
}

//这是测试语句,一会儿会删除
print "The page your requested is '$page'";
print '<br/>';
$vars = print_r($getVars, TRUE);
print "The following GET vars were passed to the page:<pre class="brush:php;toolbar:false">".$vars."
";
ログイン後にコピー
すべてがうまくいけば、ブラウザを開いて次のように入力できます:

<?php
/**
 * 定义文档路径
 */
define("SERVER_ROOT", dirname(__FILE__));
define('SITE_ROOT' , 'http://你的域名.com');
/** 
 * 引入router.php 
 */
 require_once(SERVER_ROOT . '/controllers/' . 'router.php');
?>
ログイン後にコピー


http://yourdomain.com/index.php?news&article=howtobuildaframework

次の出力が表示されます

上記の出力がない場合は、サーバー構成が正しいかどうかを確認し、コードにエラーがないかどうかを確認してください。

The page you requested is 'news'
	The following GET vars were passed to the page:

	Array
	(
		[article] => howtobuildaframework
	)
	
ログイン後にコピー

次に、上記の情報を直接出力する代わりに、router.php がページを生成できるように、Web サイトにページを追加しましょう。


コントローラーの作成

コントローラーフォルダーに「news.php」という名前の新しいファイルを作成し、次のクラスを定義します:

<?php
/**
 * 这个文件处理文章的查询,并提供文章
 */
class News_Controller
{
    /**
     * $template变量会保存与此控制器相关的"view(视图)"的文件名,不包括.php后缀 
     */
    public $template = 'news';

    /**
     * 此方法为route.php默认调用
     * 
     * @param array $getVars 传入到index.php的GET变量数组
     */
    public function main(array $getVars)
    {
        //测试代码,以后会删除
        print "We are in news!";
        print '<br/>';
        $vars = print_r($getVars, TRUE);
        print 
        (
            "The following GET vars were passed to this controller:" .
            "<pre class="brush:php;toolbar:false">".$vars."
" ); } }
ログイン後にコピー
route.php のテスト コードをコピーし、それを main 関数に配置したことに注意してください。次に、route.php のコードを変更しましょう:

<?php
/**
 * 此文件会把所有的传入参数分派到相应的控制器中
 */

//获取请求参数
$request = $_SERVER['QUERY_STRING'];

//解析请求页面和其它GET变量
$parsed = explode('&' , $request);

//页面是第一个元素
$page = array_shift($parsed);

//剩余的为GET变量,也把它们解析出来
$getVars = array();
foreach ($parsed as $argument)
{
    //split GET vars along '=' symbol to separate variable, values
    list($variable , $value) = split('=' , $argument);
    $getVars[$variable] = $value;
}

//构成控制器文件路径
$target = SERVER_ROOT . '/controllers/' . $page . '.php';

//引入目标文件
if (file_exists($target))
{
    include_once($target);

    //修改page变量,以符合命名规范(如$page="news",我们的约定是首字母大写,控制器的话就在后面加上“<strong>_Controller”</strong>,即News_Controller)
    $class = ucfirst($page) . '_Controller';

    //初始化对应的类
    if (class_exists($class))
    {
        $controller = new $class;
    }
    else
    {
        //类的命名正确吗?
        die('class does not exist!');
    }
}
else
{
    //不能在controllers找到此文件
    die('page does not exist!');
}

//一但初始化了控制器,就调用它的默认函数main();
//把get变量传给它
$controller->main($getVars);?>
ログイン後にコピー
http://yourdomain.com/index.php?news&article=howtobuildaframework に再度アクセスすると、News_Controller から出力された情報が表示されます。現在、エラーを処理するために die() を使用していることに注意してください。他のより適切なエラー処理で制御できますが、現時点では http://yourdomain.com/index.php などの他のページにアクセスしてみてください。 ?books の場合、「ページが存在しません!」というエラーが表示されます。 News_Controller を完成させるモデルを作成します。読者が読むためのニュース スニペットがいくつかあると仮定すると、News_Controller コントローラーがモデルを呼び出して、関連するニュース スニペットがデータベースに保存されているかファイルに保存されているかに関係なく、それらを取得する必要があります。次のコードを使用して、モデル フォルダー「news.php」に新しいファイルを作成します:



<?php
/**
 * 新闻模型为新闻控制器做复杂的后台操作
 */
class News_Model
{
    public function __construct()
    {
        print 'I am the news model';
    }
}
ログイン後にコピー

现在,我们需要对新闻控制器稍做一些更改,打开controllers里的news.php,把News_Controller类的main函数的代码改为如下,这样,我们就会在“News_Model”初始化时,看到打印在屏幕上的信息:

public function main(array $getVars)
{
    $newsModel = new News_Model;
}
ログイン後にコピー
现在刷新页面,你会看到:

Fatal error: Class 'News_Model' not found in /var/www/mvc/controllers/news.php on line xx
	
ログイン後にコピー
等一下,这不是我们想要的结果!我们正试图去加载一个不存在的类。那么原因就是我们并没有引入/models/news.php文件。为了解决这个问题,让们重新来看一下router.php,然后在它的顶部添加一些代码:

//当类初始化时,自动引入相关文件
function __autoload($className)
{
    //解析文件名,得到文件的存放路径,如News_Model表示存放在models文件夹里的news.php(这里是作者的命名约定)
    list($filename , $suffix) = split('_' , $className);

    //构成文件路径
    $file = SERVER_ROOT . '/models/' . strtolower($filename) . '.php';

    //获取文件
    if (file_exists($file))
    {
        //引入文件
        include_once($file);        
    }
    else
    {
        //文件不存在
        die("File '$filename' containing class '$className' not found.");    
    }
}
ログイン後にコピー
这个函数重载了PHP内置的autoload函数。当我们试图去初始化一个不存在的类时,这个‘魔术方法’允许我们拦截php所执行的动作。通过使用__autoload函数,我们能够告诉php寻找包含此类的文件的位置。假设你遵循了这篇文章中类和文件名的命名约定,那么每当你初始化一个类时,你就不必手动去引入包含此类的文件了!

保存route.php,再刷新一次浏览器,你会看到:

I am the news model
ログイン後にコピー

让我们在新闻模型类里定义一些函数来提供文章。现在,我们只简单的定义了一个数组,并保存一些文章,然后提供一个函数,让控制器从中根据标题获取一篇文章。修改models/news.php:


<?php
/**
 * 新闻模型为新闻控制器做复杂的后台操作
 *
 */
class News_Model
{
    /**
     * 文章数组. key为文章标题, 值为相应的
     * 文章。
     */
    private $articles = array
    (
        //文章1
        'new' => array
        (
            'title' => 'New Website' ,
            'content' => 'Welcome to the site! We are glad to have you here.'
        )
        ,
        //2
        'mvc' => array
        (
            'title' => 'PHP MVC Frameworks are Awesome!' ,
            'content' => 'It really is very easy. Take it from us!'
        )
        ,
        //3
        'test' => array
        (
            'title' => 'Testing' ,
            'content' => 'This is just a measly test article.'
        )
    );

    public function __construct()
    {
    }

    /**
     * 根据标题获取文章
     * 
     * @param string $articleName
     * 
     * @return array $article
     */
    public function get_article($articleName)
    {
        //从数组中获取文章
        $article = $this->articles[$articleName];
    
        return $article;
    }

}?>

ログイン後にコピー
现在修改controllers/news.php中的main函数:

public function main(array $getVars)
{
    $newsModel = new News_Model;
    
    //获取一篇文章
    $article = $newsModel->get_article('test');
    
    print_r($article);
}
ログイン後にコピー
现在我们并没有考虑过滤用户输入的问题,因为我们现在只是为了尽快让大家掌握PHP MVC的基本内容,所以我们现在不必太关心这些。

如果访问如下网址:

§ http://yourdomain.com/mvc/index.php?news&article=test

你会看到如下输出:

Array ( [title] => Testing [content] => This is just a measly test article. ) 
ログイン後にコピー

创建视图(VIEW

现在我们已经有控制器和模型了,只差一个视图。视图是表现层,它是你的应用中,与用户接触最频繁的部分。之前我提到过,视图是提供与业务逻辑分离的用户接口,有很多方法可以做到这个。你可以使用模板引擎Smarty或其它类似的。你也可以写一个自己的模板引擎,但那肯定是相当艰巨的任务。最后,你可以使用原生php视图。

对于目前来说,php视图足够了。这个就像以前php与html代码混合编程一样,但是有一点不同是,我们的业务逻辑已经和视图分离了。看一下如下代码:

<html>
    <head></head>
    <body>
        <h1>Welcome to Our Website!</h1>
        <hr/>
        <h2>News</h2>
        <h4><?=$data['title'];?></h4>
        <p><?=$data['content'];?></p>
    </body>
</html>
ログイン後にコピー

注意,嵌入的php标签利用了PHP 快捷操作符。这样就能够把我们的内容直接输出到HTML里面了。在views文件夹里新建一个文件“news.php”,把上述代码拷贝进来。现在我们有了视图文件,但是我们需要一个与视图交互的方法。在models文件夹里新建一个文件“view.php”,添加如下代码:


<?php
/**
 * 在我们的MVC框架中,处理视图的功能
 */
class View_Model
{
    /**
     * 保存赋给视图模板的变量
     */
    private $data = array();

    /**
     * 保存视图渲染状态
     */
    private $render = FALSE;

    /**
     * 加载一个视图模板
     */
    public function __construct($template)
    {
        //构成完整文件路径
        $file = SERVER_ROOT . '/views/' . strtolower($template) . '.php';
    
        if (file_exists($file))
        {
            /**
             * 当模型对象销毁时才能渲染视图
             * 如果现在就渲染视图,那么我们就不能给视图模板赋予变量
             * 所以此处先保存要渲染的视图文件路径
             */
            $this->render = $file;
        }        
    }

    /**
     * 接受从控制器赋予的变量,并保存在data数组中
     * 
     * @param $variable
     * @param $value
     */
    public function assign($variable , $value)
    {
        $this->data[$variable] = $value;
    }

    public function __destruct()
    {
        //把类中的data数组变为该函数的局部变量,以方便在视图模板中使用
        $data = $this->data;
    
        //渲染视图
        include($this->render);
    }
}
ログイン後にコピー

现在,最后一件要做的事就是从News_Controller里加载视图。修改controllers/news.php:

<?php
/*
 *这个文件处理文章的查询,并产生新闻文章* 
 */
 class News_Controller{ 
    /** 
     * $template变量会保存与此控制器相关的"view(视图)"的文件名,不包括.php后缀
     * 
     */
     public $template = 'news'; 
    /**
     * 此方法为route.php默认调用
     * 
     * @param array $getVars 传入到index.php的GET变量数组 
     */ 
     public function main(array $getVars) {
         $newsModel = new News_Model; 
         //获取一片文章 
         $article = $newsModel->get_article($getVars['article']); 
         //创建一个视图,并传入该控制器的template变量 
         $view = new View_Model($this->template); 
         //把文章数据赋给视图模板 
         $view->assign('title' , $article['title']); 
         $view->assign('content' , $article['content']); 
     }
}
?>
ログイン後にコピー


再加载页面,你就能够看到你的视图模板中的变量,已经被正确的替换掉了。好了,你的简单的MVC框架已经搭建好了,下面我会继续讲《开发自己PHP MVC框架(二)》
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles