`

ThinkPHP最佳实践——自己的一点体会

    博客分类:
  • php
阅读更多

更多是写给刚接触thinkphp的菜鸟看的,呵呵,自己还不敢自居***

 

主要分以下几个部分,以1.5版本为例

 

文件组织结构 ——都知道tp比较rails,也比较java framework。从官方给出的例子和文档,我隐约总结了以下几点

 

1.COC,现在在框架流行这个,约定大于配置(编程)。核心包在ThinkPHP文件夹中,围绕lib/ThinkPHP/Core,主要把结构分成了Action Model两层。具体涉及到很多,主要就是插件扩展和结合第三方库(类/函数),主要关系到Vendor/Lib/Common三个目录,文档上有详细介绍,需要注意的是命名,比如Lib下一般Org/Com开头,详细见源码import方法。

 

2.App和ThinkPHP。tp的mvc采用的单入口,前端控制器+路由形式,一个单独的应用主要的代码组织结构就是

围绕Tp两层 + Tp扩展基础库(Date/Image)等 + 第三方库

 

其中一个官方推荐是——高于应用的全局Public文件夹(主要是view层相关),一样全局的(放Tp下)和局部的(放App Common or Lib下)

 

PS:推荐/Public/AppName/Css(Js Images)的形式,在view层用__PUBLIC__/**

         或者/AppName/Common(Web)/Css(Js Images)的形式,在view层用__WEB__/**,通过修改源码ThinkTemplate parse方法加入自己的view常量。

 

推荐第三方*** ——几个很好用的东东,虽然有的部分和php自带或tp自己实现的重叠

1.phpmailer

2.securimage

3.model-pagination(我自己又实现了一种)

4.httpdownload

 

--no-php--(view tier refer)

5.blueprint

6.jquery + plugin

7.kindeditor/fckeditor

 

Mvc中Action(Command)的OOD ——从java***的一些汲取的,比如filter\chain\strategy,本身前端控制器到Command处理对象,就是一种Strategy Design Pattern。出发点贯彻了php的简介性,无interface abstract class,只需要extends Action就可以了。所以很多时候你可以来个BaseAction来处理一些常用的逻辑,比如

log

session check

access filter / tracker

error display / redirect

http header set

common libs import / requre

common page variables assign

 

推荐为abstract

 

Mvc中View Tier的Tiles ——Tiles无非就是重用的目的,如何尽量重复使用html代码组成各种不用的page,这点每个人都有自己的体会,我只是就自己的一点经历,随便说点,欢迎大家拍砖和纠正

 

1.page divide + include这个想必大家都在用,比如化分出来一个 html_head,html_main_nav / sidebar,html_main_content,html_foot等,关键为非就是每一快的动态变量的设计,

 

比如<meta>标签里的作者信息、copyright等,

<head>标签里的js css等

navigation bar的list和current css区别等

 

PS:我主要使用tp自带的template,但我想smarty common-template discuz-template等其他的都差不多吧,正如jsp-tiles、sitemesh-tiles、freemarker macro差不多一样。

注意一点,php整个页面无论如何divide include,使用的多是全局变量,这点和java中的模板引擎不同。

 

2.tp自带的template有几个标签很好用,因为最初设计时候,就是多皮肤(style)的支持,有@ :等符号可以便捷动态寻找加载不同皮肤(默认default文件夹)下不同模块下的文件。

 

PS:修改included文件后,记得要clear View Cache

 

WebUI、Web flow、Access Control等功能的自定义扩展 ——

Tp自己有个rbac实现,我只是看看源码,到没有用过,不多说。我有两个实现方式,一个对于简单的,通过配置和Action控制,基本Session验证,自定义TagLib实现基本的Url/Page级别的验证。一个复杂点的,模型建立在数据库段,抽象可访问资源,通过php简洁优秀的反射机制实现粒度到业务逻辑方法级别的权限控制。

 

WebUI一般框架都不会自己费力去实现一个的,不是很多lib都可选么,不错,比如Extjs Jquery UI等,grails自带一个基于prototype+***。我业余时间收集了一些jquery相关的,大概40个常用的plugin,并用java的freemarker实现了一些基本的web ui组件,加上blueprint等css框架,web代码写起来都特别简单并且相似。下面是一些源码

 

<#-- JQuery and JQuery plugins -->

<#assign beginPath="/swsj/zftl/" />

<#assign default_js_list=['']>
<#assign default_css_list=['normal.css', 'widget.css']>

<#assign default_include_feature_list=[
	'common_css',
	'cookie',
	'drag',
	'nice_form', 
	'hot_key', 
	'layout', 
	'mask',
	'tip',
	'validate',
	'weebox']>

<#assign refer_widget_list=[
	'accordion',
	'chart',
	'color_picker',
	'count_down',
	'date_picker',
	'dock',
	'editor',
	'grid',
	'light_box',
	'linked_select',
	'menu',
	'messager',
	'multiple_select',
	'panel',
	'process_bar',
	'rater',
	'scroll',
	'shuffle',
	'slider',
	'status_bar',
	'tab',
	'time_picker',
	'timer',
	'tree',
	'window'
	]>

<#-- html head, js/css refer -->
<#macro html_head widget_list=['all']>
<script type="text/javascript" src="${beginPath}js/jquery1.2.6.js"></script>


<script type="text/javascript" src="${beginPath}js/bgiframe.js"></script>
<script type="text/javascript" src="${beginPath}js/chili.pack.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.cookie.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.dimensions.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.easing.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.metadata.js"></script>

<script type="text/javascript" src="${beginPath}js/jquery.jNice.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.hotkeys.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.maskedinput.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.tooltip.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.validate.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.weebox.js"></script>

<link href="${beginPath}css/weebox.css" rel="stylesheet" type="text/css" />
<link href="${beginPath}css/jquery.tooltip.css" rel="stylesheet" type="text/css" />

<#list widget_list as widget_refer>

<#if widget_refer == 'all' || widget_refer == 'blueprint'>
<!-- Blue Print Css Framework -->
<link href="${beginPath}css/blueprint/blueprint/screen.css" rel="stylesheet" type="text/css" />
<!--[if IE]><link rel="stylesheet" href="${beginPath}/css/blueprint/blueprint/lib/ie.css" type="text/css" media="screen, projection"><![endif]-->
<!-- Import plugins -->
<link rel="stylesheet" href="${beginPath}css/blueprint/blueprint/plugins/buttons/buttons.css" type="text/css" media="screen, projection">	
</#if>


<#if widget_refer == 'all' || widget_refer == 'openfire'>
<link href="${beginPath}css/openfire/global.css" rel="stylesheet" type="text/css" />
</#if>


<#if widget_refer == 'all' || widget_refer == 'accordion'>
<script type="text/javascript" src="${beginPath}js/jquery.accordion.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'color_picker'>
<script type="text/javascript" src="${beginPath}js/jquery.colorpicker.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'count_down'>
<script type="text/javascript" src="${beginPath}js/jquery.countdown.js"></script>
<script type="text/javascript" src="${beginPath}js/jquery.countdown.compat.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'chart'>
<script type="text/javascript" src="${beginPath}js/jscharts.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'date_picker'>
<script type="text/javascript" src="${beginPath}js/ui.datepicker.js"></script>
<link href="${beginPath}css/ui.datepicker.css" rel="stylesheet" type="text/css" />
</#if>

<#if widget_refer == 'all' || widget_refer == 'dock'>
<script type="text/javascript" src="${beginPath}js/jquery.dock.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'editor'>
<#assign kindEditorBeginPath = '/swsj/crud/editor/kindeditor/' />
<!--
<script type="text/javascript" charset="utf-8" src="${kindEditorBeginPath}src/lang/zh_CN.js"></script>
<script type="text/javascript" charset="utf-8" src="${kindEditorBeginPath}src/kindeditor-core.js"></script>
<script type="text/javascript" charset="utf-8" src="${kindEditorBeginPath}src/plugin-all.js"></script>
-->
<script type="text/javascript" charset="utf-8" src="${kindEditorBeginPath}build/kindeditor.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'grid'>
<script type="text/javascript" src="${beginPath}js/flexigrid.js"></script>
<link href="${beginPath}css/flexigrid.css" rel="stylesheet" type="text/css" />
</#if>

<#if widget_refer == 'all' || widget_refer == 'messager'>
<script type="text/javascript" src="${beginPath}js/jquery.messager.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'timer'>
<script type="text/javascript" src="${beginPath}js/jquery.timers.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'tree'>
<script type="text/javascript" src="${beginPath}js/jquery.treeview.js"></script>
<link href="${beginPath}css/jquery.treeview.css" rel="stylesheet" type="text/css" />
</#if>

<#if widget_refer == 'all' || widget_refer == 'ui.pack'>
<script type="text/javascript" src="${beginPath}js/jquery-ui-1.6.custom.min.js"></script>
<link href="${beginPath}css/ui.all.css" rel="stylesheet" type="text/css" />
</#if>

<#if widget_refer == 'all' || widget_refer == 'valid'>
<script type="text/javascript" src="${beginPath}js/valid.js"></script>
</#if>

<#if widget_refer == 'all' || widget_refer == 'jniceform'>
<link href="${beginPath}css/jNice.css" rel="stylesheet" type="text/css" />
</#if>
</#list>


<#if ext_js_list?exists>
<#list ext_js_list as ext_js_file>
<script type="text/javascript" src="${beginPath}js/${ext_js_file}"></script>
</#list>
</#if>

<#list default_css_list as ext_css_file>
<link href="${beginPath}css/default/${ext_css_file}" rel="stylesheet" type="text/css" />
</#list>

<#if ext_css_list?exists>
<#list ext_css_list as ext_css_file>
<link href="${beginPath}css/${ext_css_file}" rel="stylesheet" type="text/css" />
</#list>
</#if>

</#macro>
<#-- End Macro: html_head -->

<#-- page header -->
<#macro page_header title="" widget_list=['all'] 
	encoding="utf-8" beginPath="/swsj/zftl/" style="smooth">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=${encoding}" />
<title>${title}</title>
<@html_head widget_list=widget_list />

<#nested>
</head>
</#macro>
<#-- End Macro: page header -->

<#macro page_body>
<#if body_id?exists>
<body id="${body_id}">
<#else>
<body>
</#if>
<#nested />
</body>
</html>
</#macro>

<#-- End Zftl Macro: Base Defination -->
 

下面的这段是jschart的封装,算例子吧

<#assign style_arr = {
	"blue":  
		{
			"bar_color": "#42aBdB", 
			"bar_border_color": "#D9EDF7", 
			"title_color": "#8C8383",
			"axis_color": "#777E81",
			"axis_name_color": "#777E81",
			"axis_value_color": "#777E81",
			"grid_color": "#ABABAB",
			
			'pie_title_color': '#7A7A7A',
			'pie_units_color': '#fff',
			'pie_values_color': '#878787'
			},
		
	"magenta":  
		{
			"bar_color": "#42aBdB", 
			"bar_border_color": "#bbb", 
			"title_color": "#8C8383",
			"axis_color": "#ABABAB",
			"axis_name_color": "#858585",
			"axis_value_color": "#858585",
			"grid_color": "#ABABAB"
			},
		
		
	"red":  
		{
			"bar_color": "#42aBdB", 
			"bar_border_color": "#D9EDF7", 
			"title_color": "#8C8383",
			"axis_color": "#777E81",
			"axis_value_color": "#777E81"
			}
} />

<#-- Chart Bar -->
<#macro basic_bar chart_div_id="mybarchart" style="blue" barvalue="false" 
	bar_opacity="0.8" bar_space_ratio="50" axis_width="1">
<#assign theme=style_arr[style] />
<#if !theme?exists>
	<#assign theme=style_arr['blue'] />
</#if>
	
<div id="${chart_div_id}">Loading...</div>
<script type="text/javascript">
	var myData = new Array(['2005', 2], ['2006', 1], ['2007', 3], ['2008', 6]);
	var colors = ['#7979DB', '#7952E9', '#792BC8', '#792BA1'];
	<#nested />
	var myChart = new JSChart('${chart_div_id}', 'bar');
	myChart.setDataArray(myData);
	myChart.colorizeBars(colors);
	
	myChart.setBarColor('${theme.bar_color}');
	myChart.setBarBorderColor('${theme.bar_border_color}');
	myChart.setBarValues(${bar_value});
	myChart.setBarSpacingRatio(${bar_space_ratio});
	myChart.setBarValues(${bar_value});
	
	myChart.setTitleColor('${theme.title_color}');
	
	myChart.setAxisColor('${theme.axis_color}');
	myChart.setAxisNameColor('${theme.axis_name_color}');
	myChart.setAxisValuesColor('${theme.axis_value_color}');
	myChart.setAxisWidth(${axis_width});
	
	myChart.setGridColor('${theme.grid_color}');
	myChart.setBarOpacity(${bar_opacity});
	
	myChart.draw();
</script>

</#macro>
<#-- End Macro Chart Bar -->

<#-- Chart Pie -->
<#macro basic_pie chart_div_id="mypiechart" style="blue">
<#assign theme=style_arr[style] />
<#if !theme?exists>
	<#assign theme=style_arr['blue'] />
</#if>
	
<div id="${chart_div_id}">Loading...</div>
<script type="text/javascript">
	var myData = new Array(['S.1', 20], ['S.2', 70], ['S.3', 30], ['S.4', 60], ['S.5', 80], ['S.6', 10]);
	var colors = ['#898A89', '#767776', '#676767', '#434443', '#B0B1B0', '#9E9F9E'];
	<#nested />
	var myChart = new JSChart('${chart_div_id}', 'pie');
	myChart.setDataArray(myData);
	myChart.colorizePie(colors);
	
	myChart.setTitleColor('${theme.pie_title_color}');
	myChart.setPieUnitsColor('${theme.pie_units_color}');
	myChart.setPieValuesColor('${theme.pie_values_color}');
	myChart.draw();
</script>

</#macro>
<#-- End Macro Chart Pie -->
 


Web flow方面——准确的说,我也不知道Web flow的一些相关规范,我所作的只是简单把Crud这些基本操作从view到action到model用代码和模板实现了一下而已,结果就是对一个表/视图,进行crud,只需要定义下这个模型就可以了——我没有扩展Model.class.php,另外用xml形式定义的,过程就是解析加载分析,根据模板分析。

 


辅助工具的使用 ——用过rails/grails的都熟悉下面这些命令吧

create app ***

create controller  model***

generate all ***

 

well,tp既然结构也这么规范,完全也可以用一些命令去简化copy工作——以为php不够熟悉,一些io代码写起来很烂,所以,不得不借助些java平台的东东了——ant,看看下面的命令你就大概明白了

ant create-app Test

ant clear-cache Test

ant delete-app Test

ant create-action Test Index

ant clear-svn Test is_recurve true

*********************

其实都是些很简单的io操作,具体没有涉及到目标代码的动态声称(懒得写了),不过还够用

 

 

终于写完了……汗,继续coding去?

well,祝愿ThinkPHP越来越好,phper越来越像大牛,呵呵

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    微信大转盘源码 —— thinkPHP后台

    微信大转盘源码 —— thinkPHP后台 账号admin 密码123456

    thinkphp, ThinkPHP3.2 ——基于PHP5的简单快速的面向对象的PHP框架.zip

    在深入讲解ThinkPHP3.2的知识点之前,先了解一下它的一些核心特性。 1. **MVC模式**:ThinkPHP3.2采用模型-视图-控制器(MVC)架构模式,将业务逻辑、数据和界面展示分离,使代码结构更加清晰。在实际开发中,模型...

    兄弟连新版ThinkPHP视频教程源代码——狄成浩

    《兄弟连新版ThinkPHP视频教程源代码——狄成浩》是一套全面介绍ThinkPHP框架的实战教学资源,由知名IT教育机构“兄弟连”提供,主讲人为狄成浩。这套教程通过源代码实例,帮助学员深入理解并掌握ThinkPHP框架的使用...

    ThinkPHP——开源PHP框架

    ThinkPHP入门和介绍~!! ThinkPHP是一个开源的PHP框架,是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。支持WIN/Unix服务器环境。

    thinkphp_3.2.4.rar

    《深入理解ThinkPHP 3.2.4框架》 ThinkPHP 3.2.4是ThinkPHP框架的一个重要版本,其主要关注历史安全更新,旨在为开发者提供更稳定、更安全的开发环境。这个版本的发布,对于那些仍在使用3.2.*系列的开发者来说,是...

    ThinkPHP5.0-快速入门手册合集(新手教程版)

    ThinkPHP V5.0——为API开发而设计的高性能框架。新版是一个颠覆和重构版本,基于PHP5设计,采用全新的架构思想,引入了很多的PHP新特性,优化了核心,减少了依赖,实现了真正的惰性加载,并针对API开发做了大量的...

    ThinkPHP_v5.0.7.zip_ThinkPHP V5.0.7_thinkphp

    首先,我们要了解ThinkPHP的核心理念——"快速、简单"。在ThinkPHP V5.0.7中,这一理念得到了充分的体现。它采用模块化设计,使得项目结构清晰,代码组织有序,大大简化了开发流程。同时,该框架支持自动路由和控制...

    thinkphp_thinkphp_thinkphp5_

    首先,我们要理解ThinkPHP5的核心设计理念——“简洁、快速、优雅”。它遵循MVC(Model-View-Controller)设计模式,将业务逻辑、数据处理和视图展示分离,使代码更易于维护和扩展。其中,模板(View)部分是用户...

    ThinkPHP框架实践-内含源码以及设计说明书(可以自己运行复现).zip

    《ThinkPHP框架实践详解》 在当今的Web开发领域,框架的应用已经成为提高开发效率和代码质量的重要工具。ThinkPHP作为国内广泛使用的PHP框架之一,深受开发者喜爱。本实践教程将带你深入理解ThinkPHP的核心概念,并...

    PHP实例开发源码——双鱼林基于ThinkPHP5图书管理系统demo.zip

    通过深入分析这些文件,开发者可以了解如何在ThinkPHP5框架下构建一个完整的Web应用,同时也可以借鉴其中的设计模式和最佳实践,提高自己的开发能力。此外,对于想了解图书管理系统的人来说,这是一个很好的起点,...

    ThinkPHP自己设计的后台系统

    通过持续学习和实践,开发者可以掌握更多高级特性和最佳实践,进一步提升开发效率和产品质量。在学习交流的过程中,我们可以相互借鉴,共同进步,让ThinkPHP成为我们构建强大后台系统的得力助手。

    thinkphp3 与thinkphp5 日志信息泄露检测脚本.zip

    在IT安全领域,日志信息泄露是一个严重的安全隐患,特别是...通过理解日志系统的运作,遵循最佳实践,并利用如“thinkphp日志信息泄露检测脚本”这样的工具,可以有效地防止这类风险,保护你的应用程序和用户数据安全。

    thinkphp5.0.rar

    它还可能涉及路由规则的定制,RESTful API的设计,以及控制器的组织结构和最佳实践。 4. **thinkphp.txt**:这个文件可能包含ThinkPHP5的安装步骤、基本配置示例、常见问题解答,或者是开发者在实践中总结的一些...

    thinkphp漏洞检测工具

    此外,了解ThinkPHP的安全最佳实践,如合理使用模型层、避免硬编码数据库连接信息、正确处理用户输入等,也是防止漏洞发生的关键。 总的来说,ThinkPHP漏洞检测工具是保障Web应用安全的重要手段。通过合理利用这些...

    thinkphp-bjyblog, 基于thinkphp开发的的个人博客系统thinkphp-bjyblog.zip

    《基于ThinkPHP开发的个人博客系统——深入解析thinkphp-bjyblog》 ThinkPHP,作为国内广泛应用的PHP框架,以其简洁、高效的特性深受开发者喜爱。本篇文章将深入解析一个基于ThinkPHP框架开发的个人博客系统——...

    thinkphp5.0完全开发手册(pdf)

    ### ThinkPHP5.0完全开发手册关键知识点概览 #### 一、ThinkPHP5.0简介与特性 - **框架定位**:ThinkPHP5.0是一个面向对象的轻量级PHP开发框架,专为敏捷Web应用开发和简化企业级应用开发而设计。 - **设计理念**:...

    ThinkPHP5快速入门

    ThinkPHP5提供了输入验证、SQL注入防御、XSS防护等安全措施,但开发者仍需保持警惕,遵循最佳安全实践,避免潜在的安全风险。 总结来说,《ThinkPHP5快速入门》涵盖了框架的基本结构、核心组件、常用功能及安全策略...

    thinkphp完整源码.rar

    总结,"thinkphp完整源码.rar"是学习和研究ThinkPHP框架的宝贵资源,通过对源码的深入理解和实践,开发者不仅可以掌握框架的使用,还能提升自己的编程技巧和架构设计能力。在实际开发中,结合框架的灵活性和强大功能...

    ThinkPHP5留言板_thinkphp5_

    总的来说,这个项目为学习ThinkPHP5提供了实践机会,涵盖了框架的基本使用,如路由、控制器、视图和模型的创建,以及如何整合第三方库和数据库操作。通过这个项目,开发者可以深入理解MVC模式,学习如何构建一个简单...

    PHP实例开发源码——基于ThinkPHP5图书管理系统demo.zip

    在实际学习过程中,建议逐步分析每个文件的功能,结合框架文档和在线教程,深入理解ThinkPHP5的工作原理和最佳实践。这样不仅可以提升你的PHP编程能力,也能为未来开发其他Web应用打下坚实基础。

Global site tag (gtag.js) - Google Analytics