Devil May Code...

Vergil's Blog

像我这种JavaScript水平较渣的php程序员,有时很想用php的方式处理前端js的数据。比如格式化日期、字符串,或者一些生成哈希的操作。

Locutus是一个试图将其他语言的标准库同化为JavaScript的项目。其实我早就关注它了,没记错的话它以前叫phpjs,所谓的其他语言(C、Go、Python、Ruby、PHP),其实主要还是php,另外几种语言目前只有寥寥可数几个函数。

Locutus一般运行于Node.js环境,这篇博文主要介绍的是如何运行在浏览器环境。

Locutus可用的php函数,作用和php同名函数相同。详情请参阅http://locutus.io/php/。

安装Node和npm

npm 全名為 Node Package Manager,是 Node.js 的包(package)管理工具, 类似 Perl 的 ppm 或 PHP 的 PEAR 等。

安装过程请自行Google、baidu。或者看这篇文章

安装Locutus

使用npm安装:

$ npm install locutus

或者可以使用bower安装:

$ bower install locutus

安装完成后,代码默认存放在当前目录的node_modules/locutus目录下。(bower安装的在bower_components/locutus/src目录下)

安装Browserify

需要在浏览器端运行Locutus,需要用一些模块包(module bundler)来构建。比如 Browserify,webpack,rollup.js。这里以Browserify为例。

使用以下命令,安装Browserify(-g代表全局):

$ npm install -g browserify

例子一:使用某个函数

以php的md5()为例:

首先,进入Locutus代码目录,可以看到如下目录结构,按语言划分的多个目录:

$ pwd
/data/htdocs/phpjs/node_modules/locutus
$ ls -l
total 32
drwxr-xr-x   6 vergil  staff   204 10 11 23:46 _util
drwxr-xr-x   5 vergil  staff   170 10 11 23:46 c
drwxr-xr-x   5 vergil  staff   170 10 11 23:46 golang
-rw-r--r--   1 vergil  staff   268  6 16 14:54 index.js
-rw-r--r--   1 vergil  staff   564  6 16 14:54 index.js.map
-rw-r--r--   1 vergil  staff  4180 10 11 23:46 package.json
drwxr-xr-x  27 vergil  staff   918 10 12 00:14 php
drwxr-xr-x   5 vergil  staff   170 10 11 23:46 python
drwxr-xr-x   5 vergil  staff   170 10 11 23:46 ruby

进入php目录,可以看到按功能或扩展(extesion)划分的目录(详见:http://locutus.io/php/):

$ cd php 
$ ls
_helpers        ctype           funchand        info            net-gopher      url
_locutus_shared datetime        i18n            json            network         var
array           exec            index.js        math            pcre            xdiff
bc              filesystem      index.js.map    misc            strings         xml

我们需要的md5()函数在strings目录下,进入该目录,可以看到很多已函数名命名的js文件:

$ cd strings
$ ls

现在,需要用browserify命令构建一个bundle:

$ browserify -r ./md5.js > /path/to/your/project/php-md5.js

注意!!这里的./md5.js是一个相对路径。不能直接写md5.js。详细用法请查看browserify文档

构建完毕后,引入该文件。测试一下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Locutus Test</title>
    <script src="php-md5.js"></script>
</head>
<body>
    <script>
        var md5 = require('/md5.js');
        console.log(md5('Locutus'));
    </script>
</body>
</html>

打开浏览器访问,这时你可以看到控制台输出了62df46620dd0154981d901a1a3203e9a

例子二:使用某个扩展

如上所述,php目录下的每一个扩展都代表一个目录,而每个目录下都有以函数名命名的js文件。此外,还有一个index.js文件。

$ pwd
/data/htdocs/phpjs/node_modules/locutus/php
$ find . -name "index.js"
./_helpers/index.js
./_locutus_shared/index.js
./array/index.js
./bc/index.js
./ctype/index.js
./datetime/index.js
./exec/index.js
./filesystem/index.js
./funchand/index.js
./i18n/index.js
./index.js
./info/index.js
./json/index.js
./math/index.js
./misc/index.js
./net-gopher/index.js
./network/index.js
./pcre/index.js
./strings/index.js
./url/index.js
./var/index.js
./xdiff/index.js
./xml/index.js

如果你想使用某个扩展的所有函数,比如array。可以使用browserify命令构建一个bundle:

$ pwd
/data/htdocs/phpjs/node_modules/locutus/php/array
$ browserify -r ./index.js > /data/htdocs/phpjs/php-array.js

另外,可以使用./file_name.js:module_name为模块起一个名字(建议)。比如php-array

$ browserify -r ./index.js:php-array > /data/htdocs/phpjs/php-array.js

引入文件,测试:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Locutus Test</title>
    <script src="php-array.js"></script>
</head>
<body>
    <script>
        /*
         * 这里要注意的是require('模块名')
         * 在browserify构建的时候使用了模块名,那么就写那个模块名,如上所示,我用的是php-array
         * 否则,browserify就让模块名为文件名,也就是/index.js
         */
        var php_array = require('php-array');
        console.log(typeof php_array.in_array);

        var in_array = php_array.in_array;
        console.log(in_array(1, ['1', '2', '3']));
        console.log(in_array(1, ['1', '2', '3'], true));
        console.log(in_array('vergil', {author: 'vergil', email: 'vergil@vip.163.com'}));
    </script>
</body>
</html>

打开浏览器访问,控制台输出如下结果:

function
true
false
true

例子三:引入全部函数

其实原理还是一样,我就不多说了,直接上代码:

$ pwd
/data/htdocs/phpjs/node_modules/locutus/php
$ browserify -r ./index.js:php-js > /data/htdocs/phpjs/php-js.js

HTML:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Locutus Test</title>
    <script src="php-js.js"></script>
</head>
<body>
    <script>
        var phpjs = require('php-js');
        //array_diff
        console.log( phpjs.array.array_diff(['red', 'green', 'blue', 'yellow'], ['red', 'blue']));
        //array_combine
        console.log ( phpjs.array.array_combine(['name', 'gender'], ['Vergil', 'male']));
        //strtotime
        console.log( phpjs.datetime.strtotime("next Thursday"));
        //pow
        console.log( phpjs.math.pow(2, 10));
        //ip2long
        console.log( phpjs.network.ip2long('8.8.8.8'));
        //uniqid
        console.log( phpjs.misc.uniqid('', true));
        //strpos
        console.log( phpjs.strings.strpos('vergil@vip.163.com', '@') );
        //base64
        var encode = phpjs.url.base64_encode('这是一个字符串');
        console.log(encode);
        console.log( phpjs.url.base64_decode(encode));
        //sprintf
        console.log ( phpjs.strings.sprintf('The %2$s contains %1$04d monkeys', 5, 'tree'));
    </script>
</body>
</html>

结果:

Object { 1="green",  3="yellow"}
 Object { name="Vergil",  gender="male"}
1476299514.638
1024
134744072
57fd397a684de7.98316832
6
JTI1RTglMjVCRiUyNTk5JTI1RTYlMjU5OCUyNUFGJTI1RTQlMjVCOCUyNTgwJTI1RTQlMjVCOCUyNUFBJTI1RTUlMjVBRCUyNTk3JTI1RTclMjVBQyUyNUE2JTI1RTQlMjVCOCUyNUIy
这是一个字符串
The tree contains 0005 monkeys

小结

  • JS太强大了...
  • 并不是意味着可以用php的方式来写js,反之,应该多学习js
  • 可以选取部分复杂的功能使用
  • 看看人家是怎么用JS来实现这些函数库的。

好了,目前就写这些吧,以后有什么再继续更新。Happy Hacking。


Powered by Typecho.