@@ -33,17 +33,6 @@ class Dumper
3333 */
3434 public static function toLine ($ var ): string
3535 {
36- static $ table ;
37- if ($ table === null ) {
38- foreach (array_merge (range ("\x00" , "\x1F" ), range ("\x7F" , "\xFF" )) as $ ch ) {
39- $ table [$ ch ] = '\x ' . str_pad (dechex (ord ($ ch )), 2 , '0 ' , STR_PAD_LEFT );
40- }
41- $ table ['\\' ] = '\\\\' ;
42- $ table ["\r" ] = '\r ' ;
43- $ table ["\n" ] = '\n ' ;
44- $ table ["\t" ] = '\t ' ;
45- }
46-
4736 if (is_bool ($ var )) {
4837 return $ var ? 'TRUE ' : 'FALSE ' ;
4938
@@ -62,9 +51,7 @@ public static function toLine($var): string
6251 } elseif (strlen ($ var ) > self ::$ maxLength ) {
6352 $ var = substr ($ var , 0 , self ::$ maxLength ) . '... ' ;
6453 }
65- return preg_match ('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u ' , $ var ) || preg_last_error ()
66- ? '" ' . strtr ($ var , $ table ) . '" '
67- : "' $ var' " ;
54+ return self ::encodeStringLine ($ var );
6855
6956 } elseif (is_array ($ var )) {
7057 $ out = '' ;
@@ -146,20 +133,10 @@ private static function _toPhp(&$var, array &$list = [], int $level = 0, int &$l
146133 } elseif ($ var === null ) {
147134 return 'null ' ;
148135
149- } elseif (is_string ($ var ) && (preg_match ('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u ' , $ var ) || preg_last_error ())) {
150- static $ table ;
151- if ($ table === null ) {
152- foreach (array_merge (range ("\x00" , "\x1F" ), range ("\x7F" , "\xFF" )) as $ ch ) {
153- $ table [$ ch ] = '\x ' . str_pad (dechex (ord ($ ch )), 2 , '0 ' , STR_PAD_LEFT );
154- }
155- $ table ['\\' ] = '\\\\' ;
156- $ table ["\r" ] = '\r ' ;
157- $ table ["\n" ] = '\n ' ;
158- $ table ["\t" ] = '\t ' ;
159- $ table ['$ ' ] = '\$ ' ;
160- $ table ['" ' ] = '\" ' ;
161- }
162- return '" ' . strtr ($ var , $ table ) . '" ' ;
136+ } elseif (is_string ($ var )) {
137+ $ res = self ::encodeStringPhp ($ var );
138+ $ line += substr_count ($ res , "\n" );
139+ return $ res ;
163140
164141 } elseif (is_array ($ var )) {
165142 $ space = str_repeat ("\t" , $ level );
@@ -242,9 +219,72 @@ private static function _toPhp(&$var, array &$list = [], int $level = 0, int &$l
242219 return '/* resource ' . get_resource_type ($ var ) . ' */ ' ;
243220
244221 } else {
245- $ res = var_export ($ var , true );
246- $ line += substr_count ($ res , "\n" );
247- return $ res ;
222+ return var_export ($ var , true );
223+ }
224+ }
225+
226+
227+ private static function encodeStringPhp (string $ s ): string
228+ {
229+ static $ special = [
230+ "\r" => '\r ' ,
231+ "\n" => '\n ' ,
232+ "\t" => "\t" ,
233+ "\e" => '\e ' ,
234+ '\\' => '\\\\' ,
235+ ];
236+ $ utf8 = preg_match ('##u ' , $ s );
237+ $ escaped = preg_replace_callback (
238+ $ utf8 ? '#[\p{C} \\\\]#u ' : '#[\x00-\x1F\x7F-\xFF \\\\]# ' ,
239+ function ($ m ) use ($ special ) {
240+ return $ special [$ m [0 ]] ?? (strlen ($ m [0 ]) === 1
241+ ? '\x ' . str_pad (strtoupper (dechex (ord ($ m [0 ]))), 2 , '0 ' , STR_PAD_LEFT ) . ''
242+ : '\u{ ' . strtoupper (ltrim (dechex (self ::utf8Ord ($ m [0 ])), '0 ' )) . '} ' );
243+ },
244+ $ s
245+ );
246+ return $ s === str_replace ('\\\\' , '\\' , $ escaped )
247+ ? "' " . preg_replace ('# \'| \\\\(?=[ \'\\\\]|$)#D ' , '\\\\$0 ' , $ s ) . "' "
248+ : '" ' . addcslashes ($ escaped , '"$ ' ) . '" ' ;
249+ }
250+
251+
252+ private static function encodeStringLine (string $ s ): string
253+ {
254+ static $ special = [
255+ "\r" => "\\r \r" ,
256+ "\n" => "\\n \n" ,
257+ "\t" => "\\t \t" ,
258+ "\e" => '\\e ' ,
259+ "' " => "' " ,
260+ ];
261+ $ utf8 = preg_match ('##u ' , $ s );
262+ $ escaped = preg_replace_callback (
263+ $ utf8 ? '#[\p{C} \']#u ' : '#[\x00-\x1F\x7F-\xFF \']# ' ,
264+ function ($ m ) use ($ special ) {
265+ return "\e[22m "
266+ . ($ special [$ m [0 ]] ?? (strlen ($ m [0 ]) === 1
267+ ? '\x ' . str_pad (strtoupper (dechex (ord ($ m [0 ]))), 2 , '0 ' , STR_PAD_LEFT )
268+ : '\u{ ' . strtoupper (ltrim (dechex (self ::utf8Ord ($ m [0 ])), '0 ' )) . '} ' ))
269+ . "\e[1m " ;
270+ },
271+ $ s
272+ );
273+ return "' " . $ escaped . "' " ;
274+ }
275+
276+
277+ private static function utf8Ord (string $ c ): int
278+ {
279+ $ ord0 = ord ($ c [0 ]);
280+ if ($ ord0 < 0x80 ) {
281+ return $ ord0 ;
282+ } elseif ($ ord0 < 0xE0 ) {
283+ return ($ ord0 << 6 ) + ord ($ c [1 ]) - 0x3080 ;
284+ } elseif ($ ord0 < 0xF0 ) {
285+ return ($ ord0 << 12 ) + (ord ($ c [1 ]) << 6 ) + ord ($ c [2 ]) - 0xE2080 ;
286+ } else {
287+ return ($ ord0 << 18 ) + (ord ($ c [1 ]) << 12 ) + (ord ($ c [2 ]) << 6 ) + ord ($ c [3 ]) - 0x3C82080 ;
248288 }
249289 }
250290
0 commit comments