Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Функция strlen - выдаёт разные результаты в разных частях сайта
 
 автор: Владимир55   (29.07.2007 в 11:07)   письмо автору
 
 

В теле скрипта используется функция

$dlina_ssylky = strlen ($out) ;  // Длина ссылки

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

Для контроля делаю так:

$dlina_ssylky = strlen ($out) ;  // Длина ссылки
echo "<br>Текст очередной ссылки:";
echo htmlspecialchars($out);
echo "Длина этой ссылки $dlina_ssylky";


Реально получаю:
Текст очередной ссылки:жХИМ 2001-вЕИЛ 2002Длина этой ссылки 22

Специально не делал перевод строк, чтобы не вкрались пробелы. Если посчитать знаки курсором, то их 19, хотя strlen утверждает, что 22!

В другой части скрипта этот же текст в составе массива обрабатывается еще раз, и тогда strlen насчитывает в нем 19 знаков!

Что бы это могло быть?

   
 
 автор: sim5   (29.07.2007 в 11:17)   письмо автору
 
   для: Владимир55   (29.07.2007 в 11:07)
 

А вы HEX-редактором строки просмотрите.

   
 
 автор: Владимир55   (29.07.2007 в 12:18)   письмо автору
 
   для: sim5   (29.07.2007 в 11:17)
 

Никогда не слышал про такой редактор! Что вы имеете в виду?

Им можно посмотреть переменную в рнр-скрипте?

   
 
 автор: cheops   (29.07.2007 в 12:23)   письмо автору
 
   для: Владимир55   (29.07.2007 в 12:18)
 

А текст откуда берётся - имеется возможность сохранить его разные варианты (длинный и короткий) в виде текстового файла и прекрепить к сообщению здесь на форуме?

   
 
 автор: Владимир55   (29.07.2007 в 12:44)   письмо автору
22 байт
 
   для: cheops   (29.07.2007 в 12:23)
 

Длинный файл у меня есть - он в Приложении.

Оператором htmlspecialchars он читается так:
жХИМ 2001-вЕИЛ 2002

А в текстовом файле выглядит вот так:
жХИМ
2001-вЕИЛ
2002

Файлу предшествовала обработка:

    $out_6 = preg_replace('|&#[0-9]+;|', '', $out_5); // Убираем цифровую мнемонику типа &#34; (кавычки) и &#160;
    $out_7 = trim ($out_6) ;
    $out_8 = $out_7 ; 
    $out = $out_8;

   
 
 автор: Trianon   (29.07.2007 в 12:51)   письмо автору
 
   для: Владимир55   (29.07.2007 в 12:44)
 

перед первым из пробелов имеется перевод строки (LF=0x0A)'
после второго из пробелов возврат каретки, перевод строки (CR=0x0D, LF=0x0A)
три символа создают разность.

Судя по разнице в этих символах, где-то в процессе обработки явный баг....

   
 
 автор: Владимир55   (29.07.2007 в 12:56)   письмо автору
 
   для: Trianon   (29.07.2007 в 12:51)
 

Нортон и Волков показывает какие-то кракозябры в этих точках.
И WinHEX тоже не показал знаков, не соответствующих буквам.

Как можно обнаружить эти и подобные знаки?

Можно ли их убрать preg_replace?

   
 
 автор: Poison   (29.07.2007 в 12:27)   письмо автору
 
   для: Владимир55   (29.07.2007 в 12:18)
 

Пропустите строку через эту функцию и посчитайте байты.


<%
function DumpPack($pack = null) {
    $len = strlen($pack);
    $row_m = 16;
    $row_c = 1;
    $dump = null;
    $file = 'dump.log';
    for ( $x = 0; $x < $len; $x++ ) {
        $dump .= sprintf( "%02X", ord( $pack{ $x } ) );
        $dump .= chr(32);
        if ( $row_c >= $row_m ) {
            $dump .= chr(10);
            $row_c = 1;
        } else {
            $row_c++;
        }
    }
    $dump = trim( $dump );
/*
    if ( $fp = fopen($file,'a+b') ) {
        fwrite($fp, $dump . chr(10) . chr(10) );
        fclose($fp);
    }
*/
    return $dump;
}

   
 
 автор: sim5   (29.07.2007 в 12:30)   письмо автору
 
   для: Владимир55   (29.07.2007 в 12:18)
 

Им можно просмотреть бинарные данные, те что ваш глаз не видит. Это можно сделать любой DOS-оболочкой, если нет редактора. У вас строки разные - 100%.

   
 
 автор: Владимир55   (29.07.2007 в 13:36)   письмо автору
 
   для: sim5   (29.07.2007 в 12:30)
 

То, что строки разные, я, конечно же, понял.

Но вот как научиться находить скрытые коды? Как ни удивительно, но WinHex этих скрытых кодов не показал! Он видит вот что:
E6 D5 C8 CC 0A 20 32 30 30 31 2D E2 C5 C8 CB 20 0D 0A 32 30 30 32
ж Х И М 2 0 0 1 - в Е И Л 2 0 0 2

   
 
 автор: Trianon   (29.07.2007 в 14:26)   письмо автору
 
   для: Владимир55   (29.07.2007 в 13:36)
 

E6 D5 C8 CC 0A 20 32 30 30 31 2D E2 C5 C8 CB 20 0D 0A 32 30 30 32

Я выделил коды, которые Вы не видите в строке.

html-браузер не показывает плоский текст дословно.
В частности любые последовательности символов пропуска заменяются одним, который может быть отображен как пробел или как переход к следующей строке (в зависимости от контекса отображения).
Не стоит смотреть браузером строки текста в надежде найти посимвольносе соответствие.

   
 
 автор: sim5   (29.07.2007 в 15:12)   письмо автору
 
   для: Владимир55   (29.07.2007 в 13:36)
 

Все что находится до 20Н - это символы управляющие, хотя многие из них имеют псевдографические обозначения (0Н - 1FH). Из тех что отметил вам Trianon, ODH вы уж точно видите, это возврат каретки. Вам может встретиться "видимая" 09Н - табуляция. Управляющие симолы в комбинации с кодом 1ВН (ESC) могут посылаться на принтер для управления печатью. Вот, любуйтесь:




С символа 20Н начинается пробел. Наберите НЕХ-редактором бинарные данные от 0Н до 1FH, сохраните, просмотрите текстовым редактором, а потом скопируйте их в поле Сообщение форума - начните сразу ввод, проследите за курсором и за тем где будет происходить ввод.

   
 
 автор: Владимир55   (29.07.2007 в 21:53)   письмо автору
 
   для: sim5   (29.07.2007 в 15:12)
 





   
 
 автор: Владимир55   (29.07.2007 в 22:07)   письмо автору
 
   для: Владимир55   (29.07.2007 в 21:53)
 

Очень интересный эксперимент!

Вероятно, есть стандартное решение этой проблемы - трансформация невидимых символов в другие знаки. Может быть, функцией ord или иначе. Чтобы любой файл неизвестного происхождения в превентивном порядке однократно обработать таким образом, что невоспроизводимые броузером знаки заменятся на отображаемые echo htmlspecialchars. Ну, а избыточные, не информативные коды, просто исчезнут. Не так, как я делал (preg_replace('|&#[0-9]+;|', '', $out_5)), а более профессионально.

Такое возможно?

========
А почему этого кода не видно в ASCII ?

$tmp_tmp = file_get_contents("tmp/5.txt"); 
$tmp = substr ($tmp_tmp, 4,1);
$tmp_1 = ord ($tmp);

echo "<br>Обработано ord $tmp_1" ;

   
 
 автор: sim5   (29.07.2007 в 22:45)   письмо автору
 
   для: Владимир55   (29.07.2007 в 22:07)
 

Ну если есть необходимость проверяйте, удаляйте. Только управляющие символы:
9Н (9В) - горизонтальная табуляция
0АР (10В) - перевод строки
0ВН (11В) - вертикальная табуляция
0DН (13В) - возврат каретки
они "не лишние", как вам будет удобней исключить их из потока удаляемых - либо используя ord или регулярное выражение, я не знаю.

>А почему этого кода не видно в ASCII ?

А откуда мне знать что там за сивол?

   
 
 автор: Владимир55   (29.07.2007 в 22:53)   письмо автору
 
   для: sim5   (29.07.2007 в 22:45)
 

Там символ 0А - это выделил Трианон (29.07.2007 в 14:26)

Его не видно.

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

$kod = chr(0A);
$tmp_25 = preg_replace($kod, '', $tmp_tmp); // Убираем скрытый ПС

   
 
 автор: Unkind   (29.07.2007 в 22:56)   письмо автору
 
   для: sim5   (29.07.2007 в 22:45)
 


Откуда привычка записывать так шестнадцатеричные числа? :) Не в Assembler случайно так записывают? И я так понимаю тут - "9В" - опечатка? В скобках должно быть 9D.

P.S. К слову http://www.google.ru/search?hl=ru&q=0hFF&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=

   
 
 автор: Владимир55   (29.07.2007 в 23:02)   письмо автору
 
   для: Unkind   (29.07.2007 в 22:56)
 

Я уже совершенно запутался....

Можно примерчик - как удалить все это?

9Н (9В) - горизонтальная табуляция
0АР (10В) - перевод строки
0ВН (11В) - вертикальная табуляция
0DН (13В) - возврат каретки

И куда делись коды 0D 0A, вызвавшие всю эту тему?

   
 
 автор: Unkind   (29.07.2007 в 23:05)   письмо автору
 
   для: Владимир55   (29.07.2007 в 23:02)
 

$kod = chr(0A);
В PHP шестнадцатеричные символы записываются так: 0x0A, поэтому
$kod = chr(0x0A);

А вообще лучше
<?php
$string 
preg_replace("|[\\0\x01-\x08\x0C\x0E-\x10\x12-\x1F]+|"""$string);
?>

   
 
 автор: Unkind   (29.07.2007 в 23:08)   письмо автору
 
   для: Владимир55   (29.07.2007 в 23:02)
 

Там символ 0А - это выделил Трианон (29.07.2007 в 14:26)
Его не видно.
...
И куда делись коды 0D 0A, вызвавшие всю эту тему?


Браузер не отображает переводы строк. Точнее только, если они находятся между тегами <pre> и </pre>. Для перевода строки в HTML есть тег <br />.

   
 
 автор: sim5   (29.07.2007 в 23:05)   письмо автору
 
   для: Unkind   (29.07.2007 в 22:56)
 

От ассемблера, ну он не такой уж и "вредный" :) Да и D (тоже сбой от ассемблера)).

   
 
 автор: Владимир55   (29.07.2007 в 23:22)   письмо автору
 
   для: sim5   (29.07.2007 в 23:05)
 

автор: Unkind (29.07.2007 в 23:08)
Там символ 0А - это выделил Трианон (29.07.2007 в 14:26)
Его не видно.
...
И куда делись коды 0D 0A, вызвавшие всю эту тему?

Браузер не отображает переводы строк. Точнее только, если они находятся между тегами <pre> и </pre>. Для перевода строки в HTML есть тег <br />.

==================
Я имел в виду, что изначально проблема высветилась от того, что в тексте обнаружились коды 0D 0A, которые мне желательно убрать. Но потом разговор ушел в строну кодов
9Н (9В) - горизонтальная табуляция
0АР (10В) - перевод строки
0ВН (11В) - вертикальная табуляция
0DН (13В) - возврат каретки

А про 0D 0A больше не упоминается.

Я сделал

$string_1 = file_get_contents("tmp/5.txt");
$string_2 = preg_replace("|[\\0\x01-\x08\x0C\x0E-\x10\x12-\x1F]+|", "", $string_1);

$file = fopen ("tmp/05.txt", "w") ;        
fputs ($file, $string_2) ;                   
fclose ($file) ;                             

попытку очистить файл от нежелательных кодов по предложенному Вами алгоритму, но проблема осталась. Этот файл 05.txt в Приложении.

Как убрать 0D 0A ?

   
 
 автор: Владимир55   (29.07.2007 в 23:43)   письмо автору
 
   для: Владимир55   (29.07.2007 в 23:22)
 

В конце концов я убрал их "в лоб"

$kod = chr(0x0A);
$string_2 = str_replace($kod,"",$string_1);

и проблема решилась.

Но непонятка, все же осталась. Вот какая.

Трианон отметил наличие кодов "возврат каретки, перевод строки (CR=0x0D, LF=0x0A)". С этим все понятно. Но теперь всплыли
0АР (10В) - перевод строки
0DН (13В) - возврат каретки

Это что, другие варианты CR и LF ?

Которые, гипотетически, тоже могут появиться в коде?

   
 
 автор: sim5   (29.07.2007 в 23:50)   письмо автору
 
   для: Владимир55   (29.07.2007 в 23:43)
 

CR=0x0D - Carriage Return (Возврат каретки) - 0DH
LF=0x0A - Line Feed (Перевод строки) - 0AH

0АН - так записываются в ассемблере (для восьмиразрядных процессоров) шестнадцатеричные значения. Десятичные как 10D, а не В - это для восмиричных (аппаратный сбой:))).

   
 
 автор: Unkind   (29.07.2007 в 23:55)   письмо автору
 
   для: sim5   (29.07.2007 в 23:50)
 

В - это для восмиричных
А почему? B - Bin Может O - Oct?

Как убрать 0D 0A ?
Так я специально сделал так, чтобы они не убирались.

Это что, другие варианты CR и LF ?
Это байты записанные в шестнадцатеричной и десятичной системах счисления соответственно.

   
 
 автор: sim5   (30.07.2007 в 00:01)   письмо автору
 
   для: Unkind   (29.07.2007 в 23:55)
 

>А почему? B - Bin Может O - Oct?

На Masm, на котором мне приходиться писать, принято - восмиричная запись как В.

Произошло переполнение стека :))

   
 
 автор: Владимир55   (30.07.2007 в 00:18)   письмо автору
 
   для: sim5   (30.07.2007 в 00:01)
 

Получается:
перевод строки - 0x0A
возврат каретки - 0x0D

Осталось только выяснить в терминах РНР:
горизонтальная табуляция - ?
вертикальная табуляция - ?

   
 
 автор: sim5   (30.07.2007 в 01:07)   письмо автору
 
   для: Владимир55   (30.07.2007 в 00:18)
 

Тоже самое - добавьте 0х до кода: 0x9, 0x0B, либо используйте десятичные значения - 9 и 11. Ноль в шестнадцатеричных значениях добавляется перед символами: A, D, C, D, E, F. Если HEX-значение начинается с цифры, то ноль перед ним можно не указывать.

   
 
 автор: Владимир55   (30.07.2007 в 01:16)   письмо автору
 
   для: sim5   (30.07.2007 в 01:07)
 

Большое спасибо!

Очень интересно.

   
 
 автор: Владимир55   (30.07.2007 в 01:36)   письмо автору
 
   для: Владимир55   (30.07.2007 в 01:16)
 

Я так подумал, что, поскольку мне нужен только текст, то можно на автомате убрать все коды 1 по 31?

   
 
 автор: Unkind   (30.07.2007 в 01:42)   письмо автору
 
   для: Владимир55   (30.07.2007 в 01:36)
 

Вы хотите убрать переводы строк? Что же это будет за текст?
И в таком случае с 0 по 31.

   
 
 автор: Владимир55   (30.07.2007 в 09:18)   письмо автору
 
   для: Unkind   (30.07.2007 в 01:42)
 

А это текст коротенький - это текст ссылки, и в нем ПС совершенно неуместны.

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

Я очень благодарен всем, кто мне помог разобраться! Теперь у меня есть прекрасный инструмент на будущее!
Так интересно!

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования