1. 前言
最近翻译 Laravel 英文文档,发现官方文档还是很详细的。从前端到后端,从基础功能介绍到各种扩展使用说明,把整个框架梳理了一遍,还提供了很多示例代码。尽管 Laravel 对环境要求有点苛刻(Laravel 5.7 要求 PHP 7.1.3+),但不得不说确实是一个功能齐全、优秀的全栈框架,值得花时间深入研究研究。
这也是为什么很多人啃不动 Laravel 的原因,因为它不仅是一个 PHP 框架,更是一个全栈框架,内容实在太多了,基础不好或相关知识面不够的人很容易就被淹没在各种概念和术语中了。
前面说的是好的一面,详细的开发文档为使用框架的开发者提供了有力支持和保障。但是从维护的角度来说,框架功能齐全就意味着文档肯定也不小,维护起来很费时间。当然,只是说文档,至于框架本身,Laravel 4 时代就已经将各个组件拆分为单个扩展包,并使用 Composer 包管理器融合到框架中,并且提供完整的单元测试保证框架的健壮性和可靠性。Laravel 文档有超过 70 个章节,半个月才翻译了 45 个章节。换句话说,整整 15 天才翻译完 60%,整个文档要花上近一个月的时间!
:joy: 所以机智的 Taylor 早早的就把 Laravel 相关项目 都放到 GitHub 上了。非不为也,实不能也。多人协作开发才是正确的工作方式。
那么如何知道文档到底有多大,做到心中有数合理规划呢?或者,换成一个更常见的问题:怎样统计文档的总字数,进而估算文档需要多长时间才能读完?
2. 方案
大繁至简。由于只是估算,我们使用一个简单的公式就可以了:
时长 = 总字数 ÷ 平均阅读速度
- 总字数 - 程序直接读取。
- 平均阅读速度 - 不同语言,不同认知水平,平均阅读速度可能有所差异。搜索发现,成人的平均阅读速度为 300-500 字/分钟。我们是阅读文档,需要精读,这里使用 280 字/分钟。
那么接下来就是获取总字数了。
3. 准备工作
PHP 中有好几个获取字符串长度的函数,常见的有 strlen
,mb_strlen
,iconv_strlen
。
我们先通过一段代码看看它们有什么区别:
$str1 = <<<STR1
15-hello,world!
STR1;
$str2 = <<<STR2
8-你好,世界!
STR2;
$str3 = <<<STR3
14-中英文混合 hello
STR3;
$str4 = <<<STR4
13-带换行
world
STR4;
$table_header = <<<HEADER
<table>
<tr>
<th>字符串</th>
<th>strlen</th>
<th>mb_strlen</th>
<th>iconv_strlen</th>
</tr>
HEADER;
$table_footer = <<<FOOTER
</table>
FOOTER;
function getRow($str)
{
$row = '<tr>';
$row .= "<td>$str</td>";
$row .= "<td>" . strlen($str) . "</td>";
$row .= "<td>" . mb_strlen($str, 'UTF-8') . "</td>";
$row .= "<td>" . iconv_strlen($str , 'UTF-8') . "</td>";
$row .= "</tr>";
return $row;
}
echo $table_header,getRow($str1),getRow($str2),getRow($str3),getRow($str4),$table_footer;
具体区别如下:
strlen
- 统计字符串的字节数,我们使用 UTF-8 编码,一个中文字符用 3 个字节表示。mb_strlen
- 统计字符串的字符数,中英文、数字、标点、空格,都算一个字符。iconv_strlen
- 统计字符串的字符数,和mb_strlen
一样,都可以指定字符集。
需要注意的是,在 Windows 中使用 \r\n
作为换行符,在 Linux 中使用 \r
(0x0D)作为换行符,而在 Mac 中使用 \n
(0x0A)作为换行符。上例中,使用 Windows 的换行,所以换行算两个字符。
因此可以选用 mb_strlen
函数统计文档字数。
如果要更准确点,我们还可以在统计字符数前过滤掉 HTML 中的标签、空格、换行符:
mb_strlen(str_replace(["\r", "\n", " "], '', strip_tags($content)));
4. 代码实现
所以,最后一个 PHP 简单的代码实现是这样的:
define('WORDS_PER_MINUTE', 180);
$count = mb_strlen(str_replace(["\r", "\n", " "], '', strip_tags($content)));
$minutes = ceil($count / WORDS_PER_MINUTE);