2013-04-05 1 views
0

У меня есть статический метод в вспомогательном классе Utility :: error_log(), который помогает нам изящно отлаживать HUGE-объекты в PHP. Метод, и это помощник-метод Полезность :: ToArray() приведены ниже:Print_r() в PHP error_log() не работает. (непечатаемые символы)

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 as $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; 
} 

Теперь, может быть немного, чтобы смотреть, но суть в том, ToArray делает махина (много рекурсии) заказов меньшей величины и возвращает все свойства в виде массивов или строк. Намного проще работать с ... Идея состоит в том, что print_r($array,true) затем делает массив строкой, и мы заносим ее в журнал.

Это не работает должным образом. Результат:

[05-Apr-2013 05:29:00] ==================================== PERSISTING SUITS & SHIRTS =================================== 
Array 
(
    [ 

А потом ничего, где, когда я звоню print_r($data) и печати в браузере, я получаю:

Array 
(
    [BRS\PageBundle\Entity\Pageroot_folder_name] => Pages 
    [id] => 43 
    [title] => Suits & Shirts 
    [depth_title] => Suits & Shirts 
    [description] => (... AND SO ON ...) 

Перед тем, как сказать, что это error_log() ограничение длины, я буду отметить, что я могу успешно $data = var_export($data,true) и отправить результат в error_log() без проблем:

[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' => (... AND SO ON ...) 

в чем проблема? Почему он работает с var_export($data,true) и print_r($data,false), но не с print_r($data,true) ??

ответ

0

Ответ - непечатаемые символы. При преобразовании объектов в массивы и их различных свойствах в строки эти строки содержат непечатаемые управляющие символы, которые мы никогда не видим, но поскольку они существуют, перерыв PHP error_log().

Решения довольно простой, но важный:

$data= preg_replace('/[^\x0A\x20-\x7E\xC0-\xD6\xD8-\xF6\xF8-\xFF]/','',$data); 

// Or to preserve extended characters, use the below expression. 
// Mind you many of these still may not display correctly in logs. 
$data= preg_replace('/(?!\n)[[:cntrl:]]+/','',$data); 

Вызывается перед отправкой $ сообщения об ошибке Бревенчатых, это снимает многие непечатаемых символы, сохраняя много символов другого pregs я нашел удален. Только в случае, если им нужно:

\x0A = [newline] 
\x20-\x7E = [space] ! " # $ % & ' () * + , - ./0 1 2 3 4 5 6 7 8 9 : ; <=> ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ]^_ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ 
\xC0-\xD6 = À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö 
\xD8-\xF6 = Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö 
\xF8-\xFF = ø ù ú û ü ý þ ÿ 

В конце концов, есть некоторая дополнительная перезапись, чтобы выделить некоторые функции для использования в других местах, но окончательное решение так просто.

EDIT: При дальнейших проверках кажется, что это более конкретно связано с Bug #64439 - "\0 causes error_log strings to be truncated".

Для тех, кто задается вопросом, символ \ 0 (или \ x00 или \ x0) является символом NULL, а в конкретном выше случае является результатом литья объекта в виде массива, который возвращает значение ключа NULL.classname.NULL.propname ,

Смежные вопросы