arrays - Print_r() to PHP error_log() not working. (non-printing characters) -
i have static method in helper class utility::error_log() helping gracefully debug huge objects in php. method, , it's helper-method utility::toarray() below:
static function error_log($message, $data=null, $max=2) { if(is_array($data) || is_object($data)) $data = print_r(self::toarray($data, $max),true); if(is_array($message) || is_object($message)) $message = print_r(self::toarray($message, $max),true); if(!empty($data)) $data = "\n".$data; if (!strstr($message, php_eol)) $message = str_pad(" ".$message." ", 50,'=',str_pad_both); error_log($message.$data); } static function toarray($object, $max = 2, $current = 0) { if($current > $max) return ucfirst(gettype($object)).'( ... )'; $current++; $return = array(); foreach((array) $object $key => $data) if (is_object($data)) $return[$key] = self::toarray($data, $max, $current); elseif (is_array($data)) $return[$key] = self::toarray($data, $max, $current); else $return[$key] = $data; return $return; }
now may bit at, gist is, toarray makes huge object (lots of recursion) orders of magnitude smaller, , returns properties either arrays or strings. easier work with... idea being print_r($array,true)
makes array string, , log it.
this doesn't work expected, however. result is:
[05-apr-2013 05:29:00] ==================================== persisting suits & shirts =================================== array ( [
and nothing, when call print_r($data)
, print browser, get:
array ( [brs\pagebundle\entity\pageroot_folder_name] => pages [id] => 43 [title] => suits & shirts [depth_title] => suits & shirts [description] => ( ... , on ... )
before error_log() length limitation, mention can $data = var_export($data,true)
, send result error_log() no problems:
[05-apr-2013 06:00:08] ==================================== persisting suits & shirts =================================== array ( '' . "\0" . 'brs\\pagebundle\\entity\\page' . "\0" . 'root_folder_name' => 'pages', 'id' => 43, 'title' => 'suits & shirts', 'depth_title' => 'suits & shirts', 'description' => ( ... , on ... )
what problem? why work var_export($data,true)
, , print_r($data,false)
, not print_r($data,true)
??
the answer non-printable characters. in conversion of objects arrays, , various properties strings, these strings contain non-printing control characters never see, exist, break php's error_log()
.
the solution rather simple, essential:
$data= preg_replace('/[^\x0a\x20-\x7e\xc0-\xd6\xd8-\xf6\xf8-\xff]/','',$data); // or preserve extended characters, use below expression. // mind many of these still may not display correctly in logs. $data= preg_replace('/(?!\n)[[:cntrl:]]+/','',$data);
called before sending $message error log, removes many non-printing characters while preserving many characters other pregs found removed. in case need them:
\x0a = [newline] \x20-\x7e = [space] ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ b c d e f g h j k l m n o p q r s t u v w x y z [ \ ] ^ _ ` b c d e f g h j k l m n o p q r s t u v w x y z { | } ~ \xc0-\xd6 = À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö \xd8-\xf6 = Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö \xf8-\xff = ø ù ú û ü ý þ ÿ
in end, there additional rewriting isolate functionality use elsewhere, ultimate solution simple.
edit: upon further review, seems more related bug #64439 - "\0 causes error_log strings truncated".
for wondering, \0 (or \x00 or \x0) null character, , in particular above case, result of casting of object array, returns key value of null.classname.null.propname
.
Comments
Post a Comment