Intereting Posts
Telegram BOT Api: как отправить фотографию с помощью PHP? AJAX терпит неудачу, в то время как данные получаются из цикла while () в php Проверка MediaWiki с учетными данными домена Windows Увеличить var_display_max_depth для xdebug Регулярное выражение для содержимого внутри <td> и </ td> Перенаправление на диалог проверки подлинности – «Произошла ошибка. Пожалуйста, повторите попытку позже" PHPmailer отправляет почту спама в hotmail. как исправить? Максимальное время выполнения 60 секунд превысило ошибку Форматирование даты mysql с помощью php Добавление дополнительного текста поиска в поисковый запрос MediaWiki с помощью InputBox PHP / JS – создание эскизов на лету или сохранение в виде файлов Пытается использовать PHP DateTime Class с Yii2, получившим класс не найденных ошибок Если CURLOPT_SSL_VERIFYPEER является ложным, передача данных больше не защищена? PHP против движка шаблонов Регулярное выражение для соответствия датам в формате ГГГГ-ММ-ДД

Пустая строка вместо нулевых значений Eloquent

Я пытаюсь создать объекты, используя функцию Mass-assign Eloquent …

$new = new Contact(Input::all()); $new->save(); 

Проблема в том, что в этом случае каждое поле заполняется пустой строкой вместо null значений, как я ожидал.

В настоящее время я разрабатываю систему, и все же некоторые столбцы таблицы не определены, поэтому с помощью этого метода следует избегать добавления каждого нового поля в $fillable array и в new Contact(array(...));

Также у меня около 20 полей в этой таблице, поэтому было бы немного уродливо иметь такой массив, как

 $new = new Contact(array( 'salutation' => Input::get('salutation'), 'first_name' => Input::get('first_name'), 'last_name' => Input::get('last_name'), 'company_id' => Input::get('company_id'), 'city' => ... ... )); 

Любые советы о том, как это сделать или исправить?

Обновление. К настоящему времени я отсортировал это, выполнив array_filter в фильтре App::before() .

Обновление В фильтре было немного беспорядка. Я в конечном итоге делаю:

 public static function allEmptyIdsToNull() { $input = Input::all(); $result = preg_grep_keys ( '/_id$/' , $input ); $nulledResults = array_map(function($item) { if (empty($item)) return null; return $item; }, $result); return array_merge($input, $nulledResults); } 

И в моих функциях.php.

 if ( ! function_exists('preg_grep_keys')) { /** * This function gets does the same as preg_grep but applies the regex * to the array keys instead to the array values as this last does. * Returns an array containing only the keys that match the exp. * * @author Daniel Klein * * @param string $pattern * @param array $input * @param integer $flags * @return array */ function preg_grep_keys($pattern, array $input, $flags = 0) { return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags))); } } 

К настоящему времени работает только с полями, которые заканчиваются на «_id». Это моя самая большая проблема, как будто связь не NULL , база данных будет вызывать ошибку, поскольку внешний ключ «» не может быть найден.

Прекрасно работает. Есть комментарии?

Используйте событие 'save' для поиска пустых моделей и явно установите для них значение null. «Проект» – это название моей модели в этом примере. Поместите это в вспомогательную функцию и подключите ее ко всем вашим моделям.

 Project::saving(function($model) { foreach ($model->toArray() as $name => $value) { if (empty($value)) { $model->{$name} = null; } } return true; }); 

ОБНОВЛЕНИЕ ЗА ЛАВРОВ 5 (11 апреля 2016 г.)

Я также закончил создание промежуточного ПО Http для очистки входных данных из http-запроса в дополнение к очистке данных до их отправки в базу данных.

 class InputCleanup { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $input = $request->input(); array_walk_recursive($input, function(&$value) { if (is_string($value)) { $value = StringHelper::trimNull($value); } }); $request->replace($input); return $next($request); } } 

Я сам искал ответ на этот вопрос, и ближе всего я могу использовать Mutators ( http://laravel.com/docs/eloquent#accessors-and-mutators ).

Эта же проблема была решена путем добавления метода (magic!) Mutator для поля внешнего ключа в модели:

 public function setHeaderImageIdAttribute($value) { $this->attributes['header_image_id'] = $value ?: null; } 

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

Laravel 4

Если необходимо, вы можете удалить любую пустую строку в массиве путем фильтрации .

 $input = array_filter(Input::all(), 'strlen'); 

Тогда, если у вас есть что-то вроде array('a' => 'a', 'b' => '') вы получите: array('a' => 'a') .

Насколько я знаю, если поле не задано в массиве для массового присвоения, тогда Laravel Eloquent ORM будет рассматривать его как NULL .


Laravel 5

 $input = array_filter(Request::all(), 'strlen'); 

или

 // If you inject the request. $input = array_filter($request->all(), 'strlen'); 

Вероятно, более общее решение:

 class EloquentBaseModel extends Eloquent { public static function boot() { parent::boot(); static::saving(function($model) { if (count($model->forcedNullFields) > 0) { foreach ($model->toArray() as $fieldName => $fieldValue) { if ( empty($fieldValue) && in_array($fieldName,$model->forcedNullFields)) { $model->attributes[$fieldName] = null; } } } return true; }); } } 

Модель, в которой вам нужно очищать пустые поля формы, должна расширять этот класс, тогда вы должны заполнить массив $ fixedNullFields именами полей, которые должны быть NULL в случае пустых полей формы:

 class SomeModel extends EloquentBaseModel { protected $forcedNullFields = ['BirthDate','AnotherNullableField']; } 

И это все, вы не должны повторять один и тот же код в мутаторах.

Для ввода формы это нормально и логичнее иметь пустые значения, а не нулевые значения.

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

 $input = Input::all(); foreach ($input as &$value) { if (empty($value) { $value = null; } } $new = new Contact(Input::all()); $new->save(); 

Лично я не одобряю подобные решения, но это работает для некоторых людей.

В своей модели Eloquent убедитесь, что $guarded пуст. Вам не нужно устанавливать $fillable .

Массовое назначение обычно не является хорошей идеей, но в некоторых сценариях это нормально, вы должны определить, когда.

См .: http://laravel.com/docs/eloquent#mass-assignment