Как решить эту ошибку?
A PHP Error was encountered Severity: Warning Message: Invalid argument supplied for foreach() Filename: admin/tour.php Line Number: 81
это строка 81:
$files = $this->multi_upload->go_upload(); var_dump($files); $images = array(); foreach ($files as $img) { //line 81 $images[] = $img['file']; }
это мои $ файлы в верхнем коде:
function go_upload($field = 'userfile') { $CI =& get_instance(); // Is $_FILES[$field] set? If not, no reason to continue. if ( ! isset($_FILES[$field]['name'][0])) { $CI->upload->set_error('upload_no_file_selected'); return FALSE; } else { $num_files = count($_FILES[$field]['name']) -1; $file_list = array(); $error_hold = array(); $error_upload = FALSE; } // Is the upload path valid? if ( ! $CI->upload->validate_upload_path()) { // errors will already be set by validate_upload_path() so just return FALSE return FALSE; } for ($i=0; $i < $num_files; $i++) { // $fname = $_FILES[$field]['name'][$i]; // echo "$fname\n\n<br><br>\n\n"; $error_hold[$i] = FALSE; // Was the file able to be uploaded? If not, determine the reason why. if ( ! is_uploaded_file($_FILES[$field]['tmp_name'][$i])) { $error = ( ! isset($_FILES[$field]['error'][$i])) ? 4 : $_FILES[$field]['error'][$i]; switch($error) { case 1: // UPLOAD_ERR_INI_SIZE $error_hold[$i] = 'upload_file_exceeds_limit'; break; case 2: // UPLOAD_ERR_FORM_SIZE $error_hold[$i] = 'upload_file_exceeds_form_limit'; break; case 3: // UPLOAD_ERR_PARTIAL $error_hold[$i] = 'upload_file_partial'; break; case 4: // UPLOAD_ERR_NO_FILE $error_hold[$i] = 'upload_no_file_selected'; break; case 6: // UPLOAD_ERR_NO_TMP_DIR $error_hold[$i] = 'upload_no_temp_directory'; break; case 7: // UPLOAD_ERR_CANT_WRITE $error_hold[$i] = 'upload_unable_to_write_file'; break; case 8: // UPLOAD_ERR_EXTENSION $error_hold[$i] = 'upload_stopped_by_extension'; break; default : $error_hold[$i] = 'upload_no_file_selected'; break; } return FALSE; } // Set the uploaded data as class variables $CI->upload->file_temp = $_FILES[$field]['tmp_name'][$i]; $CI->upload->file_name = $_FILES[$field]['name'][$i]; $CI->upload->file_size = $_FILES[$field]['size'][$i]; $CI->upload->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type'][$i]); $CI->upload->file_type = strtolower($CI->upload->file_type); $CI->upload->file_ext = $CI->upload->get_extension($_FILES[$field]['name'][$i]); // Convert the file size to kilobytes if ($CI->upload->file_size > 0) { $CI->upload->file_size = round($CI->upload->file_size/1024, 2); } // Is the file type allowed to be uploaded? if ( ! $CI->upload->is_allowed_filetype()) { $error_hold[$i] = 'upload_invalid_filetype'; } // Is the file size within the allowed maximum? if ( ! $CI->upload->is_allowed_filesize()) { $error_hold[$i] = 'upload_invalid_filesize'; } // Are the image dimensions within the allowed size? // Note: This can fail if the server has an open_basdir restriction. if ( ! $CI->upload->is_allowed_dimensions()) { $error_hold[$i] = 'upload_invalid_dimensions'; } // Sanitize the file name for security $CI->upload->file_name = $CI->upload->clean_file_name($CI->upload->file_name); // Remove white spaces in the name if ($CI->upload->remove_spaces == TRUE) { $CI->upload->file_name = preg_replace("/\s+/", "_", $CI->upload->file_name); } /* * Validate the file name * This function appends an number onto the end of * the file if one with the same name already exists. * If it returns false there was a problem. */ $CI->upload->orig_name = $CI->upload->file_name; if ($CI->upload->overwrite == FALSE) { $CI->upload->file_name = $CI->upload->set_filename($CI->upload->upload_path, $CI->upload->file_name); if ($CI->upload->file_name === FALSE) { $error_hold[$i] = TRUE; } } /* * Move the file to the final destination * To deal with different server configurations * we'll attempt to use copy() first. If that fails * we'll use move_uploaded_file(). One of the two should * reliably work in most environments */ if ( ! @copy($CI->upload->file_temp, $CI->upload->upload_path.$CI->upload->file_name)) { if ( ! @move_uploaded_file($CI->upload->file_temp, $CI->upload->upload_path.$CI->upload->file_name)) { $error_hold[$i] = 'upload_destination_error'; } } /* * Run the file through the XSS hacking filter * This helps prevent malicious code from being * embedded within a file. Scripts can easily * be disguised as images or other file types. */ if ($CI->upload->xss_clean == TRUE) { $CI->upload->do_xss_clean(); } if ($error_hold[$i]) { $error_upload = TRUE; // echo $error_hold[$i]; } else { if ($imageVar = $this->multiple_image_properties($CI->upload->upload_path.$CI->upload->file_name)) { $file_list[] = array( 'name' => $CI->upload->file_name, 'file' => $CI->upload->upload_path.$CI->upload->file_name, 'size' => $CI->upload->file_size, 'ext' => $CI->upload->file_ext, 'image_type' => $imageVar->image_type, 'height' => $imageVar->height, 'width' => $imageVar->width ); } else { $file_list[] = array( 'name' => $CI->upload->file_name, 'file' => $CI->upload->upload_path.$CI->upload->file_name, 'size' => $CI->upload->file_size, 'type' => $CI->upload->file_type, 'ext' => $CI->upload->file_ext, ); } } // For debugging /* if (strlen($error_hold[$i]) > 1) { print_r($error_hold); } */ } // end for loop // Add error display for individual files if ($error_upload) { $this->set_error($error_hold); return FALSE; } else { return $file_list; } }
Простой ответ заключается в том, что $files
не является массивом. foreach
работает только с массивами. Мы не знаем, что такое ценность, но в любом случае это неправильно. Вам нужно будет посмотреть на функцию go_upload
чтобы понять, почему она не делает то, что вы ожидаете.
Собственно, делая это, вы получите файл или значение, которое хотите.
foreach ($files as $img) { //line 81 echo $img; // echo the Var and you will see.. }
Эта строка -> $files = $this->multi_upload->go_upload();
вероятно, из файлового объекта в вашей форме, не так ли? Затем он должен быть назван как этот file[]
а не только file
. Вы должны быть конкретными, что это массив. Иначе ничего не произойдет.
Чтобы избежать этого предупреждения, вы должны посчитать массив:
if (count($files) > 0) { foreach ($files as $img) { //line 81 $images[] = $img['file']; } }
Что касается «Недопустимый аргумент, предоставленный для ошибки foreach ()», это, вероятно, связано с тем, что $ files не является массивом (или подобным). Лучший способ сделать это IMHO:
$files = $this->multi_upload->go_upload(); echo '<pre>'; echo "Files:\n"; print_r($files); echo '</pre>'; $images = array(); foreach ($files as $img) { //this is line 80 $images[] = $img['file']; } if ( ! $files ) { $this->session->set_flashdata('error', $this->upload->display_errors()); redirect('admin/tour/insert_foreign'); }
Пожалуйста, внесите это изменение и покажите нам результат.
Я полагаю, что просто расскажу, как я обрабатываю несколько загрузок в CI, это немного отличается от вашего метода:
Форма выглядит так:
<?php echo form_open_multipart('upload/multiple_upload');?> <input type="file" name="userfile[]" size="20" /><br /> <input type="file" name="userfile[]" size="20" /><br /> </form>
Функция Upload / multiple_upload в контроллере выглядит следующим образом:
function multiple_upload() { $config['upload_path'] = './userpics/originals/'; // server directory $config['allowed_types'] = 'gif|jpg|png'; // by extension, will check for whether it is an image $config['max_size'] = '512'; // in kb //$config['max_width'] = '1024'; //$config['max_height'] = '768'; $this->load->library('myupload'); $error = array(); $data = array(); for ($i=0;$i<count($_FILES['userfile']['name']);$i++) { $this->myupload->initialize($config); if (!$this->myupload->do_upload('userfile',$i)) { $error[] = $this->myupload->display_errors(); } $data[$i] = $this->myupload->data(); //gradually build up upload->data() } if ( count($error) > 0 ) { print_r($error); } else { print_r($data); } }
На этом этапе я сделал копию класса загрузки CI и вставил его в каталог библиотеки приложений. Необходимо внести несколько изменений. Я назвал его myupload.
@ Строка 143:
public function do_upload($field = 'userfile')
изменить на
public function do_upload($field = 'userfile', $i = 0)
Любые строки в этой функции над строкой 200, вы должны добавить [$ i] в конец переменных $ _FILES.
Пример:
is_uploaded_file($_FILES[$field]['tmp_name'])
изменить на:
is_uploaded_file($_FILES[$field]['tmp_name'][$i])
Есть 9 строк для обновления.
Вы уверены, что получаете массив? есть несколько возвратов FALSE. Поэтому вы должны проверить,
if ($files !== FALSE)
или отбрасывая его в (пустой) массив (если false возвращает) с
$files = (array) $this->multi_upload->go_upload();