MediaWiki REL1_31
QuickArrayReader.php
Go to the documentation of this file.
1<?php
2
10 private $vars = [];
11
15 function __construct( $string ) {
16 $scalarTypes = [
17 T_LNUMBER => true,
18 T_DNUMBER => true,
19 T_STRING => true,
20 T_CONSTANT_ENCAPSED_STRING => true,
21 ];
22 $skipTypes = [
23 T_WHITESPACE => true,
24 T_COMMENT => true,
25 T_DOC_COMMENT => true,
26 ];
27 $tokens = token_get_all( $string );
28 $count = count( $tokens );
29 for ( $i = 0; $i < $count; ) {
30 while ( isset( $skipTypes[$tokens[$i][0]] ) ) {
31 $i++;
32 }
33 switch ( $tokens[$i][0] ) {
34 case T_OPEN_TAG:
35 $i++;
36 break;
37 case T_VARIABLE:
38 // '$messages' -> 'messages'
39 $varname = trim( substr( $tokens[$i][1], 1 ) );
40 $varindex = null;
41
42 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
43 }
44
45 if ( $tokens[$i] === '[' ) {
46 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
47 }
48
49 if ( isset( $scalarTypes[$tokens[$i][0]] ) ) {
50 $varindex = $this->parseScalar( $tokens[$i] );
51 } else {
52 throw $this->except( $tokens[$i], 'scalar index' );
53 }
54 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
55 }
56
57 if ( $tokens[$i] !== ']' ) {
58 throw $this->except( $tokens[$i], ']' );
59 }
60 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
61 }
62 }
63
64 if ( $tokens[$i] !== '=' ) {
65 throw $this->except( $tokens[$i], '=' );
66 }
67 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
68 }
69
70 if ( isset( $scalarTypes[$tokens[$i][0]] ) ) {
71 $buildval = $this->parseScalar( $tokens[$i] );
72 } elseif ( $tokens[$i][0] === T_ARRAY ) {
73 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
74 }
75 if ( $tokens[$i] !== '(' ) {
76 throw $this->except( $tokens[$i], '(' );
77 }
78 $buildval = [];
79 do {
80 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
81 }
82
83 if ( $tokens[$i] === ')' ) {
84 break;
85 }
86 if ( isset( $scalarTypes[$tokens[$i][0]] ) ) {
87 $key = $this->parseScalar( $tokens[$i] );
88 }
89 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
90 }
91
92 if ( $tokens[$i][0] !== T_DOUBLE_ARROW ) {
93 throw $this->except( $tokens[$i], '=>' );
94 }
95 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
96 }
97
98 if ( isset( $scalarTypes[$tokens[$i][0]] ) ) {
99 $val = $this->parseScalar( $tokens[$i] );
100 }
102 $buildval[$key] = $val;
104 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
105 }
106
107 if ( $tokens[$i] === ',' ) {
108 continue;
109 } elseif ( $tokens[$i] === ')' ) {
110 break;
111 } else {
112 throw $this->except( $tokens[$i], ', or )' );
113 }
114 } while ( true );
115 } else {
116 throw $this->except( $tokens[$i], 'scalar or array' );
117 }
118 if ( is_null( $varindex ) ) {
119 $this->vars[$varname] = $buildval;
120 } else {
122 $this->vars[$varname][$varindex] = $buildval;
124 }
125 while ( isset( $skipTypes[$tokens[++$i][0]] ) ) {
126 }
127 if ( $tokens[$i] !== ';' ) {
128 throw $this->except( $tokens[$i], ';' );
129 }
130 $i++;
131 break;
132 default:
133 throw $this->except( $tokens[$i], 'open tag, whitespace, or variable.' );
134 }
135 }
136 }
137
143 private function except( $got, $expected ) {
144 if ( is_array( $got ) ) {
145 $got = token_name( $got[0] ) . " ('" . $got[1] . "')";
146 } else {
147 $got = "'" . $got . "'";
148 }
149
150 return new Exception( "Expected $expected, got $got" );
151 }
152
160 function parseScalar( $token ) {
161 if ( is_array( $token ) ) {
162 $str = $token[1];
163 } else {
164 $str = $token;
165 }
166 if ( $str !== '' && $str[0] == '\'' ) {
167 // Single-quoted string
168 // @fixme trim() call is due to mystery bug where whitespace gets
169 // appended to the token; without it we ended up reading in the
170 // extra quote on the end!
171 return strtr( substr( trim( $str ), 1, -1 ),
172 [ '\\\'' => '\'', '\\\\' => '\\' ] );
173 }
174
176 if ( $str !== '' && $str[0] == '"' ) {
177 // Double-quoted string
178 // @fixme trim() call is due to mystery bug where whitespace gets
179 // appended to the token; without it we ended up reading in the
180 // extra quote on the end!
182 return stripcslashes( substr( trim( $str ), 1, -1 ) );
183 }
185
186 if ( substr( $str, 0, 4 ) === 'true' ) {
187 return true;
188 }
189
190 if ( substr( $str, 0, 5 ) === 'false' ) {
191 return false;
192 }
193
194 if ( substr( $str, 0, 4 ) === 'null' ) {
195 return null;
196 }
197
198 // Must be some kind of numeric value, so let PHP's weak typing
199 // be useful for a change
200 return $str;
201 }
202
207 function getVar( $varname ) {
208 if ( isset( $this->vars[$varname] ) ) {
209 return $this->vars[$varname];
210 } else {
211 return null;
212 }
213 }
214}
wfRestoreWarnings()
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
Quickie parser class that can happily read the subset of PHP we need for our localization arrays safe...
except( $got, $expected)
parseScalar( $token)
Parse a scalar value in PHP.
$tokens