Я унаследовал базу данных MySQL, которая содержит темы электронной почты и тела сообщений, сгенерированные в Microsoft Outlook (версии для Windows и Mac OS X).
Когда я пытаюсь использовать PHP, чтобы получить тела сообщений из БД, а затем запустить json_encode
на них JSON содержит несколько (неэкранированных) символов новой строки, что делает вывод недействительным.
Я никогда не видел этого раньше, но после дальнейшего расследования я понял, что каждый случай новой строки был между <style>
тег и </style>
пометьте, что (казалось бы) между ними не было ничего, кроме новой строки.
Я тогда побежал preg_match
чтобы захватить пробел / новые строки между одним набором style
теги. После этого и запуска strlen
по результатам я вернул номер 2460
,
Затем я перебрал все символы в захваченном «пробеле» и попытался вывести их. Сначала я видел только пробелы, но когда добавил "\n"
между каждым символом, затем я внезапно увидел следующий результат (за вычетом некоторого потенциального начального и конечного пробелов):
<
!
-
-/
*
F
o
n
t
D
e
f
i
n
i
t
i
o
n
s
*
/@
f
o
n
t
-
f
a
c
e{
f
o
n
t
-
f
a
m
i
l
y
:
H
e
l
v
e
t
i
c
a
;p
a
n
o
s
e
-
1
:
2
1
1
6
4
2
2
2
2
2
4
;
}@
f
o
n
t
-
f
a
c
e{
f
o
n
t
-
f
a
m
i
l
y
:
H
e
l
v
e
t
i
c
a
;p
a
n
o
s
e
-
1
:
2
1
1
6
4
2
2
2
2
2
4
;
}@
f
o
n
t
-
f
a
c
e{
f
o
n
t
-
f
a
m
i
l
y
:
C
a
l
i
b
r
i
;p
a
n
o
s
e
-
1
:
2
1
5
5
2
2
2
4
3
2
4
;
}@
f
o
n
t
-
f
a
c
e{
f
o
n
t
-
f
a
m
i
l
y
:
T
a
h
o
m
a
;p
a
n
o
s
e
-
1
:
2
1
1
6
4
3
5
4
4
2
4
;
}@
f
o
n
t
-
f
a
c
e{
f
o
n
t
-
f
a
m
i
l
y
:
C
o
n
s
o
l
a
s
;p
a
n
o
s
e
-
1
:
2
1
1
6
9
2
2
4
3
2
4
;
}/
*
S
t
y
l
e
D
e
f
i
n
i
t
i
o
n
s
*
/p
.
M
s
o
N
o
r
m
a
l
,
l
i
.
M
s
o
N
o
r
m
a
l
,
d
i
v
.
M
s
o
N
o
r
m
a
l{
m
a
r
g
i
n
:
0
i
n
;m
a
r
g
i
n
-
b
o
t
t
o
m
:
.
0
0
0
1
p
t
;f
o
n
t
-
s
i
z
e
:
1
2
.
0
p
t
;f
o
n
t
-
f
a
m
i
l
y
:
"T
i
m
e
s
N
e
w
R
o
m
a
n
",
"s
e
r
i
f
";
}a
:
l
i
n
k
,
s
p
a
n
.
M
s
o
H
y
p
e
r
l
i
n
k{
m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;c
o
l
o
r
:
b
l
u
e
;t
e
x
t
-
d
e
c
o
r
a
t
i
o
n
:
u
n
d
e
r
l
i
n
e
;
}a
:
v
i
s
i
t
e
d
,
s
p
a
n
.
M
s
o
H
y
p
e
r
l
i
n
k
F
o
l
l
o
w
e
d{
m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;c
o
l
o
r
:
p
u
r
p
l
e
;t
e
x
t
-
d
e
c
o
r
a
t
i
o
n
:
u
n
d
e
r
l
i
n
e
;
}p
.
M
s
o
P
l
a
i
n
T
e
x
t
,
l
i
.
M
s
o
P
l
a
i
n
T
e
x
t
,
d
i
v
.
M
s
o
P
l
a
i
n
T
e
x
t{
m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;m
s
o
-
s
t
y
l
e
-
l
i
n
k
:
"P
l
a
i
n
T
e
x
t
C
h
a
r
";m
a
r
g
i
n
:
0
i
n
;m
a
r
g
i
n
-
b
o
t
t
o
m
:
.
0
0
0
1
p
t
;f
o
n
t
-
s
i
z
e
:
1
0
.
5
p
t
;f
o
n
t
-
f
a
m
i
l
y
:
C
o
n
s
o
l
a
s
;
}p{
m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;m
a
r
g
i
n
:
0
i
n
;m
a
r
g
i
n
-
b
o
t
t
o
m
:
.
0
0
0
1
p
t
;f
o
n
t
-
s
i
z
e
:
1
2
.
0
p
t
;f
o
n
t
-
f
a
m
i
l
y
:
"T
i
m
e
s
N
e
w
R
o
m
a
n
",
"s
e
r
i
f
";
}p
.
M
s
o
A
c
e
t
a
t
e
,
l
i
.
M
s
o
A
c
e
t
a
t
e
,
d
i
v
.
M
s
o
A
c
e
t
a
t
e{
m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;m
s
o
-
s
t
y
l
e
-
l
i
n
k
:
"B
a
l
l
o
o
n
T
e
x
t
C
h
a
r
";m
a
r
g
i
n
:
0
i
n
;m
a
r
g
i
n
-
b
o
t
t
o
m
:
.
0
0
0
1
p
t
;f
o
n
t
-
s
i
z
e
:
8
.
0
p
t
;f
o
n
t
-
f
a
m
i
l
y
:
"T
a
h
o
m
a
",
"s
a
n
s
-
s
e
r
i
f
";
}s
p
a
n
.
P
l
a
i
n
T
e
x
t
C
h
a
r{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
"P
l
a
i
n
T
e
x
t
C
h
a
r
";m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;m
s
o
-
s
t
y
l
e
-
l
i
n
k
:
"P
l
a
i
n
T
e
x
t
";f
o
n
t
-
f
a
m
i
l
y
:
C
o
n
s
o
l
a
s
;
}s
p
a
n
.
B
a
l
l
o
o
n
T
e
x
t
C
h
a
r{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
"B
a
l
l
o
o
n
T
e
x
t
C
h
a
r
";m
s
o
-
s
t
y
l
e
-
p
r
i
o
r
i
t
y
:
9
9
;m
s
o
-
s
t
y
l
e
-
l
i
n
k
:
"B
a
l
l
o
o
n
T
e
x
t
";f
o
n
t
-
f
a
m
i
l
y
:
"T
a
h
o
m
a
",
"s
a
n
s
-
s
e
r
i
f
";
}p
.
m
s
o
c
h
p
d
e
f
a
u
l
t
,
l
i
.
m
s
o
c
h
p
d
e
f
a
u
l
t
,
d
i
v
.
m
s
o
c
h
p
d
e
f
a
u
l
t{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
m
s
o
c
h
p
d
e
f
a
u
l
t
;m
a
r
g
i
n
:
0
i
n
;m
a
r
g
i
n
-
b
o
t
t
o
m
:
.
0
0
0
1
p
t
;f
o
n
t
-
s
i
z
e
:
1
0
.
0
p
t
;f
o
n
t
-
f
a
m
i
l
y
:
"T
i
m
e
s
N
e
w
R
o
m
a
n
",
"s
e
r
i
f
";
}s
p
a
n
.
p
l
a
i
n
t
e
x
t
c
h
a
r
0{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
p
l
a
i
n
t
e
x
t
c
h
a
r
;f
o
n
t
-
f
a
m
i
l
y
:
C
o
n
s
o
l
a
s
;
}s
p
a
n
.
b
a
l
l
o
o
n
t
e
x
t
c
h
a
r
0{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
b
a
l
l
o
o
n
t
e
x
t
c
h
a
r
;f
o
n
t
-
f
a
m
i
l
y
:
"T
a
h
o
m
a
",
"s
a
n
s
-
s
e
r
i
f
";
}s
p
a
n
.
e
m
a
i
l
s
t
y
l
e
2
2{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
e
m
a
i
l
s
t
y
l
e
2
2
;f
o
n
t
-
f
a
m
i
l
y
:
"C
a
l
i
b
r
i
",
"s
a
n
s
-
s
e
r
i
f
";c
o
l
o
r
:
b
l
a
c
k
;
}s
p
a
n
.
e
m
a
i
l
s
t
y
l
e
2
3{
m
s
o
-
s
t
y
l
e
-
n
a
m
e
:
e
m
a
i
l
s
t
y
l
e
2
3
;f
o
n
t
-
f
a
m
i
l
y
:
"C
a
l
i
b
r
i
",
"s
a
n
s
-
s
e
r
i
f
";c
o
l
o
r
:
#
1
F
4
9
7
D
;
}s
p
a
n
.
E
m
a
i
l
S
t
y
l
e
2
7{
m
s
o
-
s
t
y
l
e
-
t
y
p
e
:
p
e
r
s
o
n
a
l
-
r
e
p
l
y
;f
o
n
t
-
f
a
m
i
l
y
:
"C
a
l
i
b
r
i
",
"s
a
n
s
-
s
e
r
i
f
";c
o
l
o
r
:
#
1
F
4
9
7
D
;
}.
M
s
o
C
h
p
D
e
f
a
u
l
t{
m
s
o
-
s
t
y
l
e
-
t
y
p
e
:
e
x
p
o
r
t
-
o
n
l
y
;f
o
n
t
-
s
i
z
e
:
1
0
.
0
p
t
;
}@
p
a
g
e
W
o
r
d
S
e
c
t
i
o
n
1{
s
i
z
e
:
8
.
5
i
n
1
1
.
0
i
n
;m
a
r
g
i
n
:
1
.
0
i
n
1
.
0
i
n
1
.
0
i
n
1
.
0
i
n
;
}d
i
v
.
W
o
r
d
S
e
c
t
i
o
n
1{
p
a
g
e
:
W
o
r
d
S
e
c
t
i
o
n
1
;
}-
-
>
Вот вывод без перевода строки:
<!--/* Font Definitions */@font-face {font-family:Helvetica; panose-1:2 11 6 4 2 2 2 2 2 4;}@font-face {font-family:Helvetica; panose-1:2 11 6 4 2 2 2 2 2 4;}@font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4;}@font-face {font-family:Consolas; panose-1:2 11 6 9 2 2 4 3 2 4;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0in; margin-bottom:.0001pt; font-size:12.0pt; font-family:"Times New Roman","serif";}a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;}a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;}p.MsoPlainText, li.MsoPlainText, div.MsoPlainText {mso-style-priority:99; mso-style-link:"Plain Text Char"; margin:0in; margin-bottom:.0001pt; font-size:10.5pt; font-family:Consolas;}p {mso-style-priority:99; margin:0in; margin-bottom:.0001pt; font-size:12.0pt; font-family:"Times New Roman","serif";}p.MsoAcetate, li.MsoAcetate, div.MsoAcetate {mso-style-priority:99; mso-style-link:"Balloon Text Char"; margin:0in; margin-bottom:.0001pt; font-size:8.0pt; font-family:"Tahoma","sans-serif";}span.PlainTextChar {mso-style-name:"Plain Text Char"; mso-style-priority:99; mso-style-link:"Plain Text"; font-family:Consolas;}span.BalloonTextChar {mso-style-name:"Balloon Text Char"; mso-style-priority:99; mso-style-link:"Balloon Text"; font-family:"Tahoma","sans-serif";}p.msochpdefault, li.msochpdefault, div.msochpdefault {mso-style-name:msochpdefault; margin:0in; margin-bottom:.0001pt; font-size:10.0pt; font-family:"Times New Roman","serif";}span.plaintextchar0 {mso-style-name:plaintextchar; font-family:Consolas;}span.balloontextchar0 {mso-style-name:balloontextchar; font-family:"Tahoma","sans-serif";}span.emailstyle22 {mso-style-name:emailstyle22; font-family:"Calibri","sans-serif"; color:black;}span.emailstyle23 {mso-style-name:emailstyle23; font-family:"Calibri","sans-serif"; color:#1F497D;}span.EmailStyle27 {mso-style-type:personal-reply; font-family:"Calibri","sans-serif"; color:#1F497D;}.MsoChpDefault {mso-style-type:export-only; font-size:10.0pt;}@page WordSection1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in;}div.WordSection1 {page:WordSection1;}-->
После некоторых исследований это выглядит как разметка стиля, созданная продуктами Microsoft Office (включая Outlook). Что меня сбивает с толку, так это то, почему я могу видеть эти символы только тогда, когда я перебираю каждый символ в строке и выводю их с символами новой строки между ними.
Что еще сбивает с толку, так это то, как обнаружить эти символы и избавиться от них, чтобы вывод JSON был правильно отформатирован без перевода строки.
Я пытался запустить такие вещи, как preg_replace('!\s!', $email_msg_body)
на каждом из тел сообщения электронной почты, но по какой-то причине, новые строки между style
теги все еще там.
В конечном счете, я просто ищу способ правильно отформатировать строку JSON, чтобы я мог ее вывести. Более того, я хотел бы понять, почему это происходит в первую очередь и как предотвратить это в будущем.
К сожалению, поскольку я унаследовал эту БД от кого-то другого, я понятия не имею, как изначально был настроен канал, который перемещает электронные письма Outlook в БД.
БД тоже latin1
закодирован. Сначала я подумал, что скрытая строка символов может содержать недопустимый символ ASCII, но после запуска ord
на каждый символ в строке, это не так.
Любая помощь приветствуется.
Спасибо.
Я наконец понял, что происходит. Это не имело ничего общего со скрытыми символами, которые выводил MS Outlook.
Это было полностью связано с тем, что я использовал ob_start
функция с функцией обратного вызова для форматирования буфера таким образом, чтобы любой пробел между двумя тегами HTML был заменен символом новой строки. Это естественным образом привело к добавлению новых строк в мою строку JSON после того, как она была отформатирована json_encode
из-за тегов в выводе MS Outlook, таким образом, проблема.
Дурак я!
Других решений пока нет …