原文については、以下を参照してください: http://www.ucai.cn/blogdetail/7028?mid=1&f=12
?オンラインで実行して効果を確認できます! ?
?
? はじめに: ThinkPHP フレームワークは、中国で広く使用されている php フレームワークです。このフレームワークがもたらす発展を詳しく見てみましょう。簡単な開発例を通して、便利で簡単な拡張設計をご紹介します。同時に、ソースコード解析の観点からフレームワークの欠点にも目を向け、総合的かつ客観的な評価を試みます。ここでは、ThinkPHP フレームワークをすでに使用していることを前提としています。基本的な使用方法については、公式ドキュメントを参照してください。
?
1. フレームワークの階層化と urlルーティング
? ? フレームワークのインストールは非常に簡単です。ダウンロード後、それを web サーバーのディレクトリに配置するだけです。ただし、デフォルトのエントリ ファイルの場所を使用しないことをお勧めします。コードとデータの保護を容易にするために、別のディレクトリに保存します。たとえば、私のエントリ ファイルと web サーバー構成ディレクトリは web ディレクトリにあります (外側のフレームの index.php は削除されませんが、使用されません)。
?
ほとんどの MVC フレームワークと同様に、次のボタンを押すだけです。フレームワークのディレクトリ構造を拡張し、独自の Controller と View を拡張して、いくつかのページを開発します。 ThinkPHP は、独自の url を整理するために、モジュール、コントローラー、および アクション の 3 層構造を提供します ( 3.1 バージョンはグループ化と呼ばれ、アクション および メソッド、3.2 はより国際的です)、ディレクトリ構造は次のとおりです:
ここでは、
1 を強くお勧めします。ビジネスは個別に階層化されており、 Controller と Model に配置する必要はありません。たとえば、ここでは関数ライブラリ
Application/Common/Common/function.php强制定义业务层名称为Service:function service($name){ return D($name, 'Service');}
?
?利点は再利用です。パフォーマンスが良いです。将来 wap ページを開発して別の コントローラー を作成したい場合は、 サービスを再利用できます。たとえば、データベースがmysqlからmongodbに移行する場合など、将来データストレージが変更された場合は、サービスを変更するだけです。 🎜>モデル。サービスはまだ変更する必要がありません。
2では、基本モジュールと業務モジュールは分離されており、相互参照はありません。基本モジュール (基本的なユーザー情報など) は、Controller と View を含まないデータ インターフェイスのみを提供します。
3 層ディレクトリはすでに一般的な web アプリケーションを処理できます。より複雑な web アプリケーションの場合は、ロードする別のエントリ ファイルを定義できます。それを解決するための別のアプリケーション。もっと複雑なアプリケーション?ポータルや非常に大規模な Web サイトの場合、php フレームワークではすべての問題を解決できるわけではありません。独自のミドルウェアとカスタマイズされたフレームワークが必要です。
?
ThinkPHP的支持4种url访问模式,分别是:
普通模式,传统url模式,所有参数分开,例如
http://localhost/tp/index.php?m=Ucai&c=User&a=index¶=xxx
路由参数:m参数表示模块,c表示控制器,a表示访问方法
兼容模式
http://localhost/tp/index.php?s=/Ucai/User/index/para/xxx
路由参数通过s参数组装,当然数据参数也可以不必放在s参数里
pathinfo模式
http://localhost/tp/index.php/Ucai/User/index/para/xxx
这种模式把入口文件和真实脚本放在一起,含义明确,也便于SEO
rewrite模式
http://localhost/tp/Ucai/User/index/para/xxx
这种模式通过web服务器的rewrite配置隐藏入口文件,显得更加友好
其中pathinfo和rewrite模式需要web服务器支持。ThinkPHP有个配置需要设置为哪种模式,其实是用在U方法里生成url链接的时候用到的,访问的时候只要web服务器支持用哪种方式都可以。
也建议ThinkPHP其实不需要配置,而是记住用户访问的方式,只要第一个访问用的是哪种模式,以后生成的url都用这种方式生成,因为用户都已经访问到了就不存在支不支持的问题了。
?
如果正常的url不能达到我们的要求,还可以通过配置路由进一步优化url,例如我们想把url配置的更加简单
http://localhost/tp/Ucai/login/xxx
我们只需要在模块配置文件中添加如下的路由配置即可,如果用正则表达式则可以更加简化
?
'URL_ROUTE_RULES' => array( 'login/:para' => 'Ucai/User/index', 'login' => 'Ucai/User/index', ),?
?
到这里我们可以看到,ThinkPHP框架支持的层次结构和url配置非常丰富,能满足各种不同的需求。当然我们建议大家不要滥用路由配置,适当少量的配置能带来更好的seo效果,但是大量的配置会给项目的维护和修改带来困难。
?
二、ThinkPHP扩展
ThinkPHP本身含有丰富的组件和驱动,我们以数据库驱动扩展和行为扩展为例来了解一下ThinkPHP的扩展设计。
1、数据库驱动扩展
? ? 虽然ThinkPHP提供了众多的数据库驱动,但是也并不能满足所有的需求。例如我们的数据很可能不是通过直接访问数据库去实现,而是通过一些中间件(例如C程序)进行转发,从而获得更好的性能,这时就需要扩展数据库驱动来支持。
? ? 扩展非常简单,在DB/Driver目录下新建自己的驱动,例如Custom.php,然后实现request和execute方法扩展就算完成了,然后再配置文件里配置DB_TYPE=’custom’,就可以使用了。这里的request表示查询,execute表示更改数据,所有其他操作都会在Model里进行解析,包装成sql语句调用这两个方法执行。
例如我所实现的最简单的query方式,通过shell命令调用sqlite执行sql语句:
?
public function query($str) { $cmd = sprintf('sqlite3 %s "%s"', $this->config['params']['dbfile'], $str); exec($cmd, $arr);}
?
?
当然这个只是示例,ThinkPHP本身就支持sqlite3,通过pdo的方式去连接就可以。实际的应用环境可能是通过连接4层协议访问中间层端口获取数据。
2、Behavior行为扩展
? ? Behavior行为设计是ThinkPHP框架的核心,通过行为配置和扩展,为系统的伸缩性和定制性提供了最大的支持。假如我们要加入登录验证的功能,按照常规我们会设计自己的父类Controller,然后所有其他的Controller都从这里继承。但有了Behavior会变得更加简单和灵活,我们只需要在tags.php(没有的话在配置目录新建)添加一个Behavior就可以了:
?
return array( 'action_begin' => array('Ucai\Behavior\AuthBehavior'), 'view_begin' => array('Ucai\Behavior\OutputBehavior'),);
?
?
程序在执行到action_begin流程时就会调用这个Behavior,我们可以根据状态进行跳转或终止执行。
?
namespace Ucai\Behavior;class AuthBehavior { // 行为扩展的执行入口必须是run public function run(&$return) { //不需要验证的action设置为true if (!$return['AUTH_PUBLIC']) { if (service('User')->checkLogin()) { $return = true; } else { header('Content-Type: text/html; charset=utf-8'); redirect(U('User/index', array('url' => $_SERVER['HTTP_REFERER'])), 5, '需要登录,5秒后跳转。。。'); } } }}
?
?
对于不需要登录的页面我们可以在Controller里添加配置,所有不配置的都会要求登录验证。
public $config = array('AUTH_PUBLIC' => true);
?
? ? 这里大家对继承和Behavior实现登录验证做一个对比,可能觉得区别不大。但是在一个复杂的项目里,这种功能会非常多,如果每个功能都放到父类里,就会非常庞大,并且部分子类可能又不需要,这时候用Behavior去定制流程就会显得游刃有余。
? ? 在上面的配置中我们还发现了一个配置OutputBehavior更能说明问题,大家有没有猜到,这个Behavior我是用来在view里输出一些共有变量,例如jscss的域名和路径等。在没有Behavior之前,大家是不是需要一个公共方法,然后每个页面都去调用一次,或者改写View的类代码?有了Behavior就显得方便许多。
?
namespace Ucai\Behavior;class OutputBehavior { public function run(&$return) { $view = \Think\Think::instance('Think\View'); $view->assign('STATIC_URL', 'http://p3.ucai.cn/static'); }}
?
?
扩展总结:通过Behavior扩展和数据库驱动扩展大家可以看到,ThinkPHP提供了很灵活的扩展和增强机制,能满足众多需求。其他存储、缓存、日志、模板引擎等如果需要也能很方便的扩展。
?
三、源码分析与不足
首先我们来分析一下框架执行的大致流程:
index.php(入口、调试模式、应用路径)
--> ThinkPHP.php(定义路径与访问模式)
--> Think\Think(类加载器、异常处理、读取共有配置)
--> Think\App(请求url调度解析、执行调度解析结果)
????? --> exec 执行用户定义的Controller的Action方法
--> Think\Dispatcher(根据url模式解析M、C、A和参数,加载模块配置)
--> Think\Controller(调用视图、包装和重定向)
?
可以看到,框架的内部流程其实比较简单,还有2个很重要的类:
Think\Hook: 监听App、Action、View的各个阶段,执行Behavior
Think\Behavior: 可配置(配置文件)可增删(代码)
?
在分析源代码的过程中,我们也看到了一些不足:
1、宏定义过多,难于维护和修改
建议:只在个别文件定义极少数几个宏,其余用类常量包装
2、面向过程代码过多,封装不清晰
建议:用面向对象思想包装
例: url の解析とパッケージ化は、__APP__ マクロを使用して Dispatcher で生成され、次に U で生成されます。 マクロはメソッド内で読み取られ、最終的な url が生成されます。実際、ラップするクラス、たとえば UrlHelper を定義でき、クラス parse と generate の 2 つのメソッドが url なので、コード構造はより明確になります。
3、一部の関数とクラス コードがカプセル化されすぎているため、再利用と改善が不便です
提案: 組み合わせを使用して独立した機能コンテンツをカプセル化します
例: モデル の検証関数は完全にクラスに分離できます。 Model 以外のオブジェクト呼び出しにも使用できます。現在の検証インターフェイスは Model の保護メソッドであり、Model の create 関数内でのみ呼び出すことができます。外部は create メソッドを確認できます。
4、コード仕様とスタイルの問題
希望コーディング スタイルをより標準化して標準化することができます。たとえば、DB クラスは、テンプレート メソッドの親クラスとして、Model を定義するすべてのメソッドを定義するために抽象メソッドを使用するか、例外をスローする必要があります。を使用する必要があります。実際、一部のメソッドのサブクラスは必要ありませんが、Db クラスは実装されていません。 ?
4. 国内で人気のある ThinkPHP? php フレームワークは開発に本当に便利さをもたらします。
フレームワーク開発者は、Web プロセスを十分に理解しており、php の関数適用に熟練しています。 。このフレームワークは、さまざまなニーズに適応する柔軟な構成と拡張を定義し、開発を加速するための豊富なコンポーネントとモジュールを提供します。最後に、ThinkPHP には非常に完全なドキュメントとコミュニティ サポートがあり、これもフレームワークの人気に不可欠な部分です。 私たちはまた、ThinkPHP が将来その構造をさらに改善し、最高の php フレームワークを構築できることを願っています。 ?