Skip to content

Commit a50bd23

Browse files
authored
Merge pull request #157 from aminurislamarnob/feature/unserializer
feat(utilities): add Unserializer tool with print_r and var_dump output
2 parents a646dd3 + 1b79c14 commit a50bd23

5 files changed

Lines changed: 836 additions & 0 deletions

File tree

components/seo/UnserializerSEO.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
export default function UnserializerSEO() {
2+
return (
3+
<div className="content-wrapper">
4+
<section>
5+
<h2>Free Online Unserializer - Parse Serialized Data Instantly</h2>
6+
<p>
7+
Paste a serialized string and instantly convert it into a
8+
human-readable format. Choose between print_r() for a quick overview
9+
or var_dump() for type-annotated detail. Ideal for inspecting
10+
WordPress options, transients, and metadata stored in the database.
11+
</p>
12+
</section>
13+
14+
<section>
15+
<h2>How to Use the Unserializer</h2>
16+
<ul>
17+
<li>
18+
<b>Step 1:</b> <br />
19+
Paste a serialized string into the input box. You can grab these
20+
from database fields, API responses, or debug logs.
21+
</li>
22+
<li>
23+
<b>Step 2:</b> <br />
24+
Select an output format — <kbd>print_r()</kbd> for a compact view or{" "}
25+
<kbd>var_dump()</kbd> for detailed type and length information.
26+
</li>
27+
<li>
28+
<b>Step 3:</b> <br />
29+
Copy the formatted output and use it in your debugging workflow.
30+
</li>
31+
</ul>
32+
</section>
33+
34+
<section>
35+
<h2>FAQs</h2>
36+
<ul>
37+
<li>
38+
<b>What is a serialized string?</b>
39+
<br />
40+
Serialization converts a data structure into a compact string
41+
representation for storage or transfer. This tool reverses that
42+
process so you can read the original data.
43+
</li>
44+
<li>
45+
<b>Where do I find serialized data?</b>
46+
<br />
47+
Common sources include the WordPress wp_options table, user meta
48+
fields, WooCommerce order meta, transient caches, and plugin
49+
settings stored in the database.
50+
</li>
51+
<li>
52+
<b>What is the difference between print_r() and var_dump()?</b>
53+
<br />
54+
print_r() shows values and structure in a concise format. var_dump()
55+
adds explicit type and length annotations for every value, which is
56+
more useful for type-sensitive debugging.
57+
</li>
58+
<li>
59+
<b>Does this tool modify the original data?</b>
60+
<br />
61+
No. The tool only reads and formats the input — nothing is stored,
62+
sent, or altered.
63+
</li>
64+
</ul>
65+
</section>
66+
</div>
67+
);
68+
}

components/utils/tools-list.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ export const tools = [
2323
"Format and beautify your JSON data for better readability and debugging. Quickly visualize and organize your JSON data with ease.",
2424
link: "/utilities/json-formatter",
2525
},
26+
{
27+
title: "Unserializer",
28+
description:
29+
"Parse serialized strings and render readable output in print_r() or var_dump() format. Useful for debugging WordPress database values.",
30+
link: "/utilities/unserializer",
31+
},
2632
{
2733
title: "JSONL Validator",
2834
description:
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import {
2+
formatPrintR,
3+
formatVarDump,
4+
isValidSerialized,
5+
unserialize,
6+
} from "./unserializer.utils";
7+
8+
describe("unserializer.utils", () => {
9+
describe("unserialize", () => {
10+
test("parses primitive values", () => {
11+
expect(unserialize('s:5:"hello";')).toEqual({
12+
type: "string",
13+
value: "hello",
14+
});
15+
expect(unserialize("i:42;")).toEqual({ type: "int", value: 42 });
16+
expect(unserialize("d:3.14;")).toEqual({ type: "float", value: 3.14 });
17+
expect(unserialize("b:1;")).toEqual({ type: "bool", value: true });
18+
expect(unserialize("b:0;")).toEqual({ type: "bool", value: false });
19+
expect(unserialize("N;")).toEqual({ type: "null" });
20+
});
21+
22+
test("parses multi-byte UTF-8 strings", () => {
23+
expect(unserialize('s:4:"😊";')).toEqual({
24+
type: "string",
25+
value: "😊",
26+
});
27+
});
28+
29+
test("parses nested arrays from sample payload", () => {
30+
const input =
31+
'a:2:{i:0;s:12:"Sample array";i:1;a:2:{i:0;s:5:"Apple";i:1;s:6:"Orange";}}';
32+
33+
expect(unserialize(input)).toEqual({
34+
type: "array",
35+
entries: [
36+
{
37+
key: { type: "int", value: 0 },
38+
value: { type: "string", value: "Sample array" },
39+
},
40+
{
41+
key: { type: "int", value: 1 },
42+
value: {
43+
type: "array",
44+
entries: [
45+
{
46+
key: { type: "int", value: 0 },
47+
value: { type: "string", value: "Apple" },
48+
},
49+
{
50+
key: { type: "int", value: 1 },
51+
value: { type: "string", value: "Orange" },
52+
},
53+
],
54+
},
55+
},
56+
],
57+
});
58+
});
59+
60+
test("resolves references", () => {
61+
const result = unserialize('a:2:{s:1:"x";s:3:"foo";s:1:"y";R:2;}');
62+
expect(result).toEqual({
63+
type: "array",
64+
entries: [
65+
{
66+
key: { type: "string", value: "x" },
67+
value: { type: "string", value: "foo" },
68+
},
69+
{
70+
key: { type: "string", value: "y" },
71+
value: { type: "string", value: "foo" },
72+
},
73+
],
74+
});
75+
});
76+
77+
test("throws clear errors for invalid input", () => {
78+
expect(() => unserialize("")).toThrow(
79+
"Please enter a serialized string."
80+
);
81+
expect(() => unserialize("xyz")).toThrow();
82+
expect(() => unserialize('a:1:{s:1:"x";R:99;}')).toThrow(
83+
"Reference index 99 does not exist"
84+
);
85+
});
86+
});
87+
88+
describe("isValidSerialized", () => {
89+
test("returns true for valid payloads and false for invalid payloads", () => {
90+
expect(isValidSerialized('s:5:"hello";')).toBe(true);
91+
expect(isValidSerialized("i:42;")).toBe(true);
92+
expect(isValidSerialized("")).toBe(false);
93+
expect(isValidSerialized("not serialized")).toBe(false);
94+
});
95+
});
96+
97+
describe("formatPrintR", () => {
98+
test("matches expected output for sample payload", () => {
99+
const input =
100+
'a:2:{i:0;s:12:"Sample array";i:1;a:2:{i:0;s:5:"Apple";i:1;s:6:"Orange";}}';
101+
const parsed = unserialize(input);
102+
103+
const expected = [
104+
"Array",
105+
"(",
106+
" [0] => Sample array",
107+
" [1] => Array",
108+
" (",
109+
" [0] => Apple",
110+
" [1] => Orange",
111+
" )",
112+
"",
113+
")",
114+
].join("\n");
115+
116+
expect(formatPrintR(parsed)).toBe(expected);
117+
});
118+
});
119+
120+
describe("formatVarDump", () => {
121+
test("matches expected output for sample payload", () => {
122+
const input =
123+
'a:2:{i:0;s:12:"Sample array";i:1;a:2:{i:0;s:5:"Apple";i:1;s:6:"Orange";}}';
124+
const parsed = unserialize(input);
125+
126+
const expected = [
127+
"array(2) {",
128+
" [0]=>",
129+
' string(12) "Sample array"',
130+
" [1]=>",
131+
" array(2) {",
132+
" [0]=>",
133+
' string(5) "Apple"',
134+
" [1]=>",
135+
' string(6) "Orange"',
136+
" }",
137+
"}",
138+
].join("\n");
139+
140+
expect(formatVarDump(parsed)).toBe(expected);
141+
});
142+
143+
test("uses UTF-8 byte length for strings", () => {
144+
const parsed = unserialize('s:4:"😊";');
145+
expect(formatVarDump(parsed)).toBe('string(4) "😊"');
146+
});
147+
});
148+
});

0 commit comments

Comments
 (0)