1. PHP / Говнокод #7215

    +168

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    function WikiExtractArticleUrl($str) { // Декодирование кирилицы из урла
     
        ErrorsOff(); // отключаем вывод ошибок нашего обработчика, дабы iconv не сорил
     
        try { // пытаемся с помощью iconv перекодировать кирилицу из утф8 в сп1251, подсунув декодированную кирилицу (из %12%%2D  и т.д.)
            $text = iconv('UTF-8', 'CP1251', rawurldecode($str));
            throw new Exception(''); // создаем новое исключение, дабы похапэ отстал от нас
        } catch(Exception $e) { // ловим ошибку iconv, типа перекодировать не надо
            $text = urldecode($str); // тупо декодируем
        }
     
        ErrorsOn(); // выключаем ошибки и возвращаем результ
     
        return $text;
     
    }

    Функция для получения крилицы из ЧПУ урла (сайт в кодировке win1251).

    Запостил: Мартин, 09 Июля 2011

    Комментарии (51) RSS

    • throw new Exception(''); // создаем новое исключение, дабы похапэ отстал от нас
          } catch(Exception $e) { // ловим ошибку iconv, типа перекодировать не надо
      Имитация блока finaly?
      Ответить
    • А вот так этот говнокод переписали:
      function WikiExtractArticleUrl($str) {
      
          global $ErrorsText, $config;
      
          ErrorsOn();
          if($config['debug']['php_errors'] == '0') {
              $config['debug']['php_errors'] = '1';
              $flag = true;
          }
      
          $err = $ErrorsText;
      
          $text = iconv('UTF-8', 'CP1251', rawurldecode($str));
          if($err != $ErrorsText) {
              $text = urldecode($str);
              $ErrorsText = $err;
          }
      
          $ErrorsText = $err;
          if(isset($flag)) $config['debug']['php_errors'] = '0';
      
          return $text;
      
      }
      Человеку нужны подсказки, как это переписать правильно. Ваше мнение?
      Ответить
      • == '0', цифры без кавычек. 1 класс вторая четверть
        Ответить
        • Я не стал полагаться на неявное преобразование. Что поделать, если в движке так сделано (по-хорошему, тут бул надо юзать). Приходится принимать его "законы"...
          Ответить
      • Плюсую говнокод.
        Ответить
      • $err = $ErrorsText;
        $text = iconv('UTF-8', 'CP1251', rawurldecode($str));
        if($err != $ErrorsText) {

        Падажжи, ёбана. Это как?
        Или $str это ипучий объект, с прописанным __toString (что мало вероятно), или заюзано set_error_handler с ебическим глобальным $ErrorsText (как оно скорее всего и работает).

        Если это действительно так, то функция в set_error_handler с глобалами достойна отдельного говнокода.
        А то, что ее глобалы используются для определения, сработал ли iconv - это вообще становится шедевром.
        Ответить
      • Мой вариант:

        function error_to_exception($errno, $errstr) {
        	throw new Exception($errstr);
        }
        
        function WikiExtractArticleUrl($str) {
        
            set_error_handler('error_to_exception');
        
        	try {
        		$text = iconv('UTF-8', 'CP1251', rawurldecode($str));
        	} catch(Exception $e) {
        		$text = urldecode($str);
        	}
        	
        	restore_error_handler();
        
        	return $text;
        }

        Перед тем как пищать про загубленный родной error_handler вашей говно-cms не поленись прочитать описание restore_error_handler();
        Оно восстанавливает обработку ошибок не в дефолтную пхп-шную, а в предыдущую. Т.е. в вашу.
        Ответить
        • Блин, форматирование в одной строчке не посмотрел.
          Грустно без любимого IDE
          Ответить
        • Думал над этим вариантом. Получается перегружать уже установленный в движке обработчик ошибок своим. Но как вариант, да. Iconv оказывается не дает исключений и без костылей не получится это реализовать.
          Ответить
          • Перегрузил, потом сразу назад вернул.

            Конечно не дает исключений. Большинство стандартных функций не дает исключений.
            Ответить
            • И в этом один из недостатков PHP. Впрочем, PHP'шники меня всё равно не поймут.
              Ответить
      • или я не понял задачи или можно вот так:

        function WikiExtractArticleUrl($str)
        {
        	$text = @iconv('UTF-8', 'CP1251', rawurldecode($str));
        	if($text!==FALSE) return $text;
        	return urldecode($str);
        }
        Ответить
        • энциклонги?
          Ответить
        • Почему вообще wiki в названии используется?
          Ответить
        • Не понял. Посоны боятся, что iconv выплюнет notice на неправильный символ и вернет строку вплоть до этого символа.
          См. пример:
          http://www.php.net/manual/en/function.iconv.php
          Ответить
          • Ну дык игнор вернет строку без гремлинов
            function WikiExtractArticleUrl($str)
            {
            	$text = @iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str));
            	if($text!==FALSE) return $text;
            	return urldecode($str);
            }
            Ответить
            • Тогда уж вот так, если они так хотят при любой ошибке iconv использовать один urldecode.

              function WikiExtractArticleUrl($str)
              {
              	$text = @iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str));
              	if(strlen($text) == mb_strlen($str, 'UTF-8')) {
              		return $text;
              	}
              
              	return urldecode($str);
              }
              Ответить
              • Ваш способ подошел, но только для пыховского обработчика ошибок. Как лучше поступить: восстановить стандартный через restore_error_handler() или перегрузить своим обработчиком-пустышкой?
                Ответить
                • Посоветовал бы такой вариант: (нотисов нет, текст декодит и в ютф8 и в 1251)
                  function WikiExtractArticleUrl($str)
                  {
                  	if(mb_detect_encoding(rawurldecode($str),'utf-8, CP1251')=='Windows-1251') return urldecode($str);
                  	return iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str));
                  }
                  Ответить
            • Ну и толку с этой строки, если от русского текста останутся одни пробелы да знаки препинания?
              Ответить
              • с русским все будет в порядке, не будет только тех символов которых в принципе нет в CP1251
                Ответить
        • У меня собачка что-то не заработала...
          Ответить
          • да, все верно, я ступил...

            собачка на функцию работать не будет, но в случае iconv достаточно добавить //ignore (см. пример выше) и нотисов не будет
            Ответить
        • Нельзя. В случае неудачи $text не будет FALSE, а будет перекодированная строка до первой ошибки. Возможно самое простое решение предложил выше yasenhui.
          Ответить
          • iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str)) и не будет никакого FALSE
            Ответить
            • А что будет? И зачем оно нам, как это может детектировать ошибку?

              А FALSE возвращается вообще при совершенно другого рода ошибках.
              Ответить
              • а будет вот что:
                текст: "❐п❑р✔и✚в♆е♁т♂"
                превратится в : "привет"
                исчезнут все utf-8 символы которых в принципе нет в CP1251, а также не будет notice выскакивать

                <?php
                var_dump(iconv('UTF-8', 'CP1251//IGNORE', '❐п❑р✔и✚в♆е♁т♂'));
                ?>


                вывод в 1251:
                h0x91b:Desktop h0x91b$ php test.php
                string(6) "привет"
                Ответить
                • iconv('UTF-8', 'CP1251//IGNORE', "\xcf\xf0\xe8\xe2\xe5\xf2!")
                  Ответить
                  • во, теперь понял что вы имели ввиду, тогда нужен mb_detect_encoding:
                    <?php
                    var_dump(iconv('UTF-8', 'CP1251//IGNORE', '❐п❑р✔и✚в♆е♁т♂'));
                    var_dump(mb_detect_encoding("\xcf\xf0\xe8\xe2\xe5\xf2!",'utf-8, CP1251'));
                    var_dump(iconv('UTF-8', 'CP1251//IGNORE', "\xcf\xf0\xe8\xe2\xe5\xf2!"));
                    ?>


                    Полная функция:
                    function WikiExtractArticleUrl($str)
                    {
                    	if(mb_detect_encoding($str,'utf-8, CP1251')=='Windows-1251') return urldecode($str);
                    	return iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str));
                    }
                    Ответить
                    • sorry
                      function WikiExtractArticleUrl($str)
                      {
                      	if(mb_detect_encoding(rawurldecode($str),'utf-8, CP1251')=='Windows-1251') return urldecode($str);
                      	return iconv('UTF-8', 'CP1251//IGNORE', rawurldecode($str));
                      }
                      Ответить
                      • Офигеть! Просим определить одну кодировку из двух, utf-8 или CP1251, а в ответ получаем Windows-1251!
                        Ответить
                        • согласен, в условии тоже надо бы писать windows-1251, чтоб путаницы не было
                          Ответить
    • Походу пора создавать ГофноФорум при Говнокоде.
      Ответить
      • Давно надо. Только ракоты все пугаются.
        Ответить
    • // тупо декодируем
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий