ThinkPHP初學(xué)者:寫一個簡單登錄頁面(一)

在了解了項目的結(jié)構(gòu)之后,接下來就該實戰(zhàn)操作了晋修。對大多數(shù)網(wǎng)站而言六水,登錄注冊的功能是不可或缺的俺孙,這也是許多網(wǎng)站開始的第一步。今天就做一個簡單版的登錄功能掷贾,來了解一下PHP與Web是如何實現(xiàn)交互的睛榄。

在開始之前,我們需要先理一下思路想帅。一個登錄的邏輯大概是這樣:用戶輸入用戶名與密碼->網(wǎng)頁校驗數(shù)據(jù)->把數(shù)據(jù)發(fā)給后端->后端從數(shù)據(jù)庫中查詢后給出響應(yīng)场靴,成功則跳轉(zhuǎn),失敗給出失敗原因港准。

關(guān)聯(lián)Controller與View

根據(jù)以上分析旨剥,我們在寫具體登錄的邏輯前,需要一個靜態(tài)的網(wǎng)頁浅缸,還需要一份數(shù)據(jù)庫轨帜,用以承載數(shù)據(jù)。靜態(tài)的網(wǎng)頁是必須的衩椒,但是不屬于討論的范疇蚌父,所以可以從網(wǎng)上尋找模板,這個網(wǎng)上有很多毛萌,當(dāng)然如果自己會寫html苟弛,手打自然是最好不過了。

不管是從網(wǎng)上下載的模板阁将,還是自己寫的HTML膏秫,其結(jié)構(gòu)都與下圖類似:

image.png

按照上文說的,我們最好應(yīng)該把 css冀痕、js荔睹、images等文件放到\Public\Home\相應(yīng)的文件夾下狸演,那么HTML文件應(yīng)該放在哪里呢言蛇?這里就需要掌握一下TP框架是如何把我們的代碼與所請求的鏈接對應(yīng)起來的。在TP中(至少在TP3.2.3版本中)宵距,TP通過訪問 http://域名:端口號/模塊名/控制器名/方法名 的規(guī)則建立了請求鏈接與實際代碼的對應(yīng)關(guān)系腊尚。例如,在第一篇文章中满哪,我們曾經(jīng)在\Application\Home\Controller\IndexController.class.php中婿斥,將框架自動生成的代碼替換成了:

echo 'Hello PHP劝篷!';

在瀏覽器中輸入http://localhost/thinkphp_3.2.3_full/就看到了這句輸出。而在瀏覽器中輸入http://localhost/thinkphp_3.2.3_full/民宿,TP框架實際上做的是:試圖尋找跟隨在域名和端口號后的模塊名娇妓、控制器名與方法名。而在這個請求中沒有找到這些活鹰,TP就會用默認的控制器名和方法名來解析這個請求哈恰,所以實際上我們輸入http://localhost/thinkphp_3.2.3_full/時,TP就會解析成http://localhost/thinkphp_3.2.3_full/Home/Index/index志群,也就是它會去尋找項目中位于Home模塊下名稱為Index的控制器下的定義為index的那個方法着绷,也就是執(zhí)行了我們替換的那句:

echo 'Hello PHP!';

那么锌云,到底HTML文件應(yīng)該放在哪里呢荠医?要知道,在TP中桑涎,是用MVC模式組織代碼的彬向。剛剛的IndexController屬于控制器層,而HTML顯然應(yīng)該屬于View層石洗,所以我們應(yīng)該把它放在View文件夾下幢泼,并要注意把引用的css、js讲衫、images等的相對路徑指定到\Public\Home\下對應(yīng)的路徑缕棵,修改后類似于下圖:

image.png

現(xiàn)在,還有另外一個問題涉兽,HTML代碼被放在了View層里招驴,那么我們應(yīng)該怎么去訪問它呢?剛剛說了枷畏,鏈接里包含的是控制器名别厘,并沒有包含View,所以只能是由Controller來調(diào)用View拥诡。這里直接給出代碼:

class IndexController extends Controller {
    public function index(){
        $this->display();
    }
}

就是把剛剛那句打印触趴,換成:

$this->display();

IndexController就會去尋找位于\View\Index\下的index.html文件。display()方法是在TP框架內(nèi)部定義的渴肉,它有幾個默認的參數(shù)冗懦,可以直接看框架中的定義:

/**
     * 模板顯示 調(diào)用內(nèi)置的模板引擎顯示方法,
     * @access protected
     * @param string $templateFile 指定要調(diào)用的模板文件
     * 默認為空 由系統(tǒng)自動定位模板文件
     * @param string $charset 輸出編碼
     * @param string $contentType 輸出類型
     * @param string $content 輸出內(nèi)容
     * @param string $prefix 模板緩存前綴
     * @return void
     */
    protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
        $this->view->display($templateFile,$charset,$contentType,$content,$prefix);
    }

這些參數(shù)都可以靈活選用仇祭,默認情況下披蕉,如果HTML文件的名稱與控制器對應(yīng)(和控制器名稱相同但全部小寫),我們可以不傳遞任何參數(shù)。例如我們把HTML文件的名稱改為'index1.html'没讲,就把

$this->display();

替換成

$this->display('index1');

就可以正常工作了眯娱。

然而,做完這些工作后爬凑,當(dāng)我們嘗試在瀏覽器中去訪問時徙缴,就出現(xiàn)了下面的問題:

image.png

稍微了解一點前端,都能看出來是css等文件沒有加載出來嘁信,而僅僅在HTML文件中定義的其他代碼顯示出來了娜搂,這是在初學(xué)時常見的事情。

那么吱抚,原因是什么呢百宇?由于我們使用的是Apache服務(wù)器,Apache服務(wù)器的根路徑實際上是www秘豹,而我們寫相對路徑時想當(dāng)然的把項目的根目錄作為根路徑了携御,所以Apache服務(wù)器自然找不到我們指定的代碼。知道了這點之后既绕,我們就可以想到兩種解決方案:給每個路徑都增加一個層級啄刹,讓它相對于www開始;另一種就是凄贩,想辦法讓Apache服務(wù)器的根路徑和項目的一致誓军。

給每個路徑增加層級,把路徑寫的死死的這種做法是不推薦的疲扎,這為我們以后修改或遷移造成了很大的麻煩昵时,所以這里優(yōu)先采用第二種方法。要實現(xiàn)這種方案椒丧,就需要配置vhost壹甥,并建立域名映射。具體步驟是:打開wamp安裝目錄下的\bin\apache\apache2.4.23\conf\extra\httpd-vhosts.conf文件壶熏,默認內(nèi)容如下:

image.png

其中的ServerName就是我們訪問的地址句柠,DocumentRoot就是指定的根目錄。這也是訪問http://localhost/時將使用的路徑“艏伲現(xiàn)在我們把這段代碼復(fù)制一份溯职,把信息改成自己的項目,如下所示:

image.png

這里的DocumentRoot就是我們項目的目錄帽哑,因為我要把項目同步到git谜酒,所以路徑改了一下名字,相當(dāng)于之前的/www/thinkphp_3.2.3_full祝拯。

除此之外绣否,還需要在C:\Windows\System32\drivers\etc\hosts文件中,為剛剛配置的域名添加本地映射了牛,內(nèi)容如下:

image.png

然后重啟Apache服務(wù)器注竿,再打開瀏覽器就可以看到正確的頁面了:

image.png

關(guān)聯(lián)數(shù)據(jù)庫

頁面顯示正常后,開始寫業(yè)務(wù)邏輯了康嘉。我們需要在MySQL中建立數(shù)據(jù)庫碉输、數(shù)據(jù)表,并插入幾條數(shù)據(jù)(由于做的功能是登錄亭珍,必須先有賬號才行)敷钾,并且把建立的數(shù)據(jù)庫和項目關(guān)聯(lián)起來。

首先肄梨,可以通過點擊wamp運行起來的圖標(biāo)阻荒,選擇MySQL->MySQL console,打開mysql控制臺众羡,在顯示Enter password時直接按回車侨赡。或者通過Windows的命令行粱侣,進入到wamp安裝目錄下的\bin\mysql\mysql5.7.14\bin目錄羊壹,然后輸入:

mysql -hlocalhost -uroot -p

按回車,也可以進入到mysql的控制臺齐婴。其中-h表示服務(wù)器名油猫,localhost表示本地;-u為數(shù)據(jù)庫用戶名柠偶,root是mysql默認用戶名情妖;-p為密碼,如果設(shè)置了密碼诱担,可直接在-p后鏈接輸入鲫售,如:-p123456,用戶沒有設(shè)置密碼该肴,顯示Enter password時情竹,直接回車即可。默認情況下是沒有設(shè)置密碼的匀哄,所以直接按回車秦效,就會進入下圖的頁面,等待輸入:

image.png

接下來需要掌握一些MySQL的命令才能繼續(xù)下去涎嚼。首先阱州,可以通過

show databases;

顯示現(xiàn)在已有的數(shù)據(jù)庫,如圖所示:

image.png

然后通過命令創(chuàng)建一個名為tplearn的數(shù)據(jù)庫:

create database tplearn;
image.png

要使用創(chuàng)建的數(shù)據(jù)庫法梯,需要使用命令:

use tplearn;
image.png

現(xiàn)在苔货,我們就有了項目需要的數(shù)據(jù)庫犀概,然后需要建一張名為user的表,用來存儲賬號信息夜惭。在控制臺輸入以下代碼:

create table if not exists user(
    id int unsigned auto_increment,
    user_name varchar(50) not null,
    user_pass varchar(50) not null,
    user_phone varchar(20) not null,
    user_email varchar(50) not null,
    user_sex tinyint unsigned not null default 0 comment '0 男 1 女',
    create_time int unsigned not null default 0,
    primary key (id)
)engine=InnoDB default charset=utf8;

這段代碼創(chuàng)建了一張名為user的表姻灶,字段有id,姓名诈茧、密碼产喉、手機號、郵箱敢会、性別曾沈,還有創(chuàng)建時間等字段,其中id是主鍵鸥昏,comment是給字段添加注釋塞俱。創(chuàng)建好后,可以用

show create table user;

desc user;

來顯示創(chuàng)建的表結(jié)構(gòu)吏垮,示意圖如下:

命令一
命令二

然后敛腌,創(chuàng)建幾個測試用的賬號,添加到數(shù)據(jù)表中惫皱,執(zhí)行以下兩條語句:

insert into user (user_name,user_pass,user_phone,user_email,user_sex,create_time)
    values      ('test1','123456','13122223333','test1@qq.com',0,0);

insert into user (user_name,user_pass,user_phone,user_email,user_sex,create_time)
    values      ('test2','654321','13133334444','test2@qq.com',1,0);

完成后像樊,可以通過

select * from user;

查看數(shù)據(jù)庫中所有的數(shù)據(jù):

image.png

現(xiàn)在,就要把數(shù)據(jù)庫與項目關(guān)聯(lián)在一起旅敷。在TP中生棍,這步操作十分簡單。只需要從\ThinkPHP\Conf\convention.php中找到注釋為“數(shù)據(jù)庫設(shè)置”的一段代碼媳谁,復(fù)制到\Application\Common\Conf\config.php中涂滴,然后配置一些字段即可,配置后代碼如下:

/* 數(shù)據(jù)庫設(shè)置 */
    'DB_TYPE' => 'mysql',     // 數(shù)據(jù)庫類型
    'DB_HOST' => '127.0.0.1', // 服務(wù)器地址
    'DB_NAME' => 'tplearn',          // 數(shù)據(jù)庫名
    'DB_USER' => 'root',      // 用戶名
    'DB_PWD' => '',          // 密碼
    'DB_PORT' => '3306',        // 端口
    'DB_PREFIX' => '',    // 數(shù)據(jù)庫表前綴
    'DB_PARAMS' => array(), // 數(shù)據(jù)庫連接參數(shù)
    'DB_DEBUG' => TRUE, // 數(shù)據(jù)庫調(diào)試模式 開啟后可以記錄SQL日志
    'DB_FIELDS_CACHE' => true,        // 啟用字段緩存
    'DB_CHARSET' => 'utf8',      // 數(shù)據(jù)庫編碼默認采用utf8
    'DB_DEPLOY_TYPE' => 0, // 數(shù)據(jù)庫部署方式:0 集中式(單一服務(wù)器),1 分布式(主從服務(wù)器)
    'DB_RW_SEPARATE' => false,       // 數(shù)據(jù)庫讀寫是否分離 主從式有效
    'DB_MASTER_NUM' => 1, // 讀寫分離后 主服務(wù)器數(shù)量
    'DB_SLAVE_NO' => '', // 指定從服務(wù)器序號

在當(dāng)前階段晴音,只需要配置前7項即可柔纵,其中數(shù)據(jù)庫表前綴指的是創(chuàng)建數(shù)據(jù)表時,名稱前加的前綴锤躁,比如創(chuàng)建的數(shù)據(jù)表為lp_user搁料,前綴就是'lp_',這里沒有前綴系羞,保持空即可」疲現(xiàn)在,數(shù)據(jù)庫就和當(dāng)前的項目關(guān)聯(lián)在一起了椒振。

關(guān)聯(lián)在一起后昭伸,又怎樣寫SQL語句,來實現(xiàn)業(yè)務(wù)呢澎迎?在TP中庐杨,有兩種方式來操作數(shù)據(jù)庫选调,一種是創(chuàng)建一個與數(shù)據(jù)表對應(yīng)的Model,Model的名稱是數(shù)據(jù)表名去掉前綴灵份,比如數(shù)據(jù)表為tp_user仁堪,Model名稱就定義為UserModel,在Model中就可以進行增刪改查等操作了各吨。另外一種,則是通過M()方法直接操作數(shù)據(jù)表袁铐。同時揭蜒,TP中還定義了一系列函數(shù),用以支持MySQL使用時的連貫操作剔桨,這些在手冊中都有詳細介紹屉更。

第一種方法需要創(chuàng)建Model類,在\Application\Home\Model下新建一個名為UserModel.class.php的php文件洒缀,內(nèi)容如下:

<?php

namespace Home\Model;

use Think\Model;

class UserModel extends Model{

}

namespace為命名空間瑰谜,定義Model或Controller時都需要指定命名空間,在自動生成的IndexController中也有這個字段树绩。然后在UserModel中寫一個測試方法萨脑,獲取數(shù)據(jù)庫中所有的賬號。

public function getUsers(){
    return $this->select();
}

這個方法的效果饺饭,就等同于"select * from user;"渤早。然后在Controller中就可以這樣引用它:

$User = D("User");
$res = $User->getUsers();

D()方法等同于 new UserModel();它是用來簡化實例化類的操作的。通過獲取UserModel的實例再調(diào)用方法就可以得到結(jié)果了瘫俊。

這種方法由于需要實例化類鹊杖,會消耗部分性能,也因為要實例化類扛芽,所以要多寫很多代碼骂蓖,適合用于操作比較頻繁、語句比較復(fù)雜的情況川尖。當(dāng)僅需要對數(shù)據(jù)表進行基本的CURD(增刪改查)時登下,還可以使用第二種方法,就是使用M()方法與建立數(shù)據(jù)表的關(guān)聯(lián)叮喳。M()方法和D()方法功能類似庐船,只是它不實例化類,性能較好嘲更,所有的CURD操作都需要直接進行筐钟,即使定義了UserModel類,M()方法也不會使用它赋朦。使用M()方法實現(xiàn)剛才的實例篓冲,如下所示:

$User = M("User");
$res = $User->select();

可以想象李破,當(dāng)數(shù)據(jù)操作較為復(fù)雜時,使用M()方法會使得Controller類比較臃腫壹将,因此具體使用哪種方法需要權(quán)衡考慮嗤攻。

完成這些工作后,終于可以寫具體的邏輯了诽俯。由于最初接觸妇菱,有許多東西需要了解,所以從零到一顯得比較復(fù)雜暴区,但是掌握了之后闯团,寫起代碼來還是蠻輕松的。剩余的內(nèi)容仙粱,請參考《ThinkPHP初學(xué)者:寫一個簡單登錄頁面(二)》房交。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市伐割,隨后出現(xiàn)的幾起案子候味,更是在濱河造成了極大的恐慌,老刑警劉巖隔心,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件白群,死亡現(xiàn)場離奇詭異,居然都是意外死亡硬霍,警方通過查閱死者的電腦和手機川抡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來须尚,“玉大人崖堤,你說我怎么就攤上這事∧痛玻” “怎么了密幔?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撩轰。 經(jīng)常有香客問我胯甩,道長,這世上最難降的妖魔是什么堪嫂? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任偎箫,我火速辦了婚禮,結(jié)果婚禮上皆串,老公的妹妹穿的比我還像新娘淹办。我一直安慰自己,他們只是感情好恶复,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布怜森。 她就那樣靜靜地躺著速挑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪副硅。 梳的紋絲不亂的頭發(fā)上姥宝,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音恐疲,去河邊找鬼腊满。 笑死,一個胖子當(dāng)著我的面吹牛培己,可吹牛的內(nèi)容都是我干的碳蛋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼漱凝,長吁一口氣:“原來是場噩夢啊……” “哼疮蹦!你這毒婦竟也來了诸迟?” 一聲冷哼從身側(cè)響起茸炒,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎阵苇,沒想到半個月后壁公,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绅项,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年紊册,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片快耿。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡囊陡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掀亥,到底是詐尸還是另有隱情撞反,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布搪花,位于F島的核電站遏片,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏撮竿。R本人自食惡果不足惜吮便,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幢踏。 院中可真熱鬧髓需,春花似錦、人聲如沸房蝉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至白热,卻和暖如春敛助,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屋确。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工纳击, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攻臀。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓焕数,卻偏偏與公主長得像,于是被迫代替她去往敵國和親刨啸。 傳聞我的和親對象是個殘疾皇子堡赔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容