За последние 24 часа нас посетили 24309 программистов и 1710 роботов. Сейчас ищет 1831 программист ...

Fatal error: Cannot redeclare

Тема в разделе "Прочие вопросы по PHP", создана пользователем woodfairy, 13 июл 2006.

  1. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    Сама ошибка в инете обсуждалась неоднократно и в большинстве случаев у народа очень простое решение проблемы. Однако, иногда встречалось и что-то нестандартное, на что все равно не было получено ответа.

    Вобщем, у меня сообщение такое:
    Код (Text):
    1. Fatal error: Cannot redeclare restoresettings() (previously declared in D:\PROJECTS\WebMailPhp\inc_settings.php:5) in D:\PROJECTS\WebMailPhp\inc_settings.php on line 151
    PHP Version 5.1.2, Microsoft-IIS/6.0

    Приложение ajax-овое. Состоит из двух частей - логин (index.php) и все остальное (page.php). Каждая из этих частей имеет движок javascript, который в свою очередь делает асинхронный запрос на processing.php. Каждая из этих трех страниц подключает файл inc_settings.php, в котором описана функция restoresettings().

    1. Проверила, нет ли дублирующего подключения - не нашла.
    2. Я заменила все require на require_once. Не помогло.
    3. Поставила запись логов error_log перед каждым известным мне подключением файла inc_settings.php с указанием страницы, с которой происходит вызов, а также в сам этот файл с указанием, что он был подключен. Никаких повторов в полученном логе не обнаружила:
    Код (Text):
    1. index.php
    2. inc_settings.php
    3. processing.php
    4. inc_settings.php
    5. page.php
    6. inc_settings.php
    7. processing.php
    8. inc_settings.php
    9. ...
    4. Переместила в другую директорию - ошибку не выводит. В прежней - выводит.

    Помогите! Может кто знает, в чем проблема?
     
  2. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    Да, еще может возникнуть вопрос, что же находится в 5-й и 151-й строках в inc_settings:
    Код (Text):
    1. <?php
    2. function RestoreSettings()
    3. {
    4.     global $strIniDir;
    5.     global $Settings; //5-я строка
    6.     $Settings = Array();
    7.     ...
    8. }//конец функции
    9. //151-я строка
    10. ...
    11. ?>
     
  3. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    а что содержится в переменной $Settings?
    и можно посмотреть полный код этой функции RestoreSettings?
     
  4. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    Функция парсит xml-файл, в котором хранятся настройки и исправляет их, если что-то где-то некорректно. Но эта функция прекрасно работает в не-ajax-овой версии системы.
    Код (Text):
    1. function RestoreSettings()
    2. {
    3.     global $strIniDir;
    4.     global $Settings;
    5.     $Settings = Array();
    6.     $FileName = $strIniDir.'settings/config.xml';
    7.     $CurTeg = '';
    8.  
    9.     function StartElement($Parser, $Name, $Attrs)
    10.     {
    11.         global $CurTeg;
    12.         $CurTeg = $Name;
    13.     }
    14.  
    15.     function EndElement($Parser, $Name)
    16.     {
    17.         global $CurTeg;
    18.         $CurTeg = '\\'.$Name;
    19.     }
    20.  
    21.     function CharacterElement($Parser, $Data)
    22.     {
    23.         global $CurTeg, $Settings, $strIniDir;
    24.         switch (strtolower($CurTeg))
    25.         {
    26.             case 'adminpassword': $Settings['txtAdminPassword'] = $Data; break;
    27.             case 'allowadvancedlogin':
    28.                 $Settings['intAllowAdvancedLogin'] = (settype($Data, 'integer') == true) ? $Data : 0;
    29.                 break;
    30.             case 'allowajax':
    31.                 $Settings['intAllowAjax'] = (settype($Data, 'integer') == true) ? $Data : 1;
    32.                 break;
    33.             case 'attachmentsizelimit':
    34.                 $Settings['intAttachmentSizeLimit'] = (settype($Data, 'integer') == true) ? $Data : 1000200;
    35.                 break;
    36.             case 'automaticcorrectloginsettings':
    37.                 $Settings['intAutomaticCorrectLoginSettings'] = (settype($Data, 'integer') == true) ? $Data : 0;
    38.                 break;
    39.             case 'crlf': $Settings['txtCrlf'] = $Data; break;
    40.             case 'defaultcharset': $Settings['txtDefaultCharset'] = $Data; break;
    41.             case 'defaultdomainoptional': $Settings['txtDefaultDomainOptional'] = $Data; break;
    42.             case 'defaultlogpath':
    43.                 $Path = $Data;
    44.                 if (strrpos($Path, '\\') > strrpos($Path, '/'))
    45.                     $Pos = strrpos($Path, '\\');
    46.                 else
    47.                     $Pos = strrpos($Path, '/');
    48.                 $Dir = substr($Path, 0, $Pos+1);
    49.                 $File = substr($Path, $Pos+1, strlen($Path));
    50.                 if ($File == '')
    51.                     $File = 'log.txt';
    52.                 if (strpos($File, '.') == false)
    53.                     $File = $File.'.txt';
    54.                 $Parts = explode('.', $File);
    55.                 if ($Parts[0] == '')
    56.                     $Parts[0] = 'log';
    57.                 if ($Parts[1] == '')
    58.                     $Parts[1] = 'txt';
    59.                 $File = $Parts[0].'.'.$Parts[1];
    60.                 if (is_dir($Dir))
    61.                     $Settings['txtDefaultLogPath'] = $Dir.$File;
    62.                 elseif (is_dir($strIniDir.'logging/'))
    63.                     $Settings['txtDefaultLogPath'] = $strIniDir.'logging/'.$File;
    64.                 else
    65.                     $Settings['txtDefaultLogPath'] = $strIniDir.$File;
    66.                 break;
    67.             case 'defaultskin': $Settings['txtDefaultSkin'] = $Data; break;
    68.             case 'defaulttempdir':
    69.                 if (is_dir($Data))
    70.                     $Settings['txtDefaultTempDir'] = $Data;
    71.                 elseif (is_dir($strIniDir.'attachments/'))
    72.                     $Settings['txtDefaultTempDir'] = $strIniDir.'attachments/';
    73.                 else
    74.                     $Settings['txtDefaultTempDir'] = $strIniDir.'/';
    75.                 break;
    76.             case 'defaulttimeoffset': $Settings['txtDefaultTimeOffset'] = $Data; break;
    77.             case 'disableerrorhandling':
    78.                 $Settings['intDisableErrorHandling'] = (settype($Data, 'integer') == true) ? $Data : 1;
    79.                 break;
    80.             case 'enablelogging':
    81.                 $Settings['intEnableLogging'] = (settype($Data, 'integer') == true) ? $Data : 1;
    82.                 break;
    83.             case 'hideloginmode':
    84.                 $Settings['intHideLoginMode'] = (settype($Data, 'integer') == true) ? $Data : 0;
    85.                 break;
    86.             case 'imapflags': $Settings['txtImapFlags'] = $Data; break;
    87.             case 'incomingmailserver': $Settings['txtIncomingMailServer'] = $Data; break;
    88.             case 'incomingmailport':
    89.                 $Settings['intIncomingMailPort'] = (settype($Data, 'integer') == true) ? $Data : 110;
    90.                 break;
    91.             case 'mailsperpage':
    92.                 $Settings['intMailsPerPage'] = (settype($Data, 'integer') == true) ? $Data : 10;
    93.                 break;
    94.             case 'outgoingmailserver': $Settings['txtOutgoingMailServer'] = $Data; break;
    95.             case 'outgoingmailport':
    96.                 $Settings['intOutgoingMailPort'] = (settype($Data, 'integer') == true) ? $Data : 25;
    97.                 break;
    98.             case 'reqsmtpauth':
    99.                 $Settings['intReqSmtpAuth'] = (settype($Data, 'integer') == true) ? $Data : 0;
    100.                 break;
    101.             case 'showtextlabels':
    102.                 $Settings['intShowTextLabels'] = (settype($Data, 'integer') == true) ? $Data : 1;
    103.                 break;
    104.             case 'windowtitle': $Settings['txtWindowTitle'] = $Data; break;
    105.         }
    106.     }
    107.  
    108.     $Settings['txtAdminPassword'] = '';
    109.     $Settings['intAllowAdvancedLogin'] = 1;
    110.     $Settings['intAllowAjax'] = 1;
    111.     $Settings['intAttachmentSizeLimit'] = 1000200;
    112.     $Settings['intAutomaticCorrectLoginSettings'] = 0;
    113.     $Settings['txtCrlf'] = '\r\n';
    114.     $Settings['txtDefaultCharset'] = '';
    115.     $Settings['txtDefaultDomainOptional'] = '';
    116.     $Settings['txtDefaultLogPath'] = $strIniDir;
    117.     $Settings['txtDefaultSkin'] = 'Default';
    118.     $Settings['txtDefaultTempDir'] = $strIniDir;
    119.     $Settings['txtDefaultTimeOffset'] = '';
    120.     $Settings['intDisableErrorHandling'] = 0;
    121.     $Settings['intEnableLogging'] = 1;
    122.     $Settings['intHideLoginMode'] = 0;
    123.     $Settings['txtImapFlags'] = 'no_flags';
    124.     $Settings['txtIncomingMailServer'] = 'localhost';
    125.     $Settings['intIncomingMailPort'] = 110;
    126.     $Settings['intMailsPerPage'] = 10;
    127.     $Settings['txtOutgoingMailServer'] = 'localhost';
    128.     $Settings['intOutgoingMailPort'] = 25;
    129.     $Settings['intReqSmtpAuth'] = 0;
    130.     $Settings['intShowTextLabels'] = 1;
    131.     $Settings['txtWindowTitle'] = '';
    132.  
    133.     $XmlParser = xml_parser_create();
    134.     xml_set_element_handler($XmlParser, 'StartElement', 'EndElement');
    135.     xml_set_character_data_handler ($XmlParser, 'CharacterElement');
    136.     if (!($FileHandler = fopen($FileName, "r"))) {
    137.         $ErrorDesc = 'File '.$FileName.' not found';
    138.         return false;
    139.     }
    140.     while ($Data = fread($FileHandler, 4096))
    141.     {
    142.         if (!xml_parse($XmlParser, $Data, feof($FileHandler))) {
    143.             $ErrorDesc = 'XML error: '.xml_error_string(xml_get_error_code($XmlParser)).' at line '.xml_get_current_line_number($XmlParser);
    144.             return false;
    145.         }
    146.     }
    147.     xml_parser_free($XmlParser);
    148.     return $Settings;
    149. }
     
  5. Goryn

    Goryn Активный пользователь

    С нами с:
    4 апр 2006
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    Ярославль
    Говоря по русски, это не возможность объявить функцию или процедуру, так как таковая уже существует!
     
  6. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    гениально! спасибо за разъяснения!

    Впрочем, наверное, я забыла написать, что искала такую же функцию по всем скриптам и не нашла! (хотя искать было незачем - я знаю свои скрипты очень хорошо)
     
  7. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    Ну вобщем пишу последние данные по указанной выше проблеме.

    Сегодня я с утра с нуля построила сайт, постепенно добавляя функциональность. Ошибки не было.

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

    Итак, processing.php
    Код (Text):
    1. require './inc_functions.php';
    2. set_error_handler('errr');
    inc_functions.php
    Код (Text):
    1. function errr($errno, $errstr, $errfile, $errline)
    2. {
    3. switch($errno){
    4.     case E_ERROR:  $er_lev = 'E_ERROR';break;
    5.     case E_WARNING: $er_lev = 'E_WARNING';break;
    6.     case E_PARSE: $er_lev = 'E_PARSE';break;
    7.     case E_NOTICE: $er_lev = 'E_NOTICE';break;
    8.     case E_CORE_ERROR: $er_lev = 'E_CORE_ERROR';break;
    9.     case E_CORE_WARNING: $er_lev = 'E_CORE_WARNING';break;
    10.     case E_COMPILE_ERROR: $er_lev = 'E_COMPILE_ERROR';break;
    11.     case E_COMPILE_WARNING: $er_lev = 'E_COMPILE_WARNING';break;
    12.     case E_USER_ERROR: $er_lev = 'E_USER_ERROR';break;
    13.     case E_USER_WARNING: $er_lev = 'E_USER_WARNING';break;
    14.     case E_USER_NOTICE: $er_lev = 'E_USER_NOTICE';break;
    15.     case E_ALL: $er_lev = 'E_ALL';break;
    16.     case E_STRICT: $er_lev = '';break;
    17.     default: $er_lev = '';
    18. }
    19. if ($er_lev != '') error_log(date('H:i:s ')." $er_lev: $errstr in $errfile on line $errline\r\n", 3, 'error.txt');
    20. }
    Объясните глупенькой, в чем дело?
     
  8. karrbon

    karrbon Активный пользователь

    С нами с:
    14 июл 2006
    Сообщения:
    11
    Симпатии:
    0
    уберите вложенные функции
     
  9. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    karrbon,
    прочитав Ваше сообщение, сразу подумала, что, конечно, эти функции должны быть вынесены, поскольку переопределяются каждый раз при вызове функции.

    Однако, во-первых, поскольку они определены внутри функции, по окончании работы этой функции они сразу уничтожаются;
    а во-вторых, если дело в них, то php должен жаловаться на переопределение этих функций, а не restoresettings.

    Все же я провела эксперимент и вынесла эти функции:
    Код (Text):
    1. Fatal error: Cannot redeclare startelement() (previously declared in D:\PROJECTS\WebMailPhp\inc_settings.php:2) in D:\PROJECTS\WebMailPhp\inc_settings.php on line 6
     
  10. karrbon

    karrbon Активный пользователь

    С нами с:
    14 июл 2006
    Сообщения:
    11
    Симпатии:
    0
    > поскольку они определены внутри функции, по окончании работы этой функции они сразу уничтожаются;

    неверно


    вообще, приведите минимальный неработающий код
     
  11. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    мой минимальный неработающий код пока что очень большой. Я постараюсь свести его к минимуму и приведу попозже
     
  12. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    karrbon,

    Извините, но пока не могу сделать минимальный работающий код.

    У меня создается впечатление, что это глюка связки php+iis
    • 1. при перемещении в другую папку те же скрипты начинают работать
    • 2. уже второй раз длительная генерация этой ошибки заканчивается ошибкой PHP has encountered an Access Violation at, от которой можно избавиться только рестартом iis
    • 3. сегодня после возникновения этой ошибки и рестарта iis ошибка cannot redeclare перестала появляться, из-за чего я и не могу сделать минимальный неработающий код :(
     
  13. karrbon

    karrbon Активный пользователь

    С нами с:
    14 июл 2006
    Сообщения:
    11
    Симпатии:
    0
  14. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    Очень похоже, только версия php более позняя и случилось это не сразу после инсталяции, а через полгода
    Да, и ошибки вроде "Memory could not be read" не было.
    Хотя "PHP has encountered an Access Violation at" похоже чем-то. По ней я сразу нашла всю нужную инфу. Но я тогда еще не думала, что это может быть связано, потому что после рестарта iis "cannot redeclare" не исчезла.
     
  15. woodfairy

    woodfairy Активный пользователь

    С нами с:
    26 июн 2006
    Сообщения:
    23
    Симпатии:
    0
    karrbon

    спасибо за помощь, больше не появляется

    тему можно закрывать