前几天看见 iVane 的 Blog 有篇文章是介绍如何动态文字替换的。但是结尾很遗憾的说这个功能强大的软件不支持中文。
我当时就答应下来帮他 Hack 一下。过了几天我差不多把这个事情给忘记了,直到他今天下午“催”了我一下,我才记得有这回事情。iVane 兄弟不好意思啦。
对了,让大家久等了。这就是支持中文的动态文字替换(Dynamic Text Replacement)。需要有几点要说明:
- 页面(HTML)的编码要是 utf-8 的(我使用这个编码测试的,其他的编码没有测试过)
- 字体文件尽量使用英文文件名,以免造成不必要的麻烦
- 第一次运行由于需要生成图片,所以效果在第二次运行的出现
- 调用的时候使用文件名(UNIX 主机请注意大小写),比如文件名为 jianyy.ttf 则在 css 中设置名称为 jianyy (参看 DEMO 的 CSS 文件)。
- 由于使用缓存机制,请务必将 dtr/cache 目录设置为可写
- 经过测试,虽然此程序使用了缓存机制,但是占用的服务器运行资源还是比较多的,请谨慎使用
- 最后就是注意下字体的版权问题,DEMO 中的字体为“简 YY 体”版权未知
最后 DEMO 在这里,打包的文件可以在这里下载,相关的教程可以参看 iVane 兄弟的相关文档。
如有任何问题,欢迎留言。
最近在编写 Grace PHP5 Framework 中,我得到很多类的实例化的心得。Grace PHP5 Framework 是一个完全基于 MVC 架构的框架,具有良好的扩展性。它对于类的调用可以说非常的灵活。
下面是调用一个模型(Module)的函数。这个函数的基本功能是指定一个模型(抽象化为类)的名称,然后它会在模型目录下面寻找这个类的脚本实例化以后返回。这样的做法有一点好处就是载入和实例化是自动的,你可以获得最大的灵活性。下面请看下面的代码,它并不长而且不复杂:
function &load_class($class_name, $param = null, $instantiate = true)
{
static $objects = array();
$class_name = ucfirst(strtolower($class_name));
if (isset($objects[$class_name])) {
return $objects[$class_name];
}
$class_file = DIR_MODELS . "/{$class_name}.inc.php";
if (file_exists($class_file)) {
require_once $class_file;
if (!class_exists($class_name)) {
return false;
} else {
$objects[$class_name] =& new $class_name($param);
return $objects[$class_name];
}
} else {
if ($instantiate) {
$objects[$class_name] = null;
}
return null;
}
}函数只有三个参数,分别是 $class_name 、$param 以及 $instaniate ,其中 $param 是构造函数的参数,$instaniate 是可选的。请注意函数中的 $objects 数组是一个静态变量,也就是当调用完这个函数的时候数组并不会释放,下次调用此函数时这个数组的数据是会保存的。这样做的好处就是可以将大部分的类实例了以后,如需要重复调用则直接返回这个类的实例就可以了,避免了重复调用,提高了性能。代码如下:
static $objects = array();
if (isset($objects[$class_name])) {
return $objects[$class_name];
}其它继续的代码就是检测是否有这个类名称的文件,如果有载入这个文件并寻找指定名称的类,如找到了这个类以后就实例化。这要求脚本中类的名称必须和脚本的文件名是一致的。我想这也有利于以后的代码管理。
$instaniate 参数这个时候就发挥了功效,这个参数会告诉函数如果未找到则在 $objects 下面做一个标记位(null)避免函数又重复的寻找文件名并重复载入和寻找。
$class_file = DIR_MODELS . "/{$class_name}.inc.php";
if (file_exists($class_file)) {
require_once $class_file;
if (!class_exists($class_name)) {
return false;
} else {
$objects[$class_name] =& new $class_name($param);
return $objects[$class_name];
}
} else {
if ($instantiate) {
$objects[$class_name] = null;
}
return null;
}其中语句:
$objects[$class_name] =& new $class_name($param);
可以多次的推敲一下。$class_name 在函数中是一个字符串变量。关键字 new 可以动态的实例化指定字符串的类(如果存在的话)。有关此调用方法可以参见 PHP 手册和这里。
此函数的不足之处就是如何去考虑传递不同个数的参数给每个不同的类的构造函数。或许可以使用 call_user_func_array 等函数实现,但是这样的做法非常的不 Grace。在这里需要推敲一下。其实 file_exists 等文件存在的测试可以交给 __autoload 函数处理,不过由于其他的函数比如 interface_exists 等也会调用 __autolaod 函数,出于兼容性的考虑,所以只在函数内做一个简单的测试。
PHP5 相对 PHP4 而言更加的面向对象。我想是时候更新我们我们的编码思想了。有关 PHP5 的类和对象,这里有一个非常好的教程。
附:此文档相关脚本打包下载,请运行 index.php 文件。