При загрузки файла выдаёт сообщение saveAs() on a non-object

при загрузки файла, выдаёт такую ошибку


Fatal error: Call to a member function saveAs() on a non-object in C:\wamp\www\mysite\protected\modules\news\controllers\NewsController.php  on line 61

61 строка


$model->image->saveAs('C:/wamp/www/mysite/images/'.$model->image);

Контроллер


<?php

        $model=new News;

      	if(isset($_POST['news']))

		{

  		    $model->attributes=$_POST['news'];

 				

			$model->image=CUploadedFile::getInstance($model,'image');	

				

			if($model->save())

			{                                 

			  $model->image->saveAs('C:/wamp/www/mysite/images'.$model->image);	

	

			}	

							

		 }  			  

?>

Форма


<form action="http://localhost/mysite/news/create/" method="post" enctype="multipart/form-data">


<input type="file" name="news[image]">

<input type="submit" value="Сохранить запись">


</form>

форму урезал, оставил только поле файл.

если убрать строчку


$model->image->saveAs('C:/wamp/www/mysite/images/'.$model->image);

то все данные что передаются из формы, сохраняются нормально

в php.ini

upload_max_filesize = 2M

файл загружаю гораздо меньше размера чем 2 мб

что может быть?

Думаю, вы не можете присвоить свойству $model->image объект CUploadedFile::getInstance($model,‘image’);

Попробуйте использовать дополнительную переменную, а в $model->image потом сохраняйте ссылку на картинку.

хм, если правильно понял так?

изменил

$file = $model->image=CUploadedFile::getInstance($model,‘image’);

и

$model->image->saveAs(‘C:/wamp/www/mysite/images/’.$file);

но всё равно тоже самое

Сделайте CVarDumper::dump($model->image) после присвоения CUploadedFile::getInstance и посмотрите, что там хранится (по всей видимости, null [Null is returned if no file is uploaded for the specified model attribute.]).

ничего не понимаю, что ещё нужно…

по пытался ещё так сделать




  $model->image->saveAs( 'C:/wamp/www/mysite/images/'.$_FILES['news']['name']['image'] );	  

  $model->image->saveAs($_FILES['news']['tmp_name']['image'], 'C:/wamp/www/mysite/images/'.$_FILES['news']['name']['image'] );	

  $model->image->saveAs('C:/wamp/tmp/'.$_FILES['news']['name']['image']);	 



не помогло

если указываю так




		 if (!move_uploaded_file($_FILES['news']['tmp_name']['image'], 'C:/wamp/www/mysite/images/'.$_FILES['news']['name']['image'])) {	

			  $res['msg'][] = 'Файл не удалось сохранить';

		 }



то всё в порядке, но хотелось штатным способом фреймворка

сделал вы сказали, прописал


$model->image = CUploadedFile::getInstance($model,'image');


CVarDumper::dump($model->image); 	



выдало




null

но почему, что я сделал не так?

в моделе указал


		public function rules()

		{

				return array(

	

					array('image', 'file', 'types'=>'jpg, gif, png', 'allowEmpty' => true),					   

				);

		}

хотя и без правил всё тоже самое

Вообще, регистр имеет значение:




<input type="file" name="News[image]">



И если хотите полность штатными средствами, то нужно генерировать файловое поле так (если не используете CActiveForm):




CHtml::activeFileField($model, 'image');



CActiveForm не использую совсем, противник смешивания PHP кода с HTML. форму делаю на чистом HTML, на шаблоннотизаторе Smarty, вот полностью форма




{if $update}<h2>Обновление записи</h2>{else}<h2>Создание новой записи</h2>{/if}

	

							   

{include file="views/message/errors.tpl"} 	


<form action="http://localhost/mysite/news/{if $update}update{else}create{/if}/" method="post" enctype="multipart/form-data">


{t lang="NewsModule.title"}:                

<input type="text" name="news[title]" size="50" value="{$model->title}">


{t lang="NewsModule.content"}:

<textarea name="news[content]" rows="10" cols="50">{$model->content}</textarea>

	

{t lang="NewsModule.image"}:      

<input type="hidden" name="MAX_FILE_SIZE" value="300000000">

<input type="file" name="news[image]">

<input type="submit" name="go" value="Сохранить запись">


</form>

регистр вроде везде одинаковый, как в самой форме news[] так и в контроллере $_POST[‘news’] всё с меаленькими буквами, кроме


$model=new News;

с большой буквы N но не думаю чтобы это имело значение.

хм, прописал в контроллере как вы написали


echo CHtml::activeFileField($model, 'image'); 

выдало это


<input id="ytNews_image" type="hidden" value="" name="News[image]" /><input name="News[image]" id="News_image" type="file" />

а CVarDumper::dump($model->image); выдало такое


CUploadedFile#1

(

    [CUploadedFile:_name] => 'JustCause_2.jpg'

    [CUploadedFile:_tempName] => 'C:\wamp\tmp\php44C4.tmp'

    [CUploadedFile:_type] => 'image/jpeg'

    [CUploadedFile:_size] => 61551

    [CUploadedFile:_error] => 0

    [CComponent:_e] => null

    [CComponent:_m] => null

)

ну значит контакт есть:)

выходит что для поля файл обязателен регистр, и как я понял он зависит от названия модели? то есть от того как пропишиш строчку

$model=new News;

если прописать

$model=new news;

то и в поле файл указать с маленькой буквы? так?

хотя для текстовых полей, проблем не было ни каких, всё видилось

А Вы загляняти в искходники getInstance и все поймете сами что и как там сделано. Сразу большая часть вопросов отпадет.

Я просто когда то напоролся на эти грабли, расслабился и назвал поля для аплоада файла так как мне захотелось все равно форму генерировал не привязывая к модели… пол часа отдал так и не догнал в чем дело, полез в исходники метода 20 минут и все стало ясно :)

страдаете… в кукбуке написано по этому поводу: How to upload a file using a model, а если файл тупо не приходит на сервер и в форме стоит неверный enctype, тогда уж извольте:


if(!empty($model->image))

 $model->image->saveAs('C:/wamp/www/mysite/images'.$model->image); // странное какое-то имя для сохранения

спасибо, я тут опять наткнулся на туже нулевую ошибку, когда отправлял форму но не указывал файл, немного полазив по форуму нашёл выход, надо делать так


if($model->image !== null)

{      

  $model->image->saveAs($upload.$model->image->name); 	

}

таким образом определяем на наличие загружаемого файла, если нет то не загружаем

кстати тоже самое что привёл пример vamp

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

Хотелось бы чтобы при отправки формы, проверялись поля что прописаны в rules() но и одновременно учитывались те поля, что передаются с формы. В данном случаи если я отправлю подробную форму, то всё нормально, а при упрощённой формы будет требовать указать поля которые прописаны в полной форме, но ведь в упрощённой форме их нет.

Тоесть смотреть не только по rules() но и учитывать те поля что передаются, если они отсутствуют, то по ним проверку не производить, такое возможно?

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

Для этого существуют сценарии. В зависимости от того, какая форма отправляется пользователем, нужно присваивать модели сценарий, например:




$model->scenario = 'fullForm';



А в rules() во все правила для полей расширенной формы добавить ‘on’=>‘fullForm’.

спасибо, буду теперь знать:)