This is an example.<\/p>\n<\/body>\n<\/html>\n\n<\/pre>\n\n
現(xiàn)在,如果你訪問(wèn)自己網(wǎng)站的根資源,你會(huì)看到example.php的內(nèi)容。這仍沒(méi)什么用,但你要清楚你要在以一種結(jié)構(gòu)和組織非常清楚的方式在開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用。<\/p>\n
為了讓Zend_View的應(yīng)用更清楚一點(diǎn),,修改你的模板(example.php)包含以下內(nèi)容:<\/p>\n\n
\n\n\n<?php echo $this->escape($this->title); ?><\/title>\n<\/head>\n 国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂
\n <?php echo $this->escape($this->body); ?>\n<\/body>\n<\/html>\n\n<\/pre>\n\n現(xiàn)在已經(jīng)添加了兩個(gè)功能。$this->escape()類方法用于所有的輸出。即使你自己創(chuàng)建輸出,就像這個(gè)例子一樣。避開(kāi)所有輸出也是一個(gè)很好的習(xí)慣,它可以在默認(rèn)情況下幫助你防止跨站腳本攻擊(XSS)。<\/p>\n
$this->title和$this->body屬性用來(lái)展示動(dòng)態(tài)數(shù)據(jù)。這些也可以在controller中定義,所以我們修改IndexController.php以指定它們:<\/p>\n\n
\n<?php\nZend::loadClass('Zend_Controller_Action');\nZend::loadClass('Zend_View');\nclass IndexController extends Zend_Controller_Action \n{\n public function indexAction()\n {\n $view = new Zend_View();\n $view->setScriptPath('\/path\/to\/views');\n $view->title = 'Dynamic Title';\n $view->body = 'This is a dynamic body.';\n echo $view->render('example.php');\n }\n public function noRouteAction()\n {\n $this->_redirect('\/');\n }\n}\n?>\n\n<\/pre>\n\n現(xiàn)在你再次訪問(wèn)根目錄,應(yīng)該就可以看到模板所使用的這些值了。因?yàn)槟阍谀0逯惺褂玫?this就是在Zend_View范圍內(nèi)所執(zhí)行的實(shí)例。<\/p>\n
要記住example.php只是一個(gè)普通的PHP腳本,所以你完全可以做你想做的。只是應(yīng)努力只在要求顯示數(shù)據(jù)時(shí)才使用模板。你的controller (controller分發(fā)的模塊)應(yīng)處理你全部的業(yè)務(wù)邏輯。<\/p>\n
在繼續(xù)之前,我想做最后一個(gè)關(guān)于Zend_View的提示。在controller的每個(gè)類方法內(nèi)初始化$view對(duì)象需要額外輸入一些內(nèi)容,而我們的主要目標(biāo)是讓快速開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用更簡(jiǎn)單。如果所有模板都放在一個(gè)目錄下,是否要在每個(gè)例子中都調(diào)用setScriptPath()也存在爭(zhēng)議。<\/p>\n
幸運(yùn)的是,Zend類包含了一個(gè)寄存器來(lái)幫助減少工作量。你可以用register()方法把你的$view對(duì)象存儲(chǔ)在寄存器:<\/p>\n\n
\n<?php\nZend::register('view', $view);\n?>\n\n<\/pre>\n\n用registry()方法進(jìn)行檢索:<\/p>\n\n
\n<?php\n$view = Zend::registry('view');\n?>\n\n<\/pre>\n\n基于這點(diǎn),本教程使用寄存器。 <\/p>\n
Zend_InputFilter<\/strong><\/p>\n
本教程討論的最后一個(gè)組件是Zend_InputFilter。這個(gè)類提供了一種簡(jiǎn)單而有效的輸入過(guò)濾方法。你可以通過(guò)提供一組待過(guò)濾數(shù)據(jù)來(lái)進(jìn)行初始化。<\/p>\n\n
\n<?php\n$filterPost = new Zend_InputFilter($_POST);\n?>\n\n<\/pre>\n\n這會(huì)將($_POST)設(shè)置為NULL,所以就不能直接進(jìn)入了。Zend_InputFilter提供了一個(gè)簡(jiǎn)單、集中的根據(jù)特定規(guī)則過(guò)濾數(shù)據(jù)的類方法集。例如,你可以用getAlpha()來(lái)獲取$_POST['name']中的字母:<\/p>\n\n
\n<?php\n\/* $_POST['name'] = 'John123Doe'; *\/\n$filterPost = new Zend_InputFilter($_POST);\n\/* $_POST = NULL; *\/\n$alphaName = $filterPost->getAlpha('name');\n\/* $alphaName = 'JohnDoe'; *\/\n?>\n\n<\/pre>\n\n每一個(gè)類方法的參數(shù)都是對(duì)應(yīng)要過(guò)濾的元素的關(guān)鍵詞。對(duì)象(例子中的$filterPost)可以保護(hù)數(shù)據(jù)不被篡改,并能更好地控制對(duì)數(shù)據(jù)的操作及一致性。因此,當(dāng)你操縱輸入數(shù)據(jù),應(yīng)始終使用Zend_InputFilter。<\/p>\n
提示:Zend_Filter提供與Zend_InputFilter方法一樣的靜態(tài)方法。<\/p>\n
構(gòu)建新聞管理系統(tǒng)<\/strong><\/p>\n
雖然預(yù)覽版提供了許多組件(甚至許多已經(jīng)被開(kāi)發(fā)),我們已經(jīng)討論了構(gòu)建一個(gè)簡(jiǎn)單程序所需要的全部組件。在這里,你會(huì)對(duì)ZF的基本結(jié)構(gòu)和設(shè)計(jì)有更清楚的理解。<\/p>\n
每個(gè)人開(kāi)發(fā)的程序都會(huì)有所不同,而Zend Framework試圖包容這些差異。同樣,這個(gè)教程是根據(jù)我的喜好寫的,請(qǐng)根據(jù)自己的偏好自行調(diào)整。<\/p>\n
當(dāng)我開(kāi)發(fā)程序時(shí),我會(huì)先做界面。這并不意味著我把時(shí)間都花在標(biāo)簽、樣式表和圖片上,而是我從一個(gè)用戶的角度去考慮問(wèn)題。因此我把程序看成是頁(yè)面的集合,每一頁(yè)都是一個(gè)獨(dú)立的網(wǎng)址。這個(gè)新聞系統(tǒng)就是由以下網(wǎng)址組成的:<\/p>\n
\/
\n\/add\/news
\n\/add\/comment
\n\/admin
\n\/admin\/approve
\n\/view\/{id}<\/span><\/p>\n你可以直接把這些網(wǎng)址和controller聯(lián)系起來(lái)。IndexController列出新聞,AddController添加新聞和評(píng)論,AdminController處理一些如批準(zhǔn)新聞之類的管理,ViewController特定新聞和對(duì)應(yīng)評(píng)論的顯示。<\/p>\n
如果你的FooController.php還在,把它刪除。修改IndexController.php,為業(yè)務(wù)邏輯以添加相應(yīng)的action和一些注釋:<\/p>\n\n
\n<?php\nZend::loadClass('Zend_Controller_Action');\nclass IndexController extends Zend_Controller_Action \n{\n public function indexAction()\n {\n \/* List the news. *\/\n }\n public function noRouteAction()\n {\n $this->_redirect('\/');\n }\n}\n?>\n\n<\/pre>\n\n接下來(lái),創(chuàng)建AddController.php文件:<\/p>\n\n
\n<?php\nZend::loadClass('Zend_Controller_Action');\nclass AddController extends Zend_Controller_Action\n{\n function indexAction()\n {\n $this->_redirect('\/');\n }\n function commentAction()\n {\n \/* Add a comment. *\/\n }\n function newsAction()\n {\n \/* Add news. *\/\n }\n function __call($action, $arguments)\n {\n $this->_redirect('\/');\n }\n}\n?>\n\n<\/pre>\n\n記住AddController的indexAction()方法不能調(diào)用。當(dāng)訪問(wèn)\/add時(shí)會(huì)執(zhí)行這個(gè)類方法。因?yàn)橛脩艨梢允止ぴL問(wèn)這個(gè)網(wǎng)址,這是有可能的,所以你要把用戶重定向到主頁(yè)、顯示錯(cuò)誤或你認(rèn)為合適的行為。<\/p>\n
接下來(lái),創(chuàng)建AdminController.php文件:<\/p>\n\n
\n<?php\nZend::loadClass('Zend_Controller_Action');\nclass AdminController extends Zend_Controller_Action\n{\n function indexAction()\n {\n \/* Display admin interface. *\/\n }\n function approveAction()\n {\n \/* Approve news. *\/\n }\n function __call($action, $arguments)\n {\n $this->_redirect('\/');\n }\n}\n?>\n\n<\/pre>\n\n最后,創(chuàng)建ViewController.php文件:<\/p>\n\n
\n<?php\nZend::loadClass('Zend_Controller_Action');\nclass ViewController extends Zend_Controller_Action\n{\n function indexAction()\n {\n $this->_redirect('\/');\n }\n function __call($id, $arguments)\n {\n \/* Display news and comments for $id. *\/\n }\n}\n?>\n\n<\/pre>\n\n和AddController一樣,index()方法不能調(diào)用,所以你可以使用你認(rèn)為合適的action。ViewController和其它的有點(diǎn)不同,因?yàn)槟悴恢朗裁床攀怯行У腶ction。為了支持像\/view\/23這樣的網(wǎng)址,你要使用__call()來(lái)支持動(dòng)態(tài)action。<\/p>\n
數(shù)據(jù)庫(kù)操作<\/strong><\/p>\n
因?yàn)閆end Framework的數(shù)據(jù)庫(kù)組件還不穩(wěn)定,而我希望這個(gè)演示可以做得簡(jiǎn)單一點(diǎn)。我使用了一個(gè)簡(jiǎn)單的類,用SQLite進(jìn)行新聞條目和評(píng)論的存儲(chǔ)和查詢。<\/p>\n\n
\n<?php\nclass Database\n{\n private $_db;\n public function __construct($filename)\n {\n $this->_db = new SQLiteDatabase($filename);\n }\n public function addComment($name, $comment, $newsId)\n {\n $name = sqlite_escape_string($name);\n $comment = sqlite_escape_string($comment);\n $newsId = sqlite_escape_string($newsId);\n $sql = \"INSERT\n INTO comments (name, comment, newsId)\n VALUES ('$name', '$comment', '$newsId')\";\n return $this->_db->query($sql);\n }\n public function addNews($title, $content)\n {\n $title = sqlite_escape_string($title);\n $content = sqlite_escape_string($content);\n $sql = \"INSERT\n INTO news (title, content)\n VALUES ('$title', '$content')\";\n return $this->_db->query($sql);\n }\n public function approveNews($ids)\n {\n foreach ($ids as $id) {\n $id = sqlite_escape_string($id);\n $sql = \"UPDATE news\n SET approval = 'T'\n WHERE id = '$id'\";\n if (!$this->_db->query($sql)) {\n return FALSE;\n }\n }\n return TRUE;\n }\n public function getComments($newsId)\n {\n $newsId = sqlite_escape_string($newsId);\n $sql = \"SELECT name, comment\n FROM comments\n WHERE newsId = '$newsId'\";\n if ($result = $this->_db->query($sql)) {\n return $result->fetchAll();\n }\n return FALSE;\n }\n public function getNews($id = 'ALL')\n {\n $id = sqlite_escape_string($id);\n switch ($id) {\n case 'ALL':\n $sql = \"SELECT id,\n title\n FROM news\n WHERE approval = 'T'\";\n break;\n case 'NEW':\n $sql = \"SELECT *\n FROM news\n WHERE approval != 'T'\";\n break;\n default:\n $sql = \"SELECT *\n FROM news\n WHERE id = '$id'\";\n break;\n }\n if ($result = $this->_db->query($sql)) {\n if ($result->numRows() != 1) {\n return $result->fetchAll();\n } else {\n return $result->fetch();\n }\n }\n return FALSE;\n }\n}\n?>\n\n<\/pre>\n\n(你可以用自己的解決方案隨意替換這個(gè)類。這里只是為你提供一個(gè)完整示例的介紹,并非建議要這么實(shí)現(xiàn)。)<\/p>\n
這個(gè)類的構(gòu)造器需要SQLite數(shù)據(jù)庫(kù)的完整路徑和文件名,你必須自己進(jìn)行創(chuàng)建。<\/p>\n\n
\n<?php\n$db = new SQLiteDatabase('\/path\/to\/db.sqlite');\n$db->query(\"CREATE TABLE news (\n id INTEGER PRIMARY KEY,\n title VARCHAR(255),\n content TEXT,\n approval CHAR(1) DEFAULT 'F'\n )\");\n$db->query(\"CREATE TABLE comments (\n id INTEGER PRIMARY KEY,\n name VARCHAR(255),\n comment TEXT,\n newsId INTEGER\n )\");\n?>\n\n<\/pre>\n\n你只需要做一次,以后直接給出Database類構(gòu)造器的完整路徑和文件名即可:<\/p>\n\n
\n<?php\n$db = new Database('\/path\/to\/db.sqlite');\n?>\n\n<\/pre>\n\n整合<\/strong><\/p>\n
為了進(jìn)行整合,在lib目錄下創(chuàng)建Database.php,loadClass()就可以找到它。你的index.php文件現(xiàn)在就會(huì)初始化$view和$db并存儲(chǔ)到寄存器。你也可以創(chuàng)建__autoload()函數(shù)自動(dòng)加載你所需要的類:<\/p>\n\n
\n<?php\ninclude 'Zend.php';\nfunction __autoload($class)\n{\n Zend::loadClass($class);\n}\n$db = new Database('\/path\/to\/db.sqlite');\nZend::register('db', $db);\n$view = new Zend_View;\n$view->setScriptPath('\/path\/to\/views');\nZend::register('view', $view);\n$controller = Zend_Controller_Front::getInstance()\n ->setControllerDirectory('\/path\/to\/controllers')\n ->dispatch();\n?>\n\n<\/pre>\n\n接下來(lái),在views目錄創(chuàng)建一些簡(jiǎn)單的模板。index.php可以用來(lái)顯示index視圖:<\/p>\n\n
\n\n\nNews<\/title>\n<\/head>\n \nNews<\/h1>\n <?php foreach ($this->news as $entry) { ?>\n