/************************************/
/* 著者: 年長の若者
/* 電子メール: wenadmin@sina.com
/* 出典: http://blog.csdn.net/hahawen
/************************************/
php は「最もシンプルな」Web スクリプト言語として、国内市場でますます大きくなり、phper も増えていますが、ほとんどの人が使っていないように感じられます。問題は、どのようなデザイン パターンが現在の作業に最適で最も適しているかということです。結局のところ、効率が最も重要です (節約された時間でゲームをプレイするのはどれほど美しいことでしょう...)。 MVC が第一の選択肢です。www.sourceforge.net には、MVC に基づく優れたオープンソース プロジェクトが多数あります。
数日前、私は会社の Web サイト、主に記事公開システムを刷新しました。私の上司は、バックエンドは好きなように設計できる、唯一の前提条件は高速であることだと言いました。そこで、シンプルな出版システムのフレームワークを構築しました。純粋に記事公開システムに注目すると、基本的に「中小規模」の企業 Web サイト向けの記事公開システムの要件を満たすことができ、バックグラウンドの PHP コードの合計は 800 行を超えず、任意の拡張をサポートします。そしてプラグイン機能。
これ以上ナンセンスではありません。以下に私の構造について話しましょう。お役に立てれば幸いです。
注: 開始する前に、テンプレート処理ツール クラス「smarttemplate」をダウンロードし、いくつかのテンプレートの簡単な使用方法を理解する必要があります。
私のテスト環境: windows2k/apache2/php4.3.2/smarttemplate クラス ライブラリ
まず、Web サイト全体でのファイルの配布について説明します。次の章では、 と を作成します。次の章に記入してください。
サーバーの Web のルート ディレクトリは「C:/Apache2/htdocs/」です
以下に Web サイトのメイン フォルダーとして「cmstest」フォルダーを作成しました
「cmstest」フォルダー内のサブファイル構造は次のとおりです:
/config.inc.php
/list1.php
/list2.php
/new.php
/ .php
/view.php
/page.js
/src/MysqlUtil.php
/src/ArticleUtil.php
/src/CoreUtil.php
/src/を追加します。 ParseTpl .php
/src/lib/smarttemplate/*.* このディレクトリは、smarttemplate クラス ライブラリの保存に使用されます
/smart/template/list1.htm
/smart/template/list2.htm
/smart/template/new.htm
/smart/template/add.htm
/smart/template/view.htm
/smart/cache/
/smart/temp/
デザイン手順:
自社 Web サイトの特徴とデザインしたテンプレートの構造を考慮し、実装する機能をまとめてリスト化します。
関数リストを分析し、関数を分類します。各タイプの関数には共通点があり、同じ方法で実装できます。
関数に従ってデータベースのテーブル構造を設計します。
データベース名を含む Web サイトの基本情報を記録する構成ファイル config.inc.php を設計します。
それぞれ 1 種類この機能は、データベース クエリ用のインターフェイス関数を設計することで、将来の同様の操作でこのインターフェイスを呼び出すだけで済むようにします。これにより、将来発生する可能性のある多数のコード重複操作が回避され、コード再利用の目的が達成されます。
テンプレート ツール用に独自のパッケージ化関数を定義します。後でそれを呼び出すときは、テンプレート ツールの使用について心配する必要はありません。独自のパッケージ化関数にそれを詰め込むだけです。
基本的な機能はこれでOKです。簡単なページの実装とテンプレートの処理を始めましょう。
次に、「最も単純な記事公開システム」を段階的に実装する方法を確認するために、単純なシステムの設計を開始します。 もちろん、これは私がシミュレーションした単純なプロジェクトにすぎません。これよりも複雑になります。
1. 私のケースの分析:
ははは、この顧客プロジェクトはとてもシンプルで嬉しいです...
list1.php: 3 つの記事リストがあります。 「php開発記事一覧」「php開発人気記事一覧」「asp開発最新記事」「新規記事追加」
list2.php: 記事リストは2つあります「asp」「開発記事一覧」「ASP開発」人気記事リスト"
new.php: 記事フォームを追加するページ
add.php: new.php フォームを処理するページ
view.php: 記事閲覧ページ
2. 分析機能
「php開発記事一覧」「asp開発記事一覧」------記事の公開順に逆順に表示し、各ページに5件ずつ表示 記事
「php開発の注目記事一覧」 「asp開発の注目記事一覧」 ------- 記事のクリック数や閲覧数順に記事を3件表示
「asp開発の最新記事」ボタン記事の公開順序は逆順に表示され、3 つの記事が表示されます
「新しい記事を追加」 ------ 記事のタイトル/著者/内容を含む記事の公開機能
「記事を表示」 - -- ------記事の内容を表示します
以下の機能を総合的に見て分類します。
1. 記事リスト: 通常のページング リスト、クリックによるリスト、公開順リスト
2. 記事公開: フォームの入力と処理
3. 記事閲覧: 記事内容の読み取りと表示
はは、確かに機能がシンプルすぎますね。
3. 設計データベース:
データベース名: cmstest
データ テーブル:
CREATE TABLE `article` (
`id` INT NOT NULL AUTO_INCREMENT、
`title` VARCHAR( 100 ) NOT NULL 、
`content` TEXT NOT NULL 、
`datetime` DATETIME NOT NULL 、
`clicks` INT( 11 ) 、
`pid` TINYINT( 2 ) NOT NULL ,
PRIMARY KEY ( `id` )
);
CREATE TABLE `cat` (
`cid` TINYINT( 2 ) NOT NULL ,
`cname` VARCHAR( 20 ) NOT NULL 、
主キー ( `cid` )
); ----------------
記事テーブルは記事コンテンツテーブルです。
------ --- -----
`id` 記事番号
`title` 記事タイトル
`content` 記事内容
`datetime` 公開時刻
`clicks` クリック数
`pid `カテゴリテーブル番号
----------------------------
cat テーブルはカテゴリテーブルです記事の
----------------------------
`cid` 分類表番号
`cname` 分類name
-- -----------------------------
上記はテーブルのデータベース構造ですこれだけでは不十分です。
INSERT INTO `cat` VALUES(1, "phpdevelopment"), (2, "aspdevelopment");
INSERT INTO `article` VALUES(1, "php 開発 1", "php 開発 1 コンテンツ ", "2004-8-1 1:1:1", 0, 1);
INSERT INTO `article` VALUES(2, "php 開発2", "php 開発 2 コンテンツ", "2004-8- 2 1:1:1", 0, 1);
INSERT INTO `article` VALUES(3, "php 開発 3", "php 開発 3 content", "2004-8-3 1:1:1" , 4, 1);
INSERT INTO `article` VALUES(4, "php 開発 4", "php 開発 4 コンテンツ", "2004-8 -4 1:1:1", 3, 1);
INSERT INTO `article` VALUES(5, "php 開発 5", "php 開発 5 コンテンツ", "2004-8-5 1:1:1 ", 2, 1);
INSERT INTO `article` VALUES(6, "php 開発 6", "php 開発 6 コンテンツ", "2004-8-6 1:1:1", 1, 1);
INSERT INTO `article` VALUES(7, "php 開発 7", "php 開発 7 コンテンツ", "2004-8-7 1:1:1", 0, 1);
INSERT INTO `article ` VALUES(8, "jsp 開発 1", "jsp 開発 1 コンテンツ", "2004-8-1 1:1:1", 0, 2);
INSERT INTO `article` VALUES(9, "jsp)開発 2", "jsp 開発 2 コンテンツ", "2004-8 -2 1:1:1", 0, 2);
INSERT INTO `article` VALUES(10, "jsp 開発 3", "jsp 開発3 コンテンツ", "2004-8-3 1:1:1 ", 4, 2);
INSERT INTO `article` VALUES(11, "jsp 開発 4", "jsp 開発 4 コンテンツ", "2004- 8-4 1:1:1", 3, 2);
INSERT INTO `article` VALUES(12, "jsp 開発 5", "jsp 開発 5 コンテンツ", "2004-8-5 1:1: 1", 2, 2);
INSERT INTO `article ` VALUES(13, "jsp 開発 6", "jsp 開発 6 コンテンツ", "2004-8-6 1:1:1", 1, 2) ;
INSERT INTO `article` VALUES(14, "jsp 開発 7", "jsp 開発 7 コンテンツ", "2004-8-7 1:1:1", 0, 2);
このようにして、私たちのデータベースは設計されています。次に、具体的な実装について説明します。
4. config.inc.php ファイルを設計します。
このファイルは、Web 上の他の特定の実装ページを設定するために使用されます。 、以下は設定のリストです
//データベース設定
define('DB_USERNAME', 'root');
define('DB_PASSWORD') , '');
define('DB_NAME', 'cmstest');
> // Web の基本パス設定
define('CMS_ROOT', 'C:/Apache2/htdocs/cmstest/');
define('CMS_SRCPATH', CMS_ROOT.'src/');
//Smarttemplate テンプレート解析ツールの設定
define('SMART_REUSE_CODE', false);
define('SMART_TEMPLATE_DIR', CMS_ROOT.'smart/template/');
define('SMART_TEMP_DIR' , CMS_ROOT.'smart/temp/');
define('SMART_CACHE_DIR', CMS_ROOT.'smart/cache/');
define('SMART_CACHE_LIFETIME', 100); ');
//インクルードされる基本ファイルには、いくつかの基本関数が含まれます
require_once CMS_SRCPATH.'MysqlUtil.php';
require_once CMS_SRCPATH .'ArticleUtil.php'; .'CoreUtil.php';
require_once CMS_SRCPATH.'ParseTpl.php';
//セッション制御
session_start(); 🎜>?>
のうち、define('CMS_ROOT', 'C:/Apache2/htdocs/cmstest/');にapach の Web パスを自分で変更します (フォルダー構造が最初に導入された場所を参照)。
5. 関数型インターフェースの作成 (1)
まず、データベース操作を簡素化するために、mysql データベース関数をラップします。インターネット上には、このようなオープンソース クラスが多数あります。ただし、ここでは私自身のニーズと習慣に基づいて mysql 関数を個人的にパッケージ化しており、それがうまく書かれているかどうかは気にしません。ここをざっと見てみましょう。異なるパッケージのクラス操作は異なります。ここでの主な目的は、コードにあまり固執せずにこの「アーキテクチャ」を理解することです。
------MysqlUtil.php--------
function dbConnect(){
global $cnn;
$ cnn =(db_pconnect?mysql_pconnect(db_host、db_name、db_password):
mysql_connect(db_host、db_name、db_password)または
die( '数据库连接错误');
mysql_select_db(DB_NAME, $cnn) or die('数据库选择错误');
mysql_query("SET AUTOCOMMIT=1");
}
関数 &dbQuery($sql){
global $cnn;
$rs = &mysql_query($sql, $cnn);
while($item=mysql_fetch_assoc($rs)){
$data[] = $item;
}
$data を返す;
}
関数 &dbGetRow($sql){
global $cnn;
$rs = mysql_query($sql) or die('sql语句执行错误');
if(mysql_num_rows($rs)>0)
return mysql_fetch_assoc($rs);
else
null を返します。
}
function dbGetOne($sql, $fildName){
$rs = dbGetRow($sql);
return sizeof($rs)==null? null: (isset($rs[$fildName])? $rs[$fildName]: null);
}
function &dbPageQuery($sql, $page=1, $pageSize=20){
if($page===null) return dbQuery($sql);
$countSql = preg_replace('|SELECT.*FROM|i','SELECT COUNT(*) count FROM', $sql);
$n = (int)dbGetOne($countSql, 'count');
$data['pageSize'] = (int)$pageSize<1? 20: (int)$pageSize;
$data['recordCount'] = $n;
$data['pageCount'] = ceil($data['recordCount']/$data['pageSize']);
$data['page'] = $data['pageCount']==0? 0: ((int)$page<1?1: (int)$page);
$data['page'] = $data['page']>$data['pageCount']? $data['pageCount']:$data['page'];
$data['isFirst'] = $data['page']>1? false: true;
$data['isLast'] = $data['page']<$data['pageCount']? false: true;
$data['start'] = ($data['page']==0)? 0: ($data['page']-1)*$data['pageSize'] 1;
$data['end'] = ($data['start'] $data['pageSize']-1);
$data['end'] = $data['end']>$data['recordCount']? $data['recordCount']: $data['end'];
$data['sql'] = $sql.' LIMIT '.($data['start']-1).','.$data['pageSize'];
$data['data'] = &dbQuery($data['sql']);
$data を返す;
}
function dbExecute($sql){
global $cnn;
mysql_query($sql, $cnn) or die('sql语句执行错误');
return mysql_affected_rows($cnn);
}
function dbDisconnect(){
global $cnn;
mysql_close($cnn);
}
function sqlGetOneById($table, $field, $id){
return "SELECT * FROM $table WHERE $field=$id";
}
function sqlMakeInsert($table, $data){
$t1 = $t2 = array();
foreach($data as $key=>$value){
$t1[] = $key;
$t2[] = "'".addslashes($value)."'";
}
return "INSERT INTO $table (".implode(",",$t1).") VALUES(".implode(",",$t2).")";
}
function sqlMakeUpdateById($table, $field, $id, $data){
$t1 = array();
foreach($data as $key=>$value){
$t1[] = "$key='".addslashes($value)."'"; WHERE $field=$id";
}
function sqlMakeDelById($table, $field , $id){
return "DELETE FROM $table WHERE $field=$id";
}
?> 5. 🎜>
実装したい関数のパッケージ化を正式に見てみましょう
---------------ArticleUtil.php--------- -------
//記事一覧を表示 Function
//getArticleList(記事カテゴリ、ソート方法、現在表示しているページ、それぞれに表示されている記事数page)
function getArticleList($catId, $order, $page, $pageSize){
$sql = "SELECT * FROM Article WHERE pid=$catId ORDER BY $order"; sql, $page, $pageSize);
}
//記事の内容をクエリ
//getArticle(記事番号)
function getArticle($id){
$sqlUpdate = "UPDATE 記事 SET クリック数 = クリック数 1 WHERE id=$id";
dbExecute($sqlUpdate);
$sql = "SELECT * FROM 記事 WHERE art_id=$id"; );
}
//記事を追加
//addArticle (記事コンテンツ配列)
function addArticle($data){
$sql = sqlMakeInsert('article', $data);
return dbExecute($sql);
}
?>
このコードはもっと簡単ではないでしょうか?これが、mysql 関数を自分でパッケージ化する利点です。
関数がどのように実装されているかを調べてみましょう。
"php 開発記事リスト"----------getArticleList(1, "id DESC", $page, 5)
"asp 開発記事リスト"--------getArticleList( 2, "id DESC", $page, 5)
"php 開発の注目の記事リスト"----getArticleList(1, "clicks DESC, id DESC", 1, 3)
"asp 開発の注目の記事List"----getArticleList(2, "clicks DESC, id DESC", 1, 3)
"ASP 開発の最新記事"----getArticleList(2, "id DESC", 1, 3)
「新しい記事を追加」-------------addArticle($data)
「記事を表示」----- getArticle($ id)
6. Smarttemplate クラスのパッケージ化 (革命はまだ成功していません。同志たちはまだ努力する必要があります)
ここでは、smarttemplate の具体的な使用方法には触れません。そうしないと、言葉が足りなくなって話が終わらないからです。以下は、特定のラッパー関数です。
-------------ParseTpl.php-----
< ; ?php
function renderTpl($viewFile, $data){
$page = new SmartTemplate($viewFile)
foreach($data as $key=>$value){
if(isset($value[データ])){
$page->assign($key, $value[データ])
unset($value[データ]); ->assign($key."_page", $value); > $page->output();
?>