前幾天下載了ThinkPHP的代碼來看,給我的印象沒有CodeIgniter(CI)的那麼好。或許是因為我下載的是最新的RC版本吧!裡面的Examples不全,打開幾個提示404,因為比較關心數據庫操作方面的代碼。另外,跑了一下裡面的Blog的Example,功能都挺完善的。不過花了十幾分鐘看了一下代碼,就害怕了。不大喜歡的原因有下:
1、代碼很大,這麼一個小blog在用了框架之後,還需要敲那麼多代碼,開發時間也不短吧。
2、把HTML、CSS、Script寫在controller裡,讓controller變得很臃腫,代碼也有點混亂。為何不寫到View裡面去呢?
protected function ajaxUploadResult($info) { // Ajax方式附件上傳提示信息設置 // 默認使用mootools opacity效果 //alert($info); $show = '<script language="JavaScript" src="' . WEB_PUBLIC_PATH . '/Js/mootools.js"></script><script language="JavaScript" type="text/javascript">' . "\n"; $show .= ' var parDoc = window.parent.document;'; $show .= ' var result = parDoc.getElementById("' . $info['uploadResult'] . '");'; if (isset($info['uploadFormId'])) { $show .= ' parDoc.getElementById("' . $info['uploadFormId'] . '").reset();'; } $show .= ' result.style.display = "block";'; $show .= " var myFx = new Fx.Style(result, 'opacity',{duration:600}).custom(0.1,1);"; if ($info['success']) { // 提示上傳成功 $show .= 'result.innerHTML = "<div style=\"color:#3333FF\"> 文件上傳成功!</div>";'; // 如果定義了成功響應方法,執行客戶端方法 // 參數為上傳的附件id,多個以逗號分割 if (isset($info['uploadResponse'])) { $show .= 'window.parent.' . $info['uploadResponse'] . '("' . $info['uploadId'] . '","' . $info['savename'] . '");'; } } else { // 上傳失敗 // 提示上傳失敗 $show .= 'result.innerHTML = "<div style=\"color:#FF0000\"> 上傳失敗:' . $info['message'] . '</div>";'; } $show .= "\n" . '</script>'; //$this->assign('_ajax_upload_',$show); header("Content-Type:text/html; charset=utf-8"); exit($show); return; }
3、混合使用了Java、 www.2cto.com 微軟.Net、PHP三種代碼風格(或者確切的說,從Java、微軟.Net借鑒了函數、文件或變量的命名風格,但是沒有PHP化)。不過在使用上比較一致,出問題幾率也不會太大,只是我不是很習慣。
4、在controller代碼裡寫Business Logic和數據庫操作。我看Model裡的代碼基本都很短,看來是基本上博客的功能都寫在controller裡面去了。比較像Fat Controller的寫法,但是數據庫的操作寫到Model裡應該好些吧(按我理解的MVC來說)。Fat Model比Fat Controller多很多好處,便於代碼重用。
5、這個要舉例說明一下,在看代碼的時候,發現一句注釋。
if (!empty($id)) { $Blog = D("BlogView"); $result = $Blog->where('Blog.id=' . $id)->find(); // 這裡為什麼用select()就讀不出來 if ($result) { $this->assign('vo', $result); } else { $this->redirect('index'); return; } } else { $this->redirect('index'); }
因為我對數據庫操作方面比較關心,之前看過部分ThinkPHP的文檔。拜托,寫這代碼的朋友,TP裡select讀出來的是記錄集,find得到的是記錄,你這麼assign過去,當然讀不出來啦。要把$result改成$result[0]才可以讀出來的嘛。這樣我感覺TP的Example編寫者也對使用者太不負責任了。不過也沒多大問題,只是一個RC版本。
6、混合有字符串式拼湊的SQL請求,有些我沒讀懂!!!可能需要時間深入探究。過多使用這類SQL,會有安全隱患吧(例如SQL注入)。
public function tag() { $Tag = M("Tag"); if (!empty($_GET['name'])) { $name = trim($_REQUEST['name']); $list = $Tag->where("module='Blog' and name='$name'")->field('id,count')->find(); $tagId = $list['id']; $count = $list['count']; import("@.ORG.Page"); $listRows = 10; $fields = 'a.id,a.userId,a.categoryId,a.cTime,a.readCount,a.commentCount,a.title,c.title as category'; $p = new Page($count, $listRows); $p->setConfig('header', '篇日志 '); $dao = D("Blog"); $list = $dao->query("select " . $fields . " from " . C('DB_PREFIX') . 'blog as a,' . C('DB_PREFIX') . 'tagged as b, ' . C('DB_PREFIX') . 'category as c where b.tagId in (' . $tagId . ') and a.categoryId= c.id and a.status=1 and a.id=b.recordId order by a.id desc limit ' . $p->firstRow . ',' . $p->listRows); if ($list) { $page = $p->show(); $this->assign("page", $page); $this->assign('list', $list); } $this->assign('tag', $name); $this->assign("count", $count); } else { $list = $Tag->where("module='Blog'")->select(); //dump($list); $this->assign('tags', $list); } $this->display(); }
7、代碼風格能體現一個程序員的水平,跟CI的Examples相比,還是有一定差距。注釋寫的比較隨意。我有時寫代碼,注釋也挺隨意的。有時候為了尊重其他人,還是需要像寫代碼一樣很大耐心地去寫注釋。
8、跟代碼無關。附帶的用戶文檔不是很人性化,在我本本上都看到字體很大,行距很大,一段簡單功能的PHP代碼就顯示了兩頁。有些代碼為了語法高亮使用了圖片,不過圖片的質量太低了,可能我玩多了單反。作成HTML其實也方便用戶使用、查找的嘛,弄個PDF多了些麻煩。
以上觀點僅針對ThinkPHP 3.0 RC1的Example而言。我沒有看過核心代碼,所以無權評論。同時也沒有否定國內MVC框架實力的意思,只不過我覺得,TP的開發者應該在一些細節上多下些功夫,多灌注一些心血,讓TP的手冊和例子的質量有所提高!
摘自 Xiaoxia