首页 理论教育PHPMVC开发实战:使用

PHPMVC开发实战:使用

【摘要】:_map属性可以将HTML表单中的元素以别名的方式映射到真实的数据表字段,和其他属性一样,_map属性也必须定义在自定义模型中,该属性的值为二维数组,下面以7.1.3节内容为基础,修改add_article.html表单元素与add动作代码,并在Article模型中创建createAdd方法,用于处理表单数据。接下来在Article模型中使用_map属性将这些元素映射为tpk_article表中的相应字段。

通过在自定义模型中定义类成员属性,可以更改模型与数据表的属性,提高自定义模型的灵活性。在自定义模型中,常见的成员属性包括fields、tableName、dbName、_map等,这些属性都必须修饰为protected权限,下面分别介绍。

1.fields属性(表字段)

在模型里可以定义fields属性,该属性的值为一个二维数组,数组元素会被系统映射为数据表字段。默认情况下,在第一次初始化模型时,系统会将数据表字段写入到缓存文件中,这些缓存文件名称与数据表名相同,如tpk_articl.php。缓存数据表字段能够提高数据的响应速度,减少查询时的资源消耗。但是默认情况下,系统会将表中的所有字段进行缓存,但往往我们只需要表中的某个字段,这无疑会造成性能损失。另外,如果数据表字段过多,在进行缓存时将会造成极大的IO开销,形成性能瓶颈,尤其在大型的分布式开发中更是需要注意。在fields属性中进行明文定义数据表字段,能够避免系统对数据表字段进行文件缓存。由于字段是明文标识的,系统在进行数据库操作时不会重复与数据表进行映射,而是与明文定义的fields属性值直接映射,这样就有效地提高了数据操作效率

定义fields属性,需要在自定义模型中进行。在定义模型字段时,系统会默认模型字段添加一个主键id,但更良好的编程习惯是显式指定,开发人员可以使用_pk元素指定主键字段,并使用_autoinc元素指定自动增长,如以下代码所示。

978-7-111-42852-7-Part02-197.jpg

如果不定义模型字段,又不需要缓存数据表字段,那么可以配置'DB_FIELDS_CACHE'=>false完全关闭字段缓存功能。如果关闭缓存,又不在自定义模型中定义fields属性,那么系统每次调用自定义模型时,都会往数据表中读取表字段。

2.tableName属性(表映射)

前面已经介绍过,模型的命名需要与数据表名相同,这样系统才能将模型与数据表进行映射,否则在调用时只能当成一个普通的系统类使用。ThinkPHP灵活之处就在于任何的操作都不是绝对的,定义模型同样也是。系统允许开发人员通过定义tableName成员属性改变当前模型与数据表映射关系,使用方式也比较简单,如以下代码所示。

978-7-111-42852-7-Part02-198.jpg

如上述代码所示,通过定义tableName属性,Article模型就被映射为news表了。tableName的值为数据表名,表名不能带表前缀,不区分大小写。需要注意的是,如果定义了fields属性,再使用tableName更改数据表名,那么fields中的字段名称需要与tableName中指定的表字段名称相同。虽然tableName能够改变表名称,但在实际应用开发中应该一个模型对应一个数据表,尽量避免使用tableName属性。

3.dbName属性(切换数据库)

dbName非常灵活和强大,尤其在超大型的分布式网站开发中,显得非常有用。dbName能够让当前模型在不牺牲性能的情况下迅速切换数据库,并且这一过程是持续的,对用户而言不需要中断当前操作。dbName默认情况下只能切换同一服务器的数据库,如果配合分布式数据库配置,也能够跨数据库服务器切换。dbName数据库切换流程如图7-4所示。

978-7-111-42852-7-Part02-199.jpg

图7-4 在自定义模型中切换数据库(www.chuimin.cn)

如图7-4所示,通常情况下Article模型被映射成tp数据库中的tpk_article数据表(根据配置文件中所配置的信息而定),如果在模型中定义了dbName属性,那么执行流程将发生改变,Article模型将会被映射为tp2数据库中的tpk_article数据表。这一过程虽然简单,但在实际应用开发中能够有效提高数据服务器的性能。利用dbName特性,开发人员可以创建两个表结构完全一样的数据库,然后在模型中动态更改dbName属性的值,实现简单的分布式开发,比如当主数据库中的tpk_article数据表过高记录时(超过百万行记录),此时可以按照记录条数比例动态切换到副数据库,就能够有效地提高数据读写性能。

切换数据库后,还可结合tableName一起使用,但意义并不大,因为通常切换数据库只作为提高性能的一种方式,如果再更改模型映射将会让代码维护变得困难。利用dbName特性,在开发数据库热备份程序时将变得容易。使用dbName非常简单,只需要在自定义模型中定义即可,代码如下。

978-7-111-42852-7-Part02-200.jpg

4._map属性(字段映射)

前面已经介绍过使用create方法可以方便地创建数据,使得表单与数据库交互变得容易。但这里面有一个不容忽视的问题,在HTML表单中的表单元素必须要与数据表中的字段名称相同,create方法才能正确创建数据,这就意味着数据表字段显式地暴露在页面中,这对要求安全严紧的网站来说是不可以接受的。虽然create方法已经对数据进行了严格的控制,但数据表字段暴露在外始终是一个安全隐患。_map属性可以将HTML表单中的元素以别名的方式映射到真实的数据表字段,和其他属性一样,_map属性也必须定义在自定义模型中,该属性的值为二维数组,下面以7.1.3节内容为基础,修改add_article.html表单元素与add动作代码,并在Article模型中创建createAdd方法,用于处理表单数据。add_article.html代码如下所示。

978-7-111-42852-7-Part02-201.jpg

978-7-111-42852-7-Part02-202.jpg

如上述代码所示,标粗的即为需要提交的表单元素,这些元素名称已经发生了改变,与数据表tpk_article中的字段完全不相关。接下来在Article模型中使用_map属性将这些元素映射为tpk_article表中的相应字段。代码如下所示。

978-7-111-42852-7-Part02-203.jpg

如上述代码所示,_map属性的值为关联数组,其中键为表单字段名称,值为需要映射的数据表字段。在处理方法中,只需要直接调用父类(Model)中的create方法即可创建正确的数据。

在表单提交处理动作中,只需要直接调用自定义模型中的createAdd方法即可,如以下代码所示。

978-7-111-42852-7-Part02-204.jpg