За последние 24 часа нас посетили 17149 программистов и 1836 роботов. Сейчас ищут 1603 программиста ...

Не создается массив $_FILES

Тема в разделе "Работа с почтой", создана пользователем My001, 6 окт 2009.

  1. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    В IE8 (IE6 и IE7 не проверял) не создается массив $_FILES и соответственно не получается отправить вложение,
    хотя в Firefox и Google Chrome все работает отлично.

    Эта проблема возникает только при динамическом создании формы отправки электронной почты.

    Помогите найти ошибку !

    При выборе пункта меню "Контакты" вызывается следующая JavaScript функция
    для создания формы отправки электронной почты:

    function Contacts(basicID, lang) {
    var TForm = document.createElement('form');
    TForm.action = 'simple_mail.php';
    TForm.enctype = 'multipart/form-data';
    TForm.method = 'post';
    TForm.target = 'mail_frame';

    var Table = document.createElement('table');
    Table.cellspacing = 0;
    Table.cellpadding = 0;
    Table.style.width = '100%';

    var TBody = document.createElement('tbody');
    var Row = document.createElement('tr');
    var Td = document.createElement('td');
    Td.style.border = 'solid 1px Gray';
    Td.style.padding = '10px 10px 10px 10px';

    var P = document.createElement('p');
    P.id = 'TitleForm';
    P.className = 'TitleForm';
    P.appendChild(document.createTextNode(Resource[lang].Welcome));
    Td.appendChild(P);

    var newElem = document.createElement('input');
    newElem.id = 'labelEmail';
    newElem.type = 'text';
    newElem.className = 'Label';
    newElem.size = 15;
    newElem.readOnly = true;
    newElem.value = Resource[lang].Email;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_from';
    newElem.name = 'mail_from';
    newElem.type = 'text';
    newElem.className = 'Field';
    newElem.size = 30;
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'labelTheme';
    newElem.type = 'text';
    newElem.className = 'Label';
    newElem.size = 15;
    newElem.readOnly = true;
    newElem.value = Resource[lang].Theme;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_subject';
    newElem.name = 'mail_subject';
    newElem.type = 'text';
    newElem.className = 'Field';
    newElem.size = 30;
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('textarea');
    newElem.id = 'mail_msg';
    newElem.name = 'mail_msg';
    newElem.className = 'mailArea';
    newElem.cols = 60;
    newElem.rows = 10;
    Td.appendChild(newElem);

    var newElem = document.createElement('span');
    newElem.id = 'InsMessage';
    newElem.style.color = 'Red';
    newElem.style.visibility = 'hidden';
    newElem.appendChild(document.createTextNode('*'));
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_file';
    newElem.name = 'mail_file';
    newElem.type = 'file';
    newElem.className = 'Field';
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'doSend';
    newElem.name = 'doSend';
    newElem.type = 'button';
    newElem.className = 'sendForm';
    newElem.value = Resource[lang].Send;
    newElem.onclick = btnClick;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'sendClear';
    newElem.type = 'button';
    newElem.className = 'sendForm';
    newElem.value = Resource[lang].Clear;
    newElem.onclick = clearArea;
    Td.appendChild(newElem);

    Row.appendChild(Td);
    TBody.appendChild(Row);
    Table.appendChild(TBody);
    TForm.appendChild(Table);

    document.getElementById(basicID).appendChild(TForm);

    }

    function clearArea() {
    document.getElementById('mail_msg').innerHTML = '';
    }

    function btnClick() {
    var msg = document.getElementById('mail_msg').value;

    if (msg == '') document.getElementById('InsMessage').style.visibility = 'visible'; else
    if (document.getElementById('InsMessage').style.visibility == 'visible')
    document.getElementById('InsMessage').style.visibility = 'hidden';

    if (msg != '') {
    this.form.submit();
    }
    }

    Форма обрабатывается следующим стандартным PHP скриптом simple_mail.php:

    <?php

    $picture = "";

    // Если поле выбора вложения не пустое - закачиваем его на сервер

    if (!empty($_FILES['mail_file']['tmp_name']))

    {

    // Закачиваем файл

    $path = $_FILES['mail_file']['name'];

    if (copy($_FILES['mail_file']['tmp_name'], $path)) $picture = $path;
    if ($_FILES['size'] > 2000000)
    copy($_FILES['mail_file']['tmp_name'], 'uploads/'.$path);
    }

    $thm = $_POST['mail_subject'];

    $msg = $_POST['mail_msg'];

    $mail_to = 'u1@localhost';

    // Отправляем почтовое сообщение

    if (empty($picture)) mail($mail_to, $thm, $msg);

    else send_mail($mail_to, $thm, $msg, $picture);

    // Вспомогательная функция для отправки почтового сообщения с вложением (Trianon)

    function send_mail($mail_to, $thema, $html, $path)

    { if ($path) {

    $fp = fopen($path,"rb");

    if (!$fp)

    { print "Cannot open file";

    exit();

    }

    $file = fread($fp, filesize($path));

    fclose($fp);

    }

    $name = $path;

    $EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём

    $boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.

    $headers = "MIME-Version: 1.0;$EOL";

    $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";

    $headers .= "From: user@myhost";



    $multipart = "--$boundary$EOL";

    $multipart .= "Content-Type: text/html; charset=windows-1251$EOL";

    $multipart .= "Content-Transfer-Encoding: base64$EOL";

    $multipart .= $EOL; // раздел между заголовками и телом html-части

    $multipart .= chunk_split(base64_encode($html));



    $multipart .= "$EOL--$boundary$EOL";

    $multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";

    $multipart .= "Content-Transfer-Encoding: base64$EOL";

    $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";

    $multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла

    $multipart .= chunk_split(base64_encode($file));



    $multipart .= "$EOL--$boundary--$EOL";



    if (!mail($mail_to, $thema, $multipart, $headers))

    {return False; //если не письмо не отправлено

    }

    else { //// если письмо отправлено

    return True;

    }

    exit;

    }

    ?>
     
  2. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Жесть

    Срочно оформляй код тегами. А еще лучше для таких простыней pastebin.org
     
  3. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    А добавляется ли для формы
    enctype="multipart/form-data"
    ???

    Обычно, если $_FILES пуст, проблема именно в этом.
     
  4. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    ещё бывает размер файла ... по умолчанию ограничение 2мега для одного и 8 для всех данных
     
  5. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Добавляется. Иначе и в Firefox были бы проблемы.
    Еще один момент, $_POST['mail_file'] содержит путь к файлу, хотя не должна.
    Та же самая форма, но не созданная динамически ведет себя иначе, т.е наоборот
    $_POST['mail_file'] - пустая, а массив $_FILES создается.

    Эта проблема существует именно для IE8, а может быть и для других версий IE.

    Что-то не так с JavaScript ... ?
     
  6. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Дело не в ограничении размера файла, в Firefox же нет проблем, и сервер и PHP настроен правильно.
     
  7. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Парни, я бы на вашем месте принципиально не отвечал в топике, пока автор не оформит код тегами.

    Пока он игнорирует это - нет элементарного уважения к людям которые будут читать его спагетти.
     
  8. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Какими тегами ? Одна JavaScript функция, что в ней не понятного ?
     
  9. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Поясняю особо одаренным.

    Видите такие кнопочки над полем для ввода сообщения?
    На них еще написано PHP, SQL, HTML, JS, CSS
    Так вот эти кнопочки служат для того, чтобы синтаксис кода был правильно подсвечен и читать его станет намного проще.

    Так понятно? :)
     
  10. karakh

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

    С нами с:
    11 дек 2007
    Сообщения:
    1.344
    Симпатии:
    0
    тегами JS. Видишь, над формой для ответа есть такие кнопочки - JS, PHP и так далее. Как ты думаешь, зачем они?

    Непонятно почему ты решил, что кто-то будет читать четыре листа кода черными буквами на сером фоне ради того чтобы тебе помочь.
     
  11. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    В IE8 (IE6 и IE7 не проверял) не создается массив $_FILES и соответственно не получается отправить вложение,
    хотя в Firefox и Google Chrome все работает отлично.

    Эта проблема возникает только при динамическом создании формы отправки электронной почты.

    Помогите найти ошибку !

    При выборе пункта меню "Контакты" вызывается следующая JavaScript функция
    для создания формы отправки электронной почты:

    [js]function Contacts(basicID, lang) {
    var TForm = document.createElement('form');
    TForm.action = 'simple_mail.php';
    TForm.enctype = 'multipart/form-data';
    TForm.method = 'post';
    TForm.target = 'mail_frame';

    var Table = document.createElement('table');
    Table.cellspacing = 0;
    Table.cellpadding = 0;
    Table.style.width = '100%';

    var TBody = document.createElement('tbody');
    var Row = document.createElement('tr');
    var Td = document.createElement('td');
    Td.style.border = 'solid 1px Gray';
    Td.style.padding = '10px 10px 10px 10px';

    var P = document.createElement('p');
    P.id = 'TitleForm';
    P.className = 'TitleForm';
    P.appendChild(document.createTextNode(Resource[lang].Welcome));
    Td.appendChild(P);

    var newElem = document.createElement('input');
    newElem.id = 'labelEmail';
    newElem.type = 'text';
    newElem.className = 'Label';
    newElem.size = 15;
    newElem.readOnly = true;
    newElem.value = Resource[lang].Email;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_from';
    newElem.name = 'mail_from';
    newElem.type = 'text';
    newElem.className = 'Field';
    newElem.size = 30;
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'labelTheme';
    newElem.type = 'text';
    newElem.className = 'Label';
    newElem.size = 15;
    newElem.readOnly = true;
    newElem.value = Resource[lang].Theme;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_subject';
    newElem.name = 'mail_subject';
    newElem.type = 'text';
    newElem.className = 'Field';
    newElem.size = 30;
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('textarea');
    newElem.id = 'mail_msg';
    newElem.name = 'mail_msg';
    newElem.className = 'mailArea';
    newElem.cols = 60;
    newElem.rows = 10;
    Td.appendChild(newElem);

    var newElem = document.createElement('span');
    newElem.id = 'InsMessage';
    newElem.style.color = 'Red';
    newElem.style.visibility = 'hidden';
    newElem.appendChild(document.createTextNode('*'));
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'mail_file';
    newElem.name = 'mail_file';
    newElem.type = 'file';
    newElem.className = 'Field';
    Td.appendChild(newElem);

    var newElem = document.createElement('br');
    Td.appendChild(newElem);
    var newElem = document.createElement('br');
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'doSend';
    newElem.name = 'doSend';
    newElem.type = 'button';
    newElem.className = 'sendForm';
    newElem.value = Resource[lang].Send;
    newElem.onclick = btnClick;
    Td.appendChild(newElem);

    var newElem = document.createElement('input');
    newElem.id = 'sendClear';
    newElem.type = 'button';
    newElem.className = 'sendForm';
    newElem.value = Resource[lang].Clear;
    newElem.onclick = clearArea;
    Td.appendChild(newElem);

    Row.appendChild(Td);
    TBody.appendChild(Row);
    Table.appendChild(TBody);
    TForm.appendChild(Table);

    document.getElementById(basicID).appendChild(TForm);

    }

    function clearArea() {
    document.getElementById('mail_msg').innerHTML = '';
    }

    function btnClick() {
    var msg = document.getElementById('mail_msg').value;

    if (msg == '') document.getElementById('InsMessage').style.visibility = 'visible'; else
    if (document.getElementById('InsMessage').style.visibility == 'visible')
    document.getElementById('InsMessage').style.visibility = 'hidden';

    if (msg != '') {
    this.form.submit();
    }
    } [/js]
    Форма обрабатывается следующим стандартным PHP скриптом simple_mail.php:

    PHP:
    1. <?php
    2.  
    3. $picture = "";
    4.  
    5. // Если поле выбора вложения не пустое - закачиваем его на сервер
    6.  
    7. if (!empty($_FILES['mail_file']['tmp_name']))
    8.  
    9. {
    10.  
    11. // Закачиваем файл
    12.  
    13. $path = $_FILES['mail_file']['name'];
    14.  
    15. if (copy($_FILES['mail_file']['tmp_name'], $path)) $picture = $path;
    16. if ($_FILES['size'] > 2000000)
    17. copy($_FILES['mail_file']['tmp_name'], 'uploads/'.$path);
    18. }
    19.  
    20. $thm = $_POST['mail_subject'];
    21.  
    22. $msg = $_POST['mail_msg'];
    23.  
    24. $mail_to = 'u1@localhost';
    25.  
    26. // Отправляем почтовое сообщение
    27.  
    28. if (empty($picture)) mail($mail_to, $thm, $msg);
    29.  
    30. else send_mail($mail_to, $thm, $msg, $picture);
    31.  
    32. // Вспомогательная функция для отправки почтового сообщения с вложением (Trianon)
    33.  
    34. function send_mail($mail_to, $thema, $html, $path)
    35.  
    36. { if ($path) {
    37.  
    38. $fp = fopen($path,"rb");
    39.  
    40. if (!$fp)
    41.  
    42. { print "Cannot open file";
    43.  
    44. exit();
    45.  
    46. }
    47.  
    48. $file = fread($fp, filesize($path));
    49.  
    50. fclose($fp);
    51.  
    52. }
    53.  
    54. $name = $path;
    55.  
    56. $EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
    57.  
    58. $boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
    59.  
    60. $headers = "MIME-Version: 1.0;$EOL";
    61.  
    62. $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";
    63.  
    64. $headers .= "From: user@myhost";
    65.  
    66.  
    67.  
    68. $multipart = "--$boundary$EOL";
    69.  
    70. $multipart .= "Content-Type: text/html; charset=windows-1251$EOL";
    71.  
    72. $multipart .= "Content-Transfer-Encoding: base64$EOL";
    73.  
    74. $multipart .= $EOL; // раздел между заголовками и телом html-части
    75.  
    76. $multipart .= chunk_split(base64_encode($html));
    77.  
    78.  
    79.  
    80. $multipart .= "$EOL--$boundary$EOL";
    81.  
    82. $multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";
    83.  
    84. $multipart .= "Content-Transfer-Encoding: base64$EOL";
    85.  
    86. $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
    87.  
    88. $multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла
    89.  
    90. $multipart .= chunk_split(base64_encode($file));
    91.  
    92.  
    93.  
    94. $multipart .= "$EOL--$boundary--$EOL";
    95.  
    96.  
    97.  
    98. if (!mail($mail_to, $thema, $multipart, $headers))
    99.  
    100. {return False; //если не письмо не отправлено
    101.  
    102. }
    103.  
    104. else { //// если письмо отправлено
    105.  
    106. return True;
    107.  
    108. }
    109.  
    110.  
    111. }
    112.  
    113. ?>
     
  12. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    My001
    Мне все же кажется, что Ie не добавляет enctype к форме.
    Собственно, если exit(print_r($_FILES)) после отправки пуст, то надо курить ман JS и поиск аналогичных ошибок в гугле.
     
  13. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Проверочный JS скрипт находит это свойство формы.
     
  14. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    Ну что ж.. Ищи в гугле похожие ошибки.
     
  15. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    1. Проблемы с
    [js]this.form.submit()[/js]
    Вроде как и работает, но теряет контекст и вываливается в ошибку в некоторых случаях.

    Поэтому лучше
    [js]function btnClick() {
    document.getElementById('Sample').submit();
    }
    [/js]

    2.Вот так работает

    [js]function Contacts(val1, val2)
    {
    var target = document.getElementById(val1);
    target.innerHTML="<form enctype='multipart/form-data' action='s.php' method='post' id='Sample'><input type='file' name='samplefile'><input type='button' onclick='btnClick()' value='Send'>";

    }
    [/js]

    Проблема именно в динамическом создании формы твоим способом. А если бы точнее - добавлении одного конкретного элемента
    Код (Text):
    1. <input type="file">
    В чем там конкретно причина - может что-то недозадал, а может глюк IE - разбирайся сам :)
     
  16. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    да точно - встречал ... когда создаешь элементы через ДОМ - то евенты (onmouseover, onclick) неработают
     
  17. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Все там работает.

    Просто уже зарегистрированные обработчики надо регистрировать для новых элементов вручную

    [js]elem.onclick = clickhandler[/js]

    У ТС проблема в другом. Форма "не понимает" что <input type="file"> принадлежит ей. Возможно просто что-то не дозадается (по аналогии с ручной регистрацией обработчиков), но есть ненулевая вероятность что это глюк/фича IE.
     
  18. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Методом научного тыка получилось.
    Для IE объект form надо добавлять вместе со свойствами:

    [js]if (isIE)
    var TForm = document.createElement(
    '<form action="simple_mail.php" enctype="multipart/form-data" method="post" target="mail_frame">');
    else {
    var TForm = document.createElement('form');
    TForm.action = 'simple_mail.php';
    TForm.enctype = 'multipart/form-data';
    TForm.method = 'post';
    TForm.target = 'mail_frame';}[/js]

    Так работает.
    Очень хочется разобраться почему именно так ?
     
  19. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Ответ один

    [js]TForm.enctype = 'multipart/form-data';[/js]

    На самом деле задается как-то хитрожопо :)
     
  20. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    Это понятно.
    Почему обязательно добавлять вместе со свойствами именно объект form ?
    Интересно, где эта особенность IE описана.
     
  21. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    My001
    В голове у разработчиков.
     
  22. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    В общем пользуйтесь F12 она сила

    [js]TForm.encoding = 'multipart/form-data';[/js]
     
  23. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Причем я вспомнил, воевал я когда-то с похожим. Это тянется давно, в 6, и 7ке тоже самое было.
    Но тогда я забил и решил через innerHTML.
     
  24. My001

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

    С нами с:
    6 окт 2009
    Сообщения:
    16
    Симпатии:
    0
    А вот добавить form с помощью innerHTML у меня не получается ни со свойствами, ни без свойств.
    Проверочный скрипт ее не находит.
     
  25. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    В div добавляй (или любой контейнер)

    HTML:
    1. <div id="target"></div>
    [js]document.getElementById('target').innerHTML = '';[/js]