Serialize ведет себя по-разному в различных ОС

sax player

Новичок
Serialize ведет себя по-разному в различных ОС

Добрый день!

На многоязычном сайте языковая поддержка реализована через ассоциативный массив, который сериализуется и хранится в текстовом файле.
Все прекрасно работает - и на локальном сервере, и на хостинге.
Однако при копировании этого файла с локального сервера (под виндоус) на хостинк (апач) - он становится не читаемым, unserialize его не может обработать.
Я выяснил, что проблема - в символе перевода строки - они разные в Виндоус и Апач.

Вопрос: нет ли функции, трансформирующей символ перевода строки во что-нибудь, что читалось бы одинаково в Виндоус и Апач?
nl2br не годится, т.к. она не заменяет перевод строки, а просто добавляет <br/>

Спасибо
 

Dovg

Продвинутый новичок
>Виндоус и Апач
телевизоры и красным :)

Делай trim перед unserialize, например.
 

sax player

Новичок
Автор оригинала: Dovg
>Виндоус и Апач
телевизоры и красным :)

Делай trim перед unserialize, например.
-~{}~ 27.05.10 15:21:

Делаю

-~{}~ 27.05.10 15:24:

Different operating system families have different line-ending conventions. When you write a text file and want to insert a line break, you need to use the correct line-ending character(s) for your operating system. Unix based systems use \n as the line ending character, Windows based systems use \r\n as the line ending characters and Macintosh based systems use \r as the line ending character.
If you use the wrong line ending characters when writing your files, you might find that other applications that open those files will "look funny".
Windows offers a text-mode translation flag ('t') which will transparently translate \n to \r\n when working with the file. In contrast, you can also use 'b' to force binary mode, which will not translate your data. To use these flags, specify either 'b' or 't' as the last character of the mode parameter.
The default translation mode depends on the SAPI and version of PHP that you are using, so you are encouraged to always specify the appropriate flag for portability reasons. You should use the 't' mode if you are working with plain-text files and you use \n to delimit your line endings in your script, but expect your files to be readable with applications such as notepad. You should use the 'b' in all other cases.
If you do not specify the 'b' flag when working with binary files, you may experience strange problems with your data, including broken image files and strange problems with \r\n characters.

-~{}~ 27.05.10 15:27:

Пытался писать с различными флагами - толку нет.
Делай trim перед unserialize - не подходит, т к проблему создает символ перевода строки внутри элемента массива.

-~{}~ 27.05.10 15:28:

А про винд и Апач - действительно смешно, юникс, конечно, сорри )))
 

mity

Новичок
Ваш наезд на serialize совершенно не обоснован.
serialize вообще рассматривает передаваемые ей строки и массивы содержащие строки как "бинарные данные".

Если Вы на одной системе запаковали строки содержащие переводы строк через \n. То распоковывая эту строчку в любой другой системе всегда получите своё \n.
 

sax player

Новичок
Ну, эт понятно.
Но решение некрасивое. К тому же тогда встает вопрос - а не может ли какой-нибудь символ в каком-либо из языков (а там и арабский, и китайский и т д) генерить такую же ошибку.

-~{}~ 27.05.10 15:46:

я пытался копать в сторону htmlentities, например

-~{}~ 27.05.10 15:48:

Да нет, оказывается

-~{}~ 27.05.10 15:53:

Все работает в обеих ОС, проблема возникает, когда я копию файла, отредактированную на локалке , заливаю на хост.
При чем если нет перевода строки - все прекрасно, я уже пару лет пользую на различных сайтах. А ща понадобились длинные тексты - ну и всплылою
 

iamFake

Mind Of Liberty
PHP:
function beauty($STR)
{
    return str_replace("\r","",$STR);
}
достаточно красивое решение?
 

SiMM

Новичок
> копию файла, отредактированную на локалке , заливаю на хост
Результат serialize не предназначен для ручной правки.
 

sax player

Новичок
Автор оригинала: iamFake
PHP:
function beauty($STR)
{
    return str_replace("\r","",$STR);
}
достаточно красивое решение?
Решение никакое, т к необратимое - форматирование потерятся.

PHP:
function ugly($STR)
{
    return str_replace("\r","@",$STR);
}
И обратно


PHP:
function very_ugly($STR, $servername)
{
  $new_string= ($servername == 'local_server')  ? str_replace("@","\r\n",$STR) : str_replace("@","\n",$STR);

return $new_string;
}
 

A1x

Новичок
sax player
в сериализованном представлении для каждого строкового значения явно указана длина. так что если править руками и указанная длина строки не совпадет после этого с фактической то
unserialize его не может обработать.
 

sax player

Новичок
Автор оригинала: A1x
sax player
в сериализованном представлении для каждого строкового значения явно указана длина. так что если править руками и указанная длина строки не совпадет после этого с фактической то
Я руками не правлю, конечно. Правит копия скрипта на локальном сервере.

-~{}~ 27.05.10 16:52:

На своем сервере файл читается, при переносе на другой - перестает
 

mity

Новичок
Попробуйте на хостинге выполнить такой код
PHP:
<pre>
<?php
  ini_set('display_errors',1); 
  error_reporting(E_ALL);
  print_r(unserialize( Ваша строка считанная из файла ));
?>
</pre>
и напишите что у Вас выводится
 

sax player

Новичок
Notice: unserialize() [function.unserialize]: Error at offset 123 of 184 bytes in /home/content/j/o/b/jobeadm/html/langs/edit_texts.php on line 44

-~{}~ 27.05.10 17:11:

Не совпадает длина, как и ожидалось
 

dimagolov

Новичок
sax player, а нафига козе баян? почему нужно править сериализованные данные, вместо того, чтобы паковать-распаковывать нужные (предварительно исправленные) получателю данные?

-~{}~ 27.05.10 09:14:

кроме того, до меня не доходит чем существенно может помешать другой тип превода строки, разве что код обработки заточен под строго определенный. но даже если и заточен, то исправить его, чтобы он понимал любой перевод строки, дело 5 минут.
 

mity

Новичок
Значит разные файлы, вот функция и не работает!
Не нужно никак и ничем править данные запакованные seriliaze !!
 

sax player

Новичок
Файлы отличаются только тем, что созданы в разных ОС, о чем , собственно, и речь. \n и \r\n
 

mity

Новичок
У вас где то происходит преобразование файла, возможно при заливке на хостинг.
Проверьте хотя бы длину вашего файл на обоих серверах.
seriliaze глубоко фиолетового какие у вас там переводы строк.

Как Вы считываете и записываете файл?
 

sax player

Новичок
Автор оригинала: dimagolov
sax player, а нафига козе баян? почему нужно править сериализованные данные, вместо того, чтобы паковать-распаковывать нужные (предварительно исправленные) получателю данные?

-~{}~ 27.05.10 09:14:

кроме того, до меня не доходит чем существенно может помешать другой тип превода строки, разве что код обработки заточен под строго определенный. но даже если и заточен, то исправить его, чтобы он понимал любой перевод строки, дело 5 минут.
Да не правлю я!

Просто обнаружилось явление: данные (массив, внутри элементов которого содержатся символы перевода строки), корректно сериализованные и читаемые на сервере под Виндоус - при переносе на юникс читаться перестают - и наоборот.

Причина - разница в символах перевода строки.

Поправить можно кодом, который я привел выше. Более элегантное решение не прсматривается.

-~{}~ 27.05.10 17:41:

Автор оригинала: mity
У вас где то происходит преобразование файла, возможно при заливке на хостинг.
Проверьте хотя бы длину вашего файл на обоих серверах.
seriliaze глубоко фиолетового какие у вас там переводы строк.

Как Вы считываете и записываете файл?
PHP:
$texts_file =$_SERVER['DOCUMENT_ROOT'].'/langs/texts_array.txt'; 
 if(file_exists($texts_file)) { //$texts = unserialize(file_get_contents($texts_file)); 
$hn = fopen($texts_file,'rt'); $texts_ser = fread($hn,filesize($texts_file));
 fclose($hn); $texts = unserialize($texts_ser);
-~{}~ 27.05.10 17:44:

Не фиолетово. Если нет перевода строк - нет и проблемы
 

mity

Новичок
Ну вот и ошибка
я же говорил бинарные данные
Открывать нужно fopen($name,"rb"); Сохранять аналогично
 
Сверху