PHP's var_export in JavaScript

Here’s what our current JavaScript equivalent to PHP's var_export looks like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
module.exports = function var_export (mixedExpression, boolReturn) { // eslint-disable-line camelcase
// discuss at: http://locutus.io/php/var_export/
// original by: Philip Peterson
// improved by: johnrembo
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: Brian Tafoya (http://www.premasolutions.com/)
// input by: Hans Henrik (http://hanshenrik.tk/)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// example 1: var_export(null)
// returns 1: null
// example 2: var_export({0: 'Kevin', 1: 'van', 2: 'Zonneveld'}, true)
// returns 2: "array (\n 0 => 'Kevin',\n 1 => 'van',\n 2 => 'Zonneveld'\n)"
// example 3: var data = 'Kevin'
// example 3: var_export(data, true)
// returns 3: "'Kevin'"

var echo = require('../strings/echo')
var retstr = ''
var iret = ''
var value
var cnt = 0
var x = []
var i = 0
var funcParts = []
// We use the last argument (not part of PHP) to pass in
// our indentation level
var idtLevel = arguments[2] || 2
var innerIndent = ''
var outerIndent = ''
var getFuncName = function (fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn)
if (!name) {
return '(Anonymous)'
}
return name[1]
}

var _makeIndent = function (idtLevel) {
return (new Array(idtLevel + 1))
.join(' ')
}
var __getType = function (inp) {
var i = 0
var match
var types
var cons
var type = typeof inp
if (type === 'object' && (inp && inp.constructor) &&
getFuncName(inp.constructor) === 'LOCUTUS_Resource') {
return 'resource'
}
if (type === 'function') {
return 'function'
}
if (type === 'object' && !inp) {
// Should this be just null?
return 'null'
}
if (type === 'object') {
if (!inp.constructor) {
return 'object'
}
cons = inp.constructor.toString()
match = cons.match(/(\w+)\(/)
if (match) {
cons = match[1].toLowerCase()
}
types = ['boolean', 'number', 'string', 'array']
for (i = 0; i < types.length; i++) {
if (cons === types[i]) {
type = types[i]
break
}
}
}
return type
}
var type = __getType(mixedExpression)

if (type === null) {
retstr = 'NULL'
} else if (type === 'array' || type === 'object') {
outerIndent = _makeIndent(idtLevel - 2)
innerIndent = _makeIndent(idtLevel)
for (i in mixedExpression) {
value = var_export(mixedExpression[i], 1, idtLevel + 2)
value = typeof value === 'string' ? value.replace(/</g, '&lt;')
.replace(/>/g, '&gt;') : value
x[cnt++] = innerIndent + i + ' => ' +
(__getType(mixedExpression[i]) === 'array' ? '\n' : '') + value
}
iret = x.join(',\n')
retstr = outerIndent + 'array (\n' + iret + '\n' + outerIndent + ')'
} else if (type === 'function') {
funcParts = mixedExpression.toString().match(/function .*?\((.*?)\) \{([\s\S]*)\}/)

// For lambda functions, var_export() outputs such as the following:
// '\000lambda_1'. Since it will probably not be a common use to
// expect this (unhelpful) form, we'll use another PHP-exportable
// construct, create_function() (though dollar signs must be on the
// variables in JavaScript); if using instead in JavaScript and you
// are using the namespaced version, note that create_function() will
// not be available as a global
retstr = "create_function ('" + funcParts[1] + "', '" +
funcParts[2].replace(new RegExp("'", 'g'), "\\'") + "')"
} else if (type === 'resource') {
// Resources treated as null for var_export
retstr = 'NULL'
} else {
retstr = typeof mixedExpression !== 'string' ? mixedExpression
: "'" + mixedExpression.replace(/(["'])/g, '\\$1').replace(/\0/g, '\\0') + "'"
}

if (!boolReturn) {
echo(retstr)
return null
}

return retstr
}
[ View on GitHub | Edit on GitHub | Source on GitHub ]

How to use

You you can install via npm install locutus and require it via require('locutus/php/var/var_export'). You could also require the var module in full so that you could access var.var_export instead.

If you intend to target the browser, you can then use a module bundler such as Browserify, webpack or rollup.js.

ES5/ES6

This function targets ES5, but as of Locutus 2.0.2 we also support ES6 functions. Locutus transpiles to ES5 before publishing to npm.

A community effort

Not unlike Wikipedia, Locutus is an ongoing community effort. Our philosophy follows The McDonald’s Theory. This means that we don't consider it to be a bad thing that many of our functions are first iterations, which may still have their fair share of issues. We hope that these flaws will inspire others to come up with better ideas.

This way of working also means that we don't offer any production guarantees, and recommend to use Locutus inspiration and learning purposes only.

Examples

Please note that these examples are distilled from test cases that automatically verify our functions still work correctly. This could explain some quirky ones.

#codeexpected result
1var_export(null)null
2var_export({0: 'Kevin', 1: 'van', 2: 'Zonneveld'}, true)"array (\n 0 => 'Kevin',\n 1 => 'van',\n 2 => 'Zonneveld'\n)"
3var data = 'Kevin' var_export(data, true)"'Kevin'"

« More PHP var functions