File Coverage

blib/lib/PHP/ParseStr.pm
Criterion Covered Total %
statement 30 30 100.0
branch 2 2 100.0
condition 4 4 100.0
subroutine 6 6 100.0
pod 0 1 0.0
total 42 43 97.6


line stmt bran cond sub pod time code
1             package PHP::ParseStr;
2              
3 1     1   494 use 5.010;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         15  
5 1     1   9 use warnings;
  1         1  
  1         49  
6              
7             our $VERSION = "0.0.2";
8              
9             use Exporter::Easy (
10 1         6 OK => [qw( php_parse_str )]
11 1     1   440 );
  1         1035  
12              
13 1     1   534 use URI;
  1         3043  
  1         165  
14              
15             =head1 NAME
16              
17             PHP::ParseStr - Implements PHP's parse_str function
18              
19             =for markdown [![Build Status](https://travis-ci.org/abayliss/php-parsestr.svg?branch=master)](https://travis-ci.org/abayliss/php-parsestr)
20              
21             =head1 SYNOPSIS
22              
23             use PHP::ParseStr qw(php_parse_str);
24             my $hr = php_parse_str("stuff[0]=things&stuff[1]=otherthings&widgit[name]=thing&widgit[id]=123");
25              
26             =head1 DESCRIPTION
27              
28             A simple implementation of PHP's C function. The inverse of
29             C (implemented by L).
30              
31             =head1 USAGE
32              
33             Pass your query string into C and get a hash ref back.
34              
35             my $hr = php_parse_str("stuff[0]=things&stuff[1]=otherthings&widgit[name]=thing&widgit[id]=123");
36             # {
37             # stuff => [ 'things', 'otherthings' ],
38             # widgit => {
39             # id => '123',
40             # name => 'thing'
41             # }
42             # }
43              
44             Note that unlike PHP's C, we return a hash ref, rather than
45             automagically creating variables in the passing scope, or filling a hash passed
46             in by reference. This is A Good Thing.
47              
48             =head1 BUGS / LIMITATIONS
49              
50             Currently I assume that anything where the "key" is numeric will be an array.
51             This will cause problems if you get structures with mixed numeric and
52             alphanumeric keys if a numeric one is encountered first.
53              
54             This module worked well enough for my purposes. YMMV. Patches welcome.
55              
56             =head1 SEE ALSO
57              
58             L does the inverse of this module.
59              
60             =head1 AUTHOR
61              
62             Andrew Bayliss
63              
64             =head1 COPYRIGHT
65              
66             This program is free software; you can redistribute
67             it and/or modify it under the same terms as Perl itself.
68              
69             The full text of the license can be found in the
70             LICENSE file included with this module.
71              
72             =cut
73              
74             # inspired by http://www.perlmonks.org/?node_id=872864
75             sub php_parse_str {
76 4     4 0 15323 my ( $str ) = @_;
77              
78 4         19 my $u = URI->new;
79 4         3525 $u->query($str);
80              
81 4         125 my %in = $u->query_form;
82 4         220 my $out = {};
83 4         15 while ( my ( $k, $v ) = each %in ) {
84 17         14 my $level = \$out;
85              
86 17         50 my @parts = $k =~ /([^\[\]]+)/g;
87 17         24 foreach (@parts) {
88 37 100       55 if ( $_ =~ /^\d+$/ ) {
89 12   100     27 $$level //= [];
90 12         20 $level = \($$level->[$_]);
91             } else {
92 25   100     44 $$level //= {};
93 25         38 $level = \($$level->{$_});
94             }
95             }
96 17         39 $$level = $v;
97             }
98              
99 4         15 return $out;
100             }
101              
102             return "Perfectly Horrible Poppycock";