Gallery:编码指引
来自站长百科
此知道描述为Gallery2框架进行编码的方法,以保证它能够在所有的平台上尽可能地稳定运行,并且能够符合Gallery2的要求。
该文档不会涉及Gallery2的编码标准,即编码风格会另辟话题。
数据库[ ]
- 请勿使用依赖DBMS的SQL片断。某些依赖DBMS的SQL 在$storage->getFunctionSql()中是抽象化的,如BIT_OR, BIT_AND等。
- 请勿直接呼叫数据库相关的方法(如mysql_connect),而是使用Gallery2的方法。
global $gallery; list ($ret, $results) = $gallery->search('SELECT * FROM [GalleryPhotoItem]');
- 请勿直接修改Map表格。而是使用GalleryCoreApi::addMapEntry($mapName, ..), ::removeMapEntry, ..。
- 注: 在G2.0中,此为MapNameMap::addMapEntry()等
- 除非必要,不要创建自己的数据库查询,而应使用Gallery2的API方法。
- 不要使用DDL(SQL 语言的CREATE TABLE, ALTER TABLE, ...子集)。而是使用Entity类别以及包含有XML描述的Maps.xml来新建或修改现有的表格。接下来,一旦你在classes/目录中运行make,Gallery2就会为所有支持的DBMS生成SQL代码。
- Locking: 当你需要更新永续性数据(存储于数据库中的数据)时,使用读/写lock。记得在完成更新后,释放这些lock。
- 提示: lockIds与itemIds不同。
大型数据集[ ]
- 当处理大型数据集时,可以考虑使用进度条和$storage->checkPoint来最大限度地限制可能出现的致命超时/错误的作用。
- 不要使用WHERE / UPDATE字句进行查询,而按较小的批次进行会比较好。 举一个WHERE / UPDATE字句较差情况的例子,假设$allItemIds为一个含有1000+id的列表:
$gallery->search("SELECT * FROM [GalleryItem] WHERE [GalleryItem::id] IN ($markers)", $allItemIds);
- 注: GalleryCoreApi::loadEntitiesById()和GalleryCoreApi::acquire*Lock()均尚未修复。这就意味着你需要按较小的批次来呼叫这些方法了。就算它们被修整为可以进行批量操作,你还是要面对服务器(不是php)的超时问题。我们无法在API深层使用进度条,因为我们不确定当前视图是否支持进度条。
PHP[ ]
- 请勿在代码中呼叫die / exit / header('Location: ...'),而应在你的视图/控制器中返回一个合适的状态/重新导向url。这样Gallery2就有机会执行/回滚开启事务(open transactions),进行清除(cleanup),并未bug打上修复补丁(如header('Location:')在某些平台上有bug,而我们在请求结尾将其修复了)。
- 对于列在modules/core/classes/GalleryPhpVm.class中的PHP函数,使用
global $gallery; $phpVm =& $gallery->getPhpVm(); $phpVm->functionName();
- 引用: 参见如何处理PHP 4.4.0中的引用。作为常识,除非这么做有意义,否则的话不要使用PHP引用。而且使用引用时的性能欠佳。参见:PHP Benchmark的相关测试
- 兼容性: G2代码必须使用PHP4和5才能运行,即PHP 4.1.0+ (对G2.2则是4.3.0+)和 PHP 5.0.4+。请勿使用任何"PHP 5"-only的OO代码,也不要使用于PHP4.1.0中不可用的方法,除非你能够提供某种回退方案。
if (function_exists('foo_bar')) { foo_bar($data); } else { myFooBar($data); }
文件系统/平台[ ]
- 请勿直接呼叫任何文件系统/平台函数(如fopen,fsockopen,exec,chmod, ...),而是使用Gallery2方法。
global $gallery; $platform =& $gallery->getPlatform(); $platform->fopen($path);
字串/文本和翻译[ ]
- 对于所有显示给最终用户的字串/文本,使用
$plugin->translate('Some text')
如果文本进入数据库,并且在自数据库进行取回时translate()被呼叫的话,使用
$gallery->i18n('Some text')
在smarty模板中:
{g->text text="Some text"}
- 注: 例外情况就是GalleryStatus对象中的可选消息,以及不使用translate()的单位测试失败的消息。
- 如果你在字串中使用HTML,请使用翻译方法进行编写。
/* 不好的写法 */ $plugin->translate('Do <b>NOT</b> do this!'); /* 好的写法 */ $plugin->translate(array('text' => 'Do %sNOT%s do this!', 'arg1' => '<b>', 'arg2' => '</b>'));
- 当字串包括变量时还是使用translate参数。
/*不好的写法*/ $plugin->translate("Next, please read chapter '$chapter'"); /*好的写法*/ $plugin->translate(array('text' => "Next, please read '%s'", 'arg1' => $chapter));
在smarty模板中:
{g->text text="Next, please read '%s'" arg1=$chapter}
杂项[ ]
- URL生成: 使用Gallery提供的方法生成所有的URL。
In PHP:
global $gallery; $urlGenerator =& $gallery->getUrlGenerator(); $url = $urlGenerator->generateUrl($params, $options);
在smarty模板中:
{g->url arg1= ....}
- 代码的修改: 请勿修改现有模块的代码,而应使用额外模块扩展Gallery2的特点集。原因:用户应能使用简单的web界面管理Gallery2。新特点的添加应当是轻点加下鼠标那么简单。我们不希望看到类似"打开文件X,找到第Y行,将A替换为B ..."这样的修改类型的安装指导。如果你需要在现有模块中进行修改,请联系模块编写者,询问一下做出改动是否会导致现有模块的不兼容,最好是以某种模块化的方式,(Factory Registrations),如某模块会检查G2 factory看看是否有针对该模块的插件,而你的新模块可以为另外的模块启用一个插件,从而以模块化的方式对功能进行扩展。